@agent-native/core 0.84.34 → 0.84.36

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 (230) hide show
  1. package/README.md +15 -51
  2. package/corpus/README.md +1 -1
  3. package/corpus/core/CHANGELOG.md +20 -0
  4. package/corpus/core/docs/content/actions.mdx +17 -24
  5. package/corpus/core/docs/content/agent-surfaces.mdx +59 -56
  6. package/corpus/core/docs/content/cloneable-saas.mdx +3 -3
  7. package/corpus/core/docs/content/faq.mdx +4 -4
  8. package/corpus/core/docs/content/getting-started.mdx +246 -204
  9. package/corpus/core/docs/content/key-concepts.mdx +9 -9
  10. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +3 -3
  11. package/corpus/core/docs/content/locales/ar-SA/faq.mdx +4 -4
  12. package/corpus/core/docs/content/locales/ar-SA/getting-started.mdx +148 -214
  13. package/corpus/core/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -9
  14. package/corpus/core/docs/content/locales/ar-SA/template-chat.mdx +2 -2
  15. package/corpus/core/docs/content/locales/ar-SA/using-your-agent.mdx +2 -2
  16. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +3 -3
  17. package/corpus/core/docs/content/locales/de-DE/faq.mdx +4 -4
  18. package/corpus/core/docs/content/locales/de-DE/getting-started.mdx +145 -211
  19. package/corpus/core/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -9
  20. package/corpus/core/docs/content/locales/de-DE/template-chat.mdx +2 -2
  21. package/corpus/core/docs/content/locales/de-DE/using-your-agent.mdx +2 -2
  22. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +3 -3
  23. package/corpus/core/docs/content/locales/es-ES/faq.mdx +4 -4
  24. package/corpus/core/docs/content/locales/es-ES/getting-started.mdx +148 -214
  25. package/corpus/core/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -9
  26. package/corpus/core/docs/content/locales/es-ES/template-chat.mdx +2 -2
  27. package/corpus/core/docs/content/locales/es-ES/using-your-agent.mdx +2 -2
  28. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  29. package/corpus/core/docs/content/locales/fr-FR/faq.mdx +4 -4
  30. package/corpus/core/docs/content/locales/fr-FR/getting-started.mdx +146 -212
  31. package/corpus/core/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -9
  32. package/corpus/core/docs/content/locales/fr-FR/template-chat.mdx +2 -2
  33. package/corpus/core/docs/content/locales/fr-FR/using-your-agent.mdx +2 -2
  34. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +3 -3
  35. package/corpus/core/docs/content/locales/hi-IN/faq.mdx +4 -4
  36. package/corpus/core/docs/content/locales/hi-IN/getting-started.mdx +149 -215
  37. package/corpus/core/docs/content/locales/hi-IN/pure-agent-apps.mdx +8 -13
  38. package/corpus/core/docs/content/locales/hi-IN/template-chat.mdx +2 -2
  39. package/corpus/core/docs/content/locales/hi-IN/using-your-agent.mdx +2 -2
  40. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  41. package/corpus/core/docs/content/locales/ja-JP/faq.mdx +4 -4
  42. package/corpus/core/docs/content/locales/ja-JP/getting-started.mdx +144 -210
  43. package/corpus/core/docs/content/locales/ja-JP/pure-agent-apps.mdx +8 -13
  44. package/corpus/core/docs/content/locales/ja-JP/template-chat.mdx +2 -2
  45. package/corpus/core/docs/content/locales/ja-JP/using-your-agent.mdx +2 -2
  46. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +3 -3
  47. package/corpus/core/docs/content/locales/ko-KR/faq.mdx +4 -4
  48. package/corpus/core/docs/content/locales/ko-KR/getting-started.mdx +146 -212
  49. package/corpus/core/docs/content/locales/ko-KR/pure-agent-apps.mdx +8 -13
  50. package/corpus/core/docs/content/locales/ko-KR/template-chat.mdx +2 -2
  51. package/corpus/core/docs/content/locales/ko-KR/using-your-agent.mdx +2 -2
  52. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +3 -3
  53. package/corpus/core/docs/content/locales/pt-BR/faq.mdx +4 -4
  54. package/corpus/core/docs/content/locales/pt-BR/getting-started.mdx +145 -211
  55. package/corpus/core/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -9
  56. package/corpus/core/docs/content/locales/pt-BR/template-chat.mdx +2 -2
  57. package/corpus/core/docs/content/locales/pt-BR/using-your-agent.mdx +2 -2
  58. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +3 -3
  59. package/corpus/core/docs/content/locales/zh-CN/faq.mdx +4 -4
  60. package/corpus/core/docs/content/locales/zh-CN/getting-started.mdx +158 -209
  61. package/corpus/core/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -9
  62. package/corpus/core/docs/content/locales/zh-CN/template-chat.mdx +2 -2
  63. package/corpus/core/docs/content/locales/zh-CN/using-your-agent.mdx +2 -2
  64. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +3 -3
  65. package/corpus/core/docs/content/locales/zh-TW/faq.mdx +4 -4
  66. package/corpus/core/docs/content/locales/zh-TW/getting-started.mdx +158 -212
  67. package/corpus/core/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -9
  68. package/corpus/core/docs/content/locales/zh-TW/template-chat.mdx +2 -2
  69. package/corpus/core/docs/content/locales/zh-TW/using-your-agent.mdx +2 -2
  70. package/corpus/core/docs/content/native-chat-ui.mdx +17 -32
  71. package/corpus/core/docs/content/pure-agent-apps.mdx +46 -26
  72. package/corpus/core/docs/content/template-chat.mdx +8 -8
  73. package/corpus/core/docs/content/using-your-agent.mdx +2 -2
  74. package/corpus/core/docs/content/what-is-agent-native.mdx +6 -6
  75. package/corpus/core/package.json +1 -1
  76. package/corpus/core/src/a2a/response-text.ts +10 -1
  77. package/corpus/core/src/agent/production-agent.ts +23 -20
  78. package/corpus/core/src/agent/run-manager.ts +46 -1
  79. package/corpus/core/src/agent/thread-data-builder.ts +15 -2
  80. package/corpus/core/src/cli/skills.ts +7 -9
  81. package/corpus/core/src/client/MultiTabAssistantChat.tsx +2 -0
  82. package/corpus/core/src/client/RunStuckBanner.tsx +172 -18
  83. package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +57 -9
  84. package/corpus/core/src/client/blocks/library/wireframe.tsx +3 -18
  85. package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +28 -32
  86. package/corpus/core/src/client/code-agent-chat-adapter.ts +8 -1
  87. package/corpus/core/src/client/sse-event-processor.ts +21 -3
  88. package/corpus/core/src/code-agents/transcript-normalizer.ts +31 -0
  89. package/corpus/core/src/db/schema.ts +5 -0
  90. package/corpus/core/src/server/agent-chat-plugin.ts +8 -2
  91. package/corpus/core/src/server/agent-teams.ts +24 -2
  92. package/corpus/core/src/styles/blocks.css +27 -6
  93. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -4
  94. package/corpus/templates/analytics/changelog/2026-07-01-smoother-chat-streaming.md +6 -0
  95. package/corpus/templates/content/actions/list-trashed-content-databases.ts +1 -1
  96. package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -9
  97. package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -9
  98. package/dist/a2a/response-text.d.ts +1 -0
  99. package/dist/a2a/response-text.d.ts.map +1 -1
  100. package/dist/a2a/response-text.js +8 -2
  101. package/dist/a2a/response-text.js.map +1 -1
  102. package/dist/agent/production-agent.d.ts.map +1 -1
  103. package/dist/agent/production-agent.js +31 -27
  104. package/dist/agent/production-agent.js.map +1 -1
  105. package/dist/agent/run-manager.d.ts +12 -0
  106. package/dist/agent/run-manager.d.ts.map +1 -1
  107. package/dist/agent/run-manager.js +32 -1
  108. package/dist/agent/run-manager.js.map +1 -1
  109. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  110. package/dist/agent/thread-data-builder.js +15 -2
  111. package/dist/agent/thread-data-builder.js.map +1 -1
  112. package/dist/cli/skills.d.ts +1 -1
  113. package/dist/cli/skills.d.ts.map +1 -1
  114. package/dist/cli/skills.js +7 -9
  115. package/dist/cli/skills.js.map +1 -1
  116. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  117. package/dist/client/MultiTabAssistantChat.js +1 -1
  118. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  119. package/dist/client/RunStuckBanner.d.ts +13 -1
  120. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  121. package/dist/client/RunStuckBanner.js +123 -16
  122. package/dist/client/RunStuckBanner.js.map +1 -1
  123. package/dist/client/blocks/library/wireframe-kit.d.ts +6 -6
  124. package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
  125. package/dist/client/blocks/library/wireframe-kit.js +52 -5
  126. package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
  127. package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
  128. package/dist/client/blocks/library/wireframe.js +1 -11
  129. package/dist/client/blocks/library/wireframe.js.map +1 -1
  130. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  131. package/dist/client/chat/widgets/builtin-tool-renderers.js +27 -31
  132. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  133. package/dist/client/code-agent-chat-adapter.d.ts.map +1 -1
  134. package/dist/client/code-agent-chat-adapter.js +5 -1
  135. package/dist/client/code-agent-chat-adapter.js.map +1 -1
  136. package/dist/client/sse-event-processor.d.ts.map +1 -1
  137. package/dist/client/sse-event-processor.js +21 -3
  138. package/dist/client/sse-event-processor.js.map +1 -1
  139. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
  140. package/dist/code-agents/transcript-normalizer.js +24 -0
  141. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  142. package/dist/collab/awareness.d.ts +2 -2
  143. package/dist/collab/awareness.d.ts.map +1 -1
  144. package/dist/collab/routes.d.ts +2 -2
  145. package/dist/db/schema.d.ts +2 -1
  146. package/dist/db/schema.d.ts.map +1 -1
  147. package/dist/db/schema.js +3 -2
  148. package/dist/db/schema.js.map +1 -1
  149. package/dist/notifications/routes.d.ts +3 -3
  150. package/dist/resources/handlers.d.ts +3 -3
  151. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  152. package/dist/server/agent-chat-plugin.js +2 -3
  153. package/dist/server/agent-chat-plugin.js.map +1 -1
  154. package/dist/server/agent-teams.d.ts.map +1 -1
  155. package/dist/server/agent-teams.js +17 -2
  156. package/dist/server/agent-teams.js.map +1 -1
  157. package/dist/server/transcribe-voice.d.ts +1 -1
  158. package/dist/styles/blocks.css +27 -6
  159. package/docs/content/actions.mdx +17 -24
  160. package/docs/content/agent-surfaces.mdx +59 -56
  161. package/docs/content/cloneable-saas.mdx +3 -3
  162. package/docs/content/faq.mdx +4 -4
  163. package/docs/content/getting-started.mdx +246 -204
  164. package/docs/content/key-concepts.mdx +9 -9
  165. package/docs/content/locales/ar-SA/cloneable-saas.mdx +3 -3
  166. package/docs/content/locales/ar-SA/faq.mdx +4 -4
  167. package/docs/content/locales/ar-SA/getting-started.mdx +148 -214
  168. package/docs/content/locales/ar-SA/pure-agent-apps.mdx +4 -9
  169. package/docs/content/locales/ar-SA/template-chat.mdx +2 -2
  170. package/docs/content/locales/ar-SA/using-your-agent.mdx +2 -2
  171. package/docs/content/locales/de-DE/cloneable-saas.mdx +3 -3
  172. package/docs/content/locales/de-DE/faq.mdx +4 -4
  173. package/docs/content/locales/de-DE/getting-started.mdx +145 -211
  174. package/docs/content/locales/de-DE/pure-agent-apps.mdx +4 -9
  175. package/docs/content/locales/de-DE/template-chat.mdx +2 -2
  176. package/docs/content/locales/de-DE/using-your-agent.mdx +2 -2
  177. package/docs/content/locales/es-ES/cloneable-saas.mdx +3 -3
  178. package/docs/content/locales/es-ES/faq.mdx +4 -4
  179. package/docs/content/locales/es-ES/getting-started.mdx +148 -214
  180. package/docs/content/locales/es-ES/pure-agent-apps.mdx +4 -9
  181. package/docs/content/locales/es-ES/template-chat.mdx +2 -2
  182. package/docs/content/locales/es-ES/using-your-agent.mdx +2 -2
  183. package/docs/content/locales/fr-FR/cloneable-saas.mdx +2 -2
  184. package/docs/content/locales/fr-FR/faq.mdx +4 -4
  185. package/docs/content/locales/fr-FR/getting-started.mdx +146 -212
  186. package/docs/content/locales/fr-FR/pure-agent-apps.mdx +4 -9
  187. package/docs/content/locales/fr-FR/template-chat.mdx +2 -2
  188. package/docs/content/locales/fr-FR/using-your-agent.mdx +2 -2
  189. package/docs/content/locales/hi-IN/cloneable-saas.mdx +3 -3
  190. package/docs/content/locales/hi-IN/faq.mdx +4 -4
  191. package/docs/content/locales/hi-IN/getting-started.mdx +149 -215
  192. package/docs/content/locales/hi-IN/pure-agent-apps.mdx +8 -13
  193. package/docs/content/locales/hi-IN/template-chat.mdx +2 -2
  194. package/docs/content/locales/hi-IN/using-your-agent.mdx +2 -2
  195. package/docs/content/locales/ja-JP/cloneable-saas.mdx +2 -2
  196. package/docs/content/locales/ja-JP/faq.mdx +4 -4
  197. package/docs/content/locales/ja-JP/getting-started.mdx +144 -210
  198. package/docs/content/locales/ja-JP/pure-agent-apps.mdx +8 -13
  199. package/docs/content/locales/ja-JP/template-chat.mdx +2 -2
  200. package/docs/content/locales/ja-JP/using-your-agent.mdx +2 -2
  201. package/docs/content/locales/ko-KR/cloneable-saas.mdx +3 -3
  202. package/docs/content/locales/ko-KR/faq.mdx +4 -4
  203. package/docs/content/locales/ko-KR/getting-started.mdx +146 -212
  204. package/docs/content/locales/ko-KR/pure-agent-apps.mdx +8 -13
  205. package/docs/content/locales/ko-KR/template-chat.mdx +2 -2
  206. package/docs/content/locales/ko-KR/using-your-agent.mdx +2 -2
  207. package/docs/content/locales/pt-BR/cloneable-saas.mdx +3 -3
  208. package/docs/content/locales/pt-BR/faq.mdx +4 -4
  209. package/docs/content/locales/pt-BR/getting-started.mdx +145 -211
  210. package/docs/content/locales/pt-BR/pure-agent-apps.mdx +4 -9
  211. package/docs/content/locales/pt-BR/template-chat.mdx +2 -2
  212. package/docs/content/locales/pt-BR/using-your-agent.mdx +2 -2
  213. package/docs/content/locales/zh-CN/cloneable-saas.mdx +3 -3
  214. package/docs/content/locales/zh-CN/faq.mdx +4 -4
  215. package/docs/content/locales/zh-CN/getting-started.mdx +158 -209
  216. package/docs/content/locales/zh-CN/pure-agent-apps.mdx +4 -9
  217. package/docs/content/locales/zh-CN/template-chat.mdx +2 -2
  218. package/docs/content/locales/zh-CN/using-your-agent.mdx +2 -2
  219. package/docs/content/locales/zh-TW/cloneable-saas.mdx +3 -3
  220. package/docs/content/locales/zh-TW/faq.mdx +4 -4
  221. package/docs/content/locales/zh-TW/getting-started.mdx +158 -212
  222. package/docs/content/locales/zh-TW/pure-agent-apps.mdx +4 -9
  223. package/docs/content/locales/zh-TW/template-chat.mdx +2 -2
  224. package/docs/content/locales/zh-TW/using-your-agent.mdx +2 -2
  225. package/docs/content/native-chat-ui.mdx +17 -32
  226. package/docs/content/pure-agent-apps.mdx +46 -26
  227. package/docs/content/template-chat.mdx +8 -8
  228. package/docs/content/using-your-agent.mdx +2 -2
  229. package/docs/content/what-is-agent-native.mdx +6 -6
  230. package/package.json +1 -1
