@agent-native/core 0.207.0-nightly-20261011124220 → 0.207.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 (108) hide show
  1. package/dist/agent/production-agent.js +23 -6
  2. package/dist/agent/thread-data-builder.js +7 -4
  3. package/dist/cli/eval.js +20 -4
  4. package/dist/client/analytics/index.d.ts +1 -1
  5. package/dist/client/analytics.d.ts +12 -3
  6. package/dist/client/analytics.js +51 -17
  7. package/dist/client/onboarding/use-onboarding.d.ts +1 -0
  8. package/dist/client/onboarding/use-onboarding.js +19 -6
  9. package/dist/collab/struct-routes.d.ts +1 -1
  10. package/dist/eval/agent-runner.js +18 -8
  11. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  12. package/dist/mcp/connect-route.js +9 -4
  13. package/dist/observability/routes.d.ts +7 -7
  14. package/dist/onboarding/plugin.js +15 -45
  15. package/dist/progress/routes.d.ts +1 -1
  16. package/dist/resources/store.js +25 -30
  17. package/dist/server/agent-discovery.js +47 -53
  18. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  19. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  20. package/dist/server/builtin-agents.d.ts +2 -0
  21. package/dist/server/builtin-agents.js +50 -3
  22. package/dist/server/credential-provider.d.ts +6 -9
  23. package/dist/server/credential-provider.js +33 -21
  24. package/dist/templates/builder-code-starter/.agents/skills/adding-a-feature/SKILL.md.patch +1 -1
  25. package/dist/templates/builder-code-starter/AGENTS.md.patch +3 -3
  26. package/dist/templates/builder-code-starter/app/components/layout/Layout.tsx.patch +6 -7
  27. package/dist/templates/builder-code-starter/app/hooks/use-navigation-state.ts.patch +21 -28
  28. package/dist/templates/builder-code-starter/app/root.tsx.patch +16 -5
  29. package/dist/templates/builder-code-starter/template-layer.json +4 -0
  30. package/dist/templates/chat/.agents/skills/secrets/SKILL.md +6 -2
  31. package/dist/templates/chat/AGENTS.md +3 -3
  32. package/dist/templates/chat/CHANGELOG.md +6 -0
  33. package/dist/templates/chat/app/components/chat/ChatHomeRedirect.tsx +25 -0
  34. package/dist/templates/chat/app/components/chat/ChatRouteContent.tsx +828 -15
  35. package/dist/templates/chat/app/components/home/HomePage.tsx +332 -0
  36. package/dist/templates/chat/app/components/layout/AgentInspector.tsx +2 -4
  37. package/dist/templates/chat/app/components/layout/Header.tsx +1 -1
  38. package/dist/templates/chat/app/components/layout/Layout.tsx +5 -6
  39. package/dist/templates/chat/app/components/layout/Sidebar.tsx +35 -11
  40. package/dist/templates/chat/app/components/ui/item.tsx +1 -0
  41. package/dist/templates/chat/app/components/ui/separator.tsx +1 -0
  42. package/dist/templates/chat/app/components/ui/skeleton.tsx +1 -0
  43. package/dist/templates/chat/app/hooks/use-navigation-state.ts +16 -22
  44. package/dist/templates/chat/app/i18n/ar-SA.ts +25 -0
  45. package/dist/templates/chat/app/i18n/de-DE.ts +26 -0
  46. package/dist/templates/chat/app/i18n/en-US.ts +25 -0
  47. package/dist/templates/chat/app/i18n/es-ES.ts +26 -0
  48. package/dist/templates/chat/app/i18n/fr-FR.ts +26 -0
  49. package/dist/templates/chat/app/i18n/hi-IN.ts +26 -0
  50. package/dist/templates/chat/app/i18n/ja-JP.ts +26 -0
  51. package/dist/templates/chat/app/i18n/ko-KR.ts +26 -0
  52. package/dist/templates/chat/app/i18n/pt-BR.ts +26 -0
  53. package/dist/templates/chat/app/i18n/zh-CN.ts +25 -0
  54. package/dist/templates/chat/app/i18n/zh-TW.ts +25 -0
  55. package/dist/templates/chat/app/lib/chat-paths.ts +479 -0
  56. package/dist/templates/chat/app/root.tsx +14 -3
  57. package/dist/templates/chat/app/routes/chat._index.tsx +5 -0
  58. package/dist/templates/chat/app/routes/home.tsx +3 -22
  59. package/dist/templates/chat/changelog/2026-10-10-home-handoff-recovery-capacity.md +6 -0
  60. package/dist/templates/default/.agents/skills/secrets/SKILL.md +6 -2
  61. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +6 -2
  62. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +6 -2
  63. package/dist/triggers/actions/manage-automation.d.ts +2 -2
  64. package/docs/content/deployment-environment-variables.mdx +10 -10
  65. package/docs/content/environment-variables.mdx +38 -6
  66. package/docs/content/getting-started.mdx +7 -7
  67. package/docs/content/multi-app-workspace.mdx +7 -3
  68. package/docs/content/template-chat-first-edits.mdx +46 -33
  69. package/package.json +4 -4
  70. package/src/templates/builder-code-starter/.agents/skills/adding-a-feature/SKILL.md.patch +1 -1
  71. package/src/templates/builder-code-starter/AGENTS.md.patch +3 -3
  72. package/src/templates/builder-code-starter/app/components/layout/Layout.tsx.patch +6 -7
  73. package/src/templates/builder-code-starter/app/hooks/use-navigation-state.ts.patch +21 -28
  74. package/src/templates/builder-code-starter/app/root.tsx.patch +16 -5
  75. package/src/templates/builder-code-starter/template-layer.json +4 -0
  76. package/src/templates/chat/.agents/skills/secrets/SKILL.md +6 -2
  77. package/src/templates/chat/AGENTS.md +3 -3
  78. package/src/templates/chat/CHANGELOG.md +6 -0
  79. package/src/templates/chat/app/components/chat/ChatHomeRedirect.tsx +25 -0
  80. package/src/templates/chat/app/components/chat/ChatRouteContent.tsx +828 -15
  81. package/src/templates/chat/app/components/home/HomePage.tsx +332 -0
  82. package/src/templates/chat/app/components/layout/AgentInspector.tsx +2 -4
  83. package/src/templates/chat/app/components/layout/Header.tsx +1 -1
  84. package/src/templates/chat/app/components/layout/Layout.tsx +5 -6
  85. package/src/templates/chat/app/components/layout/Sidebar.tsx +35 -11
  86. package/src/templates/chat/app/components/ui/item.tsx +1 -0
  87. package/src/templates/chat/app/components/ui/separator.tsx +1 -0
  88. package/src/templates/chat/app/components/ui/skeleton.tsx +1 -0
  89. package/src/templates/chat/app/hooks/use-navigation-state.ts +16 -22
  90. package/src/templates/chat/app/i18n/ar-SA.ts +25 -0
  91. package/src/templates/chat/app/i18n/de-DE.ts +26 -0
  92. package/src/templates/chat/app/i18n/en-US.ts +25 -0
  93. package/src/templates/chat/app/i18n/es-ES.ts +26 -0
  94. package/src/templates/chat/app/i18n/fr-FR.ts +26 -0
  95. package/src/templates/chat/app/i18n/hi-IN.ts +26 -0
  96. package/src/templates/chat/app/i18n/ja-JP.ts +26 -0
  97. package/src/templates/chat/app/i18n/ko-KR.ts +26 -0
  98. package/src/templates/chat/app/i18n/pt-BR.ts +26 -0
  99. package/src/templates/chat/app/i18n/zh-CN.ts +25 -0
  100. package/src/templates/chat/app/i18n/zh-TW.ts +25 -0
  101. package/src/templates/chat/app/lib/chat-paths.ts +479 -0
  102. package/src/templates/chat/app/root.tsx +14 -3
  103. package/src/templates/chat/app/routes/chat._index.tsx +5 -0
  104. package/src/templates/chat/app/routes/home.tsx +3 -22
  105. package/src/templates/chat/changelog/2026-10-10-home-handoff-recovery-capacity.md +6 -0
  106. package/src/templates/default/.agents/skills/secrets/SKILL.md +6 -2
  107. package/src/templates/headless/.agents/skills/secrets/SKILL.md +6 -2
  108. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +6 -2
