@agent-native/core 0.63.0 → 0.63.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/cli/code-agent-executor.js +1 -1
  2. package/dist/cli/code-agent-executor.js.map +1 -1
  3. package/dist/cli/create.js +1 -1
  4. package/dist/cli/create.js.map +1 -1
  5. package/dist/client/NewWorkspaceAppFlow.js +1 -1
  6. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  7. package/dist/client/chat/index.d.ts +2 -1
  8. package/dist/client/chat/index.d.ts.map +1 -1
  9. package/dist/client/chat/index.js +2 -1
  10. package/dist/client/chat/index.js.map +1 -1
  11. package/dist/client/chat-view-transition.d.ts +17 -0
  12. package/dist/client/chat-view-transition.d.ts.map +1 -1
  13. package/dist/client/chat-view-transition.js +46 -0
  14. package/dist/client/chat-view-transition.js.map +1 -1
  15. package/dist/client/index.d.ts +2 -1
  16. package/dist/client/index.d.ts.map +1 -1
  17. package/dist/client/index.js +2 -1
  18. package/dist/client/index.js.map +1 -1
  19. package/dist/client/use-agent-chat-home-handoff.d.ts +27 -0
  20. package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -0
  21. package/dist/client/use-agent-chat-home-handoff.js +120 -0
  22. package/dist/client/use-agent-chat-home-handoff.js.map +1 -0
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/styles/agent-native.css +2 -6
  28. package/dist/templates/workspace-root/README.md +4 -4
  29. package/docs/content/actions.md +32 -42
  30. package/docs/content/agent-surfaces.md +105 -84
  31. package/docs/content/agent-teams.md +2 -14
  32. package/docs/content/agent-web-surfaces.md +4 -4
  33. package/docs/content/authentication.md +40 -24
  34. package/docs/content/automations.md +18 -36
  35. package/docs/content/blueprint-installer.md +3 -0
  36. package/docs/content/cli-adapters.md +24 -168
  37. package/docs/content/client.md +11 -77
  38. package/docs/content/cloneable-saas.md +1 -1
  39. package/docs/content/code-agents-ui.md +43 -0
  40. package/docs/content/components.md +10 -23
  41. package/docs/content/context-awareness.md +3 -3
  42. package/docs/content/creating-templates.md +20 -18
  43. package/docs/content/database.md +1 -1
  44. package/docs/content/deployment.md +5 -37
  45. package/docs/content/dispatch.md +17 -28
  46. package/docs/content/drop-in-agent.md +24 -111
  47. package/docs/content/durable-resume.md +4 -0
  48. package/docs/content/embedding-sdk.md +141 -135
  49. package/docs/content/evals.md +3 -3
  50. package/docs/content/extensions.md +1 -1
  51. package/docs/content/external-agents.md +34 -60
  52. package/docs/content/faq.md +5 -5
  53. package/docs/content/frames.md +13 -4
  54. package/docs/content/getting-started.md +96 -142
  55. package/docs/content/harness-agents.md +24 -7
  56. package/docs/content/human-approval.md +1 -1
  57. package/docs/content/key-concepts.md +14 -99
  58. package/docs/content/local-file-mode.md +2 -2
  59. package/docs/content/mcp-apps.md +9 -2
  60. package/docs/content/mcp-clients.md +8 -3
  61. package/docs/content/mcp-protocol.md +11 -29
  62. package/docs/content/messaging.md +1 -1
  63. package/docs/content/migration-workbench.md +14 -175
  64. package/docs/content/multi-app-workspace.md +1 -1
  65. package/docs/content/multi-tenancy.md +18 -47
  66. package/docs/content/native-chat-ui.md +15 -12
  67. package/docs/content/observability.md +16 -4
  68. package/docs/content/observational-memory.md +1 -1
  69. package/docs/content/pure-agent-apps.md +17 -124
  70. package/docs/content/real-time-collaboration.md +14 -14
  71. package/docs/content/routing.md +71 -0
  72. package/docs/content/sandbox-adapters.md +78 -4
  73. package/docs/content/security.md +59 -39
  74. package/docs/content/server.md +16 -8
  75. package/docs/content/sharing.md +1 -6
  76. package/docs/content/skills-guide.md +3 -1
  77. package/docs/content/template-analytics.md +1 -1
  78. package/docs/content/template-assets.md +12 -3
  79. package/docs/content/template-brain.md +64 -72
  80. package/docs/content/template-chat.md +32 -4
  81. package/docs/content/template-clips.md +35 -4
  82. package/docs/content/template-design.md +19 -3
  83. package/docs/content/template-dispatch.md +9 -0
  84. package/docs/content/template-forms.md +15 -10
  85. package/docs/content/template-plan.md +7 -0
  86. package/docs/content/template-slides.md +14 -14
  87. package/docs/content/template-videos.md +10 -12
  88. package/docs/content/tracking.md +66 -55
  89. package/docs/content/using-your-agent.md +6 -16
  90. package/docs/content/what-is-agent-native.md +5 -11
  91. package/docs/content/workspace-management.md +2 -2
  92. package/docs/content/workspace.md +20 -160
  93. package/package.json +1 -1
  94. package/src/templates/workspace-root/README.md +4 -4
