How to delegate all AI work to the agent chat. Use when delegating AI work from UI or scripts to the agent, when a user asks for agent behavior or LLM-powered features, when tempted to add inline LLM calls, or when sending messages to the agent from application code.
65
80%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
The app's default AI surface is the agent chat. Any user-facing work that asks
the model to research, analyze, generate, recommend, synthesize, or reason over
multiple steps must start or continue in the AgentSidebar so users can see,
steer, and audit the work. UI buttons use sendToAgentChat() with
openSidebar: true, and follow-up or revision text belongs in that same thread
instead of a second app-local textbox.
Actions are tools, not alternate AI runtimes. Keep them deterministic and
focused: provider reads, validation, deterministic transforms, CRUD, and
persistence are good action work. Let the agent orchestrate several such tools
when the workflow is AI-shaped or user-steerable. Server-side one-shot model
calls are a rare escape hatch for narrow text transforms only; use
completeText() from @agent-native/core/server only when the work
intentionally does not need tools, chat history, run state, side effects, or
user steering.
The agent is the single AI interface. It has context about the full project, can read/write any file, and can run scripts. Inline LLM calls bypass this — they create a shadow AI that doesn't know what the agent knows and can't coordinate with it.
From the UI (client):
import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
sendToAgentChat({
message: "Generate a summary of this document",
context: documentContent, // optional hidden context (not shown in chat UI)
submit: true, // auto-submit to the agent
openSidebar: true,
});Treat the visible message as the user's request or the shortest clear
description of an app-initiated operation. Put context the user did not type —
IDs, URLs, filenames, current selection or screen state, serialized records,
upload instructions, and bounded source excerpts — in the context field.
context is model input carried through the agent turn; it is stripped from
the rendered user message, so do not concatenate it into message with labels,
blank-line sections, or <context> tags yourself.
Use the related surface for each kind of supporting input:
| Surface | Use for |
|---|---|
message | User-authored intent or a concise app action description |
context | Derived metadata and bounded text needed to carry out that intent |
setAgentChatContextItem | Context staged for a later user-submitted prompt; keep it keyed so updates replace stale context |
images, referenceImagePaths, attachments | Binary or visual inputs; describe only the handling instructions in context |
If an app builds a prompt from a form, selection, upload, or editor state, keep
the visible message short and pass the assembled details as context. Preserve
the user's actual freeform text in message when it is the request; do not
restate it as metadata in context unless the agent needs a structured copy.
This boundary applies to auto-submitted turns and prefills. A hidden context field is not a license to send unbounded records or secrets: cap excerpts, prefer stable IDs and URLs, and use an action or resource lookup for full data.
From the UI, in the background:
import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
sendToAgentChat({
message: "Analyze this import and create any missing records",
context: `Import batch id: ${batchId}`,
submit: true,
newTab: true,
background: true,
openSidebar: false,
});This is still a full agent run: tools, actions, thread state, and run tracking all remain active. It simply does not focus or open the sidebar.
Use this silent form only for explicitly background or system-initiated work. It is not the default for a user clicking an AI-labeled button; visible work should open the sidebar so the user can follow and redirect the run.
From scripts (Node):
import { agentChat } from "@agent-native/core";
agentChat.submit("Process the uploaded images and create thumbnails");For narrow server-side text transforms:
import { completeText } from "@agent-native/core/server";
const result = await completeText({
systemPrompt: "Return exactly one sentiment label.",
input: messageBody,
maxOutputTokens: 12,
temperature: 0,
});If the narrow exception is exposed to the UI, wrap it in an action so the UI and agent share the same operation. Keep it clearly non-conversational and do not call provider SDKs directly.
From the UI, detecting when agent is done:
import { useAgentChatGenerating } from "@agent-native/core/client/agent-chat";
function MyComponent() {
const isGenerating = useAgentChatGenerating();
// Show loading state while agent is working
}submit vs PrefillThe submit option controls whether the message is sent automatically or placed in the chat input for user review:
submit value | Behavior | Use when |
|---|---|---|
true | Auto-submits to the agent immediately | Routine operations with clear intent; keep openSidebar: true for visible work |
false | Prefills the AgentSidebar composer | Review, edit, or add detail before the run; use the existing sidebar thread |
| omitted | Uses the project's default setting | General-purpose delegation |
// Auto-submit: routine operation
sendToAgentChat({ message: "Update the project summary", submit: true });
// Prefill: let user review before sending
sendToAgentChat({
message: "Delete all projects older than 30 days",
submit: false,
openSidebar: true,
});The AgentSidebar composer is the default prompt surface. When a button needs the user to describe what to create, prefill that same composer and let the user edit or complete it:
<Button
onClick={() =>
sendToAgentChat({
message: "Help me create a research report from this brief:",
context: researchBrief,
submit: false,
openSidebar: true,
})
}
>
Start in agent
</Button>Never auto-submit a generic creative prompt when the user has not said what they want. Auto-submit without additional input is fine when intent is unambiguous:
Use a Popover only for compact, structured parameters the UI must validate, such as a date range, target, or approval choice. Do not add a second freeform prompt or follow-up textbox for an AI workflow; keep the conversation and revisions in the AgentSidebar thread.
sendToAgentChat() delegates from app code to the agent. The other axis of
delegation is the agent handing work to a sub-agent through the Agent Teams
run-manager. The main chat stays the orchestrator: it spawns sub-agents, then
reads and integrates their results.
Every sub-agent brief must specify four things, or the sub-agent will guess:
Background sub-agents must use the core run-manager / Agent Teams infrastructure rather than ad-hoc LLM calls.
import Anthropic from "@anthropic-ai/sdk" in client or server codeimport OpenAI from "openai" in client or server codegenerateText(), streamText(), etc.completeText() for workflows that need tools, database writes,
auditability, user steering, or multi-step reasoning. Use the agent chat
instead, optionally with background: true.Scripts may call external APIs (image generation, search, etc.) — but the AI reasoning and orchestration still goes through the agent. A script is a tool the agent uses, not a replacement for the agent.
completeText() is allowed for small server-side transforms such as
classification, extraction, rewriting a short string, or normalizing messy
provider text. It deliberately runs with tools: [] and does not create chat
thread state.
sendToAgentChat() delegates work to the local agent — the one running alongside your app. When the work should go to a different agent entirely (e.g., asking an analytics agent for data, or a calendar agent for availability), use the A2A (agent-to-agent) protocol instead.
import { callAgent } from "@agent-native/core/a2a";
// Call a different agent — not the local agent chat
const stats = await callAgent(
"https://analytics.example.com",
"What were last week's signups?",
{ apiKey: process.env.ANALYTICS_A2A_KEY },
);See the a2a-protocol skill for the full pattern.
pnpm action <name> to perform complex operationscc2a915
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.