@@ -15,9 +15,11 @@ most apps need.
15
15
  For a normal app, start with the [Agent-Native app configuration guide](/docs/agent-native-config),
16
16
  then use [Deployment: Environment Variables](/docs/deployment-environment-variables)
17
17
  and [Authentication](/docs/authentication) for the deliberate environment-only
18
- parts. Keep user-, organization-, and workspace-scoped credentials in the
19
- database-backed secret or connection store; use environment variables for
20
- deploy-level configuration.
18
+ parts. LLM provider keys can be app-wide fallbacks on self-hosted deployments;
19
+ production Hosted-workspace runtimes block that fallback. See [LLM provider
20
+ keys](#llm-provider-keys) for local setup, scoped keys, and deployment sharing
21
+ and billing. Keep user-, organization-, and workspace-scoped credentials in the
22
+ database-backed secret or connection store.
21
23
 
22
24
  For committed, non-secret app defaults, use `agent-native.config.ts` first. If a
23
25
  public config value must vary by deployment, use its deterministic
@@ -79,7 +81,7 @@ public app behavior, use the config paths above instead.
79
81
  | `SECRETS_ENCRYPTION_KEY` | Legacy app-local/shared encryption fallback. | A stable encryption key; prefer the workspace key for new shared vaults. |
80
82
  | `WORKSPACE_SECRETS_ENCRYPTION_KEY` | Stable encryption key for a workspace-shared secrets vault. | The same stable key in every app that reads the vault. |
81
83
  | `WORKSPACE_SECRETS_ENCRYPTION_KEY_PREVIOUS` | Previous workspace key during rotation. | The old key only; remove it after migration. |
82
- | `ANTHROPIC_API_KEY` | Optional deploy-level fallback for the embedded production agent. | An API key; prefer scoped credentials for multi-tenant apps. |
84
+ | `ANTHROPIC_API_KEY` | Shared fallback for self-hosted apps, including remote databases. | An Anthropic API key; saved personal, organization, or workspace-scoped keys take precedence. |
83
85
  | `AGENT_ENGINE` | Explicitly selects the agent engine instead of auto-detecting from provider keys. | A registered engine name such as `anthropic`, `ai-sdk:openai`, `builder`, or `codex-cli`. |
84
86
  | `AGENT_BUILT_IN_ENGINES` | Restricts which built-in engines are registered at all, so the rest never appear in the model picker or resolve by name. | A comma-separated list of built-in engine names such as `ai-sdk:openai`; unset registers every built-in. |
85
87
  | `AGENT_SOURCE_SWEEP_TOOL_CALL_THRESHOLD` | Read-only source/search tool calls one turn may make before the agent is told to converge and answer from what it gathered. | A positive integer; defaults to 24. Raise it for research-shaped apps that legitimately inspect many records. |
@@ -169,8 +171,38 @@ specific Google API integrations; they are not required for browser sign-in.
169
171
 
170
172
  ## Optional AI, search, and email fallbacks
171
173
 
172
- These are deploy-level fallbacks for single-tenant or local use. Hosted,
173
- multi-user apps should prefer the scoped credential and connection store.
174
+ ### LLM provider keys {#llm-provider-keys}
175
+
176
+ For local development, put a supported provider key in the app's `.env` file
177
+ before starting `pnpm dev`. For example:
178
+
179
+ ```dotenv
180
+ ANTHROPIC_API_KEY=replace-with-your-key
181
+ ```
182
+
183
+ For an app-wide fallback, set a supported provider key in the server-side
184
+ environment of a self-hosted app. This also works with a remote PostgreSQL
185
+ database. Any signed-in user without a personal, organization-scoped, or
186
+ workspace-scoped provider key can use the deployment's provider account, and
187
+ usage is billed to that account. Anonymous public runs and synthetic traffic do
188
+ not receive this fallback. Personal, organization, and workspace-scoped keys
189
+ take precedence. Setting a deployment key opts in to
190
+ app-wide access and billing; no extra shared-key flag is needed. Production
191
+ Hosted-workspace runtimes block deployment provider-key fallbacks.
192
+
193
+ To keep a key scoped, select **Custom keys** in the app's LLM setup. In a
194
+ PostgreSQL app, a personal key stays with its user; organization scope shares a
195
+ key with the active organization and is available to admins. The app stores
196
+ these saved keys in its encrypted database-backed credential store.
197
+
198
+ To use Builder's managed provider, connect with **Use Builder.io** in the app's
199
+ LLM setup. This uses the Builder connection instead of a provider API key from
200
+ the table below.
201
+
202
+ The table below lists optional deployment-level fallbacks for self-hosted apps.
203
+ See the LLM guidance above for which users can use the deployment provider key
204
+ and how usage is billed. Production Hosted-workspace runtimes block deployment
205
+ provider-key fallbacks.
174
206
 
175
207
  Every provider key below selects its engine on its own: dropping one in is
176
208
  enough, and `AGENT_ENGINE` is only needed to pick between several.
@@ -20,8 +20,7 @@ In this guide, you'll create an agent with a chat UI and call its included
20
20
  - [Node.js](https://nodejs.org) 22.22 or later
21
21
  - [pnpm](https://pnpm.io) available on your `PATH` (run `corepack enable` in
22
22
  the generated app if it is not)
23
- - An LLM connection for the agent: Builder.io, an Anthropic or OpenAI API key,
24
- or a local Ollama model
23
+ - Optional while setting up; required to run the agent: Builder.io, an Anthropic/OpenAI key, or local Ollama
25
24
 
26
25
  ## Create an agent
27
26
 
@@ -64,11 +63,12 @@ enter an email or password for local development.
64
63
 
65
64
  </Callout>
66
65
 
67
- ## Connect an LLM
66
+ ## Connect an LLM (optional) {#connect-an-llm}
68
67
 
69
- Next, connect an LLM. Select **Use Builder.io** to use free credits, or
70
- select **Custom keys**, choose a provider, and enter the requested connection
71
- details.
68
+ Connect with **Use Builder.io**, add a personal or organization key through
69
+ **Custom keys**, or set a provider key in `.env` for local development and in
70
+ the deployment environment for app-wide use on self-hosted apps. See the [LLM
71
+ provider setup](/docs/environment-variables#llm-provider-keys).
72
72
 
73
73
  ## Run the action from the agent
74
74
 
@@ -76,7 +76,7 @@ An action is a typed function that your React UI can call from code and agents
76
76
  can use as a tool. The Chat template includes a simple `hello` action so you
77
77
  can try the pattern before writing one yourself.
78
78
 
79
- In the agent panel, ask:
79
+ In the prompt on the **Get started** page, ask:
80
80
 
81
81
  > Call the hello action for Alex.
82
82
 
@@ -260,7 +260,10 @@ By default every workspace can reach the hosted first-party apps (Mail, Calendar
260
260
  "workspaceCore": "@my-company-platform/shared",
261
261
  "builtinAgents": {
262
262
  "mode": "selected",
263
- "include": ["mail", "calendar"]
263
+ "include": ["mail", "calendar", "design"],
264
+ "urls": {
265
+ "design": "https://design.example.test"
266
+ }
264
267
  }
265
268
  }
266
269
  }
@@ -268,10 +271,11 @@ By default every workspace can reach the hosted first-party apps (Mail, Calendar
268
271
 
269
272
  - `mode`: `"all"` (default, every public first-party app), `"none"` (no built-ins), or `"selected"` (only `include`).
270
273
  - `include`: the built-ins this workspace offers when `mode` is `"selected"`. Anything else stays unknown to the workspace.
274
+ - `urls` (optional): maps built-in IDs to HTTPS base URL overrides for offered built-ins without changing the offered agents. It replaces the canonical hosted URL, including in a seeded manifest that still uses that default, while custom connected remote-agent URLs and workspace-app overlays retain priority. Unknown IDs and invalid URLs fail parsing. Each value must be a trimmed absolute HTTPS URL with no credentials, query, or fragment. Local-development routing keeps priority and uses local URLs.
271
275
 
272
- Unknown ids log a warning and are ignored. A standalone app can use the same key in its own `package.json`. `agent-native dev` and workspace deploys pass the value to every app as `AGENT_NATIVE_BUILTIN_AGENTS_JSON`.
276
+ Unknown IDs in `include` log a warning and are ignored. A standalone app can use the same key in its own `package.json`. `agent-native dev` and workspace deploys pass the value to every app as `AGENT_NATIVE_BUILTIN_AGENTS_JSON`.
273
277
 
274
- This config controls the app list, agent discovery, and agent-to-agent calls. Mounted workspace apps and connected remote agents are unaffected, and MCP app access stays a separate routing permission.
278
+ This config controls the app list, agent discovery, and agent-to-agent calls. Mounted workspace apps and custom connected remote-agent URLs retain priority, and MCP app access stays a separate routing permission.
275
279
 
276
280
  ## Shared MCP servers {#shared-mcp}
277
281
 
@@ -1,18 +1,20 @@
1
1
  ---
2
2
  title: "Chat: Your First Feature"
3
- description: "The one file that renders Chat's starter screen, what its real props do, and a full walkthrough of adding a feature end to end."
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
4
  ---
5
5
 
6
6
  # Your First Feature
7
7
 
8
- This page is for developers extending the [Chat template](/docs/template-chat). It covers the single file that renders the starter chat screen, then walks through everything the agent typically touches when you ask for a real feature.
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
9
 
10
10
  ## First code to inspect {#first-code}
11
11
 
12
12
  - `actions/hello.ts` is the starter behavior the agent can call. Replace it or
13
13
  add actions beside it.
14
- - `app/routes/_index.tsx` renders the full-page chat surface. Adjust the
15
- suggestions, empty state, composer, or surrounding layout here.
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.
16
18
  - `AGENTS.md` tells the built-in agent how to work inside this app.
17
19
 
18
20
  <FileTree
@@ -32,12 +34,28 @@ This page is for developers extending the [Chat template](/docs/template-chat).
32
34
  note: "standard navigation action",
33
35
  },
34
36
  {
35
- path: "app/routes/_index.tsx",
36
- note: "renders the full-page chat surface; edit suggestions, empty state, composer",
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",
37
43
  },
38
44
  {
39
45
  path: "app/routes/chat.$threadId.tsx",
40
- note: "re-exports _index.tsx so /chat/:threadId renders the same surface with a thread id in the URL",
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",
41
59
  },
42
60
  {
43
61
  path: "AGENTS.md",
@@ -46,46 +64,41 @@ This page is for developers extending the [Chat template](/docs/template-chat).
46
64
  ]}
47
65
  />
48
66
 
49
- The real starter file is more than a bare `<AgentChatSurface />` — it wires thread-URL sync, a tab identity for multi-tab runs, and a hero composer layout, and its copy comes from i18n keys rather than literal strings:
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:
50
68
 
51
69
  <AnnotatedCode
52
70
  id="doc-block-chat4"
53
- title="app/routes/_index.tsx (trimmed)"
54
- filename="app/routes/_index.tsx"
71
+ title="app/components/chat/ChatRouteContent.tsx (trimmed)"
72
+ filename="app/components/chat/ChatRouteContent.tsx"
55
73
  language="tsx"
56
74
  code={
57
- 'import {\n AgentChatSurface,\n markAgentChatHomeHandoff,\n} from "@agent-native/core/client/agent-chat";\nimport { useT } from "@agent-native/core/client/i18n";\nimport { useEffect } from "react";\nimport { useNavigate, useParams } from "react-router";\n\nimport { TAB_ID } from "@/lib/tab-id";\n\nfunction chatThreadPath(threadId: string | null) {\n return threadId ? `/chat/${encodeURIComponent(threadId)}` : "/";\n}\n\nexport default function ChatRoute() {\n const { threadId } = useParams();\n const navigate = useNavigate();\n const t = useT();\n const threadUrlSync = threadId\n ? { routeThreadId: threadId, getPath: chatThreadPath, navigate }\n : undefined;\n\n useEffect(() => {\n function handleChatRunning(event: Event) {\n const detail = (event as CustomEvent).detail;\n if (detail?.isRunning === true) markAgentChatHomeHandoff("chat");\n }\n window.addEventListener("agentNative.chatRunning", handleChatRunning);\n return () =>\n window.removeEventListener("agentNative.chatRunning", handleChatRunning);\n }, []);\n\n return (\n <AgentChatSurface\n mode="page"\n chatViewTransition\n threadUrlSync={threadUrlSync}\n browserTabId={TAB_ID}\n dynamicSuggestions={false}\n suggestions={[\n t("chat.suggestionCapabilities"),\n t("chat.suggestionCustomize"),\n t("chat.suggestionActions"),\n ]}\n emptyStateText={t("chat.emptyState")}\n centerComposerWhenEmpty\n composerLayoutVariant="hero"\n composerPlaceholder={t("chat.composerPlaceholder")}\n composerSlot={\n <div className="mx-auto mb-5 max-w-xl px-4 text-center">\n <h1>{t("chat.heroTitle")}</h1>\n <p>{t("chat.heroDescription")}</p>\n </div>\n }\n />\n );\n}'
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}'
58
76
  }