@@ -1,27 +1,29 @@
1
1
  ---
2
- title: "Pure-Agent Apps"
3
- description: "Apps where the agent is the whole product: the app-agent loop is the front door, and UI is added only when humans need it."
2
+ title: "Automation-First Apps"
3
+ description: "No-browser Agent-Native apps for scheduled jobs, queues, scripts, integration workers, and external agents."
4
4
  ---
5
5
 
6
- # Pure-Agent Apps
6
+ # Automation-First Apps
7
7
 
8
- A pure-agent app is the minimal end of agent-native: the app-agent loop is the
9
- product, not a dashboard. You send a request from the terminal, Slack, email, a
10
- scheduled job, another agent, or Chat "summarize my unread emails," "post the
11
- daily metrics to Slack" — and the agent acts and returns the result wherever it
12
- belongs. It is still a real app: actions, sessions, app state, history,
13
- settings, credentials, and share records all live in SQL.
8
+ Most Agent-Native products should start with chat and grow into inline results
9
+ and durable app pages. Use this pattern when the primary surface is not a
10
+ browser UI yet: scheduled reports, queues, integration workers, CLI loops, or
11
+ another app or agent calling this app over MCP/A2A.
14
12
 
15
- <Diagram id="doc-block-1rfgtal" title="The app-agent loop is the front door" summary={"Many entry points reach one agent loop over SQL-backed actions and state; results return to wherever the request came from. UI is added only when humans need to supervise."}>
13
+ Automation-first does **not** mean stateless. The app-agent loop still uses the
14
+ same Agent-Native contract: actions, sessions, app state, history, settings,
15
+ credentials, and share records live in SQL.
16
+
17
+ <Diagram id="doc-block-automation-first" title="Automation-first still uses the app contract" summary={"Jobs, scripts, channels, and external agents reach one Agent-Native loop over SQL-backed actions and state."}>
16
18
 
