@agent-native/core 0.210.0-nightly-20261019153056 → 0.210.0

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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent/action-error-details.d.ts +26 -0
  3. package/dist/agent/action-error-details.js +99 -0
  4. package/dist/agent/execution-fence.d.ts +9 -2
  5. package/dist/agent/execution-fence.js +42 -12
  6. package/dist/agent/production-agent.js +9 -0
  7. package/dist/agent/run-manager.js +14 -14
  8. package/dist/agent/run-store.js +8 -6
  9. package/dist/agent/tool-error-redaction.d.ts +8 -1
  10. package/dist/agent/tool-error-redaction.js +70 -7
  11. package/dist/collab/awareness.d.ts +2 -2
  12. package/dist/collab/routes.d.ts +1 -1
  13. package/dist/collab/struct-routes.d.ts +1 -1
  14. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  15. package/dist/mcp/actions/create-org-service-token.js +6 -3
  16. package/dist/mcp/actions/set-service-principal-lifecycle.js +1 -0
  17. package/dist/mcp/actions/set-service-principal-policy.js +1 -0
  18. package/dist/mcp/direct-action-call.js +39 -10
  19. package/dist/notifications/routes.d.ts +3 -3
  20. package/dist/observability/routes.d.ts +3 -3
  21. package/dist/onboarding/workspace-services.js +1 -1
  22. package/dist/progress/routes.d.ts +1 -1
  23. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  24. package/dist/secrets/routes.d.ts +6 -6
  25. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  26. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  27. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  28. package/dist/templates/chat/.agents/skills/actions/SKILL.md +2 -2
  29. package/dist/templates/chat/netlify.toml +0 -1
  30. package/dist/templates/default/.agents/skills/actions/SKILL.md +2 -2
  31. package/dist/templates/factory/.agents/skills/review-prs/SKILL.md +44 -21
  32. package/dist/templates/headless/.agents/skills/actions/SKILL.md +2 -2
  33. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +2 -2
  34. package/docs/content/actions-defining.mdx +2 -2
  35. package/docs/content/template-chat-agent.mdx +88 -0
  36. package/docs/content/template-chat-developers.mdx +586 -104
  37. package/docs/content/template-chat-features.mdx +158 -0
  38. package/docs/content/template-chat-integrations.mdx +66 -0
  39. package/docs/content/template-chat.mdx +36 -166
  40. package/docs/content/template-clips-developers.mdx +1 -1
  41. package/docs/content/template-clips-integrations.mdx +50 -5
  42. package/package.json +4 -4
  43. package/src/templates/chat/.agents/skills/actions/SKILL.md +2 -2
  44. package/src/templates/chat/netlify.toml +0 -1
  45. package/src/templates/default/.agents/skills/actions/SKILL.md +2 -2
  46. package/src/templates/factory/.agents/skills/review-prs/SKILL.md +44 -21
  47. package/src/templates/headless/.agents/skills/actions/SKILL.md +2 -2
  48. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +2 -2
  49. package/docs/content/template-chat-first-edits.mdx +0 -158
@@ -3,8 +3,9 @@ name: review-prs
3
3
  description: >-
4
4
  Review recent BuilderIO/agent-native human pull requests, approve eligible
5
5
  internal PRs, and merge changes that are ready by Steve's bar. Use for
6
- scheduled or manual PR sweeps; flag external non-bug work and unresolved major
7
- product or UX decisions to Steve.
6
+ scheduled or manual PR sweeps; flag external work needing a major product
7
+ call or new framework API, and unresolved major product or UX decisions, to
8
+ Steve.
8
9
  user-invocable: true
9
10
  scope: dev
10
11
  metadata:
@@ -20,10 +21,12 @@ approve an external or unverified author.
20
21
 
21
22
  Approval and merge readiness are separate. A **Ready to merge by Steve's bar**
22
23
  result means merge the PR under the guarded merge procedure below. For a
23
- confirmed external author, only a clear bug fix enters evidence review and the
24
- possible merge flow; external authors are never eligible for an approval
25
- review. Surface other external work for Steve's explicit approval before a full
26
- review or merge; a scheduled or manual sweep is not that approval.
24
+ confirmed external author, a clear bug fix or a bounded improvement that
25
+ follows existing patterns enters evidence review and the possible merge flow;
26
+ external authors are never eligible for an approval review. Surface external
27
+ work that needs a major product call or a new framework API for Steve's explicit
28
+ approval before a full review or merge; a scheduled or manual sweep is not that
29
+ approval.
27
30
 
