@agent-native/core 0.131.5 → 0.131.7

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 (350) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +70 -0
  3. package/corpus/core/docs/content/agent-native-toolkit.mdx +13 -6
  4. package/corpus/core/docs/content/cloneable-saas.mdx +5 -5
  5. package/corpus/core/docs/content/creating-templates.mdx +9 -0
  6. package/corpus/core/docs/content/deployment.mdx +18 -12
  7. package/corpus/core/docs/content/doctor.mdx +8 -1
  8. package/corpus/core/docs/content/drop-in-agent.mdx +1 -1
  9. package/corpus/core/docs/content/extensions.mdx +18 -18
  10. package/corpus/core/docs/content/faq.mdx +4 -4
  11. package/corpus/core/docs/content/key-concepts.mdx +30 -21
  12. package/corpus/core/docs/content/security.mdx +2 -2
  13. package/corpus/core/docs/content/template-brain-developers.mdx +4 -1
  14. package/corpus/core/docs/content/template-mail-developers.mdx +4 -1
  15. package/corpus/core/docs/content/what-is-agent-native.mdx +6 -6
  16. package/corpus/core/package.json +1 -1
  17. package/corpus/core/src/a2a/client.ts +449 -66
  18. package/corpus/core/src/a2a/correlation.ts +31 -0
  19. package/corpus/core/src/a2a/invoke.ts +4 -2
  20. package/corpus/core/src/a2a/types.ts +4 -0
  21. package/corpus/core/src/action.ts +3 -0
  22. package/corpus/core/src/agent/action-continuation-guidance.ts +2 -1
  23. package/corpus/core/src/agent/engine/registry.ts +98 -6
  24. package/corpus/core/src/agent/production-agent.ts +151 -18
  25. package/corpus/core/src/agent/run-loop-with-resume.ts +190 -3
  26. package/corpus/core/src/agent/run-manager.ts +117 -41
  27. package/corpus/core/src/agent/thread-debug-history.ts +86 -0
  28. package/corpus/core/src/agent/types.ts +3 -1
  29. package/corpus/core/src/cli/create.ts +11 -1
  30. package/corpus/core/src/cli/templates-meta.ts +2 -2
  31. package/corpus/core/src/client/agent-chat-adapter.ts +91 -13
  32. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +11 -9
  33. package/corpus/core/src/client/sse-event-processor.ts +17 -3
  34. package/corpus/core/src/db/client.ts +57 -17
  35. package/corpus/core/src/guards/no-env-credentials.ts +2 -0
  36. package/corpus/core/src/integrations/adapters/slack.ts +8 -3
  37. package/corpus/core/src/localization/default-messages.ts +44 -0
  38. package/corpus/core/src/observability/traces.ts +78 -5
  39. package/corpus/core/src/scripts/call-agent.ts +294 -11
  40. package/corpus/core/src/scripts/describe-workspace-apps.ts +2 -2
  41. package/corpus/core/src/secrets/crypto.ts +156 -35
  42. package/corpus/core/src/secrets/storage.ts +64 -26
  43. package/corpus/core/src/server/agent-capabilities.ts +1 -1
  44. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +113 -7
  45. package/corpus/core/src/server/agent-chat/context-tools.ts +2 -0
  46. package/corpus/core/src/server/agent-chat/plugin-options.ts +34 -1
  47. package/corpus/core/src/server/agent-chat/prompt-resources.ts +1 -1
  48. package/corpus/core/src/server/agent-chat-plugin.ts +91 -59
  49. package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +19 -7
  50. package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +19 -7
  51. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
  53. package/corpus/core/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +19 -7
  54. package/corpus/core/src/vite/client.ts +1 -0
  55. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +5 -4
  56. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +6 -4
  57. package/corpus/templates/analytics/AGENTS.md +7 -4
  58. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +4 -3
  59. package/corpus/templates/analytics/changelog/2026-07-30-delegated-analytics-questions-now-return-a-useful-current-me.md +6 -0
  60. package/corpus/templates/analytics/changelog/2026-07-30-scheduled-dashboard-emails-complete-every-panel-without-pool.md +6 -0
  61. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +28 -1
  62. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +18 -11
  63. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +4 -4
  64. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +9 -5
  65. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +6 -2
  66. package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +11 -4
  67. package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +49 -31
  68. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +16 -8
  69. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +9 -3
  70. package/corpus/templates/analytics/server/lib/production-serverless-runtime.ts +11 -0
  71. package/corpus/templates/analytics/server/lib/real-data-actions.ts +10 -0
  72. package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -2
  73. package/corpus/templates/analytics/server/plugins/analytics-alert-jobs.ts +2 -1
  74. package/corpus/templates/analytics/server/plugins/dashboard-report-jobs.ts +2 -1
  75. package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +1 -12
  76. package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +54 -6
  77. package/corpus/templates/brain/.agents/skills/brain/SKILL.md +20 -9
  78. package/corpus/templates/brain/.agents/skills/ingestion-and-connectors/SKILL.md +33 -1
  79. package/corpus/templates/brain/AGENTS.md +3 -1
  80. package/corpus/templates/brain/README.md +4 -1
  81. package/corpus/templates/brain/actions/_schemas.ts +30 -8
  82. package/corpus/templates/brain/actions/ask-brain.ts +124 -14
  83. package/corpus/templates/brain/actions/create-source.ts +18 -2
  84. package/corpus/templates/brain/actions/enqueue-captures-distillation.ts +8 -123
  85. package/corpus/templates/brain/actions/enqueue-distillation.ts +6 -127
  86. package/corpus/templates/brain/actions/import-capture.ts +17 -5
  87. package/corpus/templates/brain/actions/import-transcript.ts +17 -5
  88. package/corpus/templates/brain/actions/update-source.ts +25 -5
  89. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +1 -1
  90. package/corpus/templates/brain/changelog/2026-07-30-blessed-resources-can-feed-cited-company-answers.md +6 -0
  91. package/corpus/templates/brain/changelog/2026-07-30-the-left-sidebar-no-longer-shows-a-blank-organization-placeh.md +6 -0
  92. package/corpus/templates/brain/server/lib/brain.ts +49 -19
  93. package/corpus/templates/brain/server/lib/distillation-queue.ts +147 -0
  94. package/corpus/templates/brain/server/lib/source-policy.ts +264 -0
  95. package/corpus/templates/brain/server/plugins/agent-chat.ts +3 -2
  96. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +116 -19
  97. package/corpus/templates/clips/app/components/meetings/google-oauth-identity-notice.tsx +51 -0
  98. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  99. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +3 -1
  100. package/corpus/templates/clips/changelog/2026-07-30-google-calendar-warning.md +6 -0
  101. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +72 -8
  102. package/corpus/templates/content/changelog/2026-07-30-the-slash-command-hint-now-stays-on-only-the-active-empty-li.md +6 -0
  103. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +506 -11
  104. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +148 -17
  105. package/corpus/templates/design/app/components/design/canvas-interactions/design-canvas-interactions.ts +357 -0
  106. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +7 -466
  107. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +15 -311
  108. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +19 -997
  109. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +8 -1216
  110. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +31 -38
  111. package/corpus/templates/design/package.json +0 -1
  112. package/corpus/templates/dispatch/AGENTS.md +8 -0
  113. package/corpus/templates/dispatch/DEVELOPING.md +29 -0
  114. package/corpus/templates/dispatch/actions/view-screen.ts +34 -2
  115. package/corpus/templates/dispatch/app/i18n-data.ts +457 -0
  116. package/corpus/templates/dispatch/changelog/2026-07-30-delegated-dispatch-work-continues-reliably-in-the-background.md +6 -0
  117. package/corpus/templates/dispatch/changelog/2026-07-30-find-failed-runs-across-apps.md +6 -0
  118. package/corpus/templates/dispatch/netlify.toml +3 -0
  119. package/corpus/templates/plan/actions/get-visual-plan.ts +10 -6
  120. package/corpus/templates/plan/actions/patch-visual-plan-source.ts +117 -1
  121. package/corpus/templates/plan/actions/update-visual-plan.ts +56 -14
  122. package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -1
  123. package/corpus/templates/plan/changelog/2026-07-30-plan-agents-recover-with-targeted-writes.md +6 -0
  124. package/corpus/templates/plan/shared/plan-content.ts +35 -0
  125. package/corpus/templates/slides/.agents/skills/analytics-data-for-decks/SKILL.md +8 -12
  126. package/corpus/templates/slides/AGENTS.md +4 -4
  127. package/corpus/templates/slides/actions/create-deck.ts +1 -1
  128. package/corpus/templates/slides/actions/duplicate-deck.ts +19 -4
  129. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -10
  130. package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +12 -1
  131. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +30 -13
  132. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +35 -0
  133. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +63 -56
  134. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +21 -76
  135. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1110 -292
  136. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +53 -0
  137. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +235 -18
  138. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +4 -1
  139. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +11 -0
  140. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +129 -0
  141. package/corpus/templates/slides/app/components/editor/selection-overlay-measurement.ts +70 -0
  142. package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +519 -65
  143. package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +36 -426
  144. package/corpus/templates/slides/app/components/visual-editor/DrawOverlay.tsx +19 -458
  145. package/corpus/templates/slides/app/context/DeckContext.tsx +179 -72
  146. package/corpus/templates/slides/app/global.css +105 -0
  147. package/corpus/templates/slides/app/i18n/en-US.ts +8 -0
  148. package/corpus/templates/slides/app/lib/deck-editor-loading.ts +26 -0
  149. package/corpus/templates/slides/app/lib/mermaid-blocks.ts +27 -0
  150. package/corpus/templates/slides/app/pages/DeckEditor.tsx +71 -38
  151. package/corpus/templates/slides/app/pages/Index.tsx +98 -41
  152. package/corpus/templates/slides/changelog/2026-07-30-deck-loading-no-longer-flashes-an-unavailable-message.md +6 -0
  153. package/corpus/templates/slides/changelog/2026-07-30-duplicating-a-deck-from-the-deck-list-now-opens-the-copy-imm.md +6 -0
  154. package/corpus/templates/slides/changelog/2026-07-30-layout-overflow-warning-is-readable-and-dismissible.md +6 -0
  155. package/corpus/templates/slides/changelog/2026-07-30-new-decks-now-start-with-an-empty-slide-list-when-no-slides-.md +6 -0
  156. package/corpus/templates/slides/changelog/2026-07-30-shared-canvas-annotations.md +6 -0
  157. package/corpus/templates/slides/changelog/2026-07-30-slide-objects-can-be-moved-as-a-group-copied-and-pasted-with.md +6 -0
  158. package/corpus/templates/slides/changelog/2026-07-30-slide-text-editing-and-object-controls-now-match-google-slides.md +6 -0
  159. package/corpus/templates/slides/changelog/2026-07-30-style-panel-now-scrolls-with-speaker-notes-open-shows-the-sl.md +6 -0
  160. package/corpus/templates/slides/changelog/2026-07-30-top-toolbar-controls-now-use-consistent-sizing-with-undo-and.md +6 -0
  161. package/corpus/templates/slides/netlify.toml +3 -1
  162. package/corpus/templates/slides/package.json +0 -1
  163. package/corpus/templates/slides/server/lib/chat-attachments.ts +18 -0
  164. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
  165. package/corpus/templates/slides/vite.config.ts +0 -1
  166. package/corpus/toolkit/CHANGELOG.md +13 -0
  167. package/corpus/toolkit/README.md +19 -0
  168. package/corpus/toolkit/agent-native.eject.json +38 -0
  169. package/corpus/toolkit/package.json +29 -1
  170. package/corpus/toolkit/src/canvas-annotations/CanvasCommentPins.tsx +861 -0
  171. package/corpus/toolkit/src/canvas-annotations/DrawOverlay.tsx +1233 -0
  172. package/corpus/toolkit/src/canvas-annotations/index.ts +15 -0
  173. package/corpus/toolkit/src/canvas-annotations/types.ts +14 -0
  174. package/corpus/toolkit/src/canvas-interactions/canvas-interactions.ts +933 -0
  175. package/corpus/toolkit/src/canvas-interactions/index.ts +67 -0
  176. package/corpus/toolkit/src/design-tweaks/scrub-input-utils.ts +311 -0
  177. package/corpus/toolkit/src/design-tweaks/scrub-input.tsx +491 -0
  178. package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +26 -171
  179. package/corpus/toolkit/src/index.ts +1 -0
  180. package/dist/a2a/client.d.ts +23 -0
  181. package/dist/a2a/client.d.ts.map +1 -1
  182. package/dist/a2a/client.js +309 -44
  183. package/dist/a2a/client.js.map +1 -1
  184. package/dist/a2a/correlation.d.ts +1 -0
  185. package/dist/a2a/correlation.d.ts.map +1 -1
  186. package/dist/a2a/correlation.js +27 -0
  187. package/dist/a2a/correlation.js.map +1 -1
  188. package/dist/a2a/invoke.d.ts.map +1 -1
  189. package/dist/a2a/invoke.js +4 -2
  190. package/dist/a2a/invoke.js.map +1 -1
  191. package/dist/a2a/types.d.ts +4 -0
  192. package/dist/a2a/types.d.ts.map +1 -1
  193. package/dist/a2a/types.js.map +1 -1
  194. package/dist/action.d.ts +3 -0
  195. package/dist/action.d.ts.map +1 -1
  196. package/dist/action.js.map +1 -1
  197. package/dist/agent/action-continuation-guidance.d.ts.map +1 -1
  198. package/dist/agent/action-continuation-guidance.js +2 -1
  199. package/dist/agent/action-continuation-guidance.js.map +1 -1
  200. package/dist/agent/engine/registry.d.ts.map +1 -1
  201. package/dist/agent/engine/registry.js +82 -8
  202. package/dist/agent/engine/registry.js.map +1 -1
  203. package/dist/agent/production-agent.d.ts +40 -1
  204. package/dist/agent/production-agent.d.ts.map +1 -1
  205. package/dist/agent/production-agent.js +113 -15
  206. package/dist/agent/production-agent.js.map +1 -1
  207. package/dist/agent/run-loop-with-resume.d.ts +21 -0
  208. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  209. package/dist/agent/run-loop-with-resume.js +163 -4
  210. package/dist/agent/run-loop-with-resume.js.map +1 -1
  211. package/dist/agent/run-manager.d.ts +16 -9
  212. package/dist/agent/run-manager.d.ts.map +1 -1
  213. package/dist/agent/run-manager.js +93 -42
  214. package/dist/agent/run-manager.js.map +1 -1
  215. package/dist/agent/thread-debug-history.d.ts +10 -0
  216. package/dist/agent/thread-debug-history.d.ts.map +1 -0
  217. package/dist/agent/thread-debug-history.js +68 -0
  218. package/dist/agent/thread-debug-history.js.map +1 -0
  219. package/dist/agent/types.d.ts +3 -1
  220. package/dist/agent/types.d.ts.map +1 -1
  221. package/dist/agent/types.js.map +1 -1
  222. package/dist/cli/create.d.ts.map +1 -1
  223. package/dist/cli/create.js +6 -1
  224. package/dist/cli/create.js.map +1 -1
  225. package/dist/cli/templates-meta.js +2 -2
  226. package/dist/cli/templates-meta.js.map +1 -1
  227. package/dist/client/agent-chat-adapter.d.ts +1 -1
  228. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  229. package/dist/client/agent-chat-adapter.js +76 -13
  230. package/dist/client/agent-chat-adapter.js.map +1 -1
  231. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  232. package/dist/client/resources/McpIntegrationDialog.js +1 -1
  233. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  234. package/dist/client/sse-event-processor.d.ts.map +1 -1
  235. package/dist/client/sse-event-processor.js +12 -3
  236. package/dist/client/sse-event-processor.js.map +1 -1
  237. package/dist/collab/routes.d.ts +1 -1
  238. package/dist/db/client.d.ts.map +1 -1
  239. package/dist/db/client.js +48 -17
  240. package/dist/db/client.js.map +1 -1
  241. package/dist/guards/no-env-credentials.d.ts.map +1 -1
  242. package/dist/guards/no-env-credentials.js +2 -0
  243. package/dist/guards/no-env-credentials.js.map +1 -1
  244. package/dist/integrations/adapters/slack.js +7 -3
  245. package/dist/integrations/adapters/slack.js.map +1 -1
  246. package/dist/localization/default-messages.d.ts +43 -0
  247. package/dist/localization/default-messages.d.ts.map +1 -1
  248. package/dist/localization/default-messages.js +43 -0
  249. package/dist/localization/default-messages.js.map +1 -1
  250. package/dist/observability/traces.d.ts +3 -1
  251. package/dist/observability/traces.d.ts.map +1 -1
  252. package/dist/observability/traces.js +73 -4
  253. package/dist/observability/traces.js.map +1 -1
  254. package/dist/progress/routes.d.ts +1 -1
  255. package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
  256. package/dist/provider-api/actions/provider-api.d.ts +13 -13
  257. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  258. package/dist/scripts/call-agent.d.ts.map +1 -1
  259. package/dist/scripts/call-agent.js +237 -12
  260. package/dist/scripts/call-agent.js.map +1 -1
  261. package/dist/scripts/describe-workspace-apps.js +2 -2
  262. package/dist/scripts/describe-workspace-apps.js.map +1 -1
  263. package/dist/secrets/crypto.d.ts +36 -21
  264. package/dist/secrets/crypto.d.ts.map +1 -1
  265. package/dist/secrets/crypto.js +134 -33
  266. package/dist/secrets/crypto.js.map +1 -1
  267. package/dist/secrets/storage.d.ts +6 -6
  268. package/dist/secrets/storage.d.ts.map +1 -1
  269. package/dist/secrets/storage.js +43 -26
  270. package/dist/secrets/storage.js.map +1 -1
  271. package/dist/server/agent-capabilities.js +1 -1
  272. package/dist/server/agent-capabilities.js.map +1 -1
  273. package/dist/server/agent-chat/action-filters-a2a.d.ts +17 -3
  274. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  275. package/dist/server/agent-chat/action-filters-a2a.js +94 -3
  276. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  277. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  278. package/dist/server/agent-chat/context-tools.js +2 -0
  279. package/dist/server/agent-chat/context-tools.js.map +1 -1
  280. package/dist/server/agent-chat/plugin-options.d.ts +23 -0
  281. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  282. package/dist/server/agent-chat/plugin-options.js +4 -1
  283. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  284. package/dist/server/agent-chat/prompt-resources.js +1 -1
  285. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  286. package/dist/server/agent-chat-plugin.d.ts +2 -1
  287. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  288. package/dist/server/agent-chat-plugin.js +79 -56
  289. package/dist/server/agent-chat-plugin.js.map +1 -1
  290. package/dist/server/realtime-token.d.ts +1 -1
  291. package/dist/templates/default/.agents/skills/secrets/SKILL.md +19 -7
  292. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +19 -7
  293. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
  294. package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
  295. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +19 -7
  296. package/dist/vite/client.d.ts.map +1 -1
  297. package/dist/vite/client.js +1 -0
  298. package/dist/vite/client.js.map +1 -1
  299. package/docs/content/agent-native-toolkit.mdx +13 -6
  300. package/docs/content/cloneable-saas.mdx +5 -5
  301. package/docs/content/creating-templates.mdx +9 -0
  302. package/docs/content/deployment.mdx +18 -12
  303. package/docs/content/doctor.mdx +8 -1
  304. package/docs/content/drop-in-agent.mdx +1 -1
  305. package/docs/content/extensions.mdx +18 -18
  306. package/docs/content/faq.mdx +4 -4
  307. package/docs/content/key-concepts.mdx +30 -21
  308. package/docs/content/security.mdx +2 -2
  309. package/docs/content/template-brain-developers.mdx +4 -1
  310. package/docs/content/template-mail-developers.mdx +4 -1
  311. package/docs/content/what-is-agent-native.mdx +6 -6
  312. package/package.json +3 -3
  313. package/src/a2a/client.ts +449 -66
  314. package/src/a2a/correlation.ts +31 -0
  315. package/src/a2a/invoke.ts +4 -2
  316. package/src/a2a/types.ts +4 -0
  317. package/src/action.ts +3 -0
  318. package/src/agent/action-continuation-guidance.ts +2 -1
  319. package/src/agent/engine/registry.ts +98 -6
  320. package/src/agent/production-agent.ts +151 -18
  321. package/src/agent/run-loop-with-resume.ts +190 -3
  322. package/src/agent/run-manager.ts +117 -41
  323. package/src/agent/thread-debug-history.ts +86 -0
  324. package/src/agent/types.ts +3 -1
  325. package/src/cli/create.ts +11 -1
  326. package/src/cli/templates-meta.ts +2 -2
  327. package/src/client/agent-chat-adapter.ts +91 -13
  328. package/src/client/resources/McpIntegrationDialog.tsx +11 -9
  329. package/src/client/sse-event-processor.ts +17 -3
  330. package/src/db/client.ts +57 -17
  331. package/src/guards/no-env-credentials.ts +2 -0
  332. package/src/integrations/adapters/slack.ts +8 -3
  333. package/src/localization/default-messages.ts +44 -0
  334. package/src/observability/traces.ts +78 -5
  335. package/src/scripts/call-agent.ts +294 -11
  336. package/src/scripts/describe-workspace-apps.ts +2 -2
  337. package/src/secrets/crypto.ts +156 -35
  338. package/src/secrets/storage.ts +64 -26
  339. package/src/server/agent-capabilities.ts +1 -1
  340. package/src/server/agent-chat/action-filters-a2a.ts +113 -7
  341. package/src/server/agent-chat/context-tools.ts +2 -0
  342. package/src/server/agent-chat/plugin-options.ts +34 -1
  343. package/src/server/agent-chat/prompt-resources.ts +1 -1
  344. package/src/server/agent-chat-plugin.ts +91 -59
  345. package/src/templates/default/.agents/skills/secrets/SKILL.md +19 -7
  346. package/src/templates/headless/.agents/skills/secrets/SKILL.md +19 -7
  347. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +18 -7
  348. package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +15 -14
  349. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +19 -7
  350. package/src/vite/client.ts +1 -0
