@agent-native/core 0.78.9 → 0.79.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 (180) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +17 -0
  3. package/corpus/core/docs/content/actions.md +4 -2
  4. package/corpus/core/docs/content/agent-surfaces.md +9 -0
  5. package/corpus/core/docs/content/extensions.md +10 -0
  6. package/corpus/core/docs/content/generative-ui.md +217 -0
  7. package/corpus/core/docs/content/key-concepts.md +2 -2
  8. package/corpus/core/docs/content/mcp-apps.md +3 -5
  9. package/corpus/core/docs/content/native-chat-ui.md +9 -5
  10. package/corpus/core/docs/content/tracking.md +9 -3
  11. package/corpus/core/package.json +1 -1
  12. package/corpus/core/src/action-ui.ts +1 -0
  13. package/corpus/core/src/agent/production-agent.ts +8 -0
  14. package/corpus/core/src/client/analytics.ts +195 -12
  15. package/corpus/core/src/client/chat/index.ts +1 -0
  16. package/corpus/core/src/client/chat/tool-call-display.tsx +5 -2
  17. package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +139 -0
  18. package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +27 -1
  19. package/corpus/core/src/client/conversation/AgentConversation.tsx +38 -0
  20. package/corpus/core/src/client/conversation/code-agent-transcript.ts +9 -0
  21. package/corpus/core/src/client/conversation/types.ts +4 -0
  22. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +27 -5
  23. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +26 -5
  24. package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +654 -0
  25. package/corpus/core/src/client/extensions/iframe-bridge.ts +30 -0
  26. package/corpus/core/src/client/extensions/index.ts +5 -0
  27. package/corpus/core/src/client/index.ts +1 -0
  28. package/corpus/core/src/client/session-replay.ts +89 -14
  29. package/corpus/core/src/code-agents/transcript-normalizer.ts +14 -0
  30. package/corpus/core/src/extensions/actions.ts +218 -1
  31. package/corpus/core/src/extensions/html-shell.ts +70 -3
  32. package/corpus/core/src/extensions/routes.ts +12 -4
  33. package/corpus/core/src/index.browser.ts +1 -0
  34. package/corpus/core/src/index.ts +1 -0
  35. package/corpus/core/src/server/agent-chat-plugin.ts +21 -9
  36. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +13 -0
  37. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/references/api.md +2 -0
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +115 -0
  39. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +198 -59
  40. package/corpus/templates/analytics/AGENTS.md +12 -0
  41. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +1105 -0
  42. package/corpus/templates/analytics/actions/dashboard-panel-order.ts +169 -0
  43. package/corpus/templates/analytics/actions/get-sql-dashboard.ts +89 -6
  44. package/corpus/templates/analytics/actions/mutate-dashboard.ts +333 -0
  45. package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +214 -0
  46. package/corpus/templates/analytics/actions/send-dashboard-report-now.ts +48 -21
  47. package/corpus/templates/analytics/actions/update-dashboard.ts +193 -100
  48. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +11 -0
  49. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
  50. package/corpus/templates/analytics/app/global.css +81 -10
  51. package/corpus/templates/analytics/app/i18n-data.ts +249 -4
  52. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +3 -3
  53. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +41 -1
  54. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/EmailReportDialog.tsx +1 -1
  55. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +4 -4
  56. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +48 -18
  57. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +32 -0
  58. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +204 -70
  59. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +1101 -227
  60. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +160 -133
  61. package/corpus/templates/analytics/changelog/2026-06-26-agents-can-now-edit-dashboards-through-a-typed-mutation-scri.md +6 -0
  62. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-bar-chart-hovers-stay-subtle-in-dark-mode.md +6 -0
  63. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-chart-moves-are-now-handled-by-panel-id-making-sim.md +6 -0
  64. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-charts-drag-smoothly-with-stable-cards-inactive-ch.md +6 -0
  65. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-charts-show-a-refresh-spinner-while-keeping-existi.md +6 -0
  66. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-edits-stay-stable-while-chart-order-and-deletions-.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-email-reports-queue-immediate-sends.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-06-26-explorer-dashboards-now-drag-charts-with-a-stable-preview-an.md +6 -0
  69. package/corpus/templates/analytics/changelog/2026-06-26-session-replay-playback-can-now-be-toggled-by-clicking-the-r.md +6 -0
  70. package/corpus/templates/analytics/changelog/2026-06-26-session-replays-now-open-from-the-full-row-and-play-with-tim.md +6 -0
  71. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +21 -0
  72. package/corpus/templates/analytics/server/lib/dashboard-report.ts +41 -17
  73. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  74. package/dist/action-ui.d.ts +1 -0
  75. package/dist/action-ui.d.ts.map +1 -1
  76. package/dist/action-ui.js +1 -0
  77. package/dist/action-ui.js.map +1 -1
  78. package/dist/agent/production-agent.d.ts.map +1 -1
  79. package/dist/agent/production-agent.js +6 -0
  80. package/dist/agent/production-agent.js.map +1 -1
  81. package/dist/client/analytics.d.ts.map +1 -1
  82. package/dist/client/analytics.js +173 -12
  83. package/dist/client/analytics.js.map +1 -1
  84. package/dist/client/chat/index.d.ts +1 -1
  85. package/dist/client/chat/index.d.ts.map +1 -1
  86. package/dist/client/chat/index.js +1 -1
  87. package/dist/client/chat/index.js.map +1 -1
  88. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  89. package/dist/client/chat/tool-call-display.js +3 -1
  90. package/dist/client/chat/tool-call-display.js.map +1 -1
  91. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts +17 -0
  92. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -0
  93. package/dist/client/chat/widgets/InlineExtensionWidget.js +85 -0
  94. package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -0
  95. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  96. package/dist/client/chat/widgets/builtin-tool-renderers.js +15 -2
  97. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  98. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  99. package/dist/client/conversation/AgentConversation.js +33 -0
  100. package/dist/client/conversation/AgentConversation.js.map +1 -1
  101. package/dist/client/conversation/code-agent-transcript.js +8 -0
  102. package/dist/client/conversation/code-agent-transcript.js.map +1 -1
  103. package/dist/client/conversation/types.d.ts +4 -0
  104. package/dist/client/conversation/types.d.ts.map +1 -1
  105. package/dist/client/conversation/types.js.map +1 -1
  106. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  107. package/dist/client/extensions/EmbeddedExtension.js +29 -1
  108. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  109. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  110. package/dist/client/extensions/ExtensionViewer.js +28 -1
  111. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  112. package/dist/client/extensions/InlineExtensionFrame.d.ts +25 -0
  113. package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -0
  114. package/dist/client/extensions/InlineExtensionFrame.js +488 -0
  115. package/dist/client/extensions/InlineExtensionFrame.js.map +1 -0
  116. package/dist/client/extensions/iframe-bridge.d.ts +2 -0
  117. package/dist/client/extensions/iframe-bridge.d.ts.map +1 -1
  118. package/dist/client/extensions/iframe-bridge.js +23 -0
  119. package/dist/client/extensions/iframe-bridge.js.map +1 -1
  120. package/dist/client/extensions/index.d.ts +1 -0
  121. package/dist/client/extensions/index.d.ts.map +1 -1
  122. package/dist/client/extensions/index.js +1 -0
  123. package/dist/client/extensions/index.js.map +1 -1
  124. package/dist/client/index.d.ts +1 -1
  125. package/dist/client/index.d.ts.map +1 -1
  126. package/dist/client/index.js +1 -1
  127. package/dist/client/index.js.map +1 -1
  128. package/dist/client/session-replay.d.ts +11 -1
  129. package/dist/client/session-replay.d.ts.map +1 -1
  130. package/dist/client/session-replay.js +74 -14
  131. package/dist/client/session-replay.js.map +1 -1
  132. package/dist/code-agents/transcript-normalizer.d.ts +2 -0
  133. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
  134. package/dist/code-agents/transcript-normalizer.js +8 -0
  135. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  136. package/dist/collab/awareness.d.ts +2 -2
  137. package/dist/collab/awareness.d.ts.map +1 -1
  138. package/dist/collab/routes.d.ts +1 -1
  139. package/dist/extensions/actions.d.ts.map +1 -1
  140. package/dist/extensions/actions.js +200 -1
  141. package/dist/extensions/actions.js.map +1 -1
  142. package/dist/extensions/html-shell.d.ts.map +1 -1
  143. package/dist/extensions/html-shell.js +70 -3
  144. package/dist/extensions/html-shell.js.map +1 -1
  145. package/dist/extensions/routes.d.ts.map +1 -1
  146. package/dist/extensions/routes.js +11 -4
  147. package/dist/extensions/routes.js.map +1 -1
  148. package/dist/index.browser.d.ts +1 -1
  149. package/dist/index.browser.d.ts.map +1 -1
  150. package/dist/index.browser.js +1 -1
  151. package/dist/index.browser.js.map +1 -1
  152. package/dist/index.d.ts +1 -1
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.js +1 -1
  155. package/dist/index.js.map +1 -1
  156. package/dist/notifications/routes.d.ts +3 -3
  157. package/dist/observability/routes.d.ts +3 -3
  158. package/dist/progress/routes.d.ts +1 -1
  159. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  160. package/dist/resources/handlers.d.ts +3 -3
  161. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  162. package/dist/server/agent-chat-plugin.js +21 -9
  163. package/dist/server/agent-chat-plugin.js.map +1 -1
  164. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  165. package/dist/server/transcribe-voice.d.ts +1 -1
  166. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +13 -0
  167. package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +2 -0
  168. package/dist/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +115 -0
  169. package/docs/content/actions.md +4 -2
  170. package/docs/content/agent-surfaces.md +9 -0
  171. package/docs/content/extensions.md +10 -0
  172. package/docs/content/generative-ui.md +217 -0
  173. package/docs/content/key-concepts.md +2 -2
  174. package/docs/content/mcp-apps.md +3 -5
  175. package/docs/content/native-chat-ui.md +9 -5
  176. package/docs/content/tracking.md +9 -3
  177. package/package.json +1 -1
  178. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +13 -0
  179. package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +2 -0
  180. package/src/templates/workspace-core/.agents/skills/generative-ui/SKILL.md +115 -0