28
31
  ## Selection and evidence
29
32
 
@@ -53,6 +56,11 @@ author and draft state:
53
56
  summary to determine whether the PR already has a current, non-dismissed
54
57
  `APPROVED` review.
55
58
 
59
+ - Before the scope gate, check a confirmed nonmember's PR from a fork for
60
+ assignees. If any assignee is a verified current BuilderIO member, ignore
61
+ the PR completely, like a draft: that person owns it under `community-prs`.
62
+ Take no review, reply, or merge action, and leave it out of the recap.
63
+
56
64
  - Reuse that review as the code assessment only after verifying the reviewer
57
65
  is a different, current BuilderIO member and is eligible under the PR's
58
66
  author- and scope-specific rules, including any independent-review
@@ -99,17 +107,28 @@ the patch looks safe or the issue is obviously valid.
99
107
 
100
108
  ## External-contribution scope gate
101
109
 
110
+ Builder devs decide bounded outside contributions; Steve keeps major product
111
+ calls and new framework APIs.
112
+
102
113
  For an author the membership API confirms is not a current BuilderIO member,
103
- continue into the normal evidence sweep only for a clear bug fix: a change that
104
- corrects a specific reported or reproducible defect by restoring intended
105
- behavior. A feature, improvement, refactor, new or changed product behavior, or
106
- mixed bug-fix-and-enhancement scope is not a clear bug fix. If the title, issue,
107
- and initial diff do not establish a clear bug fix, treat it as non-bug work.
108
-
109
- For external non-bug work, stop before the full code review, approval or review
110
- action, merge-readiness disposition, author-facing draft, or merge. Report it to
111
- Steve as **Needs Steve's approval for scope**, with the PR link, author, stated
112
- scope, and why it is not a clear bug fix. Wait for Steve's explicit go-ahead on
114
+ continue into the normal evidence sweep for a clear bug fix or a bounded
115
+ improvement. A clear bug fix corrects a specific reported or reproducible
116
+ defect by restoring intended behavior. A bounded improvement stays within one
117
+ established workflow, app, or framework area and follows the patterns already
118
+ there.
119
+
120
+ External work needs Steve when it makes a major product call (as defined under
121
+ Product and UX decisions) or adds a new framework API: a new public export,
122
+ configuration option, action, plugin or hook contract, or CLI surface in a
123
+ published package under `packages/`. A fix or bounded improvement to an existing
124
+ API stays with devs when it keeps that API's contract. If the title, issue, and
125
+ initial diff do not establish a clear bug fix or a bounded improvement, treat it
126
+ as needing Steve.
127
+
128
+ For external work that needs Steve, stop before the full code review, approval
129
+ or review action, merge-readiness disposition, author-facing draft, or merge.
130
+ Report it to Steve as **Needs Steve's approval for scope**, with the PR link,
131
+ author, stated scope, and which call it needs. Wait for Steve's explicit go-ahead on
113
132
  that PR before continuing. Invoking or scheduling `review-prs`, approving a
114
133
  different PR, or prior approval of another external contribution does not
115
134
  authorize it. If membership is unknown, use the existing unknown-membership
@@ -118,6 +137,8 @@ solely because membership could not be verified. Keep the no-approval outcome,
118
137
  report the missing membership check, and assess merge readiness under the
119
138
  existing unknown-membership policy.
120
139
 
140
+ Builder devs own outside PRs end to end with `community-prs`.
141
+
121
142
  ## Liamdebeasi approval policy
122
143
 
123
144
  For a PR authored by the exact GitHub login `liamdebeasi` and immutable user
@@ -296,9 +317,10 @@ merge scope and must remain completely untouched.
296
317
  For a PR that fails an approval gate, do not submit an approval. Flag the exact
297
318
  concern and the evidence needed to resolve it. External or unverified authors
298
319
  never receive an approval review, but their PRs can still be merged when they
299
- meet the readiness gate below. Confirmed external bug fixes must also pass the
300
- external-contribution scope gate; confirmed external non-bug work remains
301
- stopped at Steve's approval gate. For unknown membership, do not apply the
320
+ meet the readiness gate below. Confirmed external PRs must also pass the
321
+ external-contribution scope gate; external work that needs a major product call
322
+ or a new framework API remains stopped at Steve's approval gate. For unknown
323
+ membership, do not apply the
302
324
  external scope gate solely because verification failed; preserve the