@@ -341,6 +341,27 @@ export interface AgentChatPluginOptions {
341
341
  */
342
342
  externalAgents?: ExternalAgentPolicy;
343
343
 
344
+ /**
345
+ * Allow this app's A2A agent to delegate to a different app through the
346
+ * built-in `call-agent` tool. Enabled by default so a receiver keeps the
347
+ * same cross-app capability as its interactive agent. Set false only for an
348
+ * intentionally isolated app. Core enforces a bounded delegation path so
349
+ * cycle safety does not depend on removing the tool.
350
+ */
351
+ a2aAgentDelegation?: boolean;
352
+
353
+ /**
354
+ * Resource budget for delegated A2A/MCP agent turns. Defaults are stricter
355
+ * than interactive chat because every retained tool result is re-sent on
356
+ * later iterations and delegated callers need a compact answer, not a raw
357
+ * transcript. Apps may raise one limit deliberately for proven workloads.
358
+ */
359
+ delegatedRunPolicy?: {
360
+ maxIterations?: number;
361
+ maxRunInputTokens?: number;
362
+ maxToolResultChars?: number;
363
+ };
364
+
344
365
  /**
345
366
  * Skip mounting the remote MCP protocol route.
346
367
  *
@@ -384,5 +405,17 @@ export interface AgentChatPluginOptions {
384
405
  * App-level default tool-call limits. Individual actions override these with
385
406
  * their own `timeoutMs` / `maxResultChars` declarations.
386
407
  */
387
- toolLimits?: { timeoutMs?: number; maxResultChars?: number };
408
+ toolLimits?: {
409
+ timeoutMs?: number;
410
+ maxResultChars?: number;
411
+ /** Absolute cap applied even when an individual action declares more. */
412
+ hardMaxResultChars?: number;
413
+ };
414
+ }
415
+
416
+ /** Cross-app agent delegation is a workspace default; false is an isolation opt-out. */
417
+ export function resolveA2AAgentDelegationEnabled(
418
+ options?: Pick<AgentChatPluginOptions, "a2aAgentDelegation">,
419
+ ): boolean {
420
+ return options?.a2aAgentDelegation !== false;
388
421
  }
