@agent-native/core 0.7.12 → 0.7.14

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 (586) hide show
  1. package/README.md +1 -1
  2. package/dist/a2a/client.d.ts +44 -1
  3. package/dist/a2a/client.d.ts.map +1 -1
  4. package/dist/a2a/client.js +88 -11
  5. package/dist/a2a/client.js.map +1 -1
  6. package/dist/a2a/handlers.d.ts +10 -0
  7. package/dist/a2a/handlers.d.ts.map +1 -1
  8. package/dist/a2a/handlers.js +287 -62
  9. package/dist/a2a/handlers.js.map +1 -1
  10. package/dist/a2a/server.d.ts.map +1 -1
  11. package/dist/a2a/server.js +95 -17
  12. package/dist/a2a/server.js.map +1 -1
  13. package/dist/a2a/task-store.d.ts +11 -1
  14. package/dist/a2a/task-store.d.ts.map +1 -1
  15. package/dist/a2a/task-store.js +38 -2
  16. package/dist/a2a/task-store.js.map +1 -1
  17. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  18. package/dist/agent/engine/ai-sdk-engine.js +26 -8
  19. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  20. package/dist/agent/engine/builder-engine.d.ts +19 -0
  21. package/dist/agent/engine/builder-engine.d.ts.map +1 -0
  22. package/dist/agent/engine/builder-engine.js +412 -0
  23. package/dist/agent/engine/builder-engine.js.map +1 -0
  24. package/dist/agent/engine/builtin.d.ts.map +1 -1
  25. package/dist/agent/engine/builtin.js +26 -10
  26. package/dist/agent/engine/builtin.js.map +1 -1
  27. package/dist/agent/engine/index.d.ts +1 -1
  28. package/dist/agent/engine/index.d.ts.map +1 -1
  29. package/dist/agent/engine/index.js +1 -1
  30. package/dist/agent/engine/index.js.map +1 -1
  31. package/dist/agent/engine/registry.d.ts +20 -1
  32. package/dist/agent/engine/registry.d.ts.map +1 -1
  33. package/dist/agent/engine/registry.js +49 -1
  34. package/dist/agent/engine/registry.js.map +1 -1
  35. package/dist/agent/engine/types.d.ts +30 -0
  36. package/dist/agent/engine/types.d.ts.map +1 -1
  37. package/dist/agent/engine/types.js +19 -1
  38. package/dist/agent/engine/types.js.map +1 -1
  39. package/dist/agent/production-agent.d.ts.map +1 -1
  40. package/dist/agent/production-agent.js +65 -7
  41. package/dist/agent/production-agent.js.map +1 -1
  42. package/dist/agent/run-manager.d.ts.map +1 -1
  43. package/dist/agent/run-manager.js +11 -1
  44. package/dist/agent/run-manager.js.map +1 -1
  45. package/dist/agent/thread-data-builder.d.ts +4 -0
  46. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  47. package/dist/agent/thread-data-builder.js +1 -0
  48. package/dist/agent/thread-data-builder.js.map +1 -1
  49. package/dist/agent/types.d.ts +8 -0
  50. package/dist/agent/types.d.ts.map +1 -1
  51. package/dist/chat-threads/store.d.ts +3 -0
  52. package/dist/chat-threads/store.d.ts.map +1 -1
  53. package/dist/chat-threads/store.js +32 -0
  54. package/dist/chat-threads/store.js.map +1 -1
  55. package/dist/checkpoints/service.d.ts +1 -0
  56. package/dist/checkpoints/service.d.ts.map +1 -1
  57. package/dist/checkpoints/service.js +26 -2
  58. package/dist/checkpoints/service.js.map +1 -1
  59. package/dist/cli/create.d.ts +30 -0
  60. package/dist/cli/create.d.ts.map +1 -1
  61. package/dist/cli/create.js +25 -13
  62. package/dist/cli/create.js.map +1 -1
  63. package/dist/cli/templates-meta.d.ts.map +1 -1
  64. package/dist/cli/templates-meta.js +11 -0
  65. package/dist/cli/templates-meta.js.map +1 -1
  66. package/dist/client/AgentPanel.d.ts +3 -1
  67. package/dist/client/AgentPanel.d.ts.map +1 -1
  68. package/dist/client/AgentPanel.js +22 -11
  69. package/dist/client/AgentPanel.js.map +1 -1
  70. package/dist/client/AgentTaskCard.d.ts.map +1 -1
  71. package/dist/client/AgentTaskCard.js +2 -0
  72. package/dist/client/AgentTaskCard.js.map +1 -1
  73. package/dist/client/AssistantChat.d.ts +2 -0
  74. package/dist/client/AssistantChat.d.ts.map +1 -1
  75. package/dist/client/AssistantChat.js +159 -84
  76. package/dist/client/AssistantChat.js.map +1 -1
  77. package/dist/client/ConnectBuilderCard.d.ts +1 -7
  78. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  79. package/dist/client/ConnectBuilderCard.js +30 -132
  80. package/dist/client/ConnectBuilderCard.js.map +1 -1
  81. package/dist/client/ErrorBoundary.d.ts +1 -3
  82. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  83. package/dist/client/ErrorBoundary.js +37 -9
  84. package/dist/client/ErrorBoundary.js.map +1 -1
  85. package/dist/client/FeedbackButton.d.ts.map +1 -1
  86. package/dist/client/FeedbackButton.js +4 -3
  87. package/dist/client/FeedbackButton.js.map +1 -1
  88. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  89. package/dist/client/MultiTabAssistantChat.js +169 -52
  90. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  91. package/dist/client/agent-chat.d.ts +11 -0
  92. package/dist/client/agent-chat.d.ts.map +1 -1
  93. package/dist/client/agent-chat.js +1 -1
  94. package/dist/client/agent-chat.js.map +1 -1
  95. package/dist/client/analytics.d.ts +5 -8
  96. package/dist/client/analytics.d.ts.map +1 -1
  97. package/dist/client/analytics.js +53 -11
  98. package/dist/client/analytics.js.map +1 -1
  99. package/dist/client/builder-mark.d.ts +9 -0
  100. package/dist/client/builder-mark.d.ts.map +1 -0
  101. package/dist/client/builder-mark.js +10 -0
  102. package/dist/client/builder-mark.js.map +1 -0
  103. package/dist/client/components/AgentPresenceChip.d.ts +12 -0
  104. package/dist/client/components/AgentPresenceChip.d.ts.map +1 -0
  105. package/dist/client/components/AgentPresenceChip.js +42 -0
  106. package/dist/client/components/AgentPresenceChip.js.map +1 -0
  107. package/dist/client/components/PresenceBar.d.ts +17 -0
  108. package/dist/client/components/PresenceBar.d.ts.map +1 -0
  109. package/dist/client/components/PresenceBar.js +118 -0
  110. package/dist/client/components/PresenceBar.js.map +1 -0
  111. package/dist/client/components/ui/popover.d.ts +8 -0
  112. package/dist/client/components/ui/popover.d.ts.map +1 -0
  113. package/dist/client/components/ui/popover.js +11 -0
  114. package/dist/client/components/ui/popover.js.map +1 -0
  115. package/dist/client/composer/ComposerPlusMenu.d.ts +7 -0
  116. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -0
  117. package/dist/client/composer/ComposerPlusMenu.js +183 -0
  118. package/dist/client/composer/ComposerPlusMenu.js.map +1 -0
  119. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  120. package/dist/client/composer/TiptapComposer.js +244 -19
  121. package/dist/client/composer/TiptapComposer.js.map +1 -1
  122. package/dist/client/composer/types.d.ts +1 -0
  123. package/dist/client/composer/types.d.ts.map +1 -1
  124. package/dist/client/composer/useVoiceDictation.d.ts +2 -0
  125. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  126. package/dist/client/composer/useVoiceDictation.js +89 -12
  127. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  128. package/dist/client/error-format.d.ts +2 -0
  129. package/dist/client/error-format.d.ts.map +1 -0
  130. package/dist/client/error-format.js +31 -0
  131. package/dist/client/error-format.js.map +1 -0
  132. package/dist/client/index.d.ts +6 -1
  133. package/dist/client/index.d.ts.map +1 -1
  134. package/dist/client/index.js +8 -1
  135. package/dist/client/index.js.map +1 -1
  136. package/dist/client/observability/ObservabilityDashboard.d.ts +5 -0
  137. package/dist/client/observability/ObservabilityDashboard.d.ts.map +1 -0
  138. package/dist/client/observability/ObservabilityDashboard.js +169 -0
  139. package/dist/client/observability/ObservabilityDashboard.js.map +1 -0
  140. package/dist/client/observability/ThumbsFeedback.d.ts +8 -0
  141. package/dist/client/observability/ThumbsFeedback.d.ts.map +1 -0
  142. package/dist/client/observability/ThumbsFeedback.js +64 -0
  143. package/dist/client/observability/ThumbsFeedback.js.map +1 -0
  144. package/dist/client/observability/index.d.ts +4 -0
  145. package/dist/client/observability/index.d.ts.map +1 -0
  146. package/dist/client/observability/index.js +4 -0
  147. package/dist/client/observability/index.js.map +1 -0
  148. package/dist/client/observability/useObservability.d.ts +128 -0
  149. package/dist/client/observability/useObservability.d.ts.map +1 -0
  150. package/dist/client/observability/useObservability.js +109 -0
  151. package/dist/client/observability/useObservability.js.map +1 -0
  152. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
  153. package/dist/client/onboarding/OnboardingPanel.js +34 -92
  154. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  155. package/dist/client/org/RequireActiveOrg.d.ts +33 -0
  156. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -0
  157. package/dist/client/org/RequireActiveOrg.js +68 -0
  158. package/dist/client/org/RequireActiveOrg.js.map +1 -0
  159. package/dist/client/org/TeamPage.d.ts.map +1 -1
  160. package/dist/client/org/TeamPage.js +125 -4
  161. package/dist/client/org/TeamPage.js.map +1 -1
  162. package/dist/client/org/hooks.d.ts +30 -0
  163. package/dist/client/org/hooks.d.ts.map +1 -1
  164. package/dist/client/org/hooks.js +115 -15
  165. package/dist/client/org/hooks.js.map +1 -1
  166. package/dist/client/org/index.d.ts +3 -2
  167. package/dist/client/org/index.d.ts.map +1 -1
  168. package/dist/client/org/index.js +2 -1
  169. package/dist/client/org/index.js.map +1 -1
  170. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  171. package/dist/client/resources/ResourcesPanel.js +8 -4
  172. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  173. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  174. package/dist/client/settings/AutomationsSection.js +2 -1
  175. package/dist/client/settings/AutomationsSection.js.map +1 -1
  176. package/dist/client/settings/BrowserSection.js +1 -1
  177. package/dist/client/settings/BrowserSection.js.map +1 -1
  178. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  179. package/dist/client/settings/SettingsPanel.js +133 -20
  180. package/dist/client/settings/SettingsPanel.js.map +1 -1
  181. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  182. package/dist/client/settings/VoiceTranscriptionSection.js +10 -4
  183. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  184. package/dist/client/settings/useBuilderStatus.d.ts +26 -0
  185. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  186. package/dist/client/settings/useBuilderStatus.js +128 -4
  187. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  188. package/dist/client/sse-event-processor.d.ts +2 -0
  189. package/dist/client/sse-event-processor.d.ts.map +1 -1
  190. package/dist/client/sse-event-processor.js +16 -2
  191. package/dist/client/sse-event-processor.js.map +1 -1
  192. package/dist/client/tools/ToolEditor.d.ts +5 -0
  193. package/dist/client/tools/ToolEditor.d.ts.map +1 -0
  194. package/dist/client/tools/ToolEditor.js +98 -0
  195. package/dist/client/tools/ToolEditor.js.map +1 -0
  196. package/dist/client/tools/ToolViewer.d.ts +5 -0
  197. package/dist/client/tools/ToolViewer.d.ts.map +1 -0
  198. package/dist/client/tools/ToolViewer.js +309 -0
  199. package/dist/client/tools/ToolViewer.js.map +1 -0
  200. package/dist/client/tools/ToolViewerPage.d.ts +2 -0
  201. package/dist/client/tools/ToolViewerPage.d.ts.map +1 -0
  202. package/dist/client/tools/ToolViewerPage.js +23 -0
  203. package/dist/client/tools/ToolViewerPage.js.map +1 -0
  204. package/dist/client/tools/ToolsListPage.d.ts +2 -0
  205. package/dist/client/tools/ToolsListPage.d.ts.map +1 -0
  206. package/dist/client/tools/ToolsListPage.js +72 -0
  207. package/dist/client/tools/ToolsListPage.js.map +1 -0
  208. package/dist/client/tools/ToolsSidebarSection.d.ts +2 -0
  209. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -0
  210. package/dist/client/tools/ToolsSidebarSection.js +188 -0
  211. package/dist/client/tools/ToolsSidebarSection.js.map +1 -0
  212. package/dist/client/tools/index.d.ts +6 -0
  213. package/dist/client/tools/index.d.ts.map +1 -0
  214. package/dist/client/tools/index.js +6 -0
  215. package/dist/client/tools/index.js.map +1 -0
  216. package/dist/client/transcription/BuilderTranscriptionCta.d.ts +9 -0
  217. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -0
  218. package/dist/client/transcription/BuilderTranscriptionCta.js +18 -0
  219. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -0
  220. package/dist/client/transcription/use-live-transcription.d.ts +29 -0
  221. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -0
  222. package/dist/client/transcription/use-live-transcription.js +156 -0
  223. package/dist/client/transcription/use-live-transcription.js.map +1 -0
  224. package/dist/client/use-builder-enabled.d.ts +17 -0
  225. package/dist/client/use-builder-enabled.d.ts.map +1 -0
  226. package/dist/client/use-builder-enabled.js +36 -0
  227. package/dist/client/use-builder-enabled.js.map +1 -0
  228. package/dist/client/use-chat-threads.d.ts +1 -0
  229. package/dist/client/use-chat-threads.d.ts.map +1 -1
  230. package/dist/client/use-chat-threads.js +29 -0
  231. package/dist/client/use-chat-threads.js.map +1 -1
  232. package/dist/client/use-db-sync.d.ts.map +1 -1
  233. package/dist/client/use-db-sync.js +10 -8
  234. package/dist/client/use-db-sync.js.map +1 -1
  235. package/dist/client/useProductionAgent.d.ts.map +1 -1
  236. package/dist/client/useProductionAgent.js +3 -1
  237. package/dist/client/useProductionAgent.js.map +1 -1
  238. package/dist/collab/agent-identity.d.ts +15 -0
  239. package/dist/collab/agent-identity.d.ts.map +1 -0
  240. package/dist/collab/agent-identity.js +14 -0
  241. package/dist/collab/agent-identity.js.map +1 -0
  242. package/dist/collab/agent-presence.d.ts +59 -0
  243. package/dist/collab/agent-presence.d.ts.map +1 -0
  244. package/dist/collab/agent-presence.js +165 -0
  245. package/dist/collab/agent-presence.js.map +1 -0
  246. package/dist/collab/awareness.d.ts +7 -0
  247. package/dist/collab/awareness.d.ts.map +1 -1
  248. package/dist/collab/awareness.js +2 -2
  249. package/dist/collab/awareness.js.map +1 -1
  250. package/dist/collab/client-struct.d.ts +43 -0
  251. package/dist/collab/client-struct.d.ts.map +1 -0
  252. package/dist/collab/client-struct.js +272 -0
  253. package/dist/collab/client-struct.js.map +1 -0
  254. package/dist/collab/client.d.ts +2 -0
  255. package/dist/collab/client.d.ts.map +1 -1
  256. package/dist/collab/client.js +15 -1
  257. package/dist/collab/client.js.map +1 -1
  258. package/dist/collab/index.d.ts +6 -1
  259. package/dist/collab/index.d.ts.map +1 -1
  260. package/dist/collab/index.js +11 -1
  261. package/dist/collab/index.js.map +1 -1
  262. package/dist/collab/json-to-yjs.d.ts +72 -0
  263. package/dist/collab/json-to-yjs.d.ts.map +1 -0
  264. package/dist/collab/json-to-yjs.js +456 -0
  265. package/dist/collab/json-to-yjs.js.map +1 -0
  266. package/dist/collab/struct-routes.d.ts +52 -0
  267. package/dist/collab/struct-routes.d.ts.map +1 -0
  268. package/dist/collab/struct-routes.js +74 -0
  269. package/dist/collab/struct-routes.js.map +1 -0
  270. package/dist/collab/ydoc-manager.d.ts +19 -0
  271. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  272. package/dist/collab/ydoc-manager.js +49 -0
  273. package/dist/collab/ydoc-manager.js.map +1 -1
  274. package/dist/db/migrations.d.ts +9 -0
  275. package/dist/db/migrations.d.ts.map +1 -1
  276. package/dist/db/migrations.js +75 -10
  277. package/dist/db/migrations.js.map +1 -1
  278. package/dist/deploy/build.js +1 -1
  279. package/dist/file-upload/builder.d.ts.map +1 -1
  280. package/dist/file-upload/builder.js +13 -5
  281. package/dist/file-upload/builder.js.map +1 -1
  282. package/dist/integrations/adapters/email.d.ts +17 -0
  283. package/dist/integrations/adapters/email.d.ts.map +1 -0
  284. package/dist/integrations/adapters/email.js +620 -0
  285. package/dist/integrations/adapters/email.js.map +1 -0
  286. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  287. package/dist/integrations/adapters/telegram.js +19 -3
  288. package/dist/integrations/adapters/telegram.js.map +1 -1
  289. package/dist/integrations/index.d.ts +1 -0
  290. package/dist/integrations/index.d.ts.map +1 -1
  291. package/dist/integrations/index.js +1 -0
  292. package/dist/integrations/index.js.map +1 -1
  293. package/dist/integrations/internal-token.d.ts +18 -0
  294. package/dist/integrations/internal-token.d.ts.map +1 -0
  295. package/dist/integrations/internal-token.js +86 -0
  296. package/dist/integrations/internal-token.js.map +1 -0
  297. package/dist/integrations/pending-tasks-retry-job.d.ts +15 -0
  298. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -0
  299. package/dist/integrations/pending-tasks-retry-job.js +199 -0
  300. package/dist/integrations/pending-tasks-retry-job.js.map +1 -0
  301. package/dist/integrations/pending-tasks-store.d.ts +40 -0
  302. package/dist/integrations/pending-tasks-store.d.ts.map +1 -0
  303. package/dist/integrations/pending-tasks-store.js +151 -0
  304. package/dist/integrations/pending-tasks-store.js.map +1 -0
  305. package/dist/integrations/plugin.d.ts.map +1 -1
  306. package/dist/integrations/plugin.js +151 -9
  307. package/dist/integrations/plugin.js.map +1 -1
  308. package/dist/integrations/task-queue-stats.d.ts +22 -0
  309. package/dist/integrations/task-queue-stats.d.ts.map +1 -0
  310. package/dist/integrations/task-queue-stats.js +117 -0
  311. package/dist/integrations/task-queue-stats.js.map +1 -0
  312. package/dist/integrations/types.d.ts +2 -0
  313. package/dist/integrations/types.d.ts.map +1 -1
  314. package/dist/integrations/webhook-handler.d.ts +23 -4
  315. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  316. package/dist/integrations/webhook-handler.js +217 -59
  317. package/dist/integrations/webhook-handler.js.map +1 -1
  318. package/dist/jobs/tools.d.ts.map +1 -1
  319. package/dist/jobs/tools.js +137 -161
  320. package/dist/jobs/tools.js.map +1 -1
  321. package/dist/mcp-client/manager.d.ts +3 -0
  322. package/dist/mcp-client/manager.d.ts.map +1 -1
  323. package/dist/mcp-client/manager.js +5 -0
  324. package/dist/mcp-client/manager.js.map +1 -1
  325. package/dist/notifications/actions.d.ts +2 -2
  326. package/dist/notifications/actions.d.ts.map +1 -1
  327. package/dist/notifications/actions.js +77 -69
  328. package/dist/notifications/actions.js.map +1 -1
  329. package/dist/oauth-tokens/google-refresh.d.ts.map +1 -1
  330. package/dist/oauth-tokens/google-refresh.js +6 -0
  331. package/dist/oauth-tokens/google-refresh.js.map +1 -1
  332. package/dist/observability/evals.d.ts +22 -0
  333. package/dist/observability/evals.d.ts.map +1 -0
  334. package/dist/observability/evals.js +371 -0
  335. package/dist/observability/evals.js.map +1 -0
  336. package/dist/observability/experiments.d.ts +24 -0
  337. package/dist/observability/experiments.d.ts.map +1 -0
  338. package/dist/observability/experiments.js +274 -0
  339. package/dist/observability/experiments.js.map +1 -0
  340. package/dist/observability/feedback.d.ts +14 -0
  341. package/dist/observability/feedback.d.ts.map +1 -0
  342. package/dist/observability/feedback.js +256 -0
  343. package/dist/observability/feedback.js.map +1 -0
  344. package/dist/observability/index.d.ts +6 -0
  345. package/dist/observability/index.d.ts.map +1 -0
  346. package/dist/observability/index.js +5 -0
  347. package/dist/observability/index.js.map +1 -0
  348. package/dist/observability/plugin.d.ts +2 -0
  349. package/dist/observability/plugin.d.ts.map +1 -0
  350. package/dist/observability/plugin.js +12 -0
  351. package/dist/observability/plugin.js.map +1 -0
  352. package/dist/observability/routes.d.ts +68 -0
  353. package/dist/observability/routes.d.ts.map +1 -0
  354. package/dist/observability/routes.js +301 -0
  355. package/dist/observability/routes.js.map +1 -0
  356. package/dist/observability/store.d.ts +77 -0
  357. package/dist/observability/store.d.ts.map +1 -0
  358. package/dist/observability/store.js +976 -0
  359. package/dist/observability/store.js.map +1 -0
  360. package/dist/observability/traces.d.ts +37 -0
  361. package/dist/observability/traces.d.ts.map +1 -0
  362. package/dist/observability/traces.js +182 -0
  363. package/dist/observability/traces.js.map +1 -0
  364. package/dist/observability/types.d.ts +159 -0
  365. package/dist/observability/types.d.ts.map +1 -0
  366. package/dist/observability/types.js +16 -0
  367. package/dist/observability/types.js.map +1 -0
  368. package/dist/onboarding/default-steps.d.ts.map +1 -1
  369. package/dist/onboarding/default-steps.js +15 -7
  370. package/dist/onboarding/default-steps.js.map +1 -1
  371. package/dist/onboarding/types.d.ts +10 -1
  372. package/dist/onboarding/types.d.ts.map +1 -1
  373. package/dist/org/context.d.ts +43 -1
  374. package/dist/org/context.d.ts.map +1 -1
  375. package/dist/org/context.js +299 -6
  376. package/dist/org/context.js.map +1 -1
  377. package/dist/org/handlers.d.ts +76 -0
  378. package/dist/org/handlers.d.ts.map +1 -1
  379. package/dist/org/handlers.js +460 -32
  380. package/dist/org/handlers.js.map +1 -1
  381. package/dist/org/index.d.ts +2 -2
  382. package/dist/org/index.d.ts.map +1 -1
  383. package/dist/org/index.js +2 -2
  384. package/dist/org/index.js.map +1 -1
  385. package/dist/org/migrations.d.ts.map +1 -1
  386. package/dist/org/migrations.js +8 -0
  387. package/dist/org/migrations.js.map +1 -1
  388. package/dist/org/plugin.d.ts +6 -0
  389. package/dist/org/plugin.d.ts.map +1 -1
  390. package/dist/org/plugin.js +71 -7
  391. package/dist/org/plugin.js.map +1 -1
  392. package/dist/org/schema.d.ts +38 -0
  393. package/dist/org/schema.d.ts.map +1 -1
  394. package/dist/org/schema.js +2 -0
  395. package/dist/org/schema.js.map +1 -1
  396. package/dist/org/types.d.ts +7 -0
  397. package/dist/org/types.d.ts.map +1 -1
  398. package/dist/progress/actions.d.ts +3 -0
  399. package/dist/progress/actions.d.ts.map +1 -1
  400. package/dist/progress/actions.js +86 -110
  401. package/dist/progress/actions.js.map +1 -1
  402. package/dist/progress/routes.d.ts +1 -1
  403. package/dist/progress/routes.js +1 -1
  404. package/dist/scripts/agent-engines/list-agent-engines.js +1 -1
  405. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  406. package/dist/scripts/agent-engines/manage-agent-engine.d.ts +10 -0
  407. package/dist/scripts/agent-engines/manage-agent-engine.d.ts.map +1 -0
  408. package/dist/scripts/agent-engines/manage-agent-engine.js +47 -0
  409. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -0
  410. package/dist/scripts/agent-engines/set-agent-engine.js +2 -2
  411. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  412. package/dist/scripts/call-agent.d.ts.map +1 -1
  413. package/dist/scripts/call-agent.js +90 -18
  414. package/dist/scripts/call-agent.js.map +1 -1
  415. package/dist/scripts/db/index.d.ts.map +1 -1
  416. package/dist/scripts/db/index.js +2 -0
  417. package/dist/scripts/db/index.js.map +1 -1
  418. package/dist/scripts/db/migrate-user-api-keys.d.ts +24 -0
  419. package/dist/scripts/db/migrate-user-api-keys.d.ts.map +1 -0
  420. package/dist/scripts/db/migrate-user-api-keys.js +224 -0
  421. package/dist/scripts/db/migrate-user-api-keys.js.map +1 -0
  422. package/dist/scripts/db/wipe-leaked-builder-keys.d.ts +27 -0
  423. package/dist/scripts/db/wipe-leaked-builder-keys.d.ts.map +1 -0
  424. package/dist/scripts/db/wipe-leaked-builder-keys.js +163 -0
  425. package/dist/scripts/db/wipe-leaked-builder-keys.js.map +1 -0
  426. package/dist/secrets/register-framework-secrets.d.ts +5 -0
  427. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  428. package/dist/secrets/register-framework-secrets.js +7 -44
  429. package/dist/secrets/register-framework-secrets.js.map +1 -1
  430. package/dist/secrets/substitution.d.ts.map +1 -1
  431. package/dist/secrets/substitution.js +14 -2
  432. package/dist/secrets/substitution.js.map +1 -1
  433. package/dist/server/action-discovery.d.ts.map +1 -1
  434. package/dist/server/action-discovery.js +39 -0
  435. package/dist/server/action-discovery.js.map +1 -1
  436. package/dist/server/action-routes.js +1 -1
  437. package/dist/server/action-routes.js.map +1 -1
  438. package/dist/server/agent-chat-plugin.d.ts +39 -0
  439. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  440. package/dist/server/agent-chat-plugin.js +869 -458
  441. package/dist/server/agent-chat-plugin.js.map +1 -1
  442. package/dist/server/agent-teams.js +1 -1
  443. package/dist/server/agent-teams.js.map +1 -1
  444. package/dist/server/analytics.d.ts +5 -6
  445. package/dist/server/analytics.d.ts.map +1 -1
  446. package/dist/server/analytics.js +6 -14
  447. package/dist/server/analytics.js.map +1 -1
  448. package/dist/server/app-name.d.ts +5 -2
  449. package/dist/server/app-name.d.ts.map +1 -1
  450. package/dist/server/app-name.js +14 -3
  451. package/dist/server/app-name.js.map +1 -1
  452. package/dist/server/app-url.d.ts.map +1 -1
  453. package/dist/server/app-url.js +10 -1
  454. package/dist/server/app-url.js.map +1 -1
  455. package/dist/server/auth.d.ts +16 -0
  456. package/dist/server/auth.d.ts.map +1 -1
  457. package/dist/server/auth.js +373 -7
  458. package/dist/server/auth.js.map +1 -1
  459. package/dist/server/better-auth-instance.d.ts +2 -0
  460. package/dist/server/better-auth-instance.d.ts.map +1 -1
  461. package/dist/server/better-auth-instance.js +4 -0
  462. package/dist/server/better-auth-instance.js.map +1 -1
  463. package/dist/server/builder-browser.d.ts +59 -1
  464. package/dist/server/builder-browser.d.ts.map +1 -1
  465. package/dist/server/builder-browser.js +139 -23
  466. package/dist/server/builder-browser.js.map +1 -1
  467. package/dist/server/collab-plugin.d.ts +4 -0
  468. package/dist/server/collab-plugin.d.ts.map +1 -1
  469. package/dist/server/collab-plugin.js +30 -4
  470. package/dist/server/collab-plugin.js.map +1 -1
  471. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  472. package/dist/server/core-routes-plugin.js +241 -33
  473. package/dist/server/core-routes-plugin.js.map +1 -1
  474. package/dist/server/credential-provider.d.ts +50 -2
  475. package/dist/server/credential-provider.d.ts.map +1 -1
  476. package/dist/server/credential-provider.js +125 -2
  477. package/dist/server/credential-provider.js.map +1 -1
  478. package/dist/server/design-token-utils.d.ts +132 -0
  479. package/dist/server/design-token-utils.d.ts.map +1 -0
  480. package/dist/server/design-token-utils.js +714 -0
  481. package/dist/server/design-token-utils.js.map +1 -0
  482. package/dist/server/email.d.ts +10 -0
  483. package/dist/server/email.d.ts.map +1 -1
  484. package/dist/server/email.js +63 -16
  485. package/dist/server/email.js.map +1 -1
  486. package/dist/server/framework-request-handler.d.ts.map +1 -1
  487. package/dist/server/framework-request-handler.js +38 -3
  488. package/dist/server/framework-request-handler.js.map +1 -1
  489. package/dist/server/google-oauth.d.ts +18 -1
  490. package/dist/server/google-oauth.d.ts.map +1 -1
  491. package/dist/server/google-oauth.js +21 -4
  492. package/dist/server/google-oauth.js.map +1 -1
  493. package/dist/server/index.d.ts +3 -3
  494. package/dist/server/index.d.ts.map +1 -1
  495. package/dist/server/index.js +3 -3
  496. package/dist/server/index.js.map +1 -1
  497. package/dist/server/onboarding-html.d.ts.map +1 -1
  498. package/dist/server/onboarding-html.js +43 -5
  499. package/dist/server/onboarding-html.js.map +1 -1
  500. package/dist/server/poll.d.ts.map +1 -1
  501. package/dist/server/poll.js +46 -5
  502. package/dist/server/poll.js.map +1 -1
  503. package/dist/server/ssr-handler.d.ts.map +1 -1
  504. package/dist/server/ssr-handler.js +2 -1
  505. package/dist/server/ssr-handler.js.map +1 -1
  506. package/dist/server/transcribe-voice.d.ts.map +1 -1
  507. package/dist/server/transcribe-voice.js +125 -21
  508. package/dist/server/transcribe-voice.js.map +1 -1
  509. package/dist/sharing/schema.d.ts +1 -1
  510. package/dist/styles/agent-native.css +16 -2
  511. package/dist/templates/default/.agents/skills/progress/SKILL.md +14 -12
  512. package/dist/templates/default/app/root.tsx +57 -13
  513. package/dist/templates/default/react-router.config.ts +3 -0
  514. package/dist/terminal/terminal-plugin.d.ts.map +1 -1
  515. package/dist/terminal/terminal-plugin.js +23 -3
  516. package/dist/terminal/terminal-plugin.js.map +1 -1
  517. package/dist/tools/actions.d.ts +3 -0
  518. package/dist/tools/actions.d.ts.map +1 -0
  519. package/dist/tools/actions.js +140 -0
  520. package/dist/tools/actions.js.map +1 -0
  521. package/dist/tools/fetch-tool.js +1 -1
  522. package/dist/tools/fetch-tool.js.map +1 -1
  523. package/dist/tools/html-shell.d.ts +2 -0
  524. package/dist/tools/html-shell.d.ts.map +1 -0
  525. package/dist/tools/html-shell.js +387 -0
  526. package/dist/tools/html-shell.js.map +1 -0
  527. package/dist/tools/routes.d.ts +2 -0
  528. package/dist/tools/routes.d.ts.map +1 -0
  529. package/dist/tools/routes.js +576 -0
  530. package/dist/tools/routes.js.map +1 -0
  531. package/dist/tools/schema.d.ts +575 -0
  532. package/dist/tools/schema.d.ts.map +1 -0
  533. package/dist/tools/schema.js +112 -0
  534. package/dist/tools/schema.js.map +1 -0
  535. package/dist/tools/store.d.ts +40 -0
  536. package/dist/tools/store.d.ts.map +1 -0
  537. package/dist/tools/store.js +190 -0
  538. package/dist/tools/store.js.map +1 -0
  539. package/dist/tools/theme.d.ts +2 -0
  540. package/dist/tools/theme.d.ts.map +1 -0
  541. package/dist/tools/theme.js +67 -0
  542. package/dist/tools/theme.js.map +1 -0
  543. package/dist/transcription/builder-transcription.d.ts +27 -0
  544. package/dist/transcription/builder-transcription.d.ts.map +1 -0
  545. package/dist/transcription/builder-transcription.js +53 -0
  546. package/dist/transcription/builder-transcription.js.map +1 -0
  547. package/dist/triggers/actions.d.ts +3 -0
  548. package/dist/triggers/actions.d.ts.map +1 -1
  549. package/dist/triggers/actions.js +189 -213
  550. package/dist/triggers/actions.js.map +1 -1
  551. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  552. package/dist/vite/action-types-plugin.js +10 -2
  553. package/dist/vite/action-types-plugin.js.map +1 -1
  554. package/dist/vite/client.d.ts.map +1 -1
  555. package/dist/vite/client.js +26 -6
  556. package/dist/vite/client.js.map +1 -1
  557. package/docs/content/a2a-protocol.md +2 -2
  558. package/docs/content/agent-mentions.md +1 -1
  559. package/docs/content/authentication.md +51 -0
  560. package/docs/content/automations.md +22 -19
  561. package/docs/content/cloneable-saas.md +59 -62
  562. package/docs/content/deployment.md +21 -61
  563. package/docs/content/faq.md +73 -43
  564. package/docs/content/getting-started.md +37 -61
  565. package/docs/content/key-concepts.md +1 -1
  566. package/docs/content/mcp-clients.md +14 -1
  567. package/docs/content/messaging.md +284 -0
  568. package/docs/content/{enterprise-workspace.md → multi-app-workspace.md} +3 -3
  569. package/docs/content/multi-tenancy.md +1 -1
  570. package/docs/content/progress.md +11 -11
  571. package/docs/content/pure-agent-apps.md +55 -28
  572. package/docs/content/template-calendar.md +61 -56
  573. package/docs/content/template-clips.md +22 -18
  574. package/docs/content/template-content.md +36 -26
  575. package/docs/content/template-dispatch.md +5 -4
  576. package/docs/content/template-forms.md +13 -11
  577. package/docs/content/template-slides.md +43 -31
  578. package/docs/content/template-video.md +49 -22
  579. package/docs/content/tools.md +107 -0
  580. package/docs/content/what-is-agent-native.md +89 -105
  581. package/docs/content/workspace-management.md +1 -1
  582. package/package.json +12 -2
  583. package/src/templates/default/.agents/skills/progress/SKILL.md +14 -12
  584. package/src/templates/default/app/root.tsx +57 -13
  585. package/src/templates/default/react-router.config.ts +3 -0
  586. package/docs/content/integrations.md +0 -198