303
325
  no-approval outcome, assess readiness under the existing unknown-membership
304
326
  policy, and name the missing check.
@@ -504,7 +526,8 @@ non-auto-approved external PR that needs an update or screenshot, include its
504
526
  draft reply in a separate section, or mark it waiting on the contributor with
505
527
  a link to Steve's outstanding request. For internal PRs, report the needed
506
528
  update or screenshot without drafting an author-facing reply. Do not add rows
507
- for bots, `steve8708`, or drafts; those are ignored completely.
529
+ for bots, `steve8708`, drafts, or external PRs assigned to a BuilderIO member;
530
+ those are ignored completely.
508
531
 
509
532
  Use this shape:
510
533
 
@@ -525,4 +548,4 @@ blocker when the PR is ready and the guarded admin merge is available.
525
548
 
526
549
  ## Related skills
527
550
 
528
- `concurrent-agents`, `verifying-changes`, `ship`, `babysit-pr`
551
+ `concurrent-agents`, `verifying-changes`, `ship`, `babysit-pr`, `community-prs`
@@ -170,10 +170,10 @@ Everything else — CRUD, settings, search, list/detail reads, auth state, anyth
170
170
  - **Do** keep one action, one job; document a reusable action (when to use it, key args, return fields to preserve) in `AGENTS.md` once it's called from outside one narrow screen; promote workflow-heavy actions (provider-backed, cross-app, MCP/A2A, multi-step) into a skill.
171
171
  - **Do** use `fail(message, { errorCode, statusCode })` for user-friendly errors and import primitives from `@agent-native/core`(`/action`) instead of redefining them; use the core `upload-image` action or `uploadFile()` for durable images/files — never base64 into SQL, markdown, or action results.
172
172
  - **Do** signal failure by throwing, using `fail()` for expected caller-readable failures. Never return `{ error: ... }` as a failure result: a normal return is treated as a successful action. Reserve bare errors for unexpected internal faults.
173
- - **Do** use `fail()` rather than a bare `Error` for caller-readable failures. It carries the action's message, `errorCode`, and `details` to the browser; unexpected errors become a generic 500. Reserve bare throws for internal faults.
173
+ - **Do** use `fail()` rather than a bare `Error` for caller-readable failures. It carries the action's message, `errorCode`, and `details` to the browser and to agents; unexpected errors become a generic 500. Reserve bare throws for internal faults.
174
174
  - **Do** give `fail()` the status that matches the cause: it defaults to `400`, and `useActionQuery` retries only `429`, `502`, `503`, and `504`. Mutations do not retry; use transient statuses only for retryable failures.
175
175
  - **Do** render `actionErrorMessage(error) ?? yourCopy` in UI, never bare `error.message`. The message keeps an `Action <name> failed:` prefix that belongs in a console, so a toast built from it reads "Action update-brand-kit failed: That name is taken." The helper returns only what the action wrote, and `undefined` when nothing did (network drop, proxy HTML page), which is why the fallback is not optional.
176
- - **Do** pass a real `errorCode` when the agent should branch on the failure rather than re-read it. Codes other than the default `action_failed` are appended to the tool result as `(errorCode: not_found)`, on both the in-app agent and MCP; `details` and the status never reach either.
176
+ - **Do** pass a real `errorCode` when the agent should branch on the failure rather than re-read it. Codes other than the default `action_failed` are appended to the tool result as `(errorCode: not_found)`, on both the in-app agent and MCP. `details` follow as an `Error details: {...}` JSON line, and as `structuredContent.error` over MCP, capped at 2,000 characters, so keep them to what the agent acts on next: ids, limits, field names. The status never reaches either.
177
177
  - **Don't** re-export actions as REST — `/_agent-native/actions/:name` is already the REST surface; duplicating it under `/api/*` hides the operation from agents.
178
178
  - **Don't** reach for provider integrations, `outputSchema`, `authorize`, `needsApproval`, or `_agentImages` without checking `references/` first — each has sharp edges covered there, not here.
179
179
 