17
19
  ```html
18
20
  <div class="diagram-pure">
19
21
  <div class="diagram-col">
20
- <div class="diagram-pill">Terminal</div>
21
- <div class="diagram-pill">Slack · email</div>
22
22
  <div class="diagram-pill">Scheduled job</div>
23
+ <div class="diagram-pill">Queue worker</div>
24
+ <div class="diagram-pill">CLI script</div>
25
+ <div class="diagram-pill">Slack · email</div>
23
26
  <div class="diagram-pill">Another agent (A2A)</div>
24
- <div class="diagram-pill">Chat</div>
25
27
  </div>
26
28
  <div class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</div>
27
29
  <div class="diagram-panel center" data-rough>
@@ -30,7 +32,9 @@ settings, credentials, and share records all live in SQL.
30
32
  </div>
31
33
  <div class="diagram-arrow diagram-muted" aria-hidden="true">&rarr;</div>
32
34
  <div class="diagram-box" data-rough>
33
- Result returns<br /><small class="diagram-muted">to where it belongs</small>
35
+ Result returns<br /><small class="diagram-muted"
36
+ >to the channel that asked</small
37
+ >
34
38
  </div>
35
39
  </div>
36
40
  ```
@@ -62,20 +66,36 @@ settings, credentials, and share records all live in SQL.
62
66
  </Diagram>