@@ -10,11 +10,11 @@ import { buildAssistantMessage, extractThreadMeta, } from "../agent/thread-data-
10
10
  import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
11
11
  import { getSession } from "./auth.js";
12
12
  import { getOrigin } from "./google-oauth.js";
13
- import { createThread, getThread, listThreads, searchThreads, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
13
+ import { createThread, forkThread, getThread, listThreads, searchThreads, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
14
14
  import { resourceListAccessible, resourceList, resourceGet, resourceGetByPath, ensurePersonalDefaults, SHARED_OWNER, } from "../resources/store.js";
15
15
  import nodePath from "node:path";
16
16
  import { readBody } from "./h3-helpers.js";
17
- import { getBuilderBrowserConnectUrl, requestBuilderBrowserConnection, } from "./builder-browser.js";
17
+ import { getBuilderBrowserConnectUrl } from "./builder-browser.js";
18
18
  // Lazy fs — loaded via dynamic import() on first use.
19
19
  // This avoids require() which bundlers convert to createRequire(import.meta.url)
20
20
  // that crashes on CF Workers where import.meta.url is undefined.
@@ -74,6 +74,44 @@ function wrapCliScript(tool, cliDefault, opts) {
74
74
  },
75
75
  };
76
76
  }
77
+ /**
78
+ * Creates the `get-framework-context` tool. Returns detailed instructions
79
+ * for framework capabilities that are summarized in the compact prompt.
80
+ * The agent calls this on-demand when it needs specifics about embeds,
81
+ * agent teams, recurring jobs, etc.
82
+ */
83
+ function createFrameworkContextEntry() {
84
+ const topicList = Object.keys(FRAMEWORK_CONTEXT_SECTIONS).join(", ");
85
+ return {
86
+ "get-framework-context": {
87
+ tool: {
88
+ description: `Read detailed framework instructions for a specific capability. Available topics: ${topicList}. Call with topic="all" to get everything.`,
89
+ parameters: {
90
+ type: "object",
91
+ properties: {
92
+ topic: {
93
+ type: "string",
94
+ description: `Topic to read. One of: ${topicList}, or "all" for everything.`,
95
+ },
96
+ },
97
+ required: ["topic"],
98
+ },
99
+ },
100
+ run: async (args) => {
101
+ const topic = String(args.topic ?? "all").toLowerCase();
102
+ if (topic === "all") {
103
+ return Object.values(FRAMEWORK_CONTEXT_SECTIONS).join("\n\n");
104
+ }
105
+ const section = FRAMEWORK_CONTEXT_SECTIONS[topic];
106
+ if (!section) {
107
+ return `Unknown topic "${topic}". Available: ${topicList}`;
108
+ }
109
+ return section;
110
+ },
111
+ readOnly: true,
112
+ },
113
+ };
114
+ }
77
115
  /**
78
116
  * Creates the `refresh-screen` tool. Writes a bump to `application_state`
79
117
  * under a well-known key; the client's `useDbSync` watches for this and
@@ -370,91 +408,87 @@ async function createResourceScriptEntries() {
370
408
  import("../scripts/resources/save-memory.js"),
371
409
  import("../scripts/resources/delete-memory.js"),
372
410
  ]);
411
+ // Wrap each CLI runner so it captures stdout and converts args properly
412
+ const listEntry = wrapCliScript({
413
+ description: "",
414
+ parameters: { type: "object", properties: {} },
415
+ }, list.default, { readOnly: true });
416
+ const readEntry = wrapCliScript({
417
+ description: "",
418
+ parameters: { type: "object", properties: {} },
419
+ }, read.default, { readOnly: true });
420
+ const writeEntry = wrapCliScript({
421
+ description: "",
422
+ parameters: { type: "object", properties: {} },
423
+ }, write.default);
424
+ const deleteEntry = wrapCliScript({
425
+ description: "",
426
+ parameters: { type: "object", properties: {} },
427
+ }, del.default);
373
428
  return {
374
- "resource-list": wrapCliScript({
375
- description: "List resources (persistent files/notes). Returns file paths, sizes, and metadata.",
376
- parameters: {
377
- type: "object",
378
- properties: {
379
- prefix: {
380
- type: "string",
381
- description: "Filter by path prefix (e.g. 'notes/')",
382
- },
383
- scope: {
384
- type: "string",
385
- description: "Which resources to list: personal, shared, or all (default: all)",
386
- enum: ["personal", "shared", "all"],
387
- },
388
- format: {
389
- type: "string",
390
- description: 'Output format: "json" or "text" (default: text)',
391
- enum: ["json", "text"],
392
- },
393
- },
394
- },
395
- }, list.default),
396
- "resource-read": wrapCliScript({
397
- description: "Read a resource by path. Returns the file contents.",
398
- parameters: {
399
- type: "object",
400
- properties: {
401
- path: {
402
- type: "string",
403
- description: "Resource path (e.g. 'LEARNINGS.md', 'notes/ideas.md')",
404
- },
405
- scope: {
406
- type: "string",
407
- description: "personal or shared (default: personal, falls back to shared)",
408
- enum: ["personal", "shared"],
409
- },
410
- },
411
- required: ["path"],
412
- },
413
- }, read.default),
414
- "resource-write": wrapCliScript({
415
- description: "Write or update a resource. Creates the resource if it doesn't exist.",
416
- parameters: {
417
- type: "object",
418
- properties: {
419
- path: {
420
- type: "string",
421
- description: "Resource path (e.g. 'LEARNINGS.md', 'notes/ideas.md')",
422
- },
423
- content: {
424
- type: "string",
425
- description: "The content to write",
426
- },
427
- scope: {
428
- type: "string",
429
- description: "personal or shared (default: personal)",
430
- enum: ["personal", "shared"],
431
- },
432
- mime: {
433
- type: "string",
434
- description: "MIME type (default: inferred from extension)",
429
+ resources: {
430
+ tool: {
431
+ description: 'Manage persistent user files and notes. Actions: "list" (browse), "read" (get contents), "write" (create/update), "delete" (remove).',
432
+ parameters: {
433
+ type: "object",
434
+ properties: {
435
+ action: {
436
+ type: "string",
437
+ description: "The operation to perform",
438
+ enum: ["list", "read", "write", "delete"],
439
+ },
440
+ path: {
441
+ type: "string",
442
+ description: "Resource path (e.g. 'LEARNINGS.md', 'notes/ideas.md'). Required for read/write/delete.",
443
+ },
444
+ content: {
445
+ type: "string",
446
+ description: "Content to write. Required for write.",
447
+ },
448
+ scope: {
449
+ type: "string",
450
+ description: "personal, shared, or all (default varies by action)",
451
+ enum: ["personal", "shared", "all"],
452
+ },
453
+ prefix: {
454
+ type: "string",
455
+ description: "Filter by path prefix when listing (e.g. 'notes/')",
456
+ },
457
+ mime: {
458
+ type: "string",
459
+ description: "MIME type for write (default: inferred from extension)",
460
+ },
461
+ format: {
462
+ type: "string",
463
+ description: 'Output format for list: "json" or "text" (default: text)',
464
+ enum: ["json", "text"],
465
+ },
435
466
  },
467
+ required: ["action"],
436
468
  },
437
- required: ["path", "content"],
438
469
  },
439
- }, write.default),
440
- "resource-delete": wrapCliScript({
441
- description: "Delete a resource by path.",
442
- parameters: {
443
- type: "object",
444
- properties: {
445
- path: {
446
- type: "string",
447
- description: "Resource path to delete",
448
- },
449
- scope: {
450
- type: "string",
451
- description: "personal or shared (default: personal)",
452
- enum: ["personal", "shared"],
453
- },
454
- },
455
- required: ["path"],
470
+ run: async (args) => {
471
+ const { action: a, ...rest } = args;
472
+ if (a === "list")
473
+ return listEntry.run(rest);
474
+ if (a === "read") {
475
+ if (!rest.path)
476
+ return "Error: path is required for read";
477
+ return readEntry.run(rest);
478
+ }
479
+ if (a === "write") {
480
+ if (!rest.path || !rest.content)
481
+ return "Error: path and content are required for write";
482
+ return writeEntry.run(rest);
483
+ }
484
+ if (a === "delete") {
485
+ if (!rest.path)
486
+ return "Error: path is required for delete";
487
+ return deleteEntry.run(rest);
488
+ }
489
+ return `Error: unknown action "${a}". Use: list, read, write, delete`;
456
490
  },
457
- }, del.default),
491
+ },
458
492
  "save-memory": wrapCliScript({
459
493
  description: "Save a memory for future conversations. Creates or updates a memory file and its index entry. Use proactively when you learn preferences, corrections, project context, or references.",
460
494
  parameters: {
@@ -502,7 +536,7 @@ async function createResourceScriptEntries() {
502
536
  }
503
537
  }
504
538
  /**
505
- * Creates chat management ActionEntries (search-chats, open-chat).
539
+ * Creates a unified chat-history ActionEntry that dispatches to search or open.
506
540
  */