@@ -1094,7 +1094,7 @@ export async function loadResourcesForPrompt(
1094
1094
  // which peer apps exist, so this block is not droppable: without it the
1095
1095
  // agent reports cross-app work as impossible instead of delegating.
1096
1096
  addSection(
1097
- `<available-apps>\nWorkspace apps available over A2A/call-agent:\n${lines.join("\n")}\n\nUse \`call-agent\` with the app id when another app owns the work or data. Use tool-search or app-specific actions for details only when needed.\n\nThese one-liners are the only cross-app detail in this prompt. Before building a capability another app may already own, before telling the user what is or is not possible across apps, and whenever the user asks which app to use, call \`describe-workspace-apps\` it reads each peer's live agent card and returns their exact callable actions. Never hand-maintain a list of workspace apps in code or docs; it goes stale silently.\n</available-apps>`,
1097
+ `<available-apps>\nWorkspace apps available over A2A/call-agent:\n${lines.join("\n")}\n\nWhen another app owns the work or data, use \`call-agent\` with the app id and a natural-language message. The receiving specialist owns source selection, schema interpretation, queries, joins, and use of its local tools. Direct action invocation is optional for an exact bounded read with a fully known schema; never use it to compensate for unreliable delegation.\n\nThese one-liners are the only cross-app detail in this prompt. Before building a capability another app may already own, before telling the user what is or is not possible across apps, and whenever the user asks which app to use, call \`describe-workspace-apps\` - it reads each peer's live agent card for current purpose and optional capability details. Never hand-maintain a list of workspace apps in code or docs; it goes stale silently.\n</available-apps>`,
1098
1098
  "required",
1099
1099
  );
1100
1100
  }