package/corpus/README.md CHANGED
@@ -27,5 +27,5 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
27
27
 
28
28
  ## Generated Counts
29
29
 
30
- - core files: 1937
31
- - template files: 4351
30
+ - core files: 1941
31
+ - template files: 4365
@@ -1,5 +1,22 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.79.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 43ea142: diag(agent): capture the durable background worker's API-key resolution state (engine, owner resolved, owner key, effective key, deploy-fallback-blocked) just before the anthropic key check. The worker stalls at `post_model_ok` and never reaches `aw_env` — the only exit between them is the anthropic key check's early return, so this pinpoints whether the worker bails for lack of an `effectiveApiKey`.
8
+
9
+ ## 0.79.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 6e25485: Add Generative UI support for transient and persisted sandboxed inline extensions in chat.
14
+
15
+ ### Patch Changes
16
+
17
+ - 6e25485: Improve session replay playback and inline extension chat surfaces.
18
+ - 6e25485: Teach generated saved extensions to persist reusable user-edited state with extensionData.
19
+
3
20
  ## 0.78.9
4
21
 
5
22
  ### Patch Changes
@@ -390,8 +390,9 @@ The query is cached under `["action", "get-lead", { leadId }]` and auto-invalida
390
390
 
391
391
  Actions can return structured widget data that the in-app chat renders