59
77
  annotations={[
60
78
  {
61
- lines: "19-21",
62
- label: "Thread URL sync",
63
- note: "`/chat/:threadId` (`chat.$threadId.tsx`) re-exports this same component. When the route has a thread id, `threadUrlSync` keeps the URL and the active thread in lock-step: switching threads pushes `/chat/<id>`, and opening that URL restores the thread.",
64
- },
65
- {
66
- lines: "38",
67
- label: "Tab identity",
68
- note: "`TAB_ID` (`app/lib/tab-id.ts`, a random id generated once per browser tab) lets the shared chat runtime tell multiple open tabs of the same app apart, so a run started in one tab isn't mistaken for one in another.",
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.",
69
82
  },
70
83
  {
71
- lines: "39-44",
72
- label: "Suggestions are i18n keys",
73
- note: 'Suggestion copy comes from `t("chat.suggestionCapabilities")` etc. (see `app/i18n/en-US.ts`), not literal English strings, and `dynamicSuggestions={false}` turns off the runtime\'s own suggestion generation in favor of these three.',
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.",
74
87
  },
75
88
  {
76
- lines: "46-47",
77
- label: "Hero composer layout",
78
- note: '`composerLayoutVariant="hero"` plus `centerComposerWhenEmpty` centers the composer with a title/description above it, instead of the plain bottom-docked composer other `mode="page"` chat routes use.',
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.",
79
92
  },
80
93
  {
81
- lines: "49-54",
82
- label: "composerSlot",
83
- note: 'Arbitrary JSX rendered above the composer only while it\'s centered — this is where the "How can I help?" heading lives. Edit this to change the empty-state pitch without touching the runtime.',
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.',
84
97
  },
85
98
  {
86
- lines: "23-31",
87
- label: "Home handoff",
88
- note: 'When a run starts on this page, `markAgentChatHomeHandoff("chat")` records that the home surface owns the active run, so navigating away and back reattaches to it instead of losing it.',
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.",
89
102
  },
90
103
  ]}