@@ -170,10 +170,10 @@ Everything else — CRUD, settings, search, list/detail reads, auth state, anyth
170
170
  - **Do** keep one action, one job; document a reusable action (when to use it, key args, return fields to preserve) in `AGENTS.md` once it's called from outside one narrow screen; promote workflow-heavy actions (provider-backed, cross-app, MCP/A2A, multi-step) into a skill.
171
171
  - **Do** use `fail(message, { errorCode, statusCode })` for user-friendly errors and import primitives from `@agent-native/core`(`/action`) instead of redefining them; use the core `upload-image` action or `uploadFile()` for durable images/files — never base64 into SQL, markdown, or action results.
172
172
  - **Do** signal failure by throwing, using `fail()` for expected caller-readable failures. Never return `{ error: ... }` as a failure result: a normal return is treated as a successful action. Reserve bare errors for unexpected internal faults.
173
- - **Do** use `fail()` rather than a bare `Error` for caller-readable failures. It carries the action's message, `errorCode`, and `details` to the browser; unexpected errors become a generic 500. Reserve bare throws for internal faults.
173
+ - **Do** use `fail()` rather than a bare `Error` for caller-readable failures. It carries the action's message, `errorCode`, and `details` to the browser and to agents; unexpected errors become a generic 500. Reserve bare throws for internal faults.
174
174
  - **Do** give `fail()` the status that matches the cause: it defaults to `400`, and `useActionQuery` retries only `429`, `502`, `503`, and `504`. Mutations do not retry; use transient statuses only for retryable failures.
175
175
  - **Do** render `actionErrorMessage(error) ?? yourCopy` in UI, never bare `error.message`. The message keeps an `Action <name> failed:` prefix that belongs in a console, so a toast built from it reads "Action update-brand-kit failed: That name is taken." The helper returns only what the action wrote, and `undefined` when nothing did (network drop, proxy HTML page), which is why the fallback is not optional.
176
- - **Do** pass a real `errorCode` when the agent should branch on the failure rather than re-read it. Codes other than the default `action_failed` are appended to the tool result as `(errorCode: not_found)`, on both the in-app agent and MCP; `details` and the status never reach either.
176
+ - **Do** pass a real `errorCode` when the agent should branch on the failure rather than re-read it. Codes other than the default `action_failed` are appended to the tool result as `(errorCode: not_found)`, on both the in-app agent and MCP. `details` follow as an `Error details: {...}` JSON line, and as `structuredContent.error` over MCP, capped at 2,000 characters, so keep them to what the agent acts on next: ids, limits, field names. The status never reaches either.
177
177
  - **Don't** re-export actions as REST — `/_agent-native/actions/:name` is already the REST surface; duplicating it under `/api/*` hides the operation from agents.
178
178
  - **Don't** reach for provider integrations, `outputSchema`, `authorize`, `needsApproval`, or `_agentImages` without checking `references/` first — each has sharp edges covered there, not here.
179
179
 