@@ -282,36 +282,38 @@ Custom routes that touch ownable data must call `getSession(event)` and wrap dat
282
282
 
283
283
  ## Write Agent Instructions {#write-agents-md}
284
284
 
285
- `AGENTS.md` is the agent's map of your app. Keep it specific and operational:
285
+ `AGENTS.md` is the agent's map of your app a small, skimmable file with a
286
+ purpose line, core rules, application-state keys, an action table, and a skills
287
+ index:
286
288
 
287
289
  ```markdown
288
290
  # My Template
289
291
 
290
- ## Product Model
292
+ One workspace for projects, tasks, and notes.
291
293
 
292
- Projects are the top-level resource. They contain tasks and notes.
294
+ ## Core Rules
293
295
 
294
- ## Navigation State
296
+ - Data lives in SQL via Drizzle. Use actions for all writes; schema is additive.
297
+ - Use `view-screen` before acting on "this project" if the screen is unclear.
295
298
 
296
- - `navigation.view`: `home` or `project`
297
- - `navigation.projectId`: selected project when on a project page
299
+ ## Application State
298
300
 
299
- ## Actions
300
-
301
- | Action | Purpose |
302
- | ---------------- | --------------------------- |
303
- | `list-projects` | List accessible projects |
304
- | `create-project` | Create a project |
305
- | `update-project` | Rename or archive a project |
301
+ - `navigation.view`: `home` | `project`
302
+ - `navigation.projectId`: selected project on a project page
306
303
 
307
- ## Rules
304
+ ## Actions
308
305
 
309
- - Use `view-screen` before acting on "this project" if the current screen is unclear.
310
- - Use actions for project changes; do not write raw SQL except for one-off maintenance/debugging when no action exists.
311
- - For shared projects, check access through framework sharing helpers.
306
+ | Action | Purpose |
307
+ | ---------------- | ------------------------ |
308
+ | `list-projects` | List accessible projects |
309
+ | `create-project` | Create a project |
312
310
  ```
313
311
 
314
- Update `AGENTS.md` whenever you add a new action, route, state key, or recurring workflow. See [Writing Agent Instructions](/docs/writing-agent-instructions) for how to keep `AGENTS.md` skimmable and word skill and tool descriptions so the agent triggers them reliably.
312
+ Update `AGENTS.md` whenever you add a new action, route, state key, or recurring
313
+ workflow. [Writing Agent Instructions](/docs/writing-agent-instructions) is the
314
+ full guide — how to keep `AGENTS.md` skimmable, what belongs in each of the four
315
+ guidance surfaces, and how to word skill and tool descriptions so the agent
316
+ triggers them reliably.
315
317
 
316
318
  ## Add Skills {#skills}
317
319
 
@@ -36,7 +36,7 @@ The framework auto-detects the dialect from the URL and configures Drizzle accor
36
36
 
37
37
  ## Builder.io Managed Database {#builder-managed}
38
38
 
39
- When connected to Builder.io, your app can use a managed database provisioned automatically no connection strings required. Coming soon.
39
+ _Planned (not yet available):_ when connected to Builder.io, your app will be able to use a managed database provisioned automatically, with no connection strings required.
40
40
 
41
41
  ## Where the DB Client Lives {#db-client}
42
42
 