91
104
  />
@@ -126,10 +139,10 @@ The rest of the feature follows from there:
126
139
  - `actions/create-note.ts` — a `defineAction` with a Zod schema (`title`, `body`), shaped like `actions/hello.ts`.
127
140
  - `actions/list-notes.ts` — a read-only action (`readOnly: true`, like `actions/view-screen.ts`) that queries the new table through `accessFilter`.
128
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`.
129
- - A new entry in the `navItems` array in `app/components/layout/Sidebar.tsx` pointing at `/notes`.
142
+ - A link in `app/components/layout/Sidebar.tsx`, added before `ChatThreadsSection` and pointing at `/notes`.
130
143
  - An `AGENTS.md` addition telling the agent notes exist and which actions manage them.
131
144
 
132
- 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"]`, 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.
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.
133
146
 
134
147
  ## Use your own agent backend {#own-agent-backend}
135
148
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.207.0-nightly-20261011124220",
3
+ "version": "0.207.0",
4
4
  "description": "The agentic application framework for building autonomous agents with intuitive UIs",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -694,8 +694,8 @@
694
694
  "yaml": "^2.9.0",
695
695
  "yjs": "^13.6.33",
696
696
  "zod": "^4.3.6",
697
- "@agent-native/agentkit": "^0.207.0-nightly-20261011124220",
698
- "@agent-native/recap-cli": "^0.5.68"
697
+ "@agent-native/recap-cli": "^0.5.69",
698
+ "@agent-native/agentkit": "^0.207.0"
699
699
  },