@@ -1,158 +0,0 @@
1
- ---
2
- title: "Chat: Your First Feature"
3
- description: "The files that render Chat's starter screens, what their real props do, and a full walkthrough of adding a feature end to end."
4
- ---
5
-
6
- # Your First Feature
7
-
8
- This page is for developers extending the [Chat template](/docs/template-chat). It covers the files that render the starter screens, then walks through everything the agent typically touches when you ask for a real feature.
9
-
10
- ## First code to inspect {#first-code}
11
-
12
- - `actions/hello.ts` is the starter behavior the agent can call. Replace it or
13
- add actions beside it.
14
- - `app/components/chat/ChatRouteContent.tsx` renders the full-page chat surface
15
- at `/chat/<threadId>`. Adjust the empty state, composer, or message slots here.
16
- - `app/components/home/HomePage.tsx` is the editable Get started landing page at
17
- `/home`. `/chat` starts a new chat.
18
- - `AGENTS.md` tells the built-in agent how to work inside this app.
19
-
20
- <FileTree
21
- id="doc-block-chat3"
22
- title="Chat template layout"
23
- entries={[
24
- {
25
- path: "actions/hello.ts",
26
- note: "the one example action; replace or add actions beside it",
27
- },
28
- {
29
- path: "actions/view-screen.ts",
30
- note: "standard context action the agent calls first",
31
- },
32
- {
33
- path: "actions/navigate.ts",
34
- note: "standard navigation action",
35
- },
36
- {
37
- path: "app/routes/home.tsx",
38
- note: "/home: the Get started landing page; /chat: starts a new chat",
39
- },
40
- {
41
- path: "app/routes/chat._index.tsx",
42
- note: "/chat: starts a new chat and hands off to /chat/:threadId",
43
- },
44
- {
45
- path: "app/routes/chat.$threadId.tsx",
46
- note: "/chat/:threadId: renders ChatRouteContent for that thread",
47
- },
48
- {
49
- path: "app/components/chat/ChatRouteContent.tsx",
50
- note: "the full-page chat surface; edit the empty state, composer, and message slots",
51
- },
52
- {
53
- path: "app/components/home/HomePage.tsx",
54
- note: "the editable Get started home page",
55
- },
56
- {
57
- path: "app/lib/chat-paths.ts",
58
- note: "Chat path helpers",
59
- },
60
- {
61
- path: "AGENTS.md",
62
- note: "chat-first guidance the built-in agent reads",
63
- },
64
- ]}
65
- />
66
-
67
- The chat surface is assembled from AgentKit pieces: a transport, a thread root, and the chat view. Its copy comes from i18n keys rather than literal strings:
68
-
69
- <AnnotatedCode
70
- id="doc-block-chat4"
71
- title="app/components/chat/ChatRouteContent.tsx (trimmed)"
72
- filename="app/components/chat/ChatRouteContent.tsx"
73
- language="tsx"
74
- code={
75
- 'import { createAgentNativeAgentKitTransport } from "@agent-native/core/client/agentkit-chat/transport";\nimport { useT } from "@agent-native/core/client/i18n";\nimport { AgentKitChat } from "@agent-native/toolkit/app/agentkit/react/components";\nimport { CoreAgentKitRoot } from "@agent-native/toolkit/app/chat/agentkit-chat/index";\nimport { useState } from "react";\nimport { useNavigate, useParams } from "react-router";\n\nimport { chatThreadPath } from "@/lib/chat-paths";\nimport { TAB_ID } from "@/lib/tab-id";\n\nexport default function ChatRouteContent() {\n const { threadId } = useParams();\n const navigate = useNavigate();\n const t = useT();\n const [transport] = useState(() =>\n createAgentNativeAgentKitTransport({\n browserTabId: TAB_ID,\n surface: "app",\n adapter: { textFormat: "markdown" },\n }),\n );\n if (!threadId) return null;\n\n return (\n <CoreAgentKitRoot\n transport={transport}\n threadId={threadId}\n labels={{ composerPlaceholder: t("chat.composerPlaceholder") }}\n slots={{ emptyState: ChatEmptyState }}\n onThreadForked={(thread) => navigate(chatThreadPath(thread.id))}\n >\n <AgentKitChat\n emptyComposerPlacement="center"\n composerProps={{ requireAgentEngine: true, voiceEnabled: true }}\n />\n </CoreAgentKitRoot>\n );\n}\n\nfunction ChatEmptyState() {\n const t = useT();\n return (\n <div className="agentkit-chat-empty-copy">\n <h1>{t("chat.heroTitle")}</h1>\n </div>\n );\n}'
76
- }
77
- annotations={[
78
- {
79
- lines: "15-21",
80
- label: "Transport",
81
- note: "`createAgentNativeAgentKitTransport` connects the chat view to the app's agent runtime. `TAB_ID` (`app/lib/tab-id.ts`, a random id generated once per browser tab) lets the runtime tell open tabs of the same app apart, so a run started in one tab isn't mistaken for one in another.",
82
- },
83
- {
84
- lines: "25-30",
85
- label: "Thread root",
86
- note: "`CoreAgentKitRoot` loads the thread named in `/chat/:threadId` (`chat.$threadId.tsx`). Visiting `/chat` creates a new thread id and hands off here. When a thread is forked, `chatThreadPath` moves the URL to the new thread.",
87
- },
88
- {
89
- lines: "29",
90
- label: "Slots",
91
- note: "Slots replace parts of the chat view. The real file also passes `message`, `runFailure`, `connectionRequest`, and `footer` slots for recovery messages, MCP connection cards, and the agent footer.",
92
- },
93
- {
94
- lines: "32-35",
95
- label: "Centered composer",
96
- note: '`emptyComposerPlacement="center"` centers the composer until the thread has a message. `requireAgentEngine` shows the Connect AI card until a model is connected.',
97
- },
98
- {
99
- lines: "40-47",
100
- label: "Empty state",
101
- note: "The heading above the centered composer. Its copy is `chat.heroTitle` in `app/i18n/en-US.ts`: edit the catalog to change the pitch, or add elements here.",
102
- },
103
- ]}
104
- />
105
-
106
- ## First edits {#first-edits}
107
-
108
- Most first features follow the same shape: a table, one or two actions, a route, a nav entry, and an `AGENTS.md` update. Ask the agent:
109
-
110
- > Add a data model for `notes`. A note has an id, title, body, and owner. Render a notes page at `/notes`, add create/list actions, and keep chat able to create notes.
111
-
112
- Chat ships with no `server/db/schema.ts` at all (see [What ships](/docs/template-chat#what-ships)), so the first change is a new file, following the same `table`/`text`/`ownableColumns` shape every other template uses:
113
-
114
- <Diff
115
- id="doc-block-chat5"
116
- title="A new notes table"
117
- filename="server/db/schema.ts"
118
- language="ts"
119
- before={""}
120
- after={
121
- 'import {\n table,\n text,\n ownableColumns,\n} from "@agent-native/core/db/schema";\n\nexport const notes = table("notes", {\n id: text("id").primaryKey(),\n title: text("title").notNull(),\n body: text("body").notNull(),\n createdAt: text("created_at").notNull(),\n updatedAt: text("updated_at").notNull(),\n ...ownableColumns(),\n});'
122
- }
123
- annotations={[
124
- {
125
- lines: "1-5",
126
- label: "Shared schema helpers",
127
- note: "`table`/`text`/`ownableColumns` come from `@agent-native/core/db/schema`, the PostgreSQL schema helpers every template uses.",
128
- },
129
- {
130
- lines: "13",
131
- label: "ownableColumns",
132
- note: "`...ownableColumns()` adds the owner/org columns the framework's `accessFilter`/`resolveAccess` helpers expect, so notes slot into the standard per-user/per-org sharing model with no extra plumbing.",
133
- },
134
- ]}
135
- />
136
-
137
- The rest of the feature follows from there:
138
-
139
- - `actions/create-note.ts` — a `defineAction` with a Zod schema (`title`, `body`), shaped like `actions/hello.ts`.
140
- - `actions/list-notes.ts` — a read-only action (`readOnly: true`, like `actions/view-screen.ts`) that queries the new table through `accessFilter`.
141
- - `app/routes/notes.tsx` — a new route; the app uses file-system routing (`flatRoutes()` in `app/routes.ts`), so adding the file is enough to mount `/notes`.
142
- - A link in `app/components/layout/Sidebar.tsx`, added before `ChatThreadsSection` and pointing at `/notes`.
143
- - An `AGENTS.md` addition telling the agent notes exist and which actions manage them.
144
-
145
- A new action is callable by chat as soon as it exists — every `defineAction` is a tool by default unless it sets `agentTool: false`. It won't necessarily be in the model's very first request, though: `server/plugins/agent-chat.ts` sets `INITIAL_TOOL_NAMES = ["view-screen", "navigate", "hello", "provider-api-request"]`, which controls only which tool schemas are sent on the first turn. Everything else, including a brand-new `create-note`, stays reachable through `tool-search` and loads on demand — add a name to that list only if you want it in the model's default toolset from message one.
146
-
147
- ## Use your own agent backend {#own-agent-backend}
148
-
149
- The template uses the built-in app-agent loop by default. To connect a custom backend, swap the chat runtime behind the agent chat plugin instead of rewriting the UI. The Chat route should stay a thin renderer around the shared chat surface; the backend choice belongs in the server plugin/runtime adapter.
150
-
151
- Use this when your model orchestration already lives elsewhere, but you still want an app with auth, threads, actions, UI state, and deployable pages.
152
-
153
- ## What's next
154
-
155
- - [**Chat**](/docs/template-chat) — what ships by default and when to pick it
156
- - [**Chat: Developer Guide**](/docs/template-chat-developers) — quick start, actions, core tables, auth, and the admin pages
157
- - [**Actions**](/docs/actions-overview) — the action system chat and UI both call
158
- - [**Native Chat UI**](/docs/native-chat-ui) — chat surface primitives and runtime options