@@ -215,10 +215,10 @@ export default defineConfig({
215
215
  | `PORT` | Server port (Node.js only) |
216
216
  | `NITRO_PRESET` | Override build preset at build time |
217
217
  | `APP_BASE_PATH` | Mount the app under a prefix (e.g. `/mail`). Set automatically by `npx @agent-native/core@latest deploy`; leave unset for standalone. |
218
- | `DATABASE_URL` | Persistent SQL connection string. Required in production. See [Database](/docs/database#production) for adapter and dialect details. |
219
- | `DATABASE_AUTH_TOKEN` | Auth token for providers that require a separate token, such as Turso/libSQL. |
220
218
  | `AGENT_PROD_CODE_EXECUTION` | Optional production code-execution mode: `off` (default), `sandboxed`, or `trusted`. See [Production Code Execution](#production-code-execution). |
221
219
 
220
+ Database connection variables (`DATABASE_URL`, `DATABASE_AUTH_TOKEN`, per-app `<APP_NAME>_DATABASE_URL`) live in [Database](/docs/database#production).
221
+
222
222
  ### Required in Production {#env-required-prod}
223
223
 
224
224
  These must be set before promoting an app to a real prod deploy. Missing values either fail-closed (the framework refuses to start / refuses to handle requests) or fall back to weaker behavior with a loud warning.
@@ -234,47 +234,15 @@ These must be set before promoting an app to a real prod deploy. Missing values
234
234
 
235
235
  ### Auth & Identity {#env-auth}
236
236
 
237
- | Variable | Description |
238
- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
239
- | `ACCESS_TOKEN` | Static bearer fallback for MCP/connect clients that cannot use OAuth. Does not enable browser auth or make the app private. |
240
- | `ACCESS_TOKENS` | Comma-separated static bearer fallbacks for MCP/connect clients. Does not enable browser auth or make the app private. |
241
- | `AUTH_SKIP_EMAIL_VERIFICATION` | Skip email verification for QA accounts. Local dev/test skips by default; hosted deploys must set this explicitly. **Disables a real security control** — only use on hosted QA environments. |
242
- | `GOOGLE_CLIENT_ID` | Google OAuth client ID. Auto-enables "Sign in with Google" in Better Auth. |
243
- | `GOOGLE_CLIENT_SECRET` | Google OAuth client secret. |
244
- | `GITHUB_CLIENT_ID` | GitHub OAuth client ID. |
245
- | `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret. |
237
+ OAuth provider credentials (Google, GitHub), static MCP bearer fallbacks (`ACCESS_TOKEN` / `ACCESS_TOKENS`), and email-verification toggles are documented in [Authentication](/docs/authentication). Set them there per the auth mode you choose.
246
238
 
247
239
  ### Inbound Webhooks {#env-webhooks}
248
240
 
249
- Inbound webhook handlers refuse forged requests when their signing secret is missing in production (was previously fail-open with a warningsee CHANGELOG / [security audit fixes](#security-config)).
250
-
251
- | Variable | Required when |
252
- | ------------------------------- | -------------------------------------------------------------------------------------------------------------- |
253
- | `EMAIL_INBOUND_WEBHOOK_SECRET` | Inbound email integration is enabled. Verifies Resend / SendGrid / Svix signatures. |
254
- | `TELEGRAM_WEBHOOK_SECRET` | Telegram bot integration is enabled. |
255
- | `WHATSAPP_APP_SECRET` | WhatsApp Business integration is enabled. |
256
- | `WHATSAPP_VERIFY_TOKEN` | WhatsApp webhook verification handshake (set in your Meta app dashboard too). |
257
- | `SLACK_SIGNING_SECRET` | Slack integration is enabled. Verifies Slack request signatures. |
258
- | `GOOGLE_DOCS_PUSH_AUDIENCE` | Google Docs Pub/Sub push integration is enabled. Set to the public URL of your push endpoint. |
259
- | `GOOGLE_DOCS_PUSH_SIGNER_EMAIL` | Google Docs Pub/Sub push integration is enabled. Set to the Pub/Sub service account email. |
260
- | `GMAIL_WATCH_TOPIC` | Gmail Pub/Sub push (mail template). Optional — disables push if unset and falls back to history-delta polling. |
261
- | `GMAIL_PUSH_AUDIENCE` | Gmail Pub/Sub push audience. |
262
- | `GMAIL_PUSH_SIGNER_EMAIL` | Gmail Pub/Sub push signer email. |
263
-
264
- For local development of any of these integrations, set `AGENT_NATIVE_ALLOW_UNVERIFIED_WEBHOOKS=1` to opt back into the old "warn and accept" behavior — never set this in prod.
241
+ Each messaging integration requires its own signing secret in production (handlers fail-closed on forged requests when the secret is missing). The per-integration variables are listed in [Messaging](/docs/messaging) and [Security](/docs/security). For local development only, `AGENT_NATIVE_ALLOW_UNVERIFIED_WEBHOOKS=1` opts back into "warn and accept" never set it in prod.
265
242
 
266
243
  ### Security Configuration (Opt-in) {#security-config}
267
244
 
268
- Defaults are strict; these flags relax behavior. Don't set them unless you specifically want the relaxed path.
269
-
270
- | Variable | Effect |
271
- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
272
- | `AGENT_NATIVE_DEBUG_ERRORS` | `=1` to include stack traces in 500 JSON responses. Useful on previews; do **not** set in real prod (was previously gated by `NODE_ENV !== "production"`, which leaked stacks on misconfigured deploys). |
273
- | `AGENT_NATIVE_ALLOW_UNVERIFIED_WEBHOOKS` | `=1` to accept webhooks without their signing secret (local dev only). Defaults to fail-closed in production. |
274
- | `AGENT_NATIVE_KEYS_WORKSPACE_FALLBACK` | `=1` to let `${keys.NAME}` resolution in tools/automations fall through user-scope → workspace-scope. Default off (user-scope only) — a malicious org member could otherwise plant a workspace `OPENAI_API_KEY` and harvest other members' requests. Turn on only if your org genuinely shares workspace-wide keys. |
275
- | `AGENT_NATIVE_MCP_HUB_MULTI_ORG` | `=1` to allow `AGENT_NATIVE_MCP_HUB_TOKEN` to serve multiple orgs from a single hub deployment. Default refuses to serve when more than one org exists in a hub deploy. Only relevant if you operate the workspace MCP hub. |
276
- | `AGENT_NATIVE_ALLOW_ENV_VAR_WRITES` | `=1` to let runtime code mutate `process.env` from the env-var write API. Off by default — required to be explicitly enabled outside dev SQLite. |
277
- | `AUTH_SKIP_EMAIL_VERIFICATION` | `=1` to skip email verification for password signups. Local dev/test skips by default; hosted deploys should use this only for QA — see Auth section above. |
245
+ Defaults are strict. A handful of opt-in flags relax behavior (debug stack traces, unverified webhooks, workspace-scoped key fallback, the MCP hub multi-org switch, runtime env-var writes). They are documented with their security trade-offs in [Security](/docs/security). Don't set them unless you specifically want the relaxed path.
278
246
 
279
247
  ### Workspace .env Inheritance {#env-inheritance}
280
248
 
@@ -25,46 +25,35 @@ If you're running a single template standalone, you don't need Dispatch — each
25
25
 
26
26
  ## What Dispatch does {#what-it-does}
27
27
 
28
- Six capabilities, all sitting on top of the same workspace database the other apps use.
28
+ Seven capabilities, all sitting on top of the same workspace database the other apps use:
29
29
 
30
- ### Central inbox
30
+ | Capability | What it gives you | Set it up |
31
+ | ------------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------- |
32
+ | **Central inbox** | Slack, email, Telegram, WhatsApp all reach one agent with shared memory + tools | **Settings → Messaging** ([Messaging](/docs/messaging)) |
33
+ | **Secret vault** | Store each credential once; rotate in one place across every app | **Vault** + access mode (all-apps or manual) |
34
+ | **Cross-app delegation** | Routes a request to the right specialist app over A2A and replies in-thread | Automatic ([A2A](/docs/a2a-protocol)) |
35
+ | **Unified MCP gateway** | One MCP connector for external agents reaches every granted workspace app | [External Agents](/docs/external-agents) |
36
+ | **Workspace resources** | Author skills/instructions/profiles once; apps inherit them at runtime | **Resources** ([Workspace](/docs/workspace#global-resources)) |
37
+ | **Dreams** | Reviews past runs/feedback and proposes durable improvements for you to approve | **Dreams** tab |
38
+ | **Approval flow** | Gate sensitive runtime changes behind inline admin review | **dispatch approval policy** |
31
39
 
32
- Slack, email, Telegram, and WhatsApp all flow into Dispatch's agent loop. Connect each platform once in **Settings → Messaging** and every channel reaches the same agent with the same memory and tools. A Slack DM and an email to `agent@yourcompany.com` end up as two surfaces on one conversation history, not two disconnected bots.
40
+ Each is detailed below.
33
41
 
34
- See [Messaging](/docs/messaging) for the credentials and webhook URLs for each platform.
42
+ ### Central inbox
35
43
 
36
- ### Secret vault
44
+ Slack, email, Telegram, and WhatsApp all flow into Dispatch's agent loop. Connect each platform once in **Settings → Messaging** and every channel reaches the same agent with the same memory and tools. A Slack DM and an email to `agent@yourcompany.com` end up as two surfaces on one conversation history, not two disconnected bots. See [Messaging](/docs/messaging) for the credentials and webhook URLs.
37
45
 
38
- Store credentials once in Dispatch's vault. By default, vault access is **all apps**: every saved key is available to every workspace app, and `sync-vault-to-app` pushes the full vault to the target app. Workspaces that need stricter separation can switch the vault to **manual** mode, where explicit per-app grants are required before sync. Non-admins can **request** a secret for an app; admins **approve**, which creates the secret and, in manual workflows, the grant. Every read, grant, sync, and rotation is captured in an audit log.
46
+ ### Secret vault
39
47
 
40
- This is what makes "rotate the OpenAI key" a one-click operation across ten apps instead of ten PRs.
48
+ Store credentials once in Dispatch's vault. By default, vault access is **all apps**: every saved key is available to every workspace app, and `sync-vault-to-app` pushes the full vault to the target app. Workspaces that need stricter separation can switch the vault to **manual** mode, where explicit per-app grants are required before sync. Non-admins can **request** a secret for an app; admins **approve**, which creates the secret and, in manual workflows, the grant. Every read, grant, sync, and rotation is captured in an audit log. This is what makes "rotate the OpenAI key" a one-click operation across ten apps instead of ten PRs.
41
49
 
42
50
  ### Cross-app delegation
43
51
 
44
- Dispatch auto-discovers the other apps in your workspace as A2A peers — no manual registration, no per-app config. When a user asks "summarize last week's signups" in Slack, Dispatch recognizes that as an analytics request and calls the analytics app over [A2A](/docs/a2a-protocol). When they ask "draft a reply to Alice", it routes to the mail app. Dispatch posts the final answer back in the originating thread.
45
-
46
- The behavioral rule lives in the dispatch agent's instructions: domain work belongs to the domain app. Dispatch is the orchestrator, not the specialist.
52
+ Dispatch auto-discovers the other apps in your workspace as A2A peers — no manual registration, no per-app config. When a user asks "summarize last week's signups" in Slack, Dispatch recognizes that as an analytics request and calls the analytics app over [A2A](/docs/a2a-protocol). When they ask "draft a reply to Alice", it routes to the mail app. Dispatch posts the final answer back in the originating thread. The behavioral rule lives in the dispatch agent's instructions: domain work belongs to the domain app. Dispatch is the orchestrator, not the specialist.
47
53
 
48
54
  ### Unified MCP gateway
49
55
 
50
- Dispatch can also be the single MCP connector for external agents. Add
51
- `https://dispatch.agent-native.com/_agent-native/mcp` once in Claude, ChatGPT,
52
- Codex, Cursor, or another MCP host, sign in through the host's OAuth flow, then
53
- manage which apps that gateway can reach from Dispatch's **Agents** page. The
54
- gateway exposes `list_apps`, `ask_app`, and `open_app`, filtered by the
55
- selected app grants, so external agents can route work to Mail, Calendar,
56
- Analytics, Brain, and workspace apps without a separate authorization for every
57
- app.
58
-
59
- When a host supports MCP Apps, that same Dispatch connector can render granted
60
- app routes inline too: email drafts, calendar invites, decks, forms, docs,
61
- designs, dashboards, clips, and other app routes can preview in chat without
62
- adding per-app connectors.
63
-
64
- Direct per-app MCP URLs such as
65
- `https://mail.agent-native.com/_agent-native/mcp` still exist when you
66
- intentionally want one isolated app surface. For most workspace use, the
67
- Dispatch gateway is the lower-friction path.
56
+ Dispatch can be the single MCP connector for external agents: add `https://dispatch.agent-native.com/_agent-native/mcp` once in Claude, ChatGPT, Codex, or Cursor, and one authorization reaches every granted workspace app instead of one connector per app. See [External Agents](/docs/external-agents) for the full connect flow, app grants, OAuth, and inline MCP App previews.
68
57
 
69
58
  ### Workspace resources
70
59
 
@@ -164,117 +164,30 @@ import { useSendToAgentChat } from "@agent-native/core/client";
164
164
  const { send, isGenerating } = useSendToAgentChat();
165
165
  ```
166
166
 
167
- ## Custom chat UI layers {#custom-chat-ui}
168
-
169
- If you do not want `<AgentSidebar>`, choose the lowest layer that still lets the
170
- framework own the agent runtime:
171
-
172
- - **`<AgentChatSurface>`** use this for a dedicated chat route or embedded
173
- panel. It keeps the standard chat/runtime wiring without the sidebar wrapper.
174
- - **`<AssistantChat>`** use this when you want to own surrounding chrome,
175
- tabs, headers, empty states, or composer slots while keeping the standard
176
- conversation renderer and adapter.
177
- - **`@agent-native/core/client/chat`** use this focused subpath when building
178
- a custom surface from pieces: `AssistantChat`, `MultiTabAssistantChat`,
179
- `useChatThreads`, `AgentConversation`, composer exports, and the standard
180
- chat adapters.
181
- - **`@agent-native/core/client/composer`** use this for the chat field itself:
182
- `PromptComposer` for the complete field, or `TiptapComposer` only when you
183
- are already wiring assistant-ui primitives yourself.
184
- - **`@agent-native/core/client/conversation`** use this for transcript
185
- rendering without the full chat runtime.
186
- - **`createAgentChatAdapter()`** — use this only when building a custom
187
- assistant-ui transport for the built-in Agent-Native chat endpoint. It
188
- connects to the same `/_agent-native/agent-chat` stream and preserves
189
- run-manager recovery, attachments, model selection, native widgets, and
190
- thread metadata.
191
- - **`createHttpAgentChatRuntime()`** — use this when a BYO agent exposes a
192
- POST endpoint that streams `AgentChatRuntime` events. Pass the runtime to
193
- `<AssistantChat runtime={runtime} />`.
194
-
195
- Avoid posting directly to `/_agent-native/agent-chat` from product UI. If a
196
- lower-level helper is missing for a real custom surface, add that named helper
197
- first so client code does not learn a second, ad hoc transport.
198
-
199
- For BYO agent runtimes, keep actions and SQL-backed app state as the contract.
200
- Adapt the runtime into `<AssistantChat runtime={...} />` when you want
201
- Agent-Native chat behavior. Use `<AssistantChat createAdapter={...} />` only
202
- for lower-level assistant-ui transports, or `PromptComposer` by itself only
203
- when the external runtime owns the transcript and loop. See
204
- [Native Chat UI](/docs/native-chat-ui#byo-agent-runtimes) and
205
- [Agent Surfaces](/docs/agent-surfaces#byo-agent).
206
-
207
- ### Build your own sidebar from pieces {#build-your-own-sidebar}
208
-
209
- The stock sidebar is optional. This example builds the agent-side UI itself.
210
- Render it inside your own shell, drawer, split pane, or route when you want to
211
- own the layout around the agent runtime:
212
-
213
- ```tsx
214
- import { AssistantChat, useChatThreads } from "@agent-native/core/client/chat";
215
-
216
- function MyAgentSidebar({ projectSlug }: { projectSlug: string }) {
217
- const threads = useChatThreads(undefined, projectSlug);
218
- const threadId = threads.activeThreadId ?? undefined;
219
-
220
- return (
221
- <aside className="grid h-full grid-cols-[220px_1fr]">
222
- <ThreadList
223
- threads={threads.threads}
224
- activeThreadId={threadId}
225
- onSelect={threads.switchThread}
226
- />
227
- <AssistantChat threadId={threadId} />
228
- </aside>
229
- );
230
- }
231
- ```
232
-
233
- If you only need the field for a custom runtime, use the composer subpath:
234
-
235
- ```tsx
236
- import { PromptComposer } from "@agent-native/core/client/composer";
237
-
238
- <PromptComposer
239
- placeholder="Ask the agent..."
240
- onSubmit={async (text, files, references, options) => {
241
- await sendToYourRuntime({ text, files, references, options });
242
- }}
243
- />;
244
- ```
245
-
246
- `TiptapComposer` is also public, but it is intentionally lower-level: render it
247
- inside an assistant-ui thread/composer context. Most app code should use
248
- `PromptComposer` or `AssistantChat`.
249
-
250
- ### Raw text completion escape hatch {#raw-text-completion}
251
-
252
- For narrow server-side transforms that intentionally do not need tools, chat
253
- history, run state, or user steering, use `completeText()` from
254
- `@agent-native/core/server`. Keep it server-only and wrap user-facing usage in
255
- an action so the UI and agent share the same operation.
256
-
257
- ```ts
258
- import { defineAction } from "@agent-native/core/action";
259
- import { completeText } from "@agent-native/core/server";
260
-
261
- export default defineAction({
262
- description: "Classify a message",
263
- run: async ({ body }: { body: string }) => {
264
- const result = await completeText({
265
- systemPrompt: "Return exactly one label.",
266
- input: body,
267
- maxOutputTokens: 12,
268
- temperature: 0,
269
- });
270
- return { label: result.text.trim() };
271
- },
272
- });
273
- ```
274
-
275
- If the work needs actions, files, database writes, auditability, or multi-step
276
- reasoning, use `sendToAgentChat()` instead, optionally with `background: true`
277
- and `openSidebar: false`.
167
+ ## When the stock sidebar isn't the fit {#custom-chat-ui}
168
+
169
+ `<AgentSidebar>` and `<AgentPanel>` cover most apps. When you need to own the
170
+ layout around the agent, or you want to power the conversation with an agent
171
+ you built elsewhere, drop down a layer — but keep letting the framework own the
172
+ runtime, actions, and SQL-backed state:
173
+
174
+ - **Own the chrome around the standard runtime.** Use `<AgentChatSurface>` for
175
+ a dedicated chat route, or `<AssistantChat>` when you want custom headers,
176
+ tabs, and empty states around the standard conversation. The full layer map —
177
+ every component, hook, composer, and adapter, with import paths — lives in
178
+ [Component API](/docs/components#agent-chat-ui).
179
+ - **Bring your own agent runtime.** If an agent you built elsewhere should
180
+ power the conversation while Agent-Native keeps the composer, transcript, tool
181
+ cards, approvals, and native widgets, pass an `AgentChatRuntime` to
182
+ `<AssistantChat runtime={...} />`. The connectors
183
+ (`createHttpAgentChatRuntime()` and the OpenAI / Claude / Vercel AI / AG-UI
184
+ helpers) and the event contract are documented in
185
+ [Native Chat UI BYO agent runtimes](/docs/native-chat-ui#byo-agent-runtimes).
186
+
187
+ Whichever layer you pick, keep actions and SQL-backed app state as the contract,
188
+ and avoid posting directly to `/_agent-native/agent-chat` from product UI. If a
189
+ named helper is missing for a real custom surface, add that helper first so
190
+ client code does not learn a second, ad hoc transport.
278
191
 
279
192
  ## Typesafe actions from the UI: `useActionMutation()` {#use-action-mutation}
280
193
 
@@ -5,6 +5,10 @@ description: "When a hosted agent run is interrupted and resumes, completed side
5
5
 
6
6
  # Durable Resume
7
7
 
8
+ > **Who is this for:** anyone who wants to understand how the framework's run
9
+ > recovery avoids duplicate side effects. This is built-in behavior — there is
10
+ > nothing to wire up.
11
+
8
12
  Hosted agent runs get interrupted: a serverless function hits its hard timeout mid-stream, a gateway drops the connection at 45s, a socket hangs up, the platform cold-starts. The framework already recovers from these by saving the conversation prefix and re-running the LLM call ("continue from where you left off"). But recovery alone has a sharp edge: if the interrupted attempt **already sent an email or created a ticket**, a naive resume could do it again.
9
13
 
10
14
  Durable resume closes that gap. On resume, the framework knows which side-effecting tool calls already completed and refuses to re-run them — at two layers.