700
700
  "devDependencies": {
701
701
  "@ai-sdk/anthropic": "^3.0.71",
@@ -765,7 +765,7 @@
765
765
  "xlsx": "^0.18.5"
766
766
  },
767
767
  "peerDependencies": {
768
- "@agent-native/core-corpus": "0.207.0-nightly-20261011124220",
768
+ "@agent-native/core-corpus": ">=0.196.0",
769
769
  "@ai-sdk/anthropic": ">=3",
770
770
  "@ai-sdk/cohere": ">=3",
771
771
  "@ai-sdk/google": ">=3",
@@ -1,7 +1,7 @@
1
1
  ===================================================================
2
2
  --- a/.agents/skills/adding-a-feature/SKILL.md
3
3
  +++ b/.agents/skills/adding-a-feature/SKILL.md
4
- @@ -129,11 +129,12 @@
4
+ @@ -131,11 +131,12 @@
5
5
  Instruction examples may name secret keys like `SLACK_WEBHOOK`, but must use
6
6
  placeholders such as `${keys.SLACK_WEBHOOK}` or `<SLACK_WEBHOOK>`. Do not paste
7
7
  real keys, internal data, or customer data into instructions as examples.
@@ -5,7 +5,7 @@
5
5
  -# Chat — Agent Guide
6
6
  +# App — Agent Guide
7
7
 
8
- -Chat is the minimal chat-first agent-native app. `/` redirects to shared sign-in; authenticated chat starts at `/home`. Actions carry capabilities; screens exist only for durable workflows.
8
+ -Chat is the minimal chat-first agent-native app. `/` redirects to shared sign-in, then `/home`, the editable Get started page. Chat lives at `/chat`; new chats start there. Actions carry capabilities; screens exist only for durable workflows.
9
9
  +This starter ships as a blank Agent-Native app canvas — that describes its
10
10
  +initial state, not necessarily its current one. See `DEVELOPING.md` before
11
11
  +making any source code change.
@@ -30,7 +30,7 @@
30
30
 
31
31
  ## Application state
32
32
 
33
- -- `navigation` describes the view and selected ids. Chat is `chat` at `/home`; `/` opens shared sign-in/signup.
33
+ -- `navigation` describes the view and selected ids. Chat is `chat` at `/chat` and `/chat/<threadId>`; the Get started page is `home` at `/home`; `/` opens shared sign-in/signup.
34
34
  +- `navigation` describes the view and selected ids. The default home view is
35
35
  + `home` at `/` (blank app canvas). No agent rail or chat is mounted by
36
36
  + default; add one only when the user asks.
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## Building a domain app
40
40
 
41
- -Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. Keep `/home` as Chat. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` maps `/home` to Chat and uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
41
+ -Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. The default Get started page lives at `/home`, and Chat stays at `/chat`; edit `app/routes/home.tsx` when replacing that page with a domain-specific home. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
42
42
  +Choose the primary workflow and route before editing. Build on the blank canvas in `app/routes/_index.tsx` or add domain routes under `app/routes/`. This starter has no Chat route, sidebar, header, or agent rail; add only the navigation the product needs. Set `app.homePath` in the existing `defineAppConfig` in `server/plugins/config.ts` as `DEVELOPING.md` describes.
43
43
 
44
44
  -Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow, including overlap rejection, cancellation freeing the slot, and authenticated landing. Skip production build and extra test suites.
@@ -1,7 +1,7 @@
1
1
  ===================================================================
2
2
  --- a/app/components/layout/Layout.tsx
3
3
  +++ b/app/components/layout/Layout.tsx
4
- @@ -1,189 +1,28 @@
4
+ @@ -1,188 +1,28 @@
5
5
  -import { useT } from "@agent-native/core/client/i18n";
6
6
  -import { HeaderActionsProvider } from "@agent-native/toolkit/app-shell/header-actions";
7
7
  -import {
@@ -23,6 +23,7 @@
23
23
  - SheetTitle,
24
24
  -} from "@/components/ui/sheet";
25
25
  -import { APP_TITLE } from "@/lib/app-config";
26
+ -import { HOME_PATH, isChatPathname } from "@/lib/chat-paths";
26
27
  -
27
28
  -import { Sidebar } from "./Sidebar";
28
29
  -
@@ -43,8 +44,8 @@
43
44
  -
44
45
  -function routeOwnsToolbar(pathname: string): boolean {
45
46
  - return (
46
- - pathname === "/home" ||
47
- - pathname.startsWith("/chat/") ||
47
+ - pathname === HOME_PATH ||
48
+ - isChatPathname(pathname) ||
48
49
  - pathname === "/database" ||
49
50
  - pathname.startsWith("/extensions")
50
51
  - );
@@ -66,8 +67,7 @@
66
67
  - const t = useT();
67
68
  - const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
68
69
  - const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
69
- - const isChatRoute =
70
- - location.pathname === "/home" || location.pathname.startsWith("/chat/");
70
+ - const isChatRoute = isChatPathname(location.pathname);
71
71
  - // Settings brings its own navigation, header, and agent toggle, so it
72
72
  - // renders full width.
73
73
  - const settingsOwnsChrome = isSettingsPathname(location.pathname);
@@ -79,8 +79,7 @@
79
79
  - const chatHomeHandoffPending = isAgentChatHomeHandoffActive("chat");
80
80
  - useAgentChatHomeHandoffLinks({
81
81
  - storageKey: "chat",
82
- - isChatPath: (pathname) =>
83
- - pathname === "/home" || pathname.startsWith("/chat/"),
82
+ - isChatPath: isChatPathname,
84
83
  - requireActiveHandoff: true,
85
84
  - });
86
85
  -
@@ -1,7 +1,18 @@
1
1
  ===================================================================
2
2
  --- a/app/hooks/use-navigation-state.ts
3
3
  +++ b/app/hooks/use-navigation-state.ts
4
- @@ -5,83 +5,37 @@
4
+ @@ -1,85 +1,41 @@
5
+ import { appBasePath, appPath } from "@agent-native/core/client/api-path";
6
+ import { useAgentRouteState } from "@agent-native/core/client/navigation";
7
+
8
+ -import {
9
+ - chatThreadPath,
10
+ - HOME_PATH,
11
+ - isChatPathname,
12
+ - NEW_CHAT_PATH,
13
+ - threadIdFromPath,
14
+ -} from "@/lib/chat-paths";
15
+ import { TAB_ID } from "@/lib/tab-id";
5
16
 
6
17
  export interface NavigationState {
7
18
  view: string;
@@ -31,19 +42,9 @@
31
42
  });
32
43
  }
33
44
 
34
- -function threadIdFromPath(pathname: string): string | null {
35
- - const match = pathname.match(/^\/chat\/([^/]+)/);
36
- - if (!match) return null;
37
- - try {
38
- - const value = decodeURIComponent(match[1]).trim();
39
- - return value || null;
40
- - } catch {
41
- - return null;
42
- - }
43
- -}
44
- -
45
45
  function viewForPath(pathname: string): string {
46
- - if (isChatPath(pathname)) return "chat";
46
+ - if (isChatPathname(pathname)) return "chat";
47
+ - if (pathname === HOME_PATH) return "home";
47
48
  - if (pathname.startsWith("/database")) return "database";
48
49
  - if (pathname.startsWith("/extensions")) return "extensions";
49
50
  - if (pathname.startsWith("/observability")) return "observability";
@@ -60,9 +61,10 @@
60
61
  function pathForView(view?: string): string {
61
62
  switch (view) {
62
63
  - case "chat":
63
- case "home":
64
64
  - case "ask":
65
- - return "/home";
65
+ - return NEW_CHAT_PATH;
66
+ case "home":
67
+ - return HOME_PATH;
66
68
  - case "database":
67
69
  - return "/database";
68
70
  - case "extensions":
@@ -77,29 +79,20 @@
77
79
  - return "/settings/organization";
78
80
  + return "/";
79
81
  default:
80
- - return "/home";
82
+ - return HOME_PATH;
81
83
  + return "/";
82
84
  }
83
85
  }
84
86
 
85
- -function pathForCommand(command: any): string {
87
+ -export function pathForCommand(command: any): string {
86
88
  - const path = pathForView(command?.view);
87
- - if (path !== "/home") return path;
89
+ - if (command?.view !== "chat" && command?.view !== "ask") return path;
88
90
  - const threadId =
89
91
  - typeof command?.threadId === "string" ? command.threadId.trim() : "";
90
- - return threadId ? `/chat/${encodeURIComponent(threadId)}` : path;
92
+ - return threadId ? chatThreadPath(threadId) : path;
91
93
  -}
92
94
  -
93
95
  function routerPath(path: string): string {
94
96
  const basePath = appBasePath();
95
97
  if (!basePath) return path;
96
98
  if (path === basePath) return "/";
97
- @@ -89,8 +43,4 @@
98
- return path.slice(basePath.length) || "/";
99
- }
100
- return path;
101
- }
102
- -
103
- -function isChatPath(pathname: string): boolean {
104
- - return pathname === "/home" || pathname.startsWith("/chat/");
105
- -}
@@ -1,7 +1,7 @@
1
1
  ===================================================================
2
2
  --- a/app/root.tsx
3
3
  +++ b/app/root.tsx
4
- @@ -1,70 +1,50 @@
4
+ @@ -1,76 +1,50 @@
5
5
  import { configureTracking } from "@agent-native/core/client/analytics";
6
6
  import { appPath } from "@agent-native/core/client/api-path";
7
7
  import { useDbSync } from "@agent-native/core/client/hooks";
@@ -33,6 +33,12 @@
33
33
  import { AppToolkitProvider } from "@/components/ui/toolkit-provider";
34
34
  import { useNavigationState } from "@/hooks/use-navigation-state";
35
35
  -import { APP_TITLE } from "@/lib/app-config";
36
+ -import {
37
+ - HOME_PATH,
38
+ - isChatPathname,
39
+ - NEW_CHAT_PATH,
40
+ - threadIdFromPath,
41
+ -} from "@/lib/chat-paths";
36
42
  +import { APP_NAME, APP_TITLE } from "@/lib/app-config";
37
43
  import { TAB_ID } from "@/lib/tab-id";
38
44
 
@@ -79,7 +85,7 @@
79
85
  <meta name="mobile-web-app-capable" content="yes" />
80
86
  <meta
81
87
  name="apple-mobile-web-app-status-bar-style"
82
- @@ -94,91 +74,19 @@
88
+ @@ -100,96 +74,19 @@
83
89
  });
84
90
  return null;
85
91
  }
@@ -104,7 +110,7 @@
104
110
  - const navigate = useNavigate();
105
111
  - const t = useT();
106
112
  - const location = useLocation();
107
- - const isChatThread = location.pathname.startsWith("/chat/");
113
+ - const isChatThread = threadIdFromPath(location.pathname) !== null;
108
114
  - useCommandMenuShortcut(useCallback(() => setCmdkOpen(true), []));
109
115
  - return (
110
116
  - <>
@@ -123,8 +129,13 @@
123
129
  - {t("chat.newChat")}
124
130
  - </CommandMenu.Item>
125
131
  - ) : null}
126
- - {!isChatThread && location.pathname !== "/home" ? (
127
- - <CommandMenu.Item onSelect={() => navigate("/home")}>
132
+ - {location.pathname !== HOME_PATH ? (
133
+ - <CommandMenu.Item onSelect={() => navigate(HOME_PATH)}>
134
+ - {t("navigation.home")}
135
+ - </CommandMenu.Item>
136
+ - ) : null}
137
+ - {!isChatPathname(location.pathname) ? (
138
+ - <CommandMenu.Item onSelect={() => navigate(NEW_CHAT_PATH)}>
128
139
  - {t("navigation.chat")}
129
140
  - </CommandMenu.Item>
130
141
  - ) : null}
@@ -5,16 +5,20 @@
5
5
  "CHANGELOG.md",
6
6
  "actions/navigate.spec.ts",
7
7
  "app/components/chat",
8
+ "app/components/home",
8
9
  "app/components/layout/AgentInspector.test.tsx",
9
10
  "app/components/layout/AgentInspector.tsx",
10
11
  "app/components/layout/Header.tsx",
11
12
  "app/components/layout/Sidebar.tsx",
12
13
  "app/i18n",
13
14
  "app/i18n-data.ts",
15
+ "app/lib/chat-paths.spec.ts",
16
+ "app/lib/chat-paths.ts",
14
17
  "app/lib/sidebar-thread-state.spec.ts",
15
18
  "app/lib/sidebar-thread-state.ts",
16
19
  "app/routes/agent.tsx",
17
20
  "app/routes/chat.$threadId.tsx",
21
+ "app/routes/chat._index.tsx",
18
22
  "app/routes/database.tsx",
19
23
  "app/routes/extensions.$id.$slug.tsx",
20
24
  "app/routes/extensions.$id.tsx",
@@ -25,8 +25,12 @@ never copy a value into app code or client-visible state.
25
25
  3. If the app truly needs its own API key, register it with the shared secrets
26
26
  surface. Do not build a parallel key form or storage table.
27
27
  4. Use deployment configuration only for a secret owned by the deployed app,
28
- such as a webhook verification secret. A deployment key must not stand in
29
- for a user's or customer's provider credential.
28
+ such as a webhook verification secret. LLM inference keys are an app-owned
29
+ exception: self-hosted apps may use provider keys from deployment env as a
30
+ shared fallback, while scoped user or organization keys take precedence.
31
+ Hosted-workspace deployments backed by a shared database must not share
32
+ those env keys across apps or tenants. This exception does not authorize
33
+ using env credentials to access user-owned provider data.
30
34
 
31
35
  ## Register an app-local API key
32
36
 
@@ -1,6 +1,6 @@
1
1
  # Chat — Agent Guide
2
2
 
3
- Chat is the minimal chat-first agent-native app. `/` redirects to shared sign-in; authenticated chat starts at `/home`. Actions carry capabilities; screens exist only for durable workflows.
3
+ Chat is the minimal chat-first agent-native app. `/` redirects to shared sign-in, then `/home`, the editable Get started page. Chat lives at `/chat`; new chats start there. Actions carry capabilities; screens exist only for durable workflows.
4
4
 
5
5
  ## Skills
6
6
 
@@ -19,12 +19,12 @@ For custom branding, keep `server/plugins/agent-native-email-branding.ts` aligne
19
19
 
20
20
  ## Application state
21
21
 
22
- - `navigation` describes the view and selected ids. Chat is `chat` at `/home`; `/` opens shared sign-in/signup.
22
+ - `navigation` describes the view and selected ids. Chat is `chat` at `/chat` and `/chat/<threadId>`; the Get started page is `home` at `/home`; `/` opens shared sign-in/signup.
23
23
  - Use `navigate` when supported and `view-screen` for a fresh read of visible details; basic navigation is already in `<current-screen>`.
24
24
 
25
25
  ## Building a domain app
26
26
 
27
- Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. Keep `/home` as Chat. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` maps `/home` to Chat and uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
27
+ Choose the primary workflow and route before editing. Add a domain route under `app/routes/` and set `app.homePath` in `server/plugins/agent-native-email-branding.ts` with `defineAppConfig`. The default Get started page lives at `/home`, and Chat stays at `/chat`; edit `app/routes/home.tsx` when replacing that page with a domain-specific home. Add a static link in `app/components/layout/Sidebar.tsx` before `ChatThreadsSection`; `Header.tsx` uses `APP_TITLE` elsewhere. Shared sidebar and AgentInspector remain.
28
28
 
29
29
  Use `adding-a-feature` for functional parity and `frontend-design` for a user-facing screen. Keep feature guidance here; do not rewrite `README.md` or `DESIGN.md`. After all edits, run one typecheck, one doctor check, and one browser smoke of the primary workflow, including overlap rejection, cancellation freeing the slot, and authenticated landing. Skip production build and extra test suites.
30
30
 
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable user-facing changes to this app are documented here.
4
4
 
5
+ ## 2026-10-10
6
+
7
+ ### Fixed
8
+
9
+ - Large prompts with full context remain available to retry when sending fails.
10
+
5
11
  ## 2026-09-30
6
12
 
7
13
  ### Improved