63
67
 
64
68
  Reach for this shape when the work runs in the background, the output leaves the
65
- app, the domain is one-shot, or you're prototyping. The agent still needs a UI —
66
- not a dashboard, but a place for humans to supervise, configure, and steer it
67
- which is why even pure-agent apps usually mount the built-in Chat shell.
69
+ app, the domain is one-shot, or you are building a callable workflow for another
70
+ system. If users need to inspect, compare, correct, or share persistent objects,
71
+ start with [Chat](/docs/template-chat) or add a small app page around the same
72
+ actions.
73
+
74
+ ## Scaffold {#scaffold}
75
+
76
+ Use the no-browser scaffold when you know you do not want a browser UI yet:
68
77
 
69
- This is the **headless** product shape. The full decision guide, what ships in
70
- the box, the scaffold, repo access, and run sharing now live in one place:
78
+ ```bash
79
+ npx @agent-native/core@latest create my-agent --headless
80
+ cd my-agent
81
+ pnpm install
82
+ ```
83
+
84
+ Then add actions and instructions exactly as you would in a chat app:
85
+
86
+ ```bash
87
+ pnpm agent "Run the daily response-insights report and post the summary."
88
+ ```
71
89
 
72
- [**Agent Surfaces Headless agent**](/docs/agent-surfaces#headless)
90
+ The `--headless` flag only chooses the initial scaffold. It does not choose a
91
+ different architecture. You can later move the same `actions/`, instructions,
92
+ skills, and SQL state into a chat app or full application surface.
73
93
 
74
- ## What's next
94
+ ## What to add next {#whats-next}
75
95
 
76
- - [**Agent Surfaces — Headless**](/docs/agent-surfaces#headless) — the full headless decision guide and APIs
77
- - [**Getting Started**](/docs/getting-started) — create a chat app or headless agent first
78
- - [**Dispatch**](/docs/template-dispatch) — the workspace template that's a great pure-agent starting point
79
- - [**Messaging the agent**](/docs/messaging) — how users talk to the agent across web, Slack, Telegram, email
96
+ - [**Getting Started**](/docs/getting-started) — the chat-first tutorial from action to inline result to durable page
97
+ - [**Agent Surfaces — Automation-first app**](/docs/agent-surfaces#headless) — the full decision guide and APIs
98
+ - [**Actions**](/docs/actions) — the operations your automation calls
99
+ - [**Messaging the agent**](/docs/messaging) — how users talk to the agent across web, Slack, Telegram, and email
80
100
  - [**Recurring Jobs**](/docs/recurring-jobs) — scheduled prompts the agent runs on its own
81
- - [**Actions**](/docs/actions) — the tools your pure-agent will call
101
+ - [**Dispatch**](/docs/template-dispatch) — the workspace control plane for shared secrets, scheduled jobs, and delegated work
@@ -5,9 +5,9 @@ description: "A minimal chat-first agent-native app: durable chat threads, actio
5
5
 
6
6
  # Chat Template
7
7
 
8
- Chat is the basic agent-native app starting point. It gives you a clean ChatGPT-style shell with chat at the center, a threads list on the left, standard app navigation, auth, live sync, actions, and one example action. Start here when you want a real browser app you can build on without committing to a domain template.
8
+ Chat is the basic agentic app starting point. It gives you a clean ChatGPT-style shell with chat at the center, a threads list on the left, standard app navigation, auth, live sync, actions, and one example action. Start here when you want a real browser app you can build on before committing to a domain template.
9
9
 
10
- If you want the smallest action-only runtime with no browser UI, start with [Pure-Agent Apps](/docs/pure-agent-apps). If you want a finished domain product shape, start from [Calendar](/docs/template-calendar), [Mail](/docs/template-mail), [Content](/docs/template-content), [Forms](/docs/template-forms), [Analytics](/docs/template-analytics), or another domain template.
10
+ If you want a finished domain product shape, start from [Calendar](/docs/template-calendar), [Mail](/docs/template-mail), [Content](/docs/template-content), [Forms](/docs/template-forms), [Analytics](/docs/template-analytics), or another domain template. If you truly do not need a browser UI yet, see [Automation-First Apps](/docs/pure-agent-apps).
11
11
 
12
12
  <WireframeBlock id="doc-block-1qu69ww">
13
13
  <Screen
@@ -104,7 +104,7 @@ That's the point. Chat is a thin, useful default shell for your own agent, not a
104
104
  ## When to pick it {#when-to-pick}
105
105
 
106
106
  - **You want a basic app users can talk to immediately** and then extend with actions and UI.
107
- - **You have a headless app that needs chat** as the first browser surface.
107
+ - **You want the default Agent-Native on-ramp**: chat first, then actions, native results, and app pages.
108
108
  - **You want to plug your own agent backend into a familiar chat UI** while keeping Agent-Native's actions, state, auth, and deployment shape.
109
109
  - **You are prototyping a custom internal tool** that does not match a domain template.
110
110
 
@@ -117,13 +117,13 @@ pnpm install
117
117
  pnpm dev
118
118
  ```
119
119
 
120
- Or start with no UI and add a chat surface later:
120
+ The no-browser scaffold is still available for automation-first work, but it is not the main Chat template path:
121
121
 
122
122
  ```bash
123
123
  npx @agent-native/core@latest create my-agent --headless
124
124
  ```
125
125
 
126
- From there, copy the Chat template's `/` route and sidebar thread list into your app, or scaffold a Chat app and move the actions from your headless agent into its `actions/` directory. The key invariant stays the same: actions are the shared surface for chat, UI, HTTP, MCP, A2A, and CLI.
126
+ Use it for scheduled jobs, queues, CLI loops, or external-agent workflows where chat and app pages are not useful yet. The key invariant stays the same: actions are the shared surface for chat, UI, HTTP, MCP, A2A, and CLI.
127
127
 
128
128
  ## First code to inspect {#first-code}
129
129
 
@@ -196,8 +196,8 @@ The agent should add a Drizzle schema, actions, route, navigation, and instructi
196
196
 
197
197
  ## What's next
198
198
 
199
- - [**Getting Started**](/docs) — choose between headless, chat, and domain templates
200
- - [**Agent Surfaces**](/docs/agent-surfaces) — headless, chat, embedded, and full-app patterns
199
+ - [**Getting Started**](/docs) — build the chat-first path from action to inline result to app page
200
+ - [**Agent Surfaces**](/docs/agent-surfaces) — chat, inline UI, app pages, embedded, automation, and external-agent patterns
201
201
  - [**Actions**](/docs/actions) — the action system chat and UI both call
202
202
  - [**Native Chat UI**](/docs/native-chat-ui) — chat surface primitives and runtime options
203
- - [**Pure-Agent Apps**](/docs/pure-agent-apps) — action-only apps that can grow into Chat later
203
+ - [**Automation-First Apps**](/docs/pure-agent-apps) — no-browser workflows for jobs, queues, scripts, and external agents
@@ -99,7 +99,7 @@ The agent isn't a separate app you tab over to. It ships as a handful of React c
99
99
 
100
100
  Not every app needs a full dashboard. When the agent _is_ the product, you can skip most of the custom UI: open the app, ask for what you want, and let the agent do the rest. The agent still has its management surface — history, workspace, settings — but the primary interaction is conversation rather than clicks.
101
101
 
102
- → [**Pure-Agent Apps**](/docs/pure-agent-apps) — apps where the agent is the whole product.
102
+ → [**Automation-First Apps**](/docs/pure-agent-apps) — no-browser apps for jobs, queues, scripts, and external agents.
103
103
 
104
104
  ## You co-edit with it {#you-co-edit}
105
105
 
@@ -113,5 +113,5 @@ When you and the agent are working on the same document, you don't take turns. W
113
113
  - [**Agent Mentions**](/docs/agent-mentions) — direct it with `@`-mentions
114
114
  - [**Voice Input**](/docs/voice-input) — direct it by speaking
115
115
  - [**Drop-in Agent**](/docs/drop-in-agent) — embed it in any React app
116
- - [**Pure-Agent Apps**](/docs/pure-agent-apps) — go UI-light when the agent is the product
116
+ - [**Automation-First Apps**](/docs/pure-agent-apps) — use no-browser apps for jobs, queues, scripts, and external agents
117
117
  - [**Real-Time Collaboration**](/docs/real-time-collaboration) — co-edit the same document together
@@ -5,13 +5,13 @@ description: "Why most AI apps feel half-built, what makes an app truly agent-na
5
5
 
6
6
  # What Is Agent-Native?
7
7
 
8
- Agent-native is a way of building software where the AI agent and the product surface around it are **equal partners**. That surface can be a headless agent with one custom action, a rich chat, or a full UI. The important part is that agents and humans share the same actions, database, and state.
8
+ Agent-native is a way of building software where the AI agent and the product surface around it are **equal partners**. The usual path starts with chat, adds typed actions, renders structured results inline, and grows into durable app pages around the same SQL state. The important part is that agents and humans share the same actions, database, and state.
9
9
 
10
10
  If you only remember one thing from this page, remember this: most AI apps today stop one step short of being useful, and that gap is the biggest mistake in the space right now.
11
11
 
12
12
  ## What it looks like as a user {#what-it-looks-like}
13
13
 
14
- Picture a background worker, inbox, calendar, form builder, or analytics dashboard. Sometimes there is no custom screen yet: you run one action or one headless app-agent prompt. Sometimes the first screen is chat: you ask what you want, the agent guides setup, shows a table or chart, and opens the right app view. Sometimes chat is docked on the right side of a full application. Across those shapes, you can:
14
+ Picture a background worker, inbox, calendar, form builder, or analytics dashboard. Often the first screen is chat: you ask what you want, the agent guides setup, shows a table or chart, and opens the right app view. Sometimes chat is docked on the right side of a full application. Sometimes there is no custom screen yet because the workflow is a scheduled job, queue, script, or external-agent integration. Across those shapes, you can:
15
15
 
16
16
  - **Start with the real operation.** One durable action can run from the CLI, HTTP, MCP, A2A, the app-agent loop, and later a UI.
17
17
  - **Click anything you'd normally click when there is a UI.** All the buttons, lists, dashboards, keyboard shortcuts — they all call the same operations the agent can call.
@@ -116,7 +116,7 @@ Even when the agent does all the heavy lifting, humans still need to:
116
116
 
117
117
  At minimum, "a UI for the agent" is an observability and management dashboard. At maximum, it's a full SaaS app with the agent embedded as a co-pilot. Both ends count as agent-native, and the surface can grow from one without a rewrite.
118
118
 
119
- You don't have to choose a shape up front. The agent can run headless, sit behind a rich chat, or live inside a full application around the same action surface — see [Agent Surfaces](/docs/agent-surfaces) for the concrete shapes and APIs.
119
+ You don't have to choose every surface up front. The agent can start in rich chat, render native inline UI, live inside a full application, or run from automation and external-agent channels around the same action surface — see [Agent Surfaces](/docs/agent-surfaces) for the concrete shapes and APIs.
120
120
 
121
121
  ## Why every app benefits from an agent {#why-every-app-benefits-from-an-agent}
122
122
 
@@ -124,7 +124,7 @@ The flip side is just as important. Existing SaaS products keep hitting the same
124
124
 
125
125
  Agent-native flips that. Because every action in the app is defined once and exposed as both a button and an agent tool, the agent can do everything the buttons can — and more — without a separate "AI world" to maintain. Natural language becomes a first-class input alongside clicks.
126
126
 
127
- The argument isn't "agents replace UI." It's "**agents belong inside applications, with a UI on top, as equal partners**." Even an app where the agent _is_ the product still needs a UI for humans to supervise, configure, and steer it — see [Agent Surfaces — Headless](/docs/agent-surfaces#headless).
127
+ The argument isn't "agents replace UI." It's "**agents belong inside applications, with a UI on top, as equal partners**." Even an automation-first app still needs some surface for humans to supervise, configure, and steer it — usually chat, a job history, or a small status page. See [Agent Surfaces — Automation-first app](/docs/agent-surfaces#headless).
128
128
 
129
129
  ## Agent + UI parity {#agent-ui-parity}
130
130
 
@@ -394,8 +394,8 @@ One action, many surfaces: the agent calls it as a tool, the UI calls it as a ty
394
394
 
395
395
  ## What's next {#whats-next}
396
396
 
397
- - [**Getting Started**](/docs/getting-started) — start with one action, pick a template, or install a skill
398
- - [**Agent Surfaces**](/docs/agent-surfaces) — choose headless, rich chat, embedded sidecar, or full app
397
+ - [**Getting Started**](/docs/getting-started) — start with chat, add an action, render a native result, and grow into a page
398
+ - [**Agent Surfaces**](/docs/agent-surfaces) — choose chat, native inline UI, full app pages, embedded sidecar, automation, or external agent access
399
399
  - [**Key Concepts**](/docs/key-concepts) — the architecture: SQL, actions, polling sync, context awareness, portability
400
400
  - [**Templates**](/docs/cloneable-saas) — templates as complete products you own
401
401
  - [**Workspace**](/docs/workspace) — the per-user customization layer (skills, memory, instructions, MCP) backed by SQL, not files
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.84.34",
3
+ "version": "0.84.36",
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": {
@@ -4,6 +4,15 @@ export interface CollectFinalResponseTextOptions {
4
4
  fallbackToPreToolText?: boolean;
5
5
  }
6
6
 
7
+ export function applyAgentTextEventToBuffer(
8
+ currentText: string,
9
+ event: AgentChatEvent,
10
+ ): string {
11
+ if (event.type === "clear") return "";
12
+ if (event.type === "text") return currentText + event.text;
13
+ return currentText;
14
+ }
15
+
7
16
  export function collectFinalResponseTextFromAgentEvents(
8
17
  events: readonly AgentChatEvent[],
9
18
  options: CollectFinalResponseTextOptions = {},
@@ -38,7 +47,7 @@ function collectTextEvents(
38
47
  let text = "";
39
48
  for (let i = startIdx; i < events.length; i++) {
40
49
  const event = events[i];
41
- if (event.type === "text") text += event.text;
50
+ text = applyAgentTextEventToBuffer(text, event);
42
51
  }
43
52
  return text;
44
53
  }
@@ -2670,7 +2670,6 @@ export async function runAgentLoop(opts: {
2670
2670
  }
2671
2671
  }
2672
2672
 
2673
- const bufferTextUntilFinalGuard = Boolean(opts.finalResponseGuard);
2674
2673
  let finalGuardRetries = 0;
2675
2674
  let iterations = 0;
2676
2675
 
@@ -2700,7 +2699,7 @@ export async function runAgentLoop(opts: {
2700
2699
  }
2701
2700
 
2702
2701
  let assistantContent: EngineContentPart[] | undefined;
2703
- let bufferedAssistantText = "";
2702
+ let streamedAssistantText = "";
2704
2703
  let terminalStopReason:
2705
2704
  | Extract<EngineEvent, { type: "stop" }>["reason"]
2706
2705
  | undefined;
@@ -2768,7 +2767,7 @@ export async function runAgentLoop(opts: {
2768
2767
 
2769
2768
  for (let retry = 0; ; retry++) {
2770
2769
  assistantContent = undefined;
2771
- bufferedAssistantText = "";
2770
+ streamedAssistantText = "";
2772
2771
  terminalStopReason = undefined;
2773
2772
  toolCallErrors.clear();
2774
2773
  try {
@@ -2833,11 +2832,8 @@ export async function runAgentLoop(opts: {
2833
2832
  }
2834
2833
  }
2835
2834
  if (event.type === "text-delta") {
2836
- if (bufferTextUntilFinalGuard) {
2837
- bufferedAssistantText += event.text;
2838
- } else {
2839
- send({ type: "text", text: event.text });
2840
- }
2835
+ streamedAssistantText += event.text;
2836
+ send({ type: "text", text: event.text });
2841
2837
  } else if (event.type === "thinking-delta") {
2842
2838
  thinkingBuffer += event.text;
2843
2839
  // Forward thinking deltas as a distinct event type so the UI
@@ -3007,21 +3003,22 @@ export async function runAgentLoop(opts: {
3007
3003
  }
3008
3004
  }
3009
3005
 
3010
- const flushBufferedAssistantText = () => {
3011
- if (!bufferTextUntilFinalGuard) return;
3012
- const text =
3013
- bufferedAssistantText || collectTextParts(assistantContentForHistory);
3006
+ const flushUnstreamedAssistantText = () => {
3007
+ if (streamedAssistantText) return;
3008
+ const text = collectTextParts(assistantContentForHistory);
3014
3009
  if (text) send({ type: "text", text });
3015
3010
  };
3016
3011
 
3017
3012
  if (toolCallParts.length === 0) {
3018
3013
  if (terminalStopReason === "max_tokens") {
3019
- flushBufferedAssistantText();
3014
+ flushUnstreamedAssistantText();
3020
3015
  appendAgentLoopContinuation(messages, "max_tokens");
3021
3016
  continue;
3022
3017
  }
3023
- const guard = opts.finalResponseGuard
3024
- ? await opts.finalResponseGuard({
3018
+ let guard: Awaited<ReturnType<AgentLoopFinalResponseGuard>> | null = null;
3019
+ if (opts.finalResponseGuard) {
3020
+ try {
3021
+ guard = await opts.finalResponseGuard({
3025
3022
  messages,
3026
3023
  assistantContent: assistantContentForHistory,
3027
3024
  text: collectTextParts(assistantContentForHistory),
@@ -3029,8 +3026,12 @@ export async function runAgentLoop(opts: {
3029
3026
  toolResults: [...toolResultHistory],
3030
3027
  retryCount: finalGuardRetries,
3031
3028
  executionMode: opts.executionMode ?? "act",
3032
- })
3033
- : null;
3029
+ });
3030
+ } catch (err) {
3031
+ send({ type: "clear" });
3032
+ throw err;
3033
+ }
3034
+ }
3034
3035
  let guardEmittedFallback = false;
3035
3036
  if (guard) {
3036
3037
  const retryMessage =
@@ -3039,16 +3040,18 @@ export async function runAgentLoop(opts: {
3039
3040
  typeof guard === "string" ? guard : guard.fallbackMessage;
3040
3041
  if (finalGuardRetries < 1) {
3041
3042
  finalGuardRetries += 1;
3043
+ send({ type: "clear" });
3042
3044
  messages.push({
3043
3045
  role: "user",
3044
3046
  content: [{ type: "text", text: retryMessage }],
3045
3047
  });
3046
3048
  continue;
3047
3049
  }
3050
+ send({ type: "clear" });
3048
3051
  send({ type: "text", text: fallbackMessage ?? retryMessage });
3049
3052
  guardEmittedFallback = true;
3050
3053
  } else {
3051
- flushBufferedAssistantText();
3054
+ flushUnstreamedAssistantText();
3052
3055
  }
3053
3056
  // Some providers (notably OpenAI Responses for gpt-5+) can stream a
3054
3057
  // successful turn that contains only reasoning content and zero output
@@ -3059,7 +3062,7 @@ export async function runAgentLoop(opts: {
3059
3062
  if (
3060
3063
  !guardEmittedFallback &&
3061
3064
  collectTextParts(assistantContentForHistory).trim().length === 0 &&
3062
- bufferedAssistantText.trim().length === 0
3065
+ streamedAssistantText.trim().length === 0
3063
3066
  ) {
3064
3067
  send({
3065
3068
  type: "text",
@@ -3076,7 +3079,7 @@ export async function runAgentLoop(opts: {
3076
3079
  // permanently disabled for the rest of a long multi-step run.
3077
3080
  finalGuardRetries = 0;
3078
3081
 
3079
- flushBufferedAssistantText();
3082
+ flushUnstreamedAssistantText();
3080
3083
 
3081
3084
  let requestedActionStop: { message: string; errorCode?: string } | null =
3082
3085
  null;
@@ -124,6 +124,30 @@ export const DEFAULT_ERRORED_RUN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
124
124
  */
125
125
  export const TERMINAL_RUN_RECONNECT_WINDOW_MS = 10 * 60 * 1000;
126
126
 
127
+ /** Fast poll cadence while a SQL-backed SSE subscription is actively receiving rows. */
128
+ export const SQL_SUBSCRIPTION_ACTIVE_POLL_MS = 125;
129
+
130
+ /** Baseline SQL-backed SSE poll cadence when the run is idle. */
131
+ export const SQL_SUBSCRIPTION_IDLE_POLL_MS = 500;
132
+
133
+ /**
134
+ * Keep briefly polling quickly after rows arrive so token streams stay smooth,
135
+ * then back off to the idle cadence if the producer goes quiet.
136
+ */
137
+ export const SQL_SUBSCRIPTION_ACTIVE_GRACE_MS = 2_000;
138
+
139
+ /** Keep terminal/status probes at the historical cadence to bound DB work. */
140
+ export const SQL_SUBSCRIPTION_STATUS_POLL_MS = 500;
141
+
142
+ export function resolveSqlSubscriptionPollMs(
143
+ now: number,
144
+ activePollUntil: number,
145
+ ): number {
146
+ return now < activePollUntil
147
+ ? SQL_SUBSCRIPTION_ACTIVE_POLL_MS
148
+ : SQL_SUBSCRIPTION_IDLE_POLL_MS;
149
+ }
150
+
127
151
  const PROVIDER_RATE_LIMITED_ERROR_CODE = "provider_rate_limited";
128
152
 
129
153
  function isPreparingActionActivityEvent(event: AgentChatEvent): boolean {
@@ -960,6 +984,8 @@ function subscribeFromSQL(
960
984
  return new ReadableStream({
961
985
  async start(controller) {
962
986
  let lastSeq = fromSeq;
987
+ let activePollUntil = 0;
988
+ let lastStatusCheckAt = 0;
963
989
  const ping = () => {
964
990
  try {
965
991
  controller.enqueue(encoder.encode(`: ping ${Date.now()}\n\n`));
@@ -976,6 +1002,9 @@ function subscribeFromSQL(
976
1002
  try {
977
1003
  // Read new events from SQL
978
1004
  const events = await getRunEventsSince(runId, lastSeq);
1005
+ if (events.length > 0) {
1006
+ activePollUntil = Date.now() + SQL_SUBSCRIPTION_ACTIVE_GRACE_MS;
1007
+ }
979
1008
  for (const { seq, eventData } of events) {
980
1009
  // Advance the cursor first, before any parse/enqueue branch can
981
1010
  // `continue`/`return`. Otherwise a single corrupt (unparseable)
@@ -1009,6 +1038,18 @@ function subscribeFromSQL(
1009
1038
 
1010
1039
  // Check if run completed (no terminal event but status changed)
1011
1040
  if (events.length === 0) {
1041
+ const now = Date.now();
1042
+ if (now - lastStatusCheckAt < SQL_SUBSCRIPTION_STATUS_POLL_MS) {
1043
+ if (!cancelled) {
1044
+ const pollMs = resolveSqlSubscriptionPollMs(
1045
+ now,
1046
+ activePollUntil,
1047
+ );
1048
+ pollTimer = setTimeout(poll, pollMs);
1049
+ }
1050
+ return;
1051
+ }
1052
+ lastStatusCheckAt = now;
1012
1053
  // Opportunistically reap a stale producer before trusting SQL's
1013
1054
  // "running" status — otherwise a crashed server leaves us polling
1014
1055
  // forever.
@@ -1099,7 +1140,11 @@ function subscribeFromSQL(
1099
1140
 
1100
1141
  // Schedule next poll
1101
1142
  if (!cancelled) {
1102
- pollTimer = setTimeout(poll, 500);
1143
+ const pollMs = resolveSqlSubscriptionPollMs(
1144
+ Date.now(),
1145
+ activePollUntil,
1146
+ );
1147
+ pollTimer = setTimeout(poll, pollMs);
1103
1148
  }
1104
1149
  } catch {
1105
1150
  // SQL error — close stream
@@ -126,8 +126,7 @@ export function buildAssistantMessage(
126
126
 
127
127
  for (const { event } of events) {
128
128
  if (event.type === "clear") {
129
- content.length = 0;
130
- toolCallCounter = 0;
129
+ clearAssistantDraftContent(content);
131
130
  continue;
132
131
  }
133
132
 
@@ -252,6 +251,20 @@ export function buildAssistantMessage(
252
251
  };
253
252
  }
254
253
 
254
+ function clearAssistantDraftContent(content: ContentPart[]): void {
255
+ for (let index = content.length - 1; index >= 0; index--) {
256
+ const part = content[index];
257
+ if (!part) continue;
258
+ if (part.type === "text") {
259
+ content.splice(index, 1);
260
+ continue;
261
+ }
262
+ if (part.type === "tool-call" && part.result === undefined) {
263
+ content.splice(index, 1);
264
+ }
265
+ }
266
+ }
267
+
255
268
  function getStoredMessage(entry: any): any {
256
269
  return entry?.message ?? entry;
257
270
  }
@@ -762,15 +762,13 @@ background, text, border, ring, fill, stroke, gradient, placeholder, decoration,
762
762
  or shadow color, rewrite it to renderer tokens or remove it. Layout-only classes
763
763
  are still discouraged; inline flex/grid styles are safer and easier to review.
764
764
 
765
- **Keep Rough.js sparse.** \`.wf-card\` and \`.wf-box\` already render with
766
- theme-safe filled backgrounds (\`--wf-card\`) and soft tokenized borders that work
767
- in both light and dark mode. Do not add \`data-rough\` to broad root wrappers,
768
- dialog shells, page panels, grid cells, or nested containers unless that single
769
- container is the visual point. The renderer sketches the outer frame and
770
- standard controls by default; use \`data-rough\` only for a deliberate one-off
771
- shape. If a mockup starts looking like stacked/overlapping sketch lines, remove
772
- rough targets from parent containers and let backgrounds plus spacing separate
773
- the surfaces.
765
+ **Keep Rough.js sparse.** The renderer sketches the outer frame, standard
766
+ \`.wf-*\` primitives, controls, and inline border dividers by default. Do not add
767
+ \`data-rough\` to broad root wrappers, dialog shells, page panels, grid cells, or
768
+ nested containers unless that single container is the visual point. Use
769
+ \`data-rough\` only for a deliberate one-off shape. If a mockup starts looking
770
+ like stacked/overlapping sketch lines, remove rough targets from parent
771
+ containers and let backgrounds plus spacing separate the surfaces.
774
772
 
775
773
  **Use literal CSS lengths for spacing.** The \`--wf-*\` tokens are for colors and
776
774
  renderer-owned visual styling, not layout spacing. Do not use guessed spacing
@@ -2685,6 +2685,8 @@ export function MultiTabAssistantChat({
2685
2685
  <RunStuckBanner
2686
2686
  threadId={tabId}
2687
2687
  apiUrl={apiUrl}
2688
+ autoRetry
2689
+ autoRetryOwnerId={browserTabId}
2688
2690
  onRetry={() => {
2689
2691
  const handle = chatRefs.current.get(tabId);
2690
2692
  handle?.sendRecoveryMessage(