@@ -32,7 +32,6 @@ import {
32
32
  sanitizeA2ACorrelationId,
33
33
  sanitizeA2ACorrelationMetadata,
34
34
  } from "../a2a/correlation.js";
35
- import { applyAgentTextEventToBuffer } from "../a2a/response-text.js";
36
35
  import {
37
36
  createA2AApproval,
38
37
  updateTaskStatusMessage,
@@ -77,6 +76,7 @@ import {
77
76
  abortTurnDurably,
78
77
  subscribeToRun,
79
78
  type ActionEntry,
79
+ type AgentLoopOutcome,
80
80
  } from "../agent/production-agent.js";
81
81
  import {
82
82
  callerHasRunAccess,
@@ -97,6 +97,7 @@ import {
97
97
  mergeThreadDataForClientSave,
98
98
  upsertUserMessage,
99
99
  } from "../agent/thread-data-builder.js";
100
+ import { appendThreadDebugHistory } from "../agent/thread-debug-history.js";
100
101
  import { attachToolSearch } from "../agent/tool-search.js";
101
102
  import type {
102
103
  AgentChatAttachment,
@@ -274,6 +275,9 @@ import {
274
275
  // ---------------------------------------------------------------------------
275
276
  import {
276
277
  createA2AEngineToolSurface,
278
+ DEFAULT_DELEGATED_MAX_ITERATIONS,
279
+ DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS,
280
+ DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS,
277
281
  filterAgentTools,
278
282
  filterPublicAgentActions,
279
283
  filterDirectA2AActions,
@@ -306,6 +310,7 @@ import {
306
310
  generateCorpusToolsPrompt,
307
311
  } from "./agent-chat/framework-prompts.js";
308
312
  import {
313
+ resolveA2AAgentDelegationEnabled,
309
314
  type AgentChatPluginOptions,
310
315
  type NitroPluginDef,
311
316
  } from "./agent-chat/plugin-options.js";
@@ -340,6 +345,11 @@ export type { AgentChatPluginOptions };
340
345
  export { runA2AAgentLoop };
341
346
  export { runMCPAgentLoop };
342
347
  export { createA2AEngineToolSurface };
348
+ export {
349
+ DEFAULT_DELEGATED_MAX_ITERATIONS,
350
+ DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS,
351
+ DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS,
352
+ };
343
353
  export { shouldBlockInProductCodeEditingSurface };
344
354
  export { loadRunCodeToolEntries };
345
355
  export { shouldDisableRecurringJobsRuntime };
@@ -516,6 +526,8 @@ export function createAgentChatPlugin(
516
526
  (env === "development" || env === "test") &&
517
527
  process.env.AGENT_MODE !== "production";
518
528
  const routePath = options?.path ?? "/_agent-native/agent-chat";
529
+ const a2aAgentDelegationEnabled =
530
+ resolveA2AAgentDelegationEnabled(options);
519
531
 
520
532
  // Mutable mode flag — persisted to the `settings` table so a user who
521
533
  // toggles to "Production" stays in prod mode across server restarts.
@@ -1623,35 +1635,43 @@ export function createAgentChatPlugin(
1623
1635
  // a day rollover (or the resources/extra content changing) only
1624
1636
  // invalidates the cached prompt prefix as late as possible.
1625
1637
  const runtimeContext = runtimeContextForEvent(context.event);
1626
- const systemPrompt = devActive
1627
- ? devPrompt +
1628
- SYSTEM_PROMPT_CACHE_SPLIT +
1629
- resources +
1630
- schemaBlock +
1631
- extra +
1632
- modelOverlay +
1633
- runtimeContext
1634
- : basePrompt +
1635
- SYSTEM_PROMPT_CACHE_SPLIT +
1636
- resources +
1637
- schemaBlock +
1638
- extra +
1639
- modelOverlay +
1640
- runtimeContext;
1638
+ // Delegated turns use native template actions in every environment,
1639
+ // so they must also receive the native-tool prompt. The interactive
1640
+ // dev prompt teaches `pnpm action` and would send this receiver back
1641
+ // into the shell loop the native action surface exists to prevent.
1642
+ const systemPrompt =
1643
+ basePrompt +
1644
+ SYSTEM_PROMPT_CACHE_SPLIT +
1645
+ resources +
1646
+ schemaBlock +
1647
+ extra +
1648
+ modelOverlay +
1649
+ runtimeContext;
1641
1650
  if (a2aRunContext) a2aRunContext.systemPrompt = systemPrompt;
1642
1651
 
1643
- // Build tools — same as interactive handler but WITHOUT call-agent
1644
- // to prevent infinite recursive A2A loops (agent calling itself).
1645
- // In dev mode, template actions are invoked via bash (not native tools),
1646
- // so they're omitted from the tool registry see allScripts comment.
1652
+ // Build tools — same as interactive handler. Cross-app delegation is
1653
+ // enabled by default; call-agent carries a bounded visited-app path
1654
+ // and rejects cycles/excessive hops before dispatch.
1655
+ // Delegated turns keep template actions as NATIVE tools even in dev,
1656
+ // unlike the interactive surface (see the allScripts comment). Dev
1657
+ // routes template actions through bash there to dodge the degenerate
1658
+ // empty-object tool call some models emit for complex schemas — a
1659
+ // person can just retry. A delegated caller cannot: with no native
1660
+ // action the sibling agent shells out, and an A2A turn that misfires
1661
+ // has no one to correct it, so it retries the same command until the
1662
+ // repetition guard kills the run minutes later. A rejected `{}` call
1663
+ // returns a schema error the model can fix on the next step, which is
1664
+ // strictly better than a shell loop nobody can see.
1647
1665
  const a2aActions = attachToolSearch(
1648
1666
  devActive
1649
1667
  ? {
1668
+ ...templateScripts,
1650
1669
  ...resourceScripts,
1651
1670
  ...docsScripts,
1652
1671
  ...(lazyContext ? frameworkContextTool : {}),
1653
1672
  ...urlTools,
1654
1673
  ...chatScripts,
1674
+ ...(a2aAgentDelegationEnabled ? callAgentScript : {}),
1655
1675
  ...fetchTool,
1656
1676
  ...webSearchTool,
1657
1677
  ...workspaceFilesTool,
@@ -1675,6 +1695,7 @@ export function createAgentChatPlugin(
1675
1695
  ...(lazyContext ? frameworkContextTool : {}),
1676
1696
  ...urlTools,
1677
1697
  ...chatScripts,
1698
+ ...(a2aAgentDelegationEnabled ? callAgentScript : {}),
1678
1699
  ...fetchTool,
1679
1700
  ...webSearchTool,
1680
1701
  ...workspaceFilesTool,
@@ -1711,6 +1732,7 @@ export function createAgentChatPlugin(
1711
1732
  // event stream so pre-tool narration never leaks as the A2A result.
1712
1733
  const a2aEvents: AgentChatEvent[] = [];
1713
1734
  const a2aToolResults: A2AToolResultSummary[] = [];
1735
+ let a2aOutcome: AgentLoopOutcome | undefined;
1714
1736
  let lastRecoverableArtifactText = "";
1715
1737
  let activityState = createA2AAgentActivityState();
1716
1738
  let lastActivityCheckpointAt = 0;
@@ -1775,8 +1797,16 @@ export function createAgentChatPlugin(
1775
1797
  runId: context.taskId,
1776
1798
  networkProtocol: "a2a",
1777
1799
  networkId: context.taskId,
1800
+ networkPeer: correlation.callerApp,
1801
+ delegationDepth: correlation.delegationDepth ?? 1,
1802
+ visitedApps:
1803
+ correlation.visitedApps ??
1804
+ (correlation.callerApp ? [correlation.callerApp] : []),
1778
1805
  threadId: context.taskId,
1779
1806
  turnId: context.taskId,
1807
+ onOutcome: (outcome) => {
1808
+ a2aOutcome = outcome;
1809
+ },
1780
1810
  send: (event) => {
1781
1811
  a2aEvents.push(event);
1782
1812
  const nextActivityState = applyA2AAgentActivityEvent(
@@ -1833,6 +1863,7 @@ export function createAgentChatPlugin(
1833
1863
  signal: controller.signal,
1834
1864
  },
1835
1865
  {
1866
+ delegatedRunPolicy: options?.delegatedRunPolicy,
1836
1867
  finalResponseGuard: options?.finalResponseGuard,
1837
1868
  runSoftTimeoutMs: options?.runSoftTimeoutMs,
1838
1869
  },
@@ -1932,7 +1963,7 @@ export function createAgentChatPlugin(
1932
1963
  const { responseText, finalText } = assembleA2AFinalResponse(
1933
1964
  a2aEvents,
1934
1965
  a2aToolResults,
1935
- { event: context.event },
1966
+ { event: context.event, outcome: a2aOutcome },
1936
1967
  );
1937
1968
 
1938
1969
  console.log(
@@ -1946,7 +1977,7 @@ export function createAgentChatPlugin(
1946
1977
  buildA2AAgentActivityPart(activityState),
1947
1978
  {
1948
1979
  type: "text" as const,
1949
- text: finalText || "(no response)",
1980
+ text: finalText,
1950
1981
  },
1951
1982
  ],
1952
1983
  };
@@ -2046,11 +2077,14 @@ export function createAgentChatPlugin(
2046
2077
  const model = normalizeModelForEngine(mcpEngine, mcpModelCandidate);
2047
2078
 
2048
2079
  // Same actions as A2A — without call-agent to prevent loops.
2049
- // In dev mode, template actions go through bash, not native tools.
2080
+ // `ask_app` is delegated too, so template actions stay native in dev
2081
+ // here for the same reason as the A2A surface above: an external
2082
+ // caller cannot nurse a shell command that misfires.
2050
2083
  const devActiveMcp = isDevMode();
2051
2084
  const mcpActions = attachToolSearch(
2052
2085
  devActiveMcp
2053
2086
  ? {
2087
+ ...templateScripts,
2054
2088
  ...resourceScripts,
2055
2089
  ...docsScripts,
2056
2090
  ...(lazyContext ? frameworkContextTool : {}),
@@ -2106,36 +2140,22 @@ export function createAgentChatPlugin(
2106
2140
  const schemaBlock = lazyContext
2107
2141
  ? ""
2108
2142
  : await buildSchemaBlock(SHARED_OWNER, databaseToolsMode);
2109
- // Build the MCP handler's own prompt — always use the bash-based
2110
- // dev prompt in dev mode because mcpActions routes template actions
2111
- // through bash (`devScriptsForA2A`), regardless of `nativeActionsInDev`.
2112
- const mcpDevPrompt =
2113
- (options?.devSystemPrompt
2114
- ? options.devSystemPrompt +
2115
- (options?.systemPrompt ??
2116
- (lazyContext
2117
- ? PROD_FRAMEWORK_PROMPT_COMPACT
2118
- : PROD_FRAMEWORK_PROMPT))
2119
- : lazyContext
2120
- ? DEV_FRAMEWORK_PROMPT_COMPACT
2121
- : DEV_FRAMEWORK_PROMPT) + devActionsPrompt;
2122
2143
  // Stable-first ordering: runtime-context (which changes daily)
2123
2144
  // goes last so the cached prompt prefix survives as long as
2124
2145
  // possible — same pattern as the other prompt-assembly sites in
2125
2146
  // this plugin (A2A above, prod/anonymous/dev handlers below).
2126
- const systemPrompt = devActiveMcp
2127
- ? mcpDevPrompt +
2128
- SYSTEM_PROMPT_CACHE_SPLIT +
2129
- resources +
2130
- schemaBlock +
2131
- buildRuntimeContextPrompt()
2132
- : basePrompt +
2133
- SYSTEM_PROMPT_CACHE_SPLIT +
2134
- resources +
2135
- schemaBlock +
2136
- buildRuntimeContextPrompt();
2147
+ // ask_app receives native template actions even in dev, so the
2148
+ // native-tool prompt is required here for the same reason as A2A.
2149
+ const systemPrompt =
2150
+ basePrompt +
2151
+ SYSTEM_PROMPT_CACHE_SPLIT +
2152
+ resources +
2153
+ schemaBlock +
2154
+ buildRuntimeContextPrompt();
2137
2155
 
2138
- let accumulatedText = "";
2156
+ const mcpEvents: AgentChatEvent[] = [];
2157
+ const mcpToolResults: A2AToolResultSummary[] = [];
2158
+ let mcpOutcome: AgentLoopOutcome | undefined;
2139
2159
  const controller = new AbortController();
2140
2160
 
2141
2161
  await runMCPAgentLoop(
@@ -2167,15 +2187,24 @@ export function createAgentChatPlugin(
2167
2187
  networkId: mcpRunId,
2168
2188
  threadId: mcpRunId,
2169
2189
  turnId: mcpRunId,
2190
+ onOutcome: (outcome) => {
2191
+ mcpOutcome = outcome;
2192
+ },
2170
2193
  send: (event) => {
2171
- accumulatedText = applyAgentTextEventToBuffer(
2172
- accumulatedText,
2173
- event,
2174
- );
2194
+ mcpEvents.push(event);
2195
+ if (event.type === "tool_done") {
2196
+ mcpToolResults.push({
2197
+ tool: event.tool,
2198
+ result: event.result,
2199
+ isError: event.isError,
2200
+ completedSideEffect: event.completedSideEffect,
2201
+ });
2202
+ }
2175
2203
  },
2176
2204
  signal: controller.signal,
2177
2205
  },
2178
2206
  {
2207
+ delegatedRunPolicy: options?.delegatedRunPolicy,
2179
2208
  finalResponseGuard: options?.finalResponseGuard,
2180
2209
  runSoftTimeoutMs: options?.runSoftTimeoutMs,
2181
2210
  },
@@ -2197,7 +2226,9 @@ export function createAgentChatPlugin(
2197
2226
  },
2198
2227
  );
2199
2228
 
2200
- return accumulatedText || "(no response)";
2229
+ return assembleA2AFinalResponse(mcpEvents, mcpToolResults, {
2230
+ outcome: mcpOutcome,
2231
+ }).finalText;
2201
2232
  },
2202
2233
  });
2203
2234
  }
@@ -2360,11 +2391,7 @@ export function createAgentChatPlugin(
2360
2391
  engine: runCtx?.engine?.name ?? "unknown",
2361
2392
  timestamp: Date.now(),
2362
2393
  };
2363
- repo._debug = debug;
2364
- const debugRuns = Array.isArray(repo._debugRuns)
2365
- ? repo._debugRuns
2366
- : [];
2367
- repo._debugRuns = [...debugRuns, debug].slice(-50);
2394
+ repo = appendThreadDebugHistory(repo, debug);
2368
2395
 
2369
2396
  const meta = extractThreadMeta(repo);
2370
2397
  await updateThreadData(
@@ -4520,6 +4547,11 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4520
4547
  const body = await readBody(event).catch(() => null);
4521
4548
  const threadId =
4522
4549
  typeof body?.threadId === "string" ? body.threadId : "";
4550
+ const reason =
4551
+ typeof body?.reason === "string" &&
4552
+ /^[a-z0-9_-]{1,64}$/i.test(body.reason)
4553
+ ? body.reason
4554
+ : "user";
4523
4555
  if (
4524
4556
  !/^[a-zA-Z0-9_-]{1,160}$/.test(turnId) ||
4525
4557
  !threadId ||
@@ -4528,7 +4560,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4528
4560
  setResponseStatus(event, 404);
4529
4561
  return { error: "Run not found" };
4530
4562
  }
4531
- await markTurnAborted(threadId, turnId);
4563
+ await markTurnAborted(threadId, turnId, reason);
4532
4564
  return { ok: true };
4533
4565
  }
4534
4566
 
@@ -223,14 +223,26 @@ Core routes plugin mounts these under `/_agent-native/secrets/` automatically:
223
223
 
224
224
  - Values are stored in `app_secrets` (created on-demand; no migration
225
225
  needed).
226
- - Encrypted at rest with AES-256-GCM. Key material is derived from
227
- `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set (for example,
226
+ - Values are encrypted at rest with AES-256-GCM. Generic app-local secrets
227
+ prefer `<APP_NAME>_SECRETS_ENCRYPTION_KEY` (for example,
228
228
  `ANALYTICS_SECRETS_ENCRYPTION_KEY`), then `SECRETS_ENCRYPTION_KEY`, then
229
- `BETTER_AUTH_SECRET`. App-scoped keys are useful when a local multi-app
230
- workspace connects one app to its production database without replacing the
231
- shared local authentication secret. If none is set, the framework uses a
232
- machine-local fallback and logs a one-time warning set stable key material
233
- in production and in every runtime that reads the same encrypted data.
229
+ `BETTER_AUTH_SECRET`.
230
+ - Workspace-shared `app_secrets` prefer
231
+ `WORKSPACE_SECRETS_ENCRYPTION_KEY`, then the legacy shared
232
+ `SECRETS_ENCRYPTION_KEY`, then a purpose-derived key from `A2A_SECRET`.
233
+ Better Auth and app-scoped keys remain legacy read candidates; a successful
234
+ legacy decrypt is compare-and-swap migrated to the preferred shared key
235
+ without changing the row timestamp.
236
+ - Set the same stable `WORKSPACE_SECRETS_ENCRYPTION_KEY` in every app that
237
+ reads a shared vault. It is intentionally separate from app-local OAuth
238
+ encryption. If the vault still relies on `A2A_SECRET`, rotating A2A material
239
+ also rotates its encryption key. Add the stable vault key everywhere and
240
+ read/migrate existing rows before rotating A2A.
241
+ - To rotate the dedicated workspace key itself, deploy the new value together
242
+ with `WORKSPACE_SECRETS_ENCRYPTION_KEY_PREVIOUS=<old value>`, let reads
243
+ migrate ciphertext, then remove the previous key after the migration window.
244
+ - If no configured key material exists, development uses a machine-local
245
+ fallback and logs a one-time warning. Production fails closed.
234
246
 
235
247
  ## Ad-hoc Keys
236
248
 
@@ -223,14 +223,26 @@ Core routes plugin mounts these under `/_agent-native/secrets/` automatically:
223
223
 
224
224
  - Values are stored in `app_secrets` (created on-demand; no migration
225
225
  needed).
226
- - Encrypted at rest with AES-256-GCM. Key material is derived from
227
- `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set (for example,
226
+ - Values are encrypted at rest with AES-256-GCM. Generic app-local secrets
227
+ prefer `<APP_NAME>_SECRETS_ENCRYPTION_KEY` (for example,
228
228
  `ANALYTICS_SECRETS_ENCRYPTION_KEY`), then `SECRETS_ENCRYPTION_KEY`, then
229
- `BETTER_AUTH_SECRET`. App-scoped keys are useful when a local multi-app
230
- workspace connects one app to its production database without replacing the
231
- shared local authentication secret. If none is set, the framework uses a
232
- machine-local fallback and logs a one-time warning set stable key material
233
- in production and in every runtime that reads the same encrypted data.
229
+ `BETTER_AUTH_SECRET`.
230
+ - Workspace-shared `app_secrets` prefer
231
+ `WORKSPACE_SECRETS_ENCRYPTION_KEY`, then the legacy shared
232
+ `SECRETS_ENCRYPTION_KEY`, then a purpose-derived key from `A2A_SECRET`.
233
+ Better Auth and app-scoped keys remain legacy read candidates; a successful
234
+ legacy decrypt is compare-and-swap migrated to the preferred shared key
235
+ without changing the row timestamp.
236
+ - Set the same stable `WORKSPACE_SECRETS_ENCRYPTION_KEY` in every app that
237
+ reads a shared vault. It is intentionally separate from app-local OAuth
238
+ encryption. If the vault still relies on `A2A_SECRET`, rotating A2A material
239
+ also rotates its encryption key. Add the stable vault key everywhere and
240
+ read/migrate existing rows before rotating A2A.
241
+ - To rotate the dedicated workspace key itself, deploy the new value together
242
+ with `WORKSPACE_SECRETS_ENCRYPTION_KEY_PREVIOUS=<old value>`, let reads
243
+ migrate ciphertext, then remove the previous key after the migration window.
244
+ - If no configured key material exists, development uses a machine-local
245
+ fallback and logs a one-time warning. Production fails closed.
234
246
 
235
247
  ## Ad-hoc Keys
236
248
 
@@ -136,12 +136,19 @@ log or return them.
136
136
  ## Advertising what this agent can do
137
137
 
138
138
  Card `skills` are derived from actions marked `publicAgent`. An app that marks
139
- none publishes `"skills": []` and peers cannot see what it offers, even though
140
- delegation still works. Mark the actions a peer should be able to see and
141
- invoke directly; leave the rest internal.
139
+ none publishes `"skills": []`, but natural-language delegation still works
140
+ because the receiving agent loads its own instructions, skills, data
141
+ dictionary, credentials, and tools. Mark only stable machine contracts that a
142
+ peer may intentionally invoke directly; leave implementation actions internal.
142
143
 
143
144
  ## Calling another agent
144
145
 
146
+ Natural-language delegation is the default for agent-to-agent work. Tell the
147
+ receiving specialist the objective, relevant IDs/date range, and desired result
148
+ shape. The receiver owns source selection, schemas, queries, joins, SQL, and
149
+ provider-specific details. Do not switch to a direct action merely because a
150
+ delegated run is slow or flaky; fix the A2A path instead.
151
+
145
152
  ### Simple: `callAgent()` (text in, text out)
146
153
 
147
154
  ```ts
@@ -162,10 +169,12 @@ production. `resolveA2ACallerAuth()` pulls the authenticated email, org domain,
162
169
  and org secret out of request context; pass them explicitly only from CLI or
163
170
  cron, where there is no request.
164
171
 
165
- ### Fast bounded read: `invokeAgentAction()`
172
+ ### Explicit machine-contract exception: `invokeAgentAction()`
166
173
 
167
- When the caller knows the exact receiver-owned read action and arguments, skip
168
- the receiver's model loop:
174
+ Use direct invocation only when a trusted integration already specifies the
175
+ exact receiver-owned semantic read action and complete arguments. It is an
176
+ optional machine API, not an agent-performance shortcut or fallback for failed
177
+ message delegation:
169
178
 
170
179
  ```ts
171
180
  import { invokeAgentAction } from "@agent-native/core/a2a";
@@ -184,7 +193,9 @@ The receiver still owns schema validation, credentials, access scoping, audit
184
193
  attribution, and exposure policy. Direct invocation is available only for
185
194
  cataloged, authenticated, explicitly exposed read-only actions that do not
186
195
  require approval. Its JWT is audience-bound to the receiving app. Use normal
187
- message delegation for planning, synthesis, multi-step work, or mutations.
196
+ message delegation whenever the receiver must interpret the request, choose a
197
+ source, consult its data dictionary, plan, synthesize, join data, or perform a
198
+ multi-step workflow.
188
199
 
189
200
  Inside an agent loop, `call-agent` exposes the same path with `action` + `input`;
190
201
  omit `message` and `taskId` in that mode.
@@ -36,11 +36,11 @@ The main agent should discover available siblings before assuming capability:
36
36
  `discoverWorkspaceAgents()`. It carries one line per app — enough to know a
37
37
  sibling exists, not enough to know what it can do.
38
38
  - Use the built-in `describe-workspace-apps` tool for actual capability.
39
- It reads each peer's live `/.well-known/agent-card.json` and returns their
40
- callable action names; pass `app: "<id>"` for one peer's full list with
41
- descriptions. Call it before building something a sibling may already own,
42
- before telling a user what is or is not possible across apps, and whenever
43
- someone asks which app to use for a job.
39
+ It reads each peer's live `/.well-known/agent-card.json` and returns its
40
+ purpose plus any optional stable machine contracts; pass `app: "<id>"` for
41
+ one peer's full description. Call it before building something a sibling may
42
+ already own, before telling a user what is or is not possible across apps,
43
+ and whenever someone asks which app to use for a job.
44
44
  - Never hand-maintain a markdown or code list of what each workspace app does.
45
45
  A stale catalog is worse than none: it reads as authoritative while pointing
46
46
  at capabilities that moved or vanished. An app's purpose belongs in its own
@@ -49,17 +49,18 @@ The main agent should discover available siblings before assuming capability:
49
49
  actions — both of which `describe-workspace-apps` reads live.
50
50
  - UI shells, headless surfaces, and scripts can read the same registry through
51
51
  `GET /_agent-native/agents?selfAppId=<app-id>`.
52
- - Code or CLI callers should use the first-class A2A invocation path
53
- (`invokeAgent()` / `agent-native invoke`) when they need to call an app by
54
- id, name, or URL.
52
+ - Code or CLI callers should use the first-class message-based A2A invocation
53
+ path (`invokeAgent()` / `agent-native invoke`) when they need to ask an app
54
+ by id, name, or URL.
55
55
  - In the agent loop, use `call-agent` with the sibling app id when another app
56
56
  owns the work or data. Never call the current app through `call-agent`; use
57
57
  local actions instead.
58
- - When the exact sibling-owned read action and input are already known, use
59
- `invokeAgentAction()` or `call-agent` with `action` + `input`. This preserves
60
- the receiver's credentials and access checks while skipping its second model
61
- loop. Use prompt-based `invokeAgent()` only when the sibling must reason,
62
- synthesize, mutate, or perform a multi-step workflow.
58
+ - Send a natural-language objective by default so the sibling can apply its own
59
+ instructions, skills, schemas, data dictionary, credentials, and tools.
60
+ `invokeAgentAction()` or `call-agent` with `action` + `input` is only for an
61
+ explicit stable semantic read contract whose complete input is already known.
62
+ Never expose or call an implementation action as a workaround for slow or
63
+ failed message delegation.
63
64
 
64
65
  Send narrow prompts to siblings: name the exact question, relevant ids, date
65
66
  ranges, and expected output shape. Preserve returned ids and URLs verbatim.
@@ -112,7 +113,7 @@ For a sales-intelligence workspace, split the job into small apps:
112
113
  | `hubspot-pipeline` | CRM deals, contacts, companies, associations | `provider-api-request` with provider `hubspot` |
113
114
  | `gong-evidence` | Calls, transcripts, snippets, speaker evidence | `provider-api-request` with provider `gong` |
114
115
  | `knowledge-base` | Internal docs, pricing rules, playbooks | local search/read actions |
115
- | `deal-brief` | Orchestration and final brief | `invokeAgent()` or `call-agent` to the three apps |
116
+ | `deal-brief` | Orchestration and final brief | message-based `invokeAgent()` or `call-agent` to the three apps |
116
117
 
117
118
  Flow: `deal-brief` asks `hubspot-pipeline` for the target account and open
118
119
  deals, asks `gong-evidence` for recent transcript evidence about those deals,
@@ -223,14 +223,26 @@ Core routes plugin mounts these under `/_agent-native/secrets/` automatically:
223
223
 
224
224
  - Values are stored in `app_secrets` (created on-demand; no migration
225
225
  needed).
226
- - Encrypted at rest with AES-256-GCM. Key material is derived from
227
- `<APP_NAME>_SECRETS_ENCRYPTION_KEY` when set (for example,
226
+ - Values are encrypted at rest with AES-256-GCM. Generic app-local secrets
227
+ prefer `<APP_NAME>_SECRETS_ENCRYPTION_KEY` (for example,
228
228
  `ANALYTICS_SECRETS_ENCRYPTION_KEY`), then `SECRETS_ENCRYPTION_KEY`, then
229
- `BETTER_AUTH_SECRET`. App-scoped keys are useful when a local multi-app
230
- workspace connects one app to its production database without replacing the
231
- shared local authentication secret. If none is set, the framework uses a
232
- machine-local fallback and logs a one-time warning set stable key material
233
- in production and in every runtime that reads the same encrypted data.
229
+ `BETTER_AUTH_SECRET`.
230
+ - Workspace-shared `app_secrets` prefer
231
+ `WORKSPACE_SECRETS_ENCRYPTION_KEY`, then the legacy shared
232
+ `SECRETS_ENCRYPTION_KEY`, then a purpose-derived key from `A2A_SECRET`.
233
+ Better Auth and app-scoped keys remain legacy read candidates; a successful
234
+ legacy decrypt is compare-and-swap migrated to the preferred shared key
235
+ without changing the row timestamp.
236
+ - Set the same stable `WORKSPACE_SECRETS_ENCRYPTION_KEY` in every app that
237
+ reads a shared vault. It is intentionally separate from app-local OAuth
238
+ encryption. If the vault still relies on `A2A_SECRET`, rotating A2A material
239
+ also rotates its encryption key. Add the stable vault key everywhere and
240
+ read/migrate existing rows before rotating A2A.
241
+ - To rotate the dedicated workspace key itself, deploy the new value together
242
+ with `WORKSPACE_SECRETS_ENCRYPTION_KEY_PREVIOUS=<old value>`, let reads
243
+ migrate ciphertext, then remove the previous key after the migration window.
244
+ - If no configured key material exists, development uses a machine-local
245
+ fallback and logs a one-time warning. Production fails closed.
234
246
 
235
247
  ## Ad-hoc Keys
236
248
 
@@ -2190,6 +2190,7 @@ function ssrStubPlugin(packages: string[]): Plugin | null {
2190
2190
  "getIsolationScope",
2191
2191
  "init",
2192
2192
  "isChangeOrigin",
2193
+ "isNodeEmpty",
2193
2194
  "mergeAttributes",
2194
2195
  "renderToString",
2195
2196
  "applyUpdate",