392
392
  natively. This is the first-party chat path for reusable tables, charts, setup
393
- summaries, and insight cards; use [MCP Apps](/docs/mcp-apps) for inline UI in
394
- external MCP hosts.
393
+ summaries, and insight cards. Use [Generative UI](/docs/generative-ui) when the
394
+ agent needs to generate arbitrary interactive controls inside the in-app chat,
395
+ and use [MCP Apps](/docs/mcp-apps) for inline UI in external MCP hosts.
395
396
 
396
397
  ```ts
397
398
  import { defineAction } from "@agent-native/core/action";
@@ -581,3 +582,4 @@ const args = parseArgs(["--name", "Steve", "--verbose", "--count=3"]);
581
582
  - [**Context Awareness**](/docs/context-awareness) — the `view-screen` + `navigate` pattern in depth
582
583
  - [**A2A Protocol**](/docs/a2a-protocol) — how other agents discover and call your actions
583
584
  - [**MCP Protocol**](/docs/mcp-protocol) — exposing actions over MCP
585
+ - [**Generative UI**](/docs/generative-ui) — rendering transient or persisted generated UI inline in chat
@@ -17,6 +17,7 @@ you want, then use the matching primitive.
17
17
  | ----------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
18
18
  | **Headless agent** | Code, jobs, scripts, another app, or another agent should call the work directly. | `agent-native create --headless`, `defineAction`, `agent-native agent`, HTTP, CLI, MCP, A2A |
19
19
  | **Rich chat on Agent-Native** | You want a standalone or embedded chat backed by the built-in agent loop. | [Chat template](/docs/template-chat), `<AgentChatSurface>`, `<AssistantChat>` |
20
+ | **Generated inline UI** | The agent should create temporary or reusable controls, pickers, calculators, or visualizers inside chat. | [Generative UI](/docs/generative-ui), `render-inline-extension`, `create-extension` |
20
21
  | **Rich chat on your agent** | You built the agent elsewhere and want Agent-Native's composer, transcript, tool cards, and native widgets. | `AgentChatRuntime`, `<AssistantChat runtime={runtime}>` |
21
22
  | **Embedded sidecar** | You already have a SaaS app and want an agent beside it with page context and host commands. | `createAgentNativeEmbeddedPlugin()`, `AgentNativeEmbedded` |
22
23
  | **Full application** | Humans and agents should share durable screens, data, navigation, and collaboration. | Templates, actions, SQL state, context awareness |
@@ -269,6 +270,10 @@ export function ProjectChat({ threadId }: { threadId: string }) {
269
270
  Actions can return explicit native widget results so chat output is not just
270
271
  text. Tables, charts, and typed product cards render as first-party React
271
272
  components in the chat, without iframes. See [Native Chat UI](/docs/native-chat-ui).
273
+ When the agent needs arbitrary generated controls instead of a predefined
274
+ React widget, use [Generative UI](/docs/generative-ui): it renders sandboxed
275
+ Alpine/Tailwind UI inline, can read app state and slot context, and can send
276
+ selected values back to chat.
272
277
 
273
278
  ## Rich chat on your agent {#byo-agent}
274
279
 
@@ -367,6 +372,8 @@ Full apps add product UI around the same action and agent contract:
367
372
  - **Live sync** — agent changes update the UI, and UI changes update the agent's context.
368
373
  - **Deep links** — action results can open the right app view.
369
374
  - **Native chat widgets** — tables, charts, cards, approvals, and typed results appear inline.
375
+ - **Generative UI and extensions** — the agent can create inline controls now
376
+ and save reusable mini-apps when the workflow needs to persist.
370
377
 
371
378
  Start from the [Chat template](/docs/template-chat) when you want a minimal app
372
379
  around your actions, or from a domain [template](/docs/cloneable-saas) when you
@@ -378,6 +385,7 @@ want a complete product shape.
378
385
  | --------------------------------------------------------------- | ------------------------- |
379
386
  | "I just need a callable tool or workflow." | Headless agent |
380
387
  | "I want the framework's agent, but chat should be the main UI." | Rich chat on Agent-Native |
388
+ | "I want the agent to make an interactive control right now." | Generated inline UI |
381
389
  | "I already have an agent; I need a polished chat UI for it." | Rich chat on your agent |
382
390
  | "I already have a SaaS app; add an agent beside it." | Embedded sidecar |
383
391
  | "The agent and UI should evolve together as the product." | Full application |
@@ -390,6 +398,7 @@ need to browse, compare, configure, or collaborate over persistent objects.
390
398
 
391
399
  - [Actions](/docs/actions) — define the headless operation once.
392
400
  - [Native Chat UI](/docs/native-chat-ui) — render typed action results in chat.
401
+ - [Generative UI](/docs/generative-ui) — generate transient or persisted sandboxed UI inline in chat.
393
402
  - [Drop-in Agent](/docs/drop-in-agent) — mount chat, sidebar, or panel surfaces.
394
403
  - [Component API](/docs/components) — lower-level React chat/composer pieces.
395
404
  - [Embedding SDK](/docs/embedding-sdk) — add Agent-Native to an existing app.
@@ -7,6 +7,12 @@ description: "Mini-apps your users build inside your template — a custom KPI t
7
7
 
8
8
  Extensions are **mini-apps your users build inside your template**.
9
9
 
10
+ When the agent needs a one-time interactive answer inside the chat itself, use
11
+ [Generative UI](/docs/generative-ui) instead. Generative UI uses the same
12
+ sandbox and bridge helpers, but `render-inline-extension` keeps the result
13
+ transient, while `create-extension` saves a reusable extension that also appears
14
+ in the Extensions view.
15
+
10
16
  If you've used QuickBooks Online, you've seen the model: QBO ships a core accounting product, and users layer on small custom widgets — a custom report, a payroll calculator, a tax-rule checker — that live inside the same app and use the same data. Extensions are the agent-native version of that idea, except your users don't write any code. They describe what they want, and the agent builds it.
11
17
 
12
18
  The framing matters: an extension isn't a generic "do whatever you want" sandbox. It's a **mini-app that extends a specific template** — Mail, Analytics, Calendar, Clips, Design — and uses that template's actions and data. A Mail extension reads emails. An Analytics extension reads a dashboard's metrics. A Calendar extension acts on the open event. They feel like part of the host product because they _are_ part of the host product.
@@ -169,12 +175,16 @@ Inside the iframe sandbox, every extension has these helpers on `window`:
169
175
  | `extensionData.list(collection, opts?)` | List persisted items | `extensionData.list('notes', { scope: 'all' })` |
170
176
  | `extensionData.get(collection, id, opts?)` | Get a single item | `extensionData.get('notes', 'note-1')` |
171
177
  | `extensionData.remove(collection, id, opts?)` | Delete a persisted item | `extensionData.remove('notes', 'note-1')` |
178
+ | `window.slotContext` | Read the page/chat context passed into this slot | `window.slotContext?.contactEmail` |
179
+ | `agentNative.ui.output(value, opts?)` | Record passive inline UI output in application state | `agentNative.ui.output({ threshold })` |
180
+ | `agentNative.chat.send(message, opts?)` | Send a prompt or selected value back to the agent chat | `agentNative.chat.send('Use Q2', { context: { q: 2 } })` |
172
181
 
173
182
  Three rules of thumb:
174
183
 
175
184
  - **Prefer `appAction` over `dbQuery`.** Actions are the template's official surface — they handle access control, scoping, and validation for you. Reach for raw SQL only when no action fits.
176
185
  - **Use `appAction` for template data.** Extension `appFetch` is limited to framework `/_agent-native/*` endpoints; template `/api/*` routes are blocked by the iframe bridge.
177
186
  - **Prefer `extensionData` over making new tables.** Each extension gets its own isolated key-value store. No schema, no migration. Set `{ scope: 'org' }` to share with the user's org, `'user'` (default) for private.
187
+ - **Use `agentNative.ui.output` for inline control values the agent should read later.** It writes `inline-ui:<extensionId>:output` to application state; `agentNative.chat.send` is for visible submit/apply messages.
178
188
 
179
189
  ```html
180
190
  <script>
@@ -0,0 +1,217 @@
1
+ ---
2
+ title: "Generative UI"
3
+ description: "Let the agent generate sandboxed interactive UI inline in chat, either transient for one turn or saved as reusable Extensions."
4
+ search: "generative UI inline extension render-inline-extension create-extension show-extension-inline sandboxed Alpine Tailwind slotContext sendToAgentChat agentNative.chat.send agentNative.ui.output"
5
+ ---
6
+
7
+ # Generative UI
8
+
9
+ Generative UI is the chat-native path for interactive surfaces the agent creates
10
+ at runtime. Instead of replying with only prose or a static table, the agent can
11
+ render a sandboxed Alpine.js/Tailwind mini-app directly inside the transcript:
12
+ controls, knobs, calculators, pickers, visualizers, dashboards, or any focused
13
+ surface that helps the user inspect and adjust an answer.
14
+
15
+ There are two lifetimes:
16
+
17
+ - **Transient** — `render-inline-extension` renders a one-time UI in the
18
+ current chat. It is not saved to the Extensions view.
19
+ - **Persisted** — `create-extension` saves the UI as an Extension and renders it
20
+ inline immediately. Later, `show-extension-inline` can load that saved
21
+ extension back into any chat.
22
+
23
+ Both paths use the same sandboxed extension runtime as [Extensions](/docs/extensions):
24
+ the generated HTML runs in an iframe with no host DOM access and reaches the app
25
+ only through scoped bridge helpers.
26
+
27
+ ```an-diagram title="Generated UI in chat" summary="The agent chooses a lifetime, returns an inline-extension payload, and chat mounts the sandboxed extension frame."
28
+ {
29
+ "html": "<div class=\"diagram-generative-ui\"><div class=\"diagram-card\" data-rough><strong>User asks</strong><small class=\"diagram-muted\">\"give me sliders for this model\"</small></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-panel\"><span class=\"diagram-pill accent\">Agent</span><small class=\"diagram-muted\">writes Alpine + Tailwind</small><div class=\"diagram-row\"><span class=\"diagram-pill\">transient</span><span class=\"diagram-pill\">persisted</span></div></div><div class=\"diagram-arrow diagram-muted\" aria-hidden=\"true\">&rarr;</div><div class=\"diagram-card\" data-rough><strong>Chat iframe</strong><small class=\"diagram-muted\">same theme · app bridge · chat output</small></div></div>",
30
+ "css": ".diagram-generative-ui{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.diagram-generative-ui .diagram-card,.diagram-generative-ui .diagram-panel{display:flex;flex-direction:column;gap:7px;padding:14px 16px;min-width:180px}.diagram-generative-ui .diagram-row{display:flex;gap:6px;flex-wrap:wrap}.diagram-generative-ui .diagram-arrow{font-size:22px;line-height:1}"
31
+ }
32
+ ```
33
+
34
+ ## When to use it {#when-to-use-it}
35
+
36
+ Use generative UI when the user needs to manipulate or inspect an answer in the
37
+ chat itself:
38
+
39
+ - tune weights, thresholds, ranges, or filters with controls
40
+ - compare generated variants side by side
41
+ - preview a calculation before committing it
42
+ - select items from app data and send the choice back to chat
43
+ - explore a temporary chart or dashboard without adding a route
44
+
45
+ Use a normal [Native Chat UI](/docs/native-chat-ui) data widget when a typed
46
+ action already knows the result shape, such as a table, chart, or insights
47
+ summary. Use [MCP Apps](/docs/mcp-apps) when an external host like Claude or
48
+ ChatGPT should render a real app route inline. Use a full app screen when the
49
+ surface is a durable product workflow users will browse outside chat.
50
+
51
+ ## Agent actions {#actions}
52
+
53
+ The built-in extension actions are the agent-facing API:
54
+
55
+ | Action | Saves to Extensions | Renders inline | Use it for |
56
+ | ------------------------- | ------------------- | -------------- | ---------------------------------------------- |
57
+ | `render-inline-extension` | No | Yes | one-time controls, pickers, calculators, demos |
58
+ | `create-extension` | Yes | Yes | reusable widgets, dashboards, mini-apps |
59
+ | `show-extension-inline` | Already saved | Yes | reopening a saved extension inside a chat |
60
+ | `update-extension` | Yes | On next render | editing an existing saved extension |
61
+
62
+ The action result declares `chatUI: { renderer: "core.inline-extension" }`.
63
+ Assistant chat and the lightweight `AgentConversation` transcript both use that
64
+ metadata to render the sandboxed UI instead of showing raw JSON.
65
+
66
+ ## Inputs from chat {#inputs}
67
+
68
+ Pass chat inputs through the action `context` argument. The generated iframe
69
+ receives that object as `window.slotContext`, and can subscribe to updates with
70
+ `window.onSlotContext(fn)`.
71
+
72
+ ```html
73
+ <div x-data="thresholdTuner">
74
+ <label class="text-sm font-medium text-foreground">Threshold</label>
75
+ <input
76
+ type="range"
77
+ min="0"
78
+ max="100"
79
+ x-model.number="threshold"
80
+ class="w-full"
81
+ />
82
+ <p class="text-sm text-muted-foreground" x-text="`Current: ${threshold}`"></p>
83
+ </div>
84
+
85
+ <script>
86
+ Alpine.data("thresholdTuner", () => ({
87
+ threshold: 50,
88
+ init() {
89
+ this.threshold = Number(window.slotContext?.threshold ?? 50);
90
+ window.onSlotContext?.((ctx) => {
91
+ if (ctx.threshold !== undefined) this.threshold = Number(ctx.threshold);
92
+ });
93
+ },
94
+ }));
95
+ </script>
96
+ ```
97
+
98
+ ## App state and app data {#app-state}
99
+
100
+ Generated UI can see and update the app through the standard extension bridge:
101
+
102
+ - `appAction(name, params)` calls template/framework actions.
103
+ - `appFetch(path, options)` calls allowed framework routes under
104
+ `/_agent-native/*`, including application-state endpoints.
105
+ - `extensionData` stores per-extension data. Transient inline UIs get a local
106
+ chat-scoped adapter; persisted extensions use the normal authenticated
107
+ database-backed extension data API.
108
+ - `dbQuery`, `dbExec`, and `extensionFetch` are available with the same role and
109
+ route gates as saved extensions.
110
+
111
+ Prefer `appAction` for domain data. Actions carry validation, access checks, and
112
+ business rules; raw SQL is for cases where no action exists.
113
+
114
+ For transient UIs, `extensionData` is intentionally local to the browser. It is
115
+ stored in host `localStorage`, is not visible to the agent or backend, does not
116
+ sync across devices, does not migrate if the UI is later promoted to a saved
117
+ Extension, and is not garbage-collected by the server. Use it only for
118
+ throwaway local UI state. If the agent or the app needs to observe a value, use
119
+ `agentNative.ui.output`, application state through `appFetch`, an `appAction`, or
120
+ `agentNative.chat.send`.
121
+
122
+ ## Outputs back to chat {#outputs}
123
+
124
+ Use passive output for controls whose current value should be readable later
125
+ without forcing the user to click a submit button:
126
+
127
+ ```html
128
+ <div x-data="{ threshold: 50 }">
129
+ <input
130
+ type="range"
131
+ min="0"
132
+ max="100"
133
+ x-model.number="threshold"
134
+ @input="agentNative.ui.output({ threshold }, { label: 'Threshold' })"
135
+ class="w-full"
136
+ />
137
+ </div>
138
+ ```
139
+
140
+ `agentNative.ui.output(value, options)` writes the current value to
141
+ application state under a conventioned key:
142
+
143
+ ```txt
144
+ inline-ui:<extensionId>:output
145
+ ```
146
+
147
+ The stored value includes the submitted `value`, `updatedAt`, `extensionId`, and
148
+ `source: "inline-ui"`, plus optional `label`, `context`, or `meta` fields. When
149
+ the user says "use that value" or "apply the current selection", the agent reads
150
+ that key with `readAppState("inline-ui:<id>:output")`.
151
+
152
+ Generated UI can send a visible prompt or result back into the current app chat:
153
+
154
+ ```html
155
+ <button
156
+ class="rounded-md bg-primary px-3 py-2 text-primary-foreground"
157
+ @click="agentNative.chat.send(`Use threshold ${threshold}`, {
158
+ context: JSON.stringify({ threshold }),
159
+ submit: true
160
+ })"
161
+ >
162
+ Apply in chat
163
+ </button>
164
+ ```
165
+
166
+ `agentNative.chat.send(message, options)` is also available as
167
+ `sendToAgentChat(message, options)`.
168
+
169
+ Options:
170
+
171
+ | Option | Default | Effect |
172
+ | ------------- | ------- | ------------------------------------------------ |
173
+ | `context` | none | hidden context appended to the submitted message |
174
+ | `submit` | `true` | `false` pre-fills/reviews instead of auto-submit |
175
+ | `openSidebar` | `true` | opens the agent sidebar when the message is sent |
176
+
177
+ This is the same app chat bridge used by normal UI components, so generated
178
+ controls can hand structured selections back to the agent without calling an LLM
179
+ directly from the iframe.
180
+
181
+ ## Styling and theming {#theming}
182
+
183
+ Generated UI uses the app's Tailwind theme tokens. Prefer semantic classes:
184
+
185
+ - `bg-background`, `text-foreground`, `border-border`
186
+ - `bg-card`, `text-card-foreground`
187
+ - `bg-primary`, `text-primary-foreground`
188
+ - `text-muted-foreground`, `bg-accent`
189
+
190
+ The extension shell injects the same CSS variables as the parent app and pushes
191
+ theme updates into the iframe. Avoid hardcoded one-off colors unless the user
192
+ asks for a specific brand treatment.
193
+
194
+ ## Security model {#security}
195
+
196
+ Generative UI is arbitrary user-authored HTML, so it always runs in the
197
+ extension sandbox:
198
+
199
+ - iframe sandbox excludes `allow-same-origin`
200
+ - no parent DOM or cookies are exposed to generated code
201
+ - bridge requests are path-allowlisted under `/_agent-native/*`
202
+ - viewer/editor/owner role policy is enforced in the parent before requests are
203
+ sent, and again server-side for saved extension data
204
+ - template `/api/*` routes are not reachable through `appFetch`; expose domain
205
+ operations as actions instead
206
+
207
+ Do not put provider tokens, private data, or internal secrets directly in the
208
+ generated HTML. Use `extensionFetch()` with `${keys.NAME}` placeholders or
209
+ template actions that resolve credentials server-side.
210
+
211
+ ## Related docs {#related}
212
+
213
+ - [Extensions](/docs/extensions) — saved sandboxed mini-apps and the bridge API.
214
+ - [Native Chat UI](/docs/native-chat-ui) — typed first-party React widgets for
215
+ action results.
216
+ - [MCP Apps](/docs/mcp-apps) — inline app routes in external MCP hosts.
217
+ - [Actions](/docs/actions) — the app/API surface generated UI should call.
@@ -246,9 +246,9 @@ See [Context Awareness](/docs/context-awareness) for the full pattern: navigatio
246
246
 
247
247
  ## One action, many surfaces {#protocols}
248
248
 
249
- Implement a domain operation once as an action; the framework exposes it to every consumer. The same `defineAction()` becomes an agent tool, a typesafe UI hook, an HTTP endpoint, a CLI command, an MCP tool, and an A2A tool, with optional `link`, `mcpApp`, or explicit native-widget metadata added only when a surface needs it. Skills and instructions cover behavior.
249
+ Implement a domain operation once as an action; the framework exposes it to every consumer. The same `defineAction()` becomes an agent tool, a typesafe UI hook, an HTTP endpoint, a CLI command, an MCP tool, and an A2A tool, with optional `link`, `mcpApp`, native-widget metadata, or Generative UI wrappers added only when a surface needs richer interaction. Skills and instructions cover behavior.
250
250
 
251
- For the full protocol/surface matrix (MCP server and OAuth, MCP Apps, A2A, deep links, native chat widgets, AgentChatRuntime connectors, Agent Web, and the adapter horizon for ACP and A2UI), and for choosing a product shape — headless, rich chat, embedded sidecar, or full app — see [Agent Surfaces](/docs/agent-surfaces).
251
+ For the full protocol/surface matrix (MCP server and OAuth, MCP Apps, A2A, deep links, native chat widgets, Generative UI, AgentChatRuntime connectors, Agent Web, and the adapter horizon for ACP and A2UI), and for choosing a product shape — headless, rich chat, embedded sidecar, or full app — see [Agent Surfaces](/docs/agent-surfaces).
252
252
 
253
253
  ## Agent modifies code {#agent-modifies-code}
254
254
 
@@ -12,11 +12,12 @@ description: "Author and embed interactive MCP App UIs inside Claude, ChatGPT, a
12
12
  | Connect an external agent/host to your app | [External Agents](/docs/external-agents) |
13
13
  | Give your agent more tools (consume other MCP servers) | [MCP Clients](/docs/mcp-clients) |
14
14
  | Build inline UIs that render in Claude/ChatGPT | **This page** — MCP Apps |
15
+ | Build generated inline UI inside Agent-Native chat | [Generative UI](/docs/generative-ui) |
15
16
  | Lower-level MCP server reference (auth, tools, custom mount) | [MCP Protocol](/docs/mcp-protocol) |
16
17
 
17
18
  MCP Apps are the official `io.modelcontextprotocol/ui` extension that lets compatible hosts — Claude, Claude Desktop, ChatGPT, VS Code GitHub Copilot, Goose, Postman, MCPJam, and Cursor — render interactive UIs inline in chat. In agent-native apps, every MCP App is a **real React route**, not a separate plain-HTML widget.
18
19
 
19
- Inside an Agent-Native app's own chat, prefer [native chat renderers](/docs/native-chat-ui) for first-party widgets such as tables, charts, typed results, and approval affordances. Use MCP Apps for external/cross-host inline UI in Claude, ChatGPT, Copilot, Cursor, and other compatible hosts, with the action `link` as the universal deep-link fallback.
20
+ Inside an Agent-Native app's own chat, prefer [native chat renderers](/docs/native-chat-ui) for first-party widgets such as tables, charts, typed results, and approval affordances. Use [Generative UI](/docs/generative-ui) when the in-app agent should create arbitrary sandboxed controls or visualizers inline. Use MCP Apps for external/cross-host inline UI in Claude, ChatGPT, Copilot, Cursor, and other compatible hosts, with the action `link` as the universal deep-link fallback.
20
21
 
21
22
  ## Authoring: optional MCP Apps UI {#mcp-apps}
22
23
 
@@ -141,7 +142,4 @@ Test MCP Apps with the lightweight fixtures around `embedApp()` and `McpAppRende
141
142
  - [External Agents](/docs/external-agents) — connecting Claude, ChatGPT, Codex, and Cursor to hosted apps; MCP Apps compatibility matrix; catalog tiers; deep links.
142
143
  - [MCP Protocol](/docs/mcp-protocol) — the auto-mounted MCP server, auth, tools, and `ask-agent`.
143
144
  - [Actions](/docs/actions) — `defineAction`, the `link` builder, `publicAgent`.
144
-
145
- ```
146
-
147
- ```
145
+ - [Generative UI](/docs/generative-ui) — generated inline UI inside the app's own chat.
@@ -13,9 +13,11 @@ normal app chat.
13
13
 
14
14
  Use native chat UI when the user should inspect output where the agent is
15
15
  already speaking: query results, response insights, setup summaries,
16
- approval/denial controls, or links into app views. Use [MCP Apps](/docs/mcp-apps)
17
- when an external host such as Claude, ChatGPT, Copilot, or Cursor should render
18
- an inline route from your app.
16
+ approval/denial controls, or links into app views. Use
17
+ [Generative UI](/docs/generative-ui) when the agent needs to create arbitrary
18
+ one-off controls, pickers, calculators, or visualizers in the in-app chat. Use
19
+ [MCP Apps](/docs/mcp-apps) when an external host such as Claude, ChatGPT,
20
+ Copilot, or Cursor should render an inline route from your app.
19
21
 
20
22
  ```an-diagram title="The native render path" summary="An action returns JSON; the runtime matches an explicit widget discriminant or chatUI.renderer; AssistantChat mounts a real React component. No iframe, no HTML execution."
21
23
  {
@@ -155,12 +157,14 @@ requiring each template to ship its own chat renderer:
155
157
  Keep chart data compact. For large datasets, aggregate in the action and link
156
158
  to the full app view with `display.primaryAction` or action `link` metadata.
157
159
 
158
- ## Native widgets vs MCP Apps {#native-vs-mcp-apps}
160
+ ## Native widgets vs Generative UI vs MCP Apps {#native-vs-mcp-apps}
159
161
 
160
- Native chat widgets and MCP Apps are complementary:
162
+ Native chat widgets, Generative UI, and MCP Apps are complementary:
161
163
 
162
164
  - **Native widgets** are for the app's own chat runtime. The action result is
163
165
  JSON, and the framework renders the built-in React widget.
166
+ - **Generative UI** is for arbitrary sandboxed Alpine/Tailwind UI that the
167
+ agent creates or reloads inline in the app's own chat.
164
168
  - **MCP Apps** are for external hosts. The action declares `mcpApp` and usually
165
169
  `link`, and the host renders a real app route inline when supported.
166
170
  - **Deep links** remain the universal fallback. Use action `link` or
@@ -144,7 +144,8 @@ configureTracking({
144
144
  endpoint: "https://analytics.example.com/api/analytics/track",
145
145
  sessionReplay: {
146
146
  enabled: true,
147
- sampleRate: 1,
147
+ requireSignedInUser: true,
148
+ sampleRate: 0.1,
148
149
  },
149
150
  getDefaultProps: (_event, props) => ({
150
151
  ...props,
@@ -156,15 +157,20 @@ configureTracking({
156
157
 
157
158
  When `sessionReplay.enabled` is truthy, the client dynamically imports `@rrweb/record` after startup and posts replay chunks to the replay endpoint. If `endpoint` ends in `/api/analytics/track` or `/track`, the replay endpoint is derived automatically as `/api/analytics/replay`. Override it explicitly with `sessionReplay.endpoint` when the replay collector lives somewhere else.
158
159
 
159
- Agent Native template roots already call `configureTracking()`, so hosted template deployments can use Vite/Netlify environment variables instead of editing code:
160
+ Agent Native template roots already call `configureTracking()`. Hosted template deployments can turn replay on with Vite/Netlify environment variables, while library consumers should prefer the explicit `configureTracking({ key, endpoint, sessionReplay })` form above:
160
161
 
161
162
  ```bash
162
163
  VITE_AGENT_NATIVE_ANALYTICS_PUBLIC_KEY=anpk_...
163
164
  VITE_AGENT_NATIVE_ANALYTICS_ENDPOINT=https://analytics.example.com/api/analytics/track
164
165
  VITE_AGENT_NATIVE_SESSION_REPLAY_ENABLED=true
165
- VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=1
166
+ VITE_AGENT_NATIVE_SESSION_REPLAY_REQUIRE_AUTH=true
167
+ VITE_AGENT_NATIVE_SESSION_REPLAY_SAMPLE_RATE=0.1
166
168
  ```
167
169
 
170
+ The browser helper also performs a best-effort, non-blocking read of the current Agent Native auth session. When `requireSignedInUser` or `VITE_AGENT_NATIVE_SESSION_REPLAY_REQUIRE_AUTH` is enabled, replay does not start unless the session resolves to a signed-in user. Signed-in replays include `userId`/`userEmail` plus `orgId`; if auth gating is disabled, anonymous recordings remain queryable by anonymous visitor, session, app/template, hostname, and path.
171
+
172
+ Session replay is sampled deterministically per browser session. A `sampleRate` of `0.1` records about 10% of eligible sessions; use `1` when the eligible population is intentionally small, such as logged-in-only dogfooding.
173
+
168
174
  Privacy defaults are intentionally conservative but still useful for playback:
169
175
 
170
176
  - Inputs are masked by default (`maskAllInputs: true`).
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.78.9",
3
+ "version": "0.79.1",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -2,6 +2,7 @@ export const ACTION_CHAT_UI_DATA_TABLE_RENDERER = "core.data-table";
2
2
  export const ACTION_CHAT_UI_DATA_CHART_RENDERER = "core.data-chart";
3
3
  export const ACTION_CHAT_UI_DATA_INSIGHTS_RENDERER = "core.data-insights";
4
4
  export const ACTION_CHAT_UI_DATA_WIDGET_RENDERER = "core.data-widget";
5
+ export const ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER = "core.inline-extension";
5
6
 
6
7
  export interface ActionChatUIConfig {
7
8
  /**
@@ -4254,6 +4254,14 @@ export function createProductionAgentHandler(
4254
4254
  `[agent-chat] resolved engine=${engine.name} model=${model} requestEngine=${requestEngine ?? "(none)"}`,
4255
4255
  );
4256
4256
 
4257
+ // DIAGNOSTIC-ONLY: the worker reaches post_model_ok but never aw_env — the
4258
+ // only exit between them is this anthropic key check. Capture the exact
4259
+ // resolution state so we know WHY effectiveApiKey is falsy in the worker
4260
+ // (owner not resolved from the HMAC/thread? owner has no stored key? deploy
4261
+ // fallback blocked?) vs the foreground which resolves it fine.
4262
+ await awaitedWorkerMark(
4263
+ `apikey_state:engine=${engine.name},owner=${ownerEmail ? "Y" : "N"},userKey=${userApiKey ? "Y" : "N"},effKey=${effectiveApiKey ? "Y" : "N"},block=${shouldBlockDeployCredentialFallback()}`,
4264
+ );
4257
4265
  // Check for API key before starting a run (only for anthropic engine)
4258
4266
  if (engine.name === "anthropic" && !effectiveApiKey) {
4259
4267
  setResponseHeader(event, "Content-Type", "text/event-stream");