507
541
  async function createChatScriptEntries() {
508
542
  try {
@@ -510,41 +544,80 @@ async function createChatScriptEntries() {
510
544
  import("../scripts/chat/search-chats.js"),
511
545
  import("../scripts/chat/open-chat.js"),
512
546
  ]);
513
- return {
514
- "search-chats": wrapCliScript({
515
- description: "Search or list past agent chat threads. Use this to find previous conversations by keyword.",
516
- parameters: {
517
- type: "object",
518
- properties: {
519
- query: {
520
- type: "string",
521
- description: "Search term to find chats by title, preview, or content",
522
- },
523
- limit: {
524
- type: "string",
525
- description: "Max number of results (default: 20)",
526
- },
527
- format: {
528
- type: "string",
529
- description: "Output format",
530
- enum: ["json", "text"],
531
- },
547
+ const searchEntry = wrapCliScript({
548
+ description: "Search or list past agent chat threads.",
549
+ parameters: {
550
+ type: "object",
551
+ properties: {
552
+ query: {
553
+ type: "string",
554
+ description: "Search term to find chats by title, preview, or content",
555
+ },
556
+ limit: {
557
+ type: "string",
558
+ description: "Max number of results (default: 20)",
559
+ },
560
+ format: {
561
+ type: "string",
562
+ description: "Output format",
563
+ enum: ["json", "text"],
532
564
  },
533
565
  },
534
- }, searchMod.default),
535
- "open-chat": wrapCliScript({
536
- description: "Open a chat thread in the UI as a new tab and focus it. Use search-chats first to find the thread ID.",
537
- parameters: {
538
- type: "object",
539
- properties: {
540
- id: {
541
- type: "string",
542
- description: "The chat thread ID to open",
566
+ },
567
+ }, searchMod.default);
568
+ const openEntry = wrapCliScript({
569
+ description: "Open a chat thread in the UI.",
570
+ parameters: {
571
+ type: "object",
572
+ properties: {
573
+ id: {
574
+ type: "string",
575
+ description: "The chat thread ID to open",
576
+ },
577
+ },
578
+ required: ["id"],
579
+ },
580
+ }, openMod.default);
581
+ return {
582
+ "chat-history": {
583
+ tool: {
584
+ description: "Manage past agent chat threads. Use action 'search' to find previous conversations by keyword, or 'open' to open a thread in the UI.",
585
+ parameters: {
586
+ type: "object",
587
+ properties: {
588
+ action: {
589
+ type: "string",
590
+ description: "The operation to perform",
591
+ enum: ["search", "open"],
592
+ },
593
+ query: {
594
+ type: "string",
595
+ description: "(search) Search term to find chats by title, preview, or content",
596
+ },
597
+ limit: {
598
+ type: "string",
599
+ description: "(search) Max number of results (default: 20)",
600
+ },
601
+ format: {
602
+ type: "string",
603
+ description: "(search) Output format",
604
+ enum: ["json", "text"],
605
+ },
606
+ id: {
607
+ type: "string",
608
+ description: "(open) The chat thread ID to open",
609
+ },
543
610
  },
611
+ required: ["action"],
544
612
  },
545
- required: ["id"],
546
613
  },
547
- }, openMod.default),
614
+ run: async (args) => {
615
+ if (args?.action === "open") {
616
+ return openEntry.run(args);
617
+ }
618
+ return searchEntry.run(args);
619
+ },
620
+ },
548
621
  };
549
622
  }
550
623
  catch {
@@ -552,20 +625,14 @@ async function createChatScriptEntries() {
552
625
  }
553
626
  }
554
627
  /**
555
- * Creates agent engine management tools (list-agent-engines, set-agent-engine,
556
- * test-agent-engine). Let the agent inspect and configure the active LLM engine.
628
+ * Creates the consolidated manage-agent-engine tool (list / set / test).
629
+ * Let the agent inspect and configure the active LLM engine.
557
630
  */
558
631
  async function createAgentEngineScriptEntries() {
559
632
  try {
560
- const [listMod, setMod, testMod] = await Promise.all([
561
- import("../scripts/agent-engines/list-agent-engines.js"),
562
- import("../scripts/agent-engines/set-agent-engine.js"),
563
- import("../scripts/agent-engines/test-agent-engine.js"),
564
- ]);
633
+ const mod = await import("../scripts/agent-engines/manage-agent-engine.js");
565
634
  return {
566
- "list-agent-engines": { tool: listMod.tool, run: listMod.run },
567
- "set-agent-engine": { tool: setMod.tool, run: setMod.run },
568
- "test-agent-engine": { tool: testMod.tool, run: testMod.run },
635
+ "manage-agent-engine": { tool: mod.tool, run: mod.run },
569
636
  };
570
637
  }
571
638
  catch {
@@ -606,275 +673,260 @@ function createBuilderBrowserTool(deps) {
606
673
  },
607
674
  },
608
675
  run: async (args) => {
609
- const configured = !!(process.env.BUILDER_PRIVATE_KEY && process.env.BUILDER_PUBLIC_KEY);
676
+ const { resolveBuilderCredentials } = await import("./credential-provider.js");
677
+ const creds = await resolveBuilderCredentials();
678
+ const configured = !!(creds.privateKey && creds.publicKey);
610
679
  const prompt = typeof args?.prompt === "string" ? args.prompt : "";
611
680
  return JSON.stringify({
612
681
  kind: "connect-builder-card",
613
682
  configured,
614
- builderEnabled: !!process.env.ENABLE_BUILDER,
615
683
  connectUrl: getBuilderBrowserConnectUrl(deps.getOrigin()),
616
- orgName: process.env.BUILDER_ORG_NAME || null,
684
+ orgName: creds.orgName || null,
617
685
  prompt,
618
686
  });
619
687
  },
620
688
  },
621
- "get-browser-connection": {
689
+ "activate-browser": {
622
690
  tool: {
623
- description: "Provision a Builder-backed browser session and return browser websocket connection details. If Builder browser access is not configured yet, this returns setup guidance instead.",
691
+ description: "Activate browser automation tools. Call this when you need to interact with a real browser e.g. to extract design tokens from a rendered page, take screenshots, read computed styles from JS-heavy sites, or test a live URL. After activation, chrome-devtools MCP tools (navigate, click, evaluate_script, take_screenshot, etc.) become available on your next action. Requires Builder.io connection.",
624
692
  parameters: {
625
693
  type: "object",
626
694
  properties: {
627
695
  sessionId: {
628
696
  type: "string",
629
- description: "Stable browser session identifier. Reuse it to reconnect to the same browser session.",
630
- },
631
- projectId: {
632
- type: "string",
633
- description: "Optional Builder project or space identifier to scope the session.",
634
- },
635
- branchName: {
636
- type: "string",
637
- description: "Optional branch name for Builder preview sessions.",
638
- },
639
- proxyOrigin: {
640
- type: "string",
641
- description: "Optional source origin to proxy from when browsing a local app.",
642
- },
643
- proxyDefaultOrigin: {
644
- type: "string",
645
- description: "Optional default origin that the browser should use for proxied requests.",
646
- },
647
- proxyDestination: {
648
- type: "string",
649
- description: "Optional destination origin for proxying local development traffic.",
697
+ description: "Optional session identifier for the browser connection. Auto-generated if omitted.",
650
698
  },
651
699
  },
652
- required: ["sessionId"],
653
700
  },
654
701
  },
655
702
  run: async (args) => {
656
- if (!process.env.BUILDER_PRIVATE_KEY ||
657
- !process.env.BUILDER_PUBLIC_KEY) {
703
+ const { resolveBuilderCredentials } = await import("./credential-provider.js");
704
+ const creds = await resolveBuilderCredentials();
705
+ if (!creds.privateKey || !creds.publicKey) {
706
+ return JSON.stringify({
707
+ error: "builder-not-connected",
708
+ message: "Builder.io is not connected. Call `connect-builder` first to enable browser automation.",
709
+ });
710
+ }
711
+ const { requestBuilderBrowserConnection } = await import("./builder-browser.js");
712
+ const sessionId = (typeof args?.sessionId === "string" && args.sessionId) ||
713
+ `an-browser-${Date.now()}`;
714
+ let connection;
715
+ try {
716
+ connection = await requestBuilderBrowserConnection({ sessionId });
717
+ }
718
+ catch (err) {
719
+ return JSON.stringify({
720
+ error: "browser-connection-failed",
721
+ message: `Failed to get browser connection: ${err?.message ?? err}`,
722
+ });
723
+ }
724
+ const wsUrl = connection.wsUrl;
725
+ if (!wsUrl) {
658
726
  return JSON.stringify({
659
- configured: false,
660
- message: "Builder browser access is not configured. Connect Builder from the workspace Resources panel before requesting a browser session.",
661
- connectUrl: getBuilderBrowserConnectUrl(deps.getOrigin()),
727
+ error: "no-ws-url",
728
+ message: "Browser connection did not return a WebSocket URL.",
662
729
  });
663
730
  }
664
- const connection = await requestBuilderBrowserConnection({
665
- sessionId: args.sessionId,
666
- projectId: args.projectId,
667
- branchName: args.branchName,
668
- proxyOrigin: args.proxyOrigin,
669
- proxyDefaultOrigin: args.proxyDefaultOrigin,
670
- proxyDestination: args.proxyDestination,
731
+ const manager = getGlobalMcpManager();
732
+ if (!manager) {
733
+ return JSON.stringify({
734
+ error: "no-mcp-manager",
735
+ message: "MCP manager is not available.",
736
+ });
737
+ }
738
+ // Add chrome-devtools-mcp server pointing at the provisioned browser
739
+ const currentConfig = manager.getConfig();
740
+ const servers = { ...(currentConfig?.servers ?? {}) };
741
+ servers["chrome-devtools"] = {
742
+ command: "npx",
743
+ args: [
744
+ "-y",
745
+ "chrome-devtools-mcp@latest",
746
+ "--wsEndpoint",
747
+ wsUrl,
748
+ "--categoryEmulation=false",
749
+ ],
750
+ type: "stdio",
751
+ };
752
+ await manager.reconfigure({
753
+ servers,
754
+ source: currentConfig?.source ?? "runtime",
671
755
  });
672
756
  return JSON.stringify({
673
- configured: true,
674
- sessionId: args.sessionId,
675
- ...connection,
757
+ success: true,
758
+ message: "Browser activated. Chrome DevTools MCP tools (mcp__chrome-devtools__*) are now available. Use them on your next action to navigate pages, read DOM, take screenshots, evaluate JavaScript, etc.",
759
+ wsUrl,
760
+ sessionId,
676
761
  });
677
762
  },
678
763
  },
679
764
  };
680
765
  }
681
766
  /**
682
- * Creates agent team orchestration tools (spawn-task, task-status, read-task-result).
683
- * These let the main agent spawn sub-agents and coordinate work.
767
+ * Creates the unified `agent-teams` tool that consolidates all sub-agent
768
+ * orchestration behind a single tool with an `action` parameter.
684
769
  */
685
770
  function createTeamTools(deps) {
686
771
  return {
687
- "spawn-task": {
772
+ "agent-teams": {
688
773
  tool: {
689
- description: "Spawn a sub-agent to handle a task in the background. The sub-agent runs independently with its own conversation thread. Use this to delegate work so the main chat stays free for new requests. A live preview card will appear in the chat showing the sub-agent's progress.",
774
+ description: "Manage sub-agent tasks. Use action 'spawn' to start a new sub-agent, 'status' to check progress, 'read-result' to get a finished task's output, 'send' to message a running sub-agent, or 'list' to see all tasks.",
690
775
  parameters: {
691
776
  type: "object",
692
777
  properties: {
778
+ action: {
779
+ type: "string",
780
+ enum: ["spawn", "status", "read-result", "send", "list"],
781
+ description: "The operation to perform",
782
+ },
693
783
  task: {
694
784
  type: "string",
695
- description: "Clear description of what the sub-agent should accomplish",
785
+ description: "(spawn) Clear description of what the sub-agent should accomplish",
696
786
  },
697
787
  instructions: {
698
788
  type: "string",
699
- description: "Optional additional instructions or context for the sub-agent",
789
+ description: "(spawn) Optional additional instructions or context for the sub-agent",
700
790
  },
701
791
  name: {
702
792
  type: "string",
703
- description: "Short name for the sub-agent tab (e.g. 'Research', 'Draft email'). If omitted, derived from the task.",
793
+ description: "(spawn) Short name for the sub-agent tab (e.g. 'Research', 'Draft email'). If omitted, derived from the task.",
704
794
  },
705
795
  agent: {
706
796
  type: "string",
707
- description: "Optional custom agent profile from agents/*.md to use for this task.",
797
+ description: "(spawn) Optional custom agent profile from agents/*.md to use for this task.",
708
798
  },
709
- },
710
- required: ["task"],
711
- },
712
- },
713
- run: async (args) => {
714
- // Capture the send function NOW (at spawn time) so that
715
- // concurrent runs don't clobber each other's send reference.
716
- const capturedSend = deps.getSend();
717
- const { spawnTask } = await import("./agent-teams.js");
718
- // Filter out team orchestration tools so sub-agents can't spawn sub-agents
719
- const teamToolNames = new Set([
720
- "spawn-task",
721
- "task-status",
722
- "read-task-result",
723
- "send-to-task",
724
- "list-tasks",
725
- ]);
726
- const subAgentActions = Object.fromEntries(Object.entries(deps.getActions()).filter(([name]) => !teamToolNames.has(name)));
727
- let instructions = args.instructions;
728
- let selectedModel = deps.getModel();
729
- let selectedName = args.name || "";
730
- if (args.agent) {
731
- const { findAccessibleCustomAgent } = await import("../resources/agents.js");
732
- const profile = await findAccessibleCustomAgent(deps.getOwner(), args.agent);
733
- if (!profile) {
734
- throw new Error(`Custom agent not found: ${args.agent}`);
735
- }
736
- const profileInstructions = `## Custom Agent Profile: ${profile.name}\n\n` +
737
- (profile.description ? `${profile.description}\n\n` : "") +
738
- profile.instructions;
739
- instructions = instructions
740
- ? `${profileInstructions}\n\n## Extra Task Context\n\n${instructions}`
741
- : profileInstructions;
742
- selectedModel = profile.model ?? selectedModel;
743
- selectedName = selectedName || profile.name;
744
- }
745
- const task = await spawnTask({
746
- description: args.task,
747
- instructions,
748
- ownerEmail: deps.getOwner(),
749
- systemPrompt: deps.getSystemPrompt(),
750
- actions: subAgentActions,
751
- engine: deps.getEngine(),
752
- model: selectedModel,
753
- parentThreadId: deps.getParentThreadId(),
754
- parentSend: (event) => {
755
- if (capturedSend)
756
- capturedSend(event);
757
- },
758
- });
759
- return JSON.stringify({
760
- taskId: task.taskId,
761
- threadId: task.threadId,
762
- status: task.status,
763
- description: task.description,
764
- name: selectedName,
765
- });
766
- },
767
- },
768
- "task-status": {
769
- tool: {
770
- description: "Check the status of a sub-agent task. Returns current status, preview of output, and current step.",
771
- parameters: {
772
- type: "object",
773
- properties: {
774
799
  taskId: {
775
800
  type: "string",
776
- description: "The task ID returned by spawn-task",
801
+ description: "(status, read-result, send) The task ID returned by a previous spawn",
777
802
  },
778
- },
779
- required: ["taskId"],
780
- },
781
- },
782
- run: async (args) => {
783
- const { getTask } = await import("./agent-teams.js");
784
- const task = await getTask(args.taskId);
785
- if (!task)
786
- return JSON.stringify({ error: "Task not found" });
787
- return JSON.stringify({
788
- taskId: task.taskId,
789
- threadId: task.threadId,
790
- status: task.status,
791
- description: task.description,
792
- preview: task.preview,
793
- currentStep: task.currentStep,
794
- summary: task.summary,
795
- });
796
- },
797
- },
798
- "read-task-result": {
799
- tool: {
800
- description: "Read the result of a completed sub-agent task. Returns the full output summary.",
801
- parameters: {
802
- type: "object",
803
- properties: {
804
- taskId: {
803
+ message: {
805
804
  type: "string",
806
- description: "The task ID returned by spawn-task",
805
+ description: "(send) Message to send to the sub-agent",
807
806
  },
808
807
  },
809
- required: ["taskId"],
808
+ required: ["action"],
810
809
  },
811
810
  },
812
811
  run: async (args) => {
813
- const { getTask } = await import("./agent-teams.js");
814
- const task = await getTask(args.taskId);
815
- if (!task)
816
- return JSON.stringify({ error: "Task not found" });
817
- if (task.status === "running") {
812
+ const action = args.action;
813
+ // ── spawn ──────────────────────────────────────────────
814
+ if (action === "spawn") {
815
+ if (!args.task)
816
+ throw new Error("'task' is required for spawn");
817
+ // Capture the send function NOW (at spawn time) so that
818
+ // concurrent runs don't clobber each other's send reference.
819
+ const capturedSend = deps.getSend();
820
+ const { spawnTask } = await import("./agent-teams.js");
821
+ // Filter out the team tool so sub-agents can't spawn sub-agents
822
+ const subAgentActions = Object.fromEntries(Object.entries(deps.getActions()).filter(([name]) => name !== "agent-teams"));
823
+ let instructions = args.instructions;
824
+ let selectedModel = deps.getModel();
825
+ let selectedName = args.name || "";
826
+ if (args.agent) {
827
+ const { findAccessibleCustomAgent } = await import("../resources/agents.js");
828
+ const profile = await findAccessibleCustomAgent(deps.getOwner(), args.agent);
829
+ if (!profile) {
830
+ throw new Error(`Custom agent not found: ${args.agent}`);
831
+ }
832
+ const profileInstructions = `## Custom Agent Profile: ${profile.name}\n\n` +
833
+ (profile.description ? `${profile.description}\n\n` : "") +
834
+ profile.instructions;
835
+ instructions = instructions
836
+ ? `${profileInstructions}\n\n## Extra Task Context\n\n${instructions}`
837
+ : profileInstructions;
838
+ selectedModel = profile.model ?? selectedModel;
839
+ selectedName = selectedName || profile.name;
840
+ }
841
+ const task = await spawnTask({
842
+ description: args.task,
843
+ instructions,
844
+ ownerEmail: deps.getOwner(),
845
+ systemPrompt: deps.getSystemPrompt(),
846
+ actions: subAgentActions,
847
+ engine: deps.getEngine(),
848
+ model: selectedModel,
849
+ parentThreadId: deps.getParentThreadId(),
850
+ parentSend: (event) => {
851
+ if (capturedSend)
852
+ capturedSend(event);
853
+ },
854
+ });
855
+ return JSON.stringify({
856
+ taskId: task.taskId,
857
+ threadId: task.threadId,
858
+ status: task.status,
859
+ description: task.description,
860
+ name: selectedName,
861
+ });
862
+ }
863
+ // ── status ─────────────────────────────────────────────
864
+ if (action === "status") {
865
+ if (!args.taskId)
866
+ throw new Error("'taskId' is required for status");
867
+ const { getTask } = await import("./agent-teams.js");
868
+ const task = await getTask(args.taskId);
869
+ if (!task)
870
+ return JSON.stringify({ error: "Task not found" });
818
871
  return JSON.stringify({
819
- status: "running",
872
+ taskId: task.taskId,
873
+ threadId: task.threadId,
874
+ status: task.status,
875
+ description: task.description,
820
876
  preview: task.preview,
821
- message: "Task is still running. Check back later.",
877
+ currentStep: task.currentStep,
878
+ summary: task.summary,
822
879
  });
823
880
  }
824
- return JSON.stringify({
825
- taskId: task.taskId,
826
- status: task.status,
827
- summary: task.summary,
828
- preview: task.preview,
829
- });
830
- },
831
- },
832
- "send-to-task": {
833
- tool: {
834
- description: "Send a message or update to a running sub-agent. Use this to redirect, add context, or give feedback to a sub-agent while it's working.",
835
- parameters: {
836
- type: "object",
837
- properties: {
838
- taskId: {
839
- type: "string",
840
- description: "The task ID returned by spawn-task",
841
- },
842
- message: {
843
- type: "string",
844
- description: "Message to send to the sub-agent",
845
- },
846
- },
847
- required: ["taskId", "message"],
848
- },
849
- },
850
- run: async (args) => {
851
- const { sendToTask } = await import("./agent-teams.js");
852
- const result = await sendToTask(args.taskId, args.message);
853
- return JSON.stringify(result);
854
- },
855
- },
856
- "list-tasks": {
857
- tool: {
858
- description: "List all sub-agent tasks and their current status. Use this to see what's running, completed, or failed.",
859
- parameters: {
860
- type: "object",
861
- properties: {},
862
- },
863
- },
864
- run: async () => {
865
- const { listTasks } = await import("./agent-teams.js");
866
- const tasks = await listTasks();
867
- if (tasks.length === 0) {
868
- return "No sub-agent tasks.";
869
- }
870
- return JSON.stringify(tasks.map((t) => ({
871
- taskId: t.taskId,
872
- threadId: t.threadId,
873
- description: t.description,
874
- status: t.status,
875
- currentStep: t.currentStep,
876
- hasResult: t.summary.length > 0,
877
- })), null, 2);
881
+ // ── read-result ────────────────────────────────────────
882
+ if (action === "read-result") {
883
+ if (!args.taskId)
884
+ throw new Error("'taskId' is required for read-result");
885
+ const { getTask } = await import("./agent-teams.js");
886
+ const task = await getTask(args.taskId);
887
+ if (!task)
888
+ return JSON.stringify({ error: "Task not found" });
889
+ if (task.status === "running") {
890
+ return JSON.stringify({
891
+ status: "running",
892
+ preview: task.preview,
893
+ message: "Task is still running. Check back later.",
894
+ });
895
+ }
896
+ return JSON.stringify({
897
+ taskId: task.taskId,
898
+ status: task.status,
899
+ summary: task.summary,
900
+ preview: task.preview,
901
+ });
902
+ }
903
+ // ── send ───────────────────────────────────────────────
904
+ if (action === "send") {
905
+ if (!args.taskId)
906
+ throw new Error("'taskId' is required for send");
907
+ if (!args.message)
908
+ throw new Error("'message' is required for send");
909
+ const { sendToTask } = await import("./agent-teams.js");
910
+ const result = await sendToTask(args.taskId, args.message);
911
+ return JSON.stringify(result);
912
+ }
913
+ // ── list ───────────────────────────────────────────────
914
+ if (action === "list") {
915
+ const { listTasks } = await import("./agent-teams.js");
916
+ const tasks = await listTasks();
917
+ if (tasks.length === 0) {
918
+ return "No sub-agent tasks.";
919
+ }
920
+ return JSON.stringify(tasks.map((t) => ({
921
+ taskId: t.taskId,
922
+ threadId: t.threadId,
923
+ description: t.description,
924
+ status: t.status,
925
+ currentStep: t.currentStep,
926
+ hasResult: t.summary.length > 0,
927
+ })), null, 2);
928
+ }
929
+ throw new Error(`Unknown action '${action}'. Use one of: spawn, status, read-result, send, list`);
878
930
  },
879
931
  },
880
932
  };
@@ -885,7 +937,173 @@ function createTeamTools(deps) {
885
937
  * Template AGENTS.md resources only need template-specific content.
886
938
  */
887
939
  /**
888
- * Framework instructions shared across both modes. The mode-specific
940
+ * Compact framework instructions for lazy-context mode. Keeps the critical
941
+ * behavioral rules but defers verbose details (chat history, agent teams,
942
+ * recurring jobs, builder.io, browser, A2A, structured memory) behind the
943
+ * `get-framework-context` tool.
944
+ */
945
+ const FRAMEWORK_CORE_COMPACT = `
946
+ ### Core Rules
947
+
948
+ 1. **Data lives in SQL** — All app state is in a SQL database. Use the available database tools. Call \`db-schema\` to see the full schema when needed.
949
+ 2. **Context awareness** — The user's current screen state is in \`<current-screen>\`, current URL in \`<current-url>\`. Use both to understand what the user is looking at. To change URL state, use \`set-search-params\` or \`set-url-path\`.
950
+ 3. **Navigate the UI** — Use the \`navigate\` tool to switch views, open items, or focus elements.
951
+ 4. **Application state** — Ephemeral UI state lives in \`application_state\`. Use \`readAppState\`/\`writeAppState\`.
952
+ 5. **Screen refresh is automatic** — The framework auto-refreshes after mutating tool calls. Only call \`refresh-screen\` when you mutated data via a path the framework can't detect.
953
+ 6. **Memory** — Use \`save-memory\` proactively when you learn preferences, corrections, or project context.
954
+ 7. **Security** — Always use parameterized queries. Never \`dangerouslySetInnerHTML\`, \`innerHTML\`, or \`eval()\`.
955
+ 8. **\`db-*\` tools are internal only** — \`db-query\`, \`db-exec\`, \`db-patch\` ONLY access the app's own SQL database (settings, application_state, template tables). They CANNOT reach BigQuery, HubSpot, GA4, Jira, or any external data source. If the user asks about a table that is NOT in the app schema (e.g. \`dbt_analytics.*\`, \`dbt_mart.*\`, or any fully-qualified \`project.dataset.table\`), use the appropriate template action instead — \`bigquery\` for warehouse tables, \`ga4-report\` for Google Analytics, \`hubspot-deals\` for HubSpot, etc. **Never use \`db-query\` for external data — it will fail.**
956
+
957
+ ### Resources
958
+
959
+ Use resource-list, resource-read, resource-write, resource-delete for persistent notes and context files.
960
+ Resources are NOT an agent scratchpad — never create executable scripts, task plans, or work-in-progress files.
961
+
962
+ ### Navigation Rule
963
+
964
+ When the user says "show me", "go to", "open", etc., ALWAYS use \`navigate\` first.
965
+
966
+ ### Extended Capabilities
967
+
968
+ You also have tools for: inline embeds, chat history search, agent teams/sub-agents, recurring jobs, A2A cross-app calls, structured memory, and browser automation (\`activate-browser\` to provision a real Chrome). Call \`get-framework-context\` to read detailed instructions for any of these when needed.
969
+ `;
970
+ /**
971
+ * Verbose framework sections returned by the `get-framework-context` tool.
972
+ * Keyed by topic so the agent can request specific sections.
973
+ */
974
+ const FRAMEWORK_CONTEXT_SECTIONS = {
975
+ embeds: `### Inline Embeds
976
+
977
+ You can embed an interactive view inline in your chat reply by writing an \`embed\` fenced code block. The chat renderer swaps the fence for a sandboxed iframe pointing at a route inside this app.
978
+
979
+ Syntax:
980
+
981
+ \`\`\`\`
982
+ \`\`\`embed
983
+ src: /some/path?param=value
984
+ aspect: 16/9
985
+ title: Optional label
986
+ \`\`\`
987
+ \`\`\`\`
988
+
989
+ Keys:
990
+ - \`src\` (required) — **must be a same-origin path starting with \`/\`**. Cross-origin URLs are blocked. No \`javascript:\` or \`data:\` URLs.
991
+ - \`aspect\` (optional) — one of \`16/9\` (default), \`4/3\`, \`3/2\`, \`2/1\`, \`21/9\`, \`1/1\`.
992
+ - \`title\` (optional) — accessible label / hover tooltip.
993
+ - \`height\` (optional) — fixed pixel height when aspect ratio isn't a good fit.
994
+
995
+ Use for charts, visualizations, previews. Don't use for simple text/tables or external sites.`,
996
+ "chat-history": `### Chat History
997
+
998
+ You can search and restore previous chat conversations using \`chat-history\`:
999
+ - \`chat-history\` (action: "search") — Search or list past chat threads by keyword
1000
+ - \`chat-history\` (action: "open") — Open a chat thread in the UI as a new tab and focus it
1001
+
1002
+ When the user asks to find a previous conversation, use \`chat-history\` with action "search" first to find matching threads, then action "open" to restore the one they want.`,
1003
+ "agent-teams": `### Agent Teams — Orchestration
1004
+
1005
+ You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents using the \`agent-teams\` tool:
1006
+ - \`agent-teams\` (action: "spawn") — Spawn a sub-agent for a task. It runs in its own thread while you stay available.
1007
+ - \`agent-teams\` (action: "status") — Check the progress of a running sub-agent.
1008
+ - \`agent-teams\` (action: "read-result") — Read the result when a sub-agent finishes.
1009
+ - \`agent-teams\` (action: "send") — Send a message to a running sub-agent.
1010
+ - \`agent-teams\` (action: "list") — List all sub-agent tasks.
1011
+
1012
+ **When to delegate vs do directly:**
1013
+ - **Delegate** when the task involves multiple tool calls, research, content generation, or anything that takes more than a few seconds.
1014
+ - **Do directly** for quick single-step tasks like navigation, reading state, or answering simple questions.
1015
+ - **Spawn multiple sub-agents** when the user asks for multiple independent things — they'll run in parallel.
1016
+
1017
+ Sub-agents have access to all template tools but **cannot spawn sub-agents themselves**.`,
1018
+ "recurring-jobs": `### Recurring Jobs
1019
+
1020
+ You can create recurring jobs that run on a cron schedule. Jobs are resource files under \`jobs/\`.
1021
+
1022
+ - \`manage-jobs\` (action: "create") — Create a new recurring job with a cron schedule and instructions
1023
+ - \`manage-jobs\` (action: "list") — List all recurring jobs and their status
1024
+ - \`manage-jobs\` (action: "update") — Update a job's schedule, instructions, or toggle enabled/disabled
1025
+ - Delete a job with \`resource-delete --path jobs/<name>.md\`
1026
+
1027
+ Convert natural language to 5-field cron format:
1028
+ - "every morning" / "daily at 9am" → \`0 9 * * *\`
1029
+ - "every weekday at 9am" → \`0 9 * * 1-5\`
1030
+ - "every hour" → \`0 * * * *\`
1031
+ - "every monday at 9am" → \`0 9 * * 1\``,
1032
+ builder: `### Connecting Builder.io
1033
+
1034
+ When the user asks to connect Builder.io or you hit a "Builder not configured" error, call the \`connect-builder\` tool. It renders a one-click Connect card inline — do NOT write out multi-step setup instructions yourself.`,
1035
+ browser: `### Browser Automation
1036
+
1037
+ You can activate a real Chrome browser via Builder.io for tasks that need full page rendering:
1038
+ - Extracting design tokens from JS-heavy or SPA websites (computed styles, rendered colors/fonts)
1039
+ - Taking screenshots of live pages
1040
+ - Testing interactive flows on deployed URLs
1041
+ - Reading content from pages that require JavaScript execution
1042
+
1043
+ **How to use:**
1044
+ 1. Call \`activate-browser\` — this provisions a Chrome instance and registers chrome-devtools MCP tools
1045
+ 2. On your next action, use \`mcp__chrome-devtools__navigate_page\`, \`mcp__chrome-devtools__evaluate_script\`, \`mcp__chrome-devtools__take_screenshot\`, etc.
1046
+ 3. If Builder is not connected, call \`connect-builder\` first
1047
+
1048
+ **When to recommend browser automation:**
1049
+ - User wants to import a design system from a URL (JS-rendered sites give almost no useful data from plain HTML fetch)
1050
+ - User asks you to check how a deployed site looks or behaves
1051
+ - Any task involving reading computed/rendered page state
1052
+ - When \`web-request\` returns minimal/skeleton HTML from a modern SPA
1053
+
1054
+ Prefer \`web-request\` for simple API calls and static pages. Use browser automation when you need the real rendered page.`,
1055
+ "call-agent": `### call-agent — External Apps Only
1056
+
1057
+ The \`call-agent\` tool sends a message to a DIFFERENT, separately-deployed app's agent (A2A protocol). It is **not** for calling actions within the current app.
1058
+
1059
+ **NEVER use \`call-agent\` to:**
1060
+ - Call your own app by name
1061
+ - Perform tasks you can accomplish with your own registered tools
1062
+
1063
+ **ONLY use \`call-agent\` when:**
1064
+ - The user explicitly asks you to communicate with a different app
1065
+ - You need data that only another deployed app can provide`,
1066
+ memory: `### Structured Memory
1067
+
1068
+ Your memory index (\`memory/MEMORY.md\`) is loaded at the start of every conversation.
1069
+
1070
+ **Tools:**
1071
+ - \`save-memory\` — Create or update a memory (name, type, description, content)
1072
+ - \`delete-memory\` — Remove a memory and its index entry
1073
+ - \`resource-read --path memory/<name>.md\` — Read the full content of a specific memory
1074
+
1075
+ **Memory types:** user, feedback, project, reference
1076
+
1077
+ **When to save (proactively):**
1078
+ - User corrects your approach → \`feedback\`
1079
+ - User shares preferences → \`user\`
1080
+ - Non-obvious pattern or gotcha → \`feedback\`
1081
+ - Personal context (contacts, team) → \`user\`
1082
+ - Project context to track → \`project\`
1083
+
1084
+ **Rules:**
1085
+ - Don't save things obvious from code or standard framework behavior
1086
+ - When updating, read first and merge — don't overwrite
1087
+ - Keep descriptions concise
1088
+ - One memory per logical topic`,
1089
+ "sql-tools": `### SQL Tools
1090
+
1091
+ - \`db-schema\` — refresh the full schema with indexes and foreign keys
1092
+ - \`db-query\` — run a SELECT (read-only; results already filtered to the current user/org)
1093
+ - \`db-exec\` — run INSERT / UPDATE / DELETE (writes already scoped; owner_email and org_id are auto-injected on INSERT)
1094
+ - \`db-patch\` — surgical search-and-replace on a large text column. Use for edits to large fields instead of re-sending multi-kilobyte strings.
1095
+
1096
+ ### When to pick which SQL tool
1097
+ - Set a short column outright, update multiple columns, or do computed updates → \`db-exec UPDATE\`
1098
+ - Change a small slice of a large text/JSON column → \`db-patch\`
1099
+ - A template-specific action exists for the table → use that action (it encodes business rules and pushes live Yjs updates)
1100
+ - Read data → \`db-query\`. Never re-add \`WHERE owner_email = ...\` — scoping already applies it.
1101
+
1102
+ ### External data sources vs the app database
1103
+ The \`db-*\` tools ONLY query the app's own SQL database. They do NOT reach external data warehouses. If the user asks about tables NOT in the schema, use the appropriate template action instead.`,
1104
+ };
1105
+ /**
1106
+ * Full framework instructions shared across both modes. The mode-specific
889
1107
  * preamble is prepended by the prompt composition below.
890
1108
  */
891
1109
  const FRAMEWORK_CORE = `
@@ -898,16 +1116,17 @@ const FRAMEWORK_CORE = `
898
1116
  5. **Screen refresh is automatic after action calls** — The framework auto-emits a refresh event after any successful mutating tool call (template actions like \`log-meal\`, \`update-form\`, \`edit-document\`, and the \`db-exec\` / \`db-patch\` tools). The UI re-fetches its queries without a full page reload. You do NOT need to call \`refresh-screen\` after an action — it's already handled. Only call \`refresh-screen\` explicitly when (a) you mutated data via a path the framework can't detect (e.g. writing directly to an external system whose results the app mirrors), or (b) you want to pass a \`scope\` hint so the UI narrows which queries to refetch. Do NOT tell the user to reload the page.
899
1117
  6. **Memory** — Use the structured memory system to persist knowledge across sessions. Use \`save-memory\` proactively when you learn preferences, corrections, or project context. Update shared AGENTS.md for instructions that should apply to all users.
900
1118
  7. **Security** — Always use \`defineAction\` with a Zod \`schema:\` for input validation. Never construct SQL with string concatenation — use parameterized queries via db-query/db-exec. Never use \`dangerouslySetInnerHTML\`, \`innerHTML\`, or \`eval()\`. Never expose secrets in responses or source code. Every table with user data must have \`owner_email\`.
1119
+ 8. **\`db-*\` tools are internal only** — \`db-query\`, \`db-exec\`, \`db-patch\` ONLY access the app's own SQL database (settings, application_state, template tables). They CANNOT reach BigQuery, HubSpot, GA4, Jira, or any external data source. If the user asks about a table that is NOT in the app schema (e.g. \`dbt_analytics.*\`, \`dbt_mart.*\`, or any fully-qualified \`project.dataset.table\`), use the appropriate template action instead — \`bigquery\` for warehouse tables, \`ga4-report\` for Google Analytics, \`hubspot-deals\` for HubSpot, etc. **Never use \`db-query\` for external data — it will fail.**
901
1120
 
902
1121
  ### Resources
903
1122
 
904
1123
  You have access to a Resources system for persistent notes and context files.
905
- Use resource-list, resource-read, resource-write, and resource-delete to manage resources.
1124
+ Use resource-list, resource-read, resource-write, resource-delete to manage resources.
906
1125
  Resources can be personal (per-user) or shared (team-wide). By default, resources are personal.
907
1126
 
908
1127
  When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource.
909
1128
 
910
- **Resources are NOT an agent scratchpad.** Never use \`resource-write\` to store executable scripts, task plans, retry notes, or work-in-progress files you're writing to yourself. Specifically, do NOT create resources under \`scripts/\` or \`tasks/\` unless the user explicitly asked for a file at that path, or a tool (like \`create-job\` or \`spawn-task\`) writes there as part of its contract. If you can't complete a task with the tools you have, say so — don't improvise by leaving behind \`FINAL-*.md\`, \`EXECUTE-NOW-*.js\`, or similar artifacts. Resources are visible to the user in the workspace sidebar; every file you write is something they'll see and have to clean up.
1129
+ **Resources are NOT an agent scratchpad.** Never use \`resource-write\` to store executable scripts, task plans, retry notes, or work-in-progress files you're writing to yourself. Specifically, do NOT create resources under \`scripts/\` or \`tasks/\` unless the user explicitly asked for a file at that path, or a tool (like \`manage-jobs\` or \`agent-teams\`) writes there as part of its contract. If you can't complete a task with the tools you have, say so — don't improvise by leaving behind \`FINAL-*.md\`, \`EXECUTE-NOW-*.js\`, or similar artifacts. Resources are visible to the user in the workspace sidebar; every file you write is something they'll see and have to clean up.
911
1130
 
912
1131
  ### Navigation Rule
913
1132
 
@@ -946,18 +1165,20 @@ Which routes are renderable as embeds is template-specific — the app's \`AGENT
946
1165
 
947
1166
  ### Chat History
948
1167
 
949
- You can search and restore previous chat conversations:
950
- - \`search-chats\` — Search or list past chat threads by keyword
951
- - \`open-chat\` — Open a chat thread in the UI as a new tab and focus it
1168
+ You can search and restore previous chat conversations using \`chat-history\`:
1169
+ - \`chat-history\` (action: "search") — Search or list past chat threads by keyword
1170
+ - \`chat-history\` (action: "open") — Open a chat thread in the UI as a new tab and focus it
952
1171
 
953
- When the user asks to find a previous conversation, use \`search-chats\` first to find matching threads, then \`open-chat\` to restore the one they want.
1172
+ When the user asks to find a previous conversation, use \`chat-history\` with action "search" first to find matching threads, then action "open" to restore the one they want.
954
1173
 
955
1174
  ### Agent Teams — Orchestration
956
1175
 
957
- You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents:
958
- - \`spawn-task\` — Spawn a sub-agent for a task. It runs in its own thread while you stay available. A live preview card appears in the chat. You can optionally choose a custom agent profile from \`agents/*.md\`.
959
- - \`task-status\` — Check the progress of a running sub-agent.
960
- - \`read-task-result\` — Read the result when a sub-agent finishes.
1176
+ You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents using the \`agent-teams\` tool:
1177
+ - \`agent-teams\` (action: "spawn") — Spawn a sub-agent for a task. It runs in its own thread while you stay available. A live preview card appears in the chat. You can optionally choose a custom agent profile from \`agents/*.md\`.
1178
+ - \`agent-teams\` (action: "status") — Check the progress of a running sub-agent.
1179
+ - \`agent-teams\` (action: "read-result") — Read the result when a sub-agent finishes.
1180
+ - \`agent-teams\` (action: "send") — Send a message to a running sub-agent.
1181
+ - \`agent-teams\` (action: "list") — List all sub-agent tasks.
961
1182
 
962
1183
  **When to delegate vs do directly:**
963
1184
  - **Delegate** when the task involves multiple tool calls, research, content generation, or anything that takes more than a few seconds. Examples: "create a deck about X", "analyze the data and write a report", "look up Y and draft an email about it".
@@ -968,18 +1189,18 @@ You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents
968
1189
  1. When the user asks for something complex, spawn a sub-agent with a clear task description.
969
1190
  2. Tell the user what you've started ("I'm having a sub-agent research that for you").
970
1191
  3. You can keep chatting — sub-agents run independently.
971
- 4. Use \`read-task-result\` to check results when needed, or the user can see live progress in the card.
1192
+ 4. Use \`agent-teams\` (action: "read-result") to check results when needed, or the user can see live progress in the card.
972
1193
  5. If the user's request has multiple steps, you can spawn one sub-agent per step, or chain them.
973
1194
 
974
- Sub-agents have access to all template tools but **cannot spawn sub-agents themselves** — only you (the orchestrator) can do that. Give the sub-agent a specific, actionable task description — it will figure out which tools to use. If a matching custom agent profile exists, pass it via the \`agent\` parameter on \`spawn-task\`.
1195
+ Sub-agents have access to all template tools but **cannot spawn sub-agents themselves** — only you (the orchestrator) can do that. Give the sub-agent a specific, actionable task description — it will figure out which tools to use. If a matching custom agent profile exists, pass it via the \`agent\` parameter on \`agent-teams\` (action: "spawn").
975
1196
 
976
1197
  ### Recurring Jobs
977
1198
 
978
1199
  You can create recurring jobs that run on a cron schedule. Jobs are resource files under \`jobs/\`. Each job has a cron schedule and instructions that the agent executes automatically.
979
1200
 
980
- - \`create-job\` — Create a new recurring job with a cron schedule and instructions
981
- - \`list-jobs\` — List all recurring jobs and their status (schedule, last run, next run, errors)
982
- - \`update-job\` — Update a job's schedule, instructions, or toggle enabled/disabled
1201
+ - \`manage-jobs\` (action: "create") — Create a new recurring job with a cron schedule and instructions
1202
+ - \`manage-jobs\` (action: "list") — List all recurring jobs and their status (schedule, last run, next run, errors)
1203
+ - \`manage-jobs\` (action: "update") — Update a job's schedule, instructions, or toggle enabled/disabled
983
1204
  - Delete a job with \`resource-delete --path jobs/<name>.md\`
984
1205
 
985
1206
  When the user asks for something recurring ("every morning", "daily at 9am", "weekly on Mondays"), create a job. Convert natural language to 5-field cron format:
@@ -996,13 +1217,9 @@ Job instructions should be self-contained — include which actions to call, wha
996
1217
 
997
1218
  When the user asks to connect Builder.io, needs Builder for LLM access / browser automation, or you hit a "Builder not configured" error, call the \`connect-builder\` tool. It renders a one-click Connect card inline in the chat — do NOT write out multi-step setup instructions yourself (no "Option 1 / Option 2", no terminal commands). Just call the tool and let the card handle the rest.
998
1219
 
999
- ### Browser Access
1000
-
1001
- Use \`get-browser-connection\` when you need a real browser session backed by Builder. It returns websocket connection details for a provisioned browser session.
1220
+ ### Browser Automation
1002
1221
 
1003
- - If the tool says Builder is not configured, call \`connect-builder\` to show the user a Connect card.
1004
- - Reuse a stable \`sessionId\` when you want to reconnect to the same browser session.
1005
- - Include proxy parameters when you need the browser to reach a local dev server through Builder's browser connection flow.
1222
+ Call \`activate-browser\` to provision a real Chrome browser. After activation, chrome-devtools MCP tools become available for navigating pages, reading rendered DOM, taking screenshots, and evaluating JavaScript. If Builder is not connected, call \`connect-builder\` first. Use browser automation proactively when tasks benefit from full page rendering (design system extraction from URLs, visual verification, SPA content reading).
1006
1223
 
1007
1224
  ### call-agent — External Apps Only
1008
1225
 
@@ -1068,7 +1285,7 @@ When the user asks you to change the UI, modify code, add a feature, fix a bug i
1068
1285
  - Do NOT read source files, list directories, or explore the codebase. You have no filesystem tools and don't need to look at code to recommend Builder.
1069
1286
  - Do NOT write an implementation plan. Do NOT write code in your response. Do NOT describe which files to create or modify. Builder will figure that out in its sandbox.
1070
1287
  - Do NOT save plans, specs, or code to \`resource-write\`. Resources are for app data, not implementation plans the user didn't ask for.
1071
- - Do NOT spawn sub-agents (\`spawn-task\`) to design, plan, or research the feature. The answer is always: call \`connect-builder\`, say one sentence, stop. Sub-agents inherit these same rules and have no code-editing tools either.
1288
+ - Do NOT spawn sub-agents (\`agent-teams\`) to design, plan, or research the feature. The answer is always: call \`connect-builder\`, say one sentence, stop. Sub-agents inherit these same rules and have no code-editing tools either.
1072
1289
  - Do NOT say "I don't have a request-code-change tool" or list what tools you lack. Just call \`connect-builder\`.
1073
1290
  - Do NOT wait for the user to ask "how" — call \`connect-builder\` the moment a code change is requested.
1074
1291
 
@@ -1098,6 +1315,34 @@ When editing code, follow the agent-native architecture:
1098
1315
  - No Node.js-specific APIs in server routes (must work on Cloudflare Workers, etc.)
1099
1316
  - Use shadcn/ui components and Tabler Icons for all UI work
1100
1317
  ${FRAMEWORK_CORE}`;
1318
+ const PROD_FRAMEWORK_PROMPT_COMPACT = `## Agent-Native Framework — Production Mode
1319
+
1320
+ You are an AI agent in an agent-native application, running in **production mode**.
1321
+
1322
+ The agent and the UI are equal partners — everything the UI can do, you can do via your tools, and vice versa. They share the same SQL database and stay in sync automatically.
1323
+
1324
+ **In production mode, you operate through registered actions exposed as tools.** These are your capabilities — use them to read data, take actions, and help the user. You cannot edit source code or access the filesystem directly. Your tools are the app's API.
1325
+
1326
+ ### Code Changes — Call \`connect-builder\`
1327
+
1328
+ When the user asks to change the UI, modify code, add a feature, or fix a bug in the app itself — call \`connect-builder\` immediately, passing the user's request as the \`prompt\`. Do NOT write code, list files, make plans, or spawn sub-agents for code changes. Builder handles it in the cloud. Mention \`npx agent-native create <app-name>\` as an offline fallback.
1329
+ ${FRAMEWORK_CORE_COMPACT}`;
1330
+ const DEV_FRAMEWORK_PROMPT_COMPACT = `## Agent-Native Framework — Development Mode
1331
+
1332
+ You are an AI agent in an agent-native application, running in **development mode**.
1333
+
1334
+ The agent and the UI are equal partners — everything the UI can do, you can do via tools/scripts, and vice versa. They share the same SQL database and stay in sync automatically.
1335
+
1336
+ **In development mode, you have UNRESTRICTED access.** You can run any shell command, read/write files, query the database, call external APIs, edit source code, and install packages.
1337
+
1338
+ **Template-specific actions are invoked via shell, NOT as direct tools.** Run them with: \`shell({ command: 'pnpm action <name> --arg value' })\`. See the "Available Actions" section below for CLI syntax.
1339
+
1340
+ When editing code, follow the agent-native architecture:
1341
+ - Every feature needs all four areas: UI + scripts + skills/instructions + application-state sync
1342
+ - All SQL must be dialect-agnostic (works on SQLite and Postgres)
1343
+ - No Node.js-specific APIs in server routes (must work on Cloudflare Workers, etc.)
1344
+ - Use shadcn/ui components and Tabler Icons for all UI work
1345
+ ${FRAMEWORK_CORE_COMPACT}`;
1101
1346
  const DEFAULT_SYSTEM_PROMPT = PROD_FRAMEWORK_PROMPT;
1102
1347
  /**
1103
1348
  * Pre-load the agent's context: AGENTS.md (template instructions), the skills
@@ -1117,7 +1362,7 @@ const DEFAULT_SYSTEM_PROMPT = PROD_FRAMEWORK_PROMPT;
1117
1362
  * AGENTS.md and restarting the server is all it takes; Vite HMR invalidates
1118
1363
  * the bundle in dev so changes land instantly.
1119
1364
  */
1120
- async function loadResourcesForPrompt(owner) {
1365
+ async function loadResourcesForPrompt(owner, compact = false) {
1121
1366
  await ensurePersonalDefaults(owner);
1122
1367
  const sections = [];
1123
1368
  // 1. Workspace AGENTS.md + skills merged into the template bundle.
@@ -1128,33 +1373,51 @@ async function loadResourcesForPrompt(owner) {
1128
1373
  if (bundle.workspaceAgentsMd && bundle.workspaceAgentsMd.trim()) {
1129
1374
  sections.push(`<resource name="AGENTS.md" scope="workspace">\n${bundle.workspaceAgentsMd.trim()}\n</resource>`);
1130
1375
  }
1131
- // 2. Template AGENTS.md.
1376
+ // 2. Template AGENTS.md — always included (critical template instructions).
1132
1377
  if (bundle.agentsMd.trim()) {
1133
1378
  sections.push(`<resource name="AGENTS.md" scope="template">\n${bundle.agentsMd.trim()}\n</resource>`);
1134
1379
  }
1135
- const skillsBlock = generateSkillsPromptBlock(bundle);
1136
- if (skillsBlock)
1137
- sections.push(skillsBlock);
1138
- }
1139
- catch { }
1140
- // LEARNINGS.md from SQL (template-level instructions are in AGENTS.md above).
1141
- // 2. Shared SQL scope
1142
- try {
1143
- const shared = await resourceGetByPath(SHARED_OWNER, "LEARNINGS.md");
1144
- if (shared?.content?.trim()) {
1145
- sections.push(`<resource name="LEARNINGS.md" scope="shared">\n${shared.content.trim()}\n</resource>`);
1380
+ // In compact mode, skip the full skills block — the agent can use
1381
+ // `docs-search` to find skills when it needs them.
1382
+ if (!compact) {
1383
+ const skillsBlock = generateSkillsPromptBlock(bundle);
1384
+ if (skillsBlock)
1385
+ sections.push(skillsBlock);
1386
+ }
1387
+ else if (Object.keys(bundle.skills).length > 0) {
1388
+ const names = Object.values(bundle.skills)
1389
+ .map((s) => s.meta.name)
1390
+ .join(", ");
1391
+ sections.push(`<skills-summary>\nSkills available in .agents/skills/: ${names}. Use \`docs-search\` to read a skill before starting a task it applies to.\n</skills-summary>`);
1146
1392
  }
1147
1393
  }
1148
1394
  catch { }
1149
- // 3. Personal memory index (skip if owner is the shared sentinel)
1150
- if (owner !== SHARED_OWNER) {
1395
+ if (compact) {
1396
+ // In compact mode, skip learnings and memory in the prompt.
1397
+ // The agent can access them via resource-read when needed.
1398
+ // Add a brief pointer so the agent knows they exist.
1399
+ sections.push(`<context-note>Shared learnings (LEARNINGS.md) and your personal memory (memory/MEMORY.md) are available via \`resource-read\`. Check them when making decisions that might benefit from prior context.</context-note>`);
1400
+ }
1401
+ else {
1402
+ // LEARNINGS.md from SQL (template-level instructions are in AGENTS.md above).
1403
+ // 2. Shared SQL scope
1151
1404
  try {
1152
- const memoryIndex = await resourceGetByPath(owner, "memory/MEMORY.md");
1153
- if (memoryIndex?.content?.trim()) {
1154
- sections.push(`<resource name="memory/MEMORY.md" scope="personal">\n${memoryIndex.content.trim()}\n</resource>`);
1405
+ const shared = await resourceGetByPath(SHARED_OWNER, "LEARNINGS.md");
1406
+ if (shared?.content?.trim()) {
1407
+ sections.push(`<resource name="LEARNINGS.md" scope="shared">\n${shared.content.trim()}\n</resource>`);
1155
1408
  }
1156
1409
  }
1157
1410
  catch { }
1411
+ // 3. Personal memory index (skip if owner is the shared sentinel)
1412
+ if (owner !== SHARED_OWNER) {
1413
+ try {
1414
+ const memoryIndex = await resourceGetByPath(owner, "memory/MEMORY.md");
1415
+ if (memoryIndex?.content?.trim()) {
1416
+ sections.push(`<resource name="memory/MEMORY.md" scope="personal">\n${memoryIndex.content.trim()}\n</resource>`);
1417
+ }
1418
+ }
1419
+ catch { }
1420
+ }
1158
1421
  }
1159
1422
  if (sections.length === 0)
1160
1423
  return "";
@@ -1272,11 +1535,9 @@ ${lines.join("\n")}`;
1272
1535
  }
1273
1536
  return `\n\n## Available Actions
1274
1537
 
1275
- **Use these actions directly to accomplish tasks. Do NOT use \`db-schema\`, \`search-files\`, or \`shell\` to explore the app these actions already connect to the correct database and services.**
1538
+ **Use these actions directly as tool calls.** They are your primary tools they handle database access, validation, and business logic internally. Prefer these over lower-level tools like \`web-request\` or \`db-query\`.
1276
1539
 
1277
- **For external data sources (BigQuery, HubSpot, Jira, GA4, etc.), use the data-source-specific action below — NOT \`db-query\`.** \`db-query\` only reaches the app's own internal database. If the user asks about tables not in the app schema, pick the matching action here.
1278
-
1279
- Parameter notation: \`name*\` = required, \`name?\` = optional. Always pass the tool's parameters as a JSON object to the tool_use call — never via shell or string-concatenated CLI flags.
1540
+ Parameter notation: \`name*\` = required, \`name?\` = optional. Pass parameters as a JSON object.
1280
1541
 
1281
1542
  ${lines.join("\n")}`;
1282
1543
  }
@@ -1421,7 +1682,7 @@ export function createAgentChatPlugin(options) {
1421
1682
  if (mcpConfig?.source) {
1422
1683
  console.log(`[mcp-client] loaded config from ${mcpConfig.source} (${Object.keys(mcpConfig.servers).length} server(s))`);
1423
1684
  }
1424
- else {
1685
+ else if (process.env.DEBUG) {
1425
1686
  console.log("[mcp-client] no configured MCP servers — skipping MCP tools");
1426
1687
  }
1427
1688
  }
@@ -1467,16 +1728,31 @@ export function createAgentChatPlugin(options) {
1467
1728
  process.once("SIGTERM", stop);
1468
1729
  process.once("SIGINT", stop);
1469
1730
  }
1470
- // Resolve actions — prefer `actions`, fall back to deprecated `scripts`
1731
+ // Resolve actions — prefer explicit `actions`, fall back to deprecated
1732
+ // `scripts`. When neither is provided, auto-discover from the filesystem
1733
+ // so templates that forget to pass `actions` still work in non-serverless
1734
+ // deployments (serverless bundles need explicit imports).
1471
1735
  const rawActions = options?.actions ?? options?.scripts;
1472
- const templateScripts = typeof rawActions === "function"
1736
+ let templateScripts = typeof rawActions === "function"
1473
1737
  ? await rawActions()
1474
1738
  : (rawActions ?? {});
1739
+ if (!rawActions && Object.keys(templateScripts).length === 0) {
1740
+ try {
1741
+ const { autoDiscoverActions } = await import("./action-discovery.js");
1742
+ templateScripts = await autoDiscoverActions(process.cwd());
1743
+ }
1744
+ catch {
1745
+ // Filesystem discovery unavailable (serverless bundle) — skip.
1746
+ }
1747
+ }
1475
1748
  // Resource, chat, docs, db, and cross-agent scripts are available in both prod and dev modes
1476
1749
  const resourceScripts = await createResourceScriptEntries();
1477
1750
  const docsScripts = await createDocsScriptEntries();
1478
1751
  const dbScripts = await createDbScriptEntries();
1479
1752
  const refreshScreenTool = createRefreshScreenEntry();
1753
+ const frameworkContextTool = createFrameworkContextEntry();
1754
+ const leanPrompt = options?.leanPrompt === true;
1755
+ const lazyContext = options?.lazyContext !== false && !leanPrompt;
1480
1756
  const urlTools = createUrlTools();
1481
1757
  const engineScripts = await createAgentEngineScriptEntries();
1482
1758
  const chatScripts = {
@@ -1658,6 +1934,12 @@ export function createAgentChatPlugin(options) {
1658
1934
  });
1659
1935
  }
1660
1936
  catch { }
1937
+ let toolActions = {};
1938
+ try {
1939
+ const { createToolActionEntries } = await import("../tools/actions.js");
1940
+ toolActions = createToolActionEntries();
1941
+ }
1942
+ catch { }
1661
1943
  // In dev mode, template actions (templateScripts and discoveredActions) are
1662
1944
  // NOT registered as native tools — the agent invokes them via shell instead.
1663
1945
  // This avoids degenerate empty-object tool calls that Anthropic models
@@ -1667,12 +1949,15 @@ export function createAgentChatPlugin(options) {
1667
1949
  ? {
1668
1950
  ...resourceScripts,
1669
1951
  ...docsScripts,
1952
+ ...(lazyContext ? frameworkContextTool : {}),
1953
+ ...urlTools,
1670
1954
  ...chatScripts,
1671
1955
  ...callAgentScript,
1672
1956
  ...automationTools,
1673
1957
  ...notificationTools,
1674
1958
  ...progressTools,
1675
1959
  ...fetchTool,
1960
+ ...toolActions,
1676
1961
  ...browserTools,
1677
1962
  ...devScriptsForA2A,
1678
1963
  }
@@ -1683,6 +1968,7 @@ export function createAgentChatPlugin(options) {
1683
1968
  ...docsScripts,
1684
1969
  ...dbScripts,
1685
1970
  ...refreshScreenTool,
1971
+ ...(lazyContext ? frameworkContextTool : {}),
1686
1972
  ...urlTools,
1687
1973
  ...chatScripts,
1688
1974
  ...callAgentScript,
@@ -1690,6 +1976,7 @@ export function createAgentChatPlugin(options) {
1690
1976
  ...notificationTools,
1691
1977
  ...progressTools,
1692
1978
  ...fetchTool,
1979
+ ...toolActions,
1693
1980
  ...browserTools,
1694
1981
  ...devScriptsForA2A,
1695
1982
  };
@@ -1767,13 +2054,14 @@ export function createAgentChatPlugin(options) {
1767
2054
  const handler = devActive && devHandler ? devHandler : prodHandler;
1768
2055
  // Build the same system prompt the interactive agent uses
1769
2056
  const owner = userEmail || "local@localhost";
1770
- const resources = await loadResourcesForPrompt(owner);
1771
- const schemaBlock = await buildSchemaBlock(owner, devActive);
2057
+ const resources = await loadResourcesForPrompt(owner, lazyContext);
2058
+ const schemaBlock = lazyContext
2059
+ ? ""
2060
+ : await buildSchemaBlock(owner, devActive);
1772
2061
  const systemPrompt = devActive
1773
2062
  ? devPrompt + resources + schemaBlock
1774
2063
  : basePrompt + resources + schemaBlock;
1775
- const model = options?.model ??
1776
- (canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
2064
+ const model = options?.model ?? "claude-sonnet-4-6";
1777
2065
  // Build tools — same as interactive handler but WITHOUT call-agent
1778
2066
  // to prevent infinite recursive A2A loops (agent calling itself).
1779
2067
  // In dev mode, template actions are invoked via shell (not native tools),
@@ -1782,7 +2070,10 @@ export function createAgentChatPlugin(options) {
1782
2070
  ? {
1783
2071
  ...resourceScripts,
1784
2072
  ...docsScripts,
2073
+ ...(lazyContext ? frameworkContextTool : {}),
2074
+ ...urlTools,
1785
2075
  ...chatScripts,
2076
+ ...toolActions,
1786
2077
  ...browserTools,
1787
2078
  ...devScriptsForA2A,
1788
2079
  }
@@ -1792,8 +2083,10 @@ export function createAgentChatPlugin(options) {
1792
2083
  ...docsScripts,
1793
2084
  ...dbScripts,
1794
2085
  ...refreshScreenTool,
2086
+ ...(lazyContext ? frameworkContextTool : {}),
1795
2087
  ...urlTools,
1796
2088
  ...chatScripts,
2089
+ ...toolActions,
1797
2090
  ...browserTools,
1798
2091
  };
1799
2092
  const a2aTools = actionsToEngineTools(a2aActions);
@@ -1852,11 +2145,26 @@ export function createAgentChatPlugin(options) {
1852
2145
  // Build system prompts — dynamic functions that pre-load resources per-request.
1853
2146
  // Production gets PROD_FRAMEWORK_PROMPT, dev gets DEV_FRAMEWORK_PROMPT.
1854
2147
  // Custom systemPrompt from options overrides the framework default entirely.
1855
- const prodPrompt = (options?.systemPrompt ?? PROD_FRAMEWORK_PROMPT) + prodActionsPrompt;
1856
- const devPrompt = (options?.devSystemPrompt
1857
- ? options.devSystemPrompt +
1858
- (options?.systemPrompt ?? PROD_FRAMEWORK_PROMPT)
1859
- : DEV_FRAMEWORK_PROMPT) + devActionsPrompt;
2148
+ const prodPrompt = (options?.systemPrompt ??
2149
+ (lazyContext
2150
+ ? PROD_FRAMEWORK_PROMPT_COMPACT
2151
+ : PROD_FRAMEWORK_PROMPT)) + prodActionsPrompt;
2152
+ // When template actions are registered as native tools in dev (via
2153
+ // `nativeActionsInDev` or `leanPrompt`), the dev prompt's "invoke
2154
+ // template actions via shell" guidance is wrong — use the prod prompt
2155
+ // + tool-format action list instead, same as production.
2156
+ const devNative = options?.nativeActionsInDev === true || leanPrompt;
2157
+ const devPrompt = devNative
2158
+ ? prodPrompt
2159
+ : (options?.devSystemPrompt
2160
+ ? options.devSystemPrompt +
2161
+ (options?.systemPrompt ??
2162
+ (lazyContext
2163
+ ? PROD_FRAMEWORK_PROMPT_COMPACT
2164
+ : PROD_FRAMEWORK_PROMPT))
2165
+ : lazyContext
2166
+ ? DEV_FRAMEWORK_PROMPT_COMPACT
2167
+ : DEV_FRAMEWORK_PROMPT) + devActionsPrompt;
1860
2168
  // Keep legacy names for the composition below
1861
2169
  const basePrompt = prodPrompt;
1862
2170
  const devPrefix = options?.devSystemPrompt ?? DEFAULT_DEV_PROMPT;
@@ -1873,8 +2181,7 @@ export function createAgentChatPlugin(options) {
1873
2181
  engineOption: options?.engine,
1874
2182
  apiKey: options?.apiKey,
1875
2183
  });
1876
- const model = options?.model ??
1877
- (canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
2184
+ const model = options?.model ?? "claude-sonnet-4-6";
1878
2185
  // Same actions as A2A — without call-agent to prevent loops.
1879
2186
  // In dev mode, template actions go through shell, not native tools.
1880
2187
  const devActiveMcp = isDevMode();
@@ -1882,7 +2189,10 @@ export function createAgentChatPlugin(options) {
1882
2189
  ? {
1883
2190
  ...resourceScripts,
1884
2191
  ...docsScripts,
2192
+ ...(lazyContext ? frameworkContextTool : {}),
2193
+ ...urlTools,
1885
2194
  ...chatScripts,
2195
+ ...toolActions,
1886
2196
  ...devScriptsForA2A,
1887
2197
  }
1888
2198
  : {
@@ -1891,14 +2201,30 @@ export function createAgentChatPlugin(options) {
1891
2201
  ...docsScripts,
1892
2202
  ...dbScripts,
1893
2203
  ...refreshScreenTool,
2204
+ ...(lazyContext ? frameworkContextTool : {}),
1894
2205
  ...urlTools,
1895
2206
  ...chatScripts,
2207
+ ...toolActions,
1896
2208
  };
1897
2209
  const mcpTools = actionsToEngineTools(mcpActions);
1898
- const resources = await loadResourcesForPrompt("local@localhost");
1899
- const schemaBlock = await buildSchemaBlock("local@localhost", devActiveMcp);
2210
+ const resources = await loadResourcesForPrompt("local@localhost", lazyContext);
2211
+ const schemaBlock = lazyContext
2212
+ ? ""
2213
+ : await buildSchemaBlock("local@localhost", devActiveMcp);
2214
+ // Build the MCP handler's own prompt — always use the shell-based
2215
+ // dev prompt in dev mode because mcpActions routes template actions
2216
+ // through shell (`devScriptsForA2A`), regardless of `nativeActionsInDev`.
2217
+ const mcpDevPrompt = (options?.devSystemPrompt
2218
+ ? options.devSystemPrompt +
2219
+ (options?.systemPrompt ??
2220
+ (lazyContext
2221
+ ? PROD_FRAMEWORK_PROMPT_COMPACT
2222
+ : PROD_FRAMEWORK_PROMPT))
2223
+ : lazyContext
2224
+ ? DEV_FRAMEWORK_PROMPT_COMPACT
2225
+ : DEV_FRAMEWORK_PROMPT) + devActionsPrompt;
1900
2226
  const systemPrompt = devActiveMcp
1901
- ? devPrompt + resources + schemaBlock
2227
+ ? mcpDevPrompt + resources + schemaBlock
1902
2228
  : basePrompt + resources + schemaBlock;
1903
2229
  let accumulatedText = "";
1904
2230
  const controller = new AbortController();
@@ -1931,7 +2257,7 @@ export function createAgentChatPlugin(options) {
1931
2257
  }
1932
2258
  };
1933
2259
  // Auto-mount template actions as HTTP endpoints under /_agent-native/actions/
1934
- // Include engine management scripts so the UI can call list/set/test-agent-engine.
2260
+ // Include engine management script so the UI can call manage-agent-engine.
1935
2261
  const httpActions = {
1936
2262
  ...discoveredActions,
1937
2263
  ...templateScripts,
@@ -2020,6 +2346,14 @@ export function createAgentChatPlugin(options) {
2020
2346
  else {
2021
2347
  repo.messages.push(assistantMsg);
2022
2348
  }
2349
+ // Store debug metadata so we can inspect what the LLM actually
2350
+ // received (system prompt, model, engine) when diagnosing issues.
2351
+ repo._debug = {
2352
+ systemPrompt: _currentRunSystemPrompt,
2353
+ model: _currentRunModel ?? resolvedModel,
2354
+ engine: _currentRunEngine?.name ?? "unknown",
2355
+ timestamp: Date.now(),
2356
+ };
2023
2357
  const meta = extractThreadMeta(repo);
2024
2358
  await updateThreadData(threadId, JSON.stringify(repo), meta.title || thread.title, meta.preview || thread.preview, repo.messages.length);
2025
2359
  }
@@ -2041,20 +2375,42 @@ export function createAgentChatPlugin(options) {
2041
2375
  // Auto-checkpoint in dev mode after file-modifying agent turns
2042
2376
  if (isDevMode()) {
2043
2377
  try {
2044
- const { createCheckpoint: gitCheckpoint, isGitRepo, hasUncommittedChanges, } = await import("../checkpoints/service.js");
2378
+ const { createCheckpoint: gitCheckpoint, isGitRepo, hasUncommittedChanges, getChangedFileNames, } = await import("../checkpoints/service.js");
2045
2379
  const cwd = process.cwd();
2046
2380
  if (isGitRepo(cwd) && hasUncommittedChanges(cwd)) {
2047
- const toolNames = new Set();
2381
+ let summary = "";
2382
+ // Try to extract the first sentence of the assistant's text response
2383
+ let assistantText = "";
2048
2384
  for (const { event } of run.events ?? []) {
2049
- if (event.type === "tool_start" &&
2050
- typeof event.tool === "string") {
2051
- toolNames.add(event.tool);
2385
+ if (event.type === "text" && typeof event.text === "string") {
2386
+ assistantText += event.text;
2387
+ }
2388
+ }
2389
+ assistantText = assistantText.trim();
2390
+ if (assistantText) {
2391
+ const firstSentence = assistantText
2392
+ .split(/(?<=[.!?\n])\s/)[0]
2393
+ ?.replace(/\n/g, " ")
2394
+ .trim();
2395
+ if (firstSentence && firstSentence.length <= 120) {
2396
+ summary = firstSentence;
2397
+ }
2398
+ else if (firstSentence) {
2399
+ summary = firstSentence.slice(0, 117) + "...";
2052
2400
  }
2053
2401
  }
2054
- const summary = toolNames.size > 0
2055
- ? `Used: ${[...toolNames].join(", ")}`
2056
- : "Agent turn";
2057
- const sha = gitCheckpoint(cwd, `[agent-native] ${summary}`);
2402
+ // Fall back to listing changed files
2403
+ if (!summary) {
2404
+ const files = getChangedFileNames(cwd);
2405
+ if (files.length > 0) {
2406
+ summary = `Update ${files.join(", ")}`;
2407
+ }
2408
+ }
2409
+ if (!summary)
2410
+ summary = "Agent turn";
2411
+ if (summary.length > 120)
2412
+ summary = summary.slice(0, 117) + "...";
2413
+ const sha = gitCheckpoint(cwd, summary);
2058
2414
  if (sha) {
2059
2415
  const { insertCheckpoint } = await import("../checkpoints/store.js");
2060
2416
  const cpId = `cp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
@@ -2080,9 +2436,7 @@ export function createAgentChatPlugin(options) {
2080
2436
  // instead of silently falling back to Anthropic + Claude.
2081
2437
  let _currentRunEngine;
2082
2438
  let _currentRunModel;
2083
- // Default to Haiku in production mode to manage costs for hosted apps
2084
- const resolvedModel = options?.model ??
2085
- (canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
2439
+ const resolvedModel = options?.model ?? "claude-sonnet-4-6";
2086
2440
  const teamTools = createTeamTools({
2087
2441
  getOwner: () => _currentRunOwner,
2088
2442
  getSystemPrompt: () => _currentRunSystemPrompt,
@@ -2092,6 +2446,7 @@ export function createAgentChatPlugin(options) {
2092
2446
  // via shell, so omit them from the native tool registry.
2093
2447
  ...resourceScripts,
2094
2448
  ...docsScripts,
2449
+ ...(lazyContext ? frameworkContextTool : {}),
2095
2450
  ...chatScripts,
2096
2451
  ...devScriptsForA2A,
2097
2452
  }
@@ -2101,6 +2456,7 @@ export function createAgentChatPlugin(options) {
2101
2456
  ...docsScripts,
2102
2457
  ...dbScripts,
2103
2458
  ...refreshScreenTool,
2459
+ ...(lazyContext ? frameworkContextTool : {}),
2104
2460
  ...urlTools,
2105
2461
  ...chatScripts,
2106
2462
  },
@@ -2108,7 +2464,7 @@ export function createAgentChatPlugin(options) {
2108
2464
  createAnthropicEngine({
2109
2465
  // Sub-agents must inherit the parent run's resolved key so a
2110
2466
  // BYO-key user can't bypass the free-tier check on the parent
2111
- // run and then have spawn-task delegations bill the platform key.
2467
+ // run and then have agent-teams spawn delegations bill the platform key.
2112
2468
  apiKey: _currentRunUserApiKey ??
2113
2469
  options?.apiKey ??
2114
2470
  process.env.ANTHROPIC_API_KEY,
@@ -2122,19 +2478,33 @@ export function createAgentChatPlugin(options) {
2122
2478
  },
2123
2479
  });
2124
2480
  // Hook into the run lifecycle to set/clear the send reference.
2125
- // Job management tools (create-job, list-jobs, update-job)
2481
+ // Job management tool (manage-jobs)
2126
2482
  let jobTools = {};
2127
2483
  try {
2128
2484
  const { createJobTools } = await import("../jobs/tools.js");
2129
2485
  jobTools = createJobTools();
2130
2486
  }
2131
2487
  catch { }
2488
+ // Lean mode: only template actions + essential framework tools. Drop
2489
+ // web-request, browser tools, teams, jobs, automations, notifications,
2490
+ // progress, call-agent, and MCP entries to keep the tool list tight and
2491
+ // prevent the LLM from reaching for web-request instead of the
2492
+ // template's native actions (e.g. log-meal).
2493
+ const leanActions = {
2494
+ ...templateScripts,
2495
+ ...resourceScripts,
2496
+ ...refreshScreenTool,
2497
+ ...urlTools,
2498
+ ...chatScripts,
2499
+ ...toolActions,
2500
+ };
2132
2501
  const prodActions = {
2133
2502
  ...templateScripts,
2134
2503
  ...resourceScripts,
2135
2504
  ...docsScripts,
2136
2505
  ...dbScripts,
2137
2506
  ...refreshScreenTool,
2507
+ ...(lazyContext ? frameworkContextTool : {}),
2138
2508
  ...urlTools,
2139
2509
  ...chatScripts,
2140
2510
  ...callAgentScript,
@@ -2144,6 +2514,7 @@ export function createAgentChatPlugin(options) {
2144
2514
  ...notificationTools,
2145
2515
  ...progressTools,
2146
2516
  ...fetchTool,
2517
+ ...toolActions,
2147
2518
  ...browserTools,
2148
2519
  ...mcpActionEntries,
2149
2520
  };
@@ -2169,32 +2540,44 @@ export function createAgentChatPlugin(options) {
2169
2540
  return "";
2170
2541
  }
2171
2542
  };
2172
- const leanPrompt = options?.leanPrompt === true;
2173
2543
  // Lean mode: use only the template's systemPrompt + actions list.
2174
- // Skip resource loading, schema block, and extraContext — those add
2175
- // DB round-trips and tokens that minimal/voice apps don't need.
2544
+ // Skip resource loading and schema block — those add DB round-trips
2545
+ // and tokens that minimal/voice apps don't need.
2176
2546
  const leanBasePrompt = (options?.systemPrompt ?? "") + prodActionsPrompt;
2547
+ // Per-request preamble shared by both prod and dev handlers. Resolves
2548
+ // owner + user API key (stashed on the closure so downstream tools can
2549
+ // reach them) and the template-authored `extraContext`. `extraContext`
2550
+ // runs in every prompt variant (lean, lazy, full) — if a template
2551
+ // defined it, they opted in; framework-provided content is what the
2552
+ // token-saving modes strip.
2553
+ const prepareRun = async (event) => {
2554
+ _currentRequestOrigin = getOrigin(event);
2555
+ const owner = await getOwnerFromEvent(event);
2556
+ _currentRunOwner = owner;
2557
+ const { getOwnerActiveApiKey } = await import("../agent/production-agent.js");
2558
+ _currentRunUserApiKey = await getOwnerActiveApiKey(owner);
2559
+ const extra = await resolveExtraContext(event, owner);
2560
+ return { owner, extra };
2561
+ };
2177
2562
  const prodHandler = createProductionAgentHandler({
2178
- actions: prodActions,
2563
+ actions: leanPrompt ? leanActions : prodActions,
2179
2564
  systemPrompt: async (event) => {
2180
- _currentRequestOrigin = getOrigin(event);
2181
- const owner = await getOwnerFromEvent(event);
2182
- _currentRunOwner = owner;
2183
- const { getOwnerActiveApiKey } = await import("../agent/production-agent.js");
2184
- _currentRunUserApiKey = await getOwnerActiveApiKey(owner);
2565
+ const { owner, extra } = await prepareRun(event);
2185
2566
  if (leanPrompt) {
2186
- _currentRunSystemPrompt = leanBasePrompt;
2567
+ _currentRunSystemPrompt = leanBasePrompt + extra;
2187
2568
  return _currentRunSystemPrompt;
2188
2569
  }
2189
- const resources = await loadResourcesForPrompt(owner);
2190
- const schemaBlock = await buildSchemaBlock(owner, false);
2191
- const extra = await resolveExtraContext(event, owner);
2570
+ const resources = await loadResourcesForPrompt(owner, lazyContext);
2571
+ // In lazy context mode, skip embedding the full schema — the agent
2572
+ // calls `db-schema` on demand. This saves ~1-2K tokens per request.
2573
+ const schemaBlock = lazyContext
2574
+ ? ""
2575
+ : await buildSchemaBlock(owner, false);
2192
2576
  _currentRunSystemPrompt =
2193
2577
  basePrompt + resources + schemaBlock + extra;
2194
2578
  return _currentRunSystemPrompt;
2195
2579
  },
2196
- model: options?.model ??
2197
- (isHostedProd ? "claude-haiku-4-5-20251001" : undefined),
2580
+ model: options?.model ?? "claude-sonnet-4-6",
2198
2581
  apiKey: options?.apiKey,
2199
2582
  skipFilesContext: leanPrompt,
2200
2583
  onEngineResolved: (engine, model) => {
@@ -2224,30 +2607,35 @@ export function createAgentChatPlugin(options) {
2224
2607
  // how Claude Code works locally and dramatically reduces the rate of
2225
2608
  // degenerate empty-object tool calls. The CLI syntax for each action is
2226
2609
  // listed in the dev system prompt's "Available Actions" section.
2227
- // In lean mode, expose the template's actions directly as native tools
2228
- // instead of routing through shell — the lean system prompt has no
2229
- // shell-usage guidance, so shell-based action invocation would break.
2610
+ // In lean mode or when `nativeActionsInDev` is set expose the
2611
+ // template's actions as native tools instead of routing through shell.
2612
+ // Templates with structured-arg actions (objects/arrays) need this to
2613
+ // avoid round-tripping JSON through the CLI parser.
2230
2614
  const devActions = leanPrompt
2231
- ? prodActions
2232
- : {
2233
- ...resourceScripts,
2234
- ...docsScripts,
2235
- ...chatScripts,
2236
- ...callAgentScript,
2237
- ...teamTools,
2238
- ...jobTools,
2239
- ...automationTools,
2240
- ...notificationTools,
2241
- ...progressTools,
2242
- ...fetchTool,
2243
- ...browserTools,
2244
- ...mcpActionEntries,
2245
- ...(await createDevScriptRegistry()),
2246
- };
2615
+ ? leanActions
2616
+ : devNative
2617
+ ? prodActions
2618
+ : {
2619
+ ...resourceScripts,
2620
+ ...docsScripts,
2621
+ ...(lazyContext ? frameworkContextTool : {}),
2622
+ ...chatScripts,
2623
+ ...callAgentScript,
2624
+ ...teamTools,
2625
+ ...jobTools,
2626
+ ...automationTools,
2627
+ ...notificationTools,
2628
+ ...progressTools,
2629
+ ...fetchTool,
2630
+ ...toolActions,
2631
+ ...browserTools,
2632
+ ...mcpActionEntries,
2633
+ ...(await createDevScriptRegistry()),
2634
+ };
2247
2635
  // Keep dev action dict in sync with runtime MCP additions. When
2248
- // leanPrompt is true, devActions === prodActions so the prod listener
2249
- // already covers it.
2250
- if (devActions !== prodActions) {
2636
+ // native-actions mode is on (lean or `nativeActionsInDev`), devActions
2637
+ // === prodActions so the prod listener already covers it.
2638
+ if (devActions !== prodActions && devActions !== leanActions) {
2251
2639
  mcpManager.onChange(() => {
2252
2640
  syncMcpActionEntries(mcpManager, devActions);
2253
2641
  });
@@ -2255,18 +2643,15 @@ export function createAgentChatPlugin(options) {
2255
2643
  devHandler = createProductionAgentHandler({
2256
2644
  actions: devActions,
2257
2645
  systemPrompt: async (event) => {
2258
- _currentRequestOrigin = getOrigin(event);
2259
- const owner = await getOwnerFromEvent(event);
2260
- _currentRunOwner = owner;
2261
- const { getOwnerActiveApiKey } = await import("../agent/production-agent.js");
2262
- _currentRunUserApiKey = await getOwnerActiveApiKey(owner);
2646
+ const { owner, extra } = await prepareRun(event);
2263
2647
  if (leanPrompt) {
2264
- _currentRunSystemPrompt = leanBasePrompt;
2648
+ _currentRunSystemPrompt = leanBasePrompt + extra;
2265
2649
  return _currentRunSystemPrompt;
2266
2650
  }
2267
- const resources = await loadResourcesForPrompt(owner);
2268
- const schemaBlock = await buildSchemaBlock(owner, true);
2269
- const extra = await resolveExtraContext(event, owner);
2651
+ const resources = await loadResourcesForPrompt(owner, lazyContext);
2652
+ const schemaBlock = lazyContext
2653
+ ? ""
2654
+ : await buildSchemaBlock(owner, true);
2270
2655
  _currentRunSystemPrompt =
2271
2656
  devPrompt + resources + schemaBlock + extra;
2272
2657
  return _currentRunSystemPrompt;
@@ -2833,10 +3218,15 @@ export function createAgentChatPlugin(options) {
2833
3218
  // Check in-memory first, then SQL (cross-isolate on Workers)
2834
3219
  const run = await getActiveRunForThreadAsync(threadId);
2835
3220
  if (!run) {
2836
- setResponseStatus(event, 404);
2837
- return { error: "No active run for this thread" };
3221
+ return {
3222
+ active: false,
3223
+ threadId,
3224
+ status: "idle",
3225
+ heartbeatAt: null,
3226
+ };
2838
3227
  }
2839
3228
  return {
3229
+ active: true,
2840
3230
  runId: run.runId,
2841
3231
  threadId: run.threadId,
2842
3232
  status: run.status,
@@ -3030,6 +3420,19 @@ export function createAgentChatPlugin(options) {
3030
3420
  await setThreadQueuedMessages(threadId, queued);
3031
3421
  return { ok: true };
3032
3422
  }
3423
+ // POST /threads/:id/fork — duplicate a thread with all its messages
3424
+ if (method === "POST" &&
3425
+ /\/threads\/[^/?]+\/fork/.test(event.node?.req?.url || event.path || "")) {
3426
+ const body = await readBody(event);
3427
+ const forked = await forkThread(threadId, owner, {
3428
+ id: body?.id,
3429
+ });
3430
+ if (!forked) {
3431
+ setResponseStatus(event, 404);
3432
+ return { error: "Thread not found" };
3433
+ }
3434
+ return forked;
3435
+ }
3033
3436
  if (method === "DELETE") {
3034
3437
  const thread = await getThread(threadId);
3035
3438
  if (!thread || thread.ownerEmail !== owner) {
@@ -3130,16 +3533,20 @@ export function createAgentChatPlugin(options) {
3130
3533
  ...templateScripts,
3131
3534
  ...resourceScripts,
3132
3535
  ...docsScripts,
3536
+ ...(lazyContext ? frameworkContextTool : {}),
3133
3537
  ...chatScripts,
3134
3538
  ...jobTools,
3135
3539
  ...automationTools,
3136
3540
  ...notificationTools,
3137
3541
  ...progressTools,
3138
3542
  ...fetchTool,
3543
+ ...toolActions,
3139
3544
  }),
3140
3545
  getSystemPrompt: async (owner) => {
3141
- const resources = await loadResourcesForPrompt(owner);
3142
- const schemaBlock = await buildSchemaBlock(owner, false);
3546
+ const resources = await loadResourcesForPrompt(owner, lazyContext);
3547
+ const schemaBlock = lazyContext
3548
+ ? ""
3549
+ : await buildSchemaBlock(owner, false);
3143
3550
  return basePrompt + resources + schemaBlock;
3144
3551
  },
3145
3552
  apiKey: options?.apiKey ?? process.env.ANTHROPIC_API_KEY,
@@ -3167,16 +3574,20 @@ export function createAgentChatPlugin(options) {
3167
3574
  ...templateScripts,
3168
3575
  ...resourceScripts,
3169
3576
  ...docsScripts,
3577
+ ...(lazyContext ? frameworkContextTool : {}),
3170
3578
  ...chatScripts,
3171
3579
  ...jobTools,
3172
3580
  ...automationTools,
3173
3581
  ...notificationTools,
3174
3582
  ...progressTools,
3175
3583
  ...fetchTool,
3584
+ ...toolActions,
3176
3585
  }),
3177
3586
  getSystemPrompt: async (owner) => {
3178
- const resources = await loadResourcesForPrompt(owner);
3179
- const schemaBlock = await buildSchemaBlock(owner, false);
3587
+ const resources = await loadResourcesForPrompt(owner, lazyContext);
3588
+ const schemaBlock = lazyContext
3589
+ ? ""
3590
+ : await buildSchemaBlock(owner, false);
3180
3591
  return basePrompt + resources + schemaBlock;
3181
3592
  },
3182
3593
  apiKey: options?.apiKey ?? process.env.ANTHROPIC_API_KEY,