@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
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/secrets/storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Storage layer for the framework secrets registry.\n *\n * Values are encrypted at rest with AES-256-GCM. The workspace-shared\n * encryption key is derived from `SECRETS_ENCRYPTION_KEY` (preferred) or the\n * existing `BETTER_AUTH_SECRET` env var (fallback so templates don't need a\n * second secret during development). Deployments that only have the legacy\n * app-scoped key continue to work until shared key material is configured;\n * once configured, new rows use the shared key and reads retain a legacy-key\n * fallback for existing rows.\n *\n * Secret values are NEVER logged and NEVER returned from any route handler.\n */\n\nimport { randomUUID } from \"node:crypto\";\n\nimport { getDbExec, isPostgres } from \"../db/client.js\";\nimport { ensureColumnExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport {\n encryptSecretValue as encryptLegacyValue,\n encryptSharedSecretValue as encryptValue,\n decryptSharedSecretValue as decryptValue,\n decryptSecretValue as decryptLegacyValue,\n hasSharedSecretEncryptionKeyMaterial,\n} from \"./crypto.js\";\nimport type { SecretScope } from \"./register.js\";\nimport { APP_SECRETS_CREATE_SQL } from \"./schema.js\";\n\n// ---------------------------------------------------------------------------\n// Table bootstrap\n// ---------------------------------------------------------------------------\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n // Postgres version of the CREATE TABLE — the generic `INTEGER` maps to\n // BIGINT on Postgres, which we need for millisecond timestamps.\n const createSql = isPostgres()\n ? APP_SECRETS_CREATE_SQL.replace(/\\bINTEGER\\b/g, \"BIGINT\")\n : APP_SECRETS_CREATE_SQL;\n\n if (isPostgres()) {\n // Hot path: in production the table and both additive columns are\n // virtually always already present. Issuing `CREATE`/`ALTER` would\n // still take an ACCESS EXCLUSIVE lock — which, in a fresh background\n // worker process behind a concurrent connection on the shared Neon DB,\n // can block ~indefinitely. `ensureTableExists` / `ensureColumnExists`\n // check `information_schema` first (a plain read, no lock) and run DDL\n // ONLY for what is actually missing, wrapping any DDL that must run in a\n // transaction-scoped `lock_timeout` so a contended lock fails fast. They\n // also re-probe after a swallowed lock-timeout and THROW if the schema\n // is still missing, so a timed-out DDL never poisons this init memo.\n await ensureTableExists(\"app_secrets\", createSql);\n await ensureColumnExists(\n \"app_secrets\",\n \"description\",\n `ALTER TABLE app_secrets ADD COLUMN IF NOT EXISTS description TEXT`,\n );\n await ensureColumnExists(\n \"app_secrets\",\n \"url_allowlist\",\n `ALTER TABLE app_secrets ADD COLUMN IF NOT EXISTS url_allowlist TEXT`,\n );\n await ensureColumnExists(\n \"app_secrets\",\n \"shared_encrypted_value\",\n `ALTER TABLE app_secrets ADD COLUMN IF NOT EXISTS shared_encrypted_value TEXT`,\n );\n return;\n }\n\n // SQLite (local dev): no ACCESS EXCLUSIVE lock problem, keep the original\n // create-then-additive-alter behaviour. SQLite has no\n // `ADD COLUMN IF NOT EXISTS`, so the ALTERs stay wrapped in try/catch.\n await client.execute(createSql);\n\n // Additive migration: description column (for ad-hoc keys)\n try {\n await client.execute(\n `ALTER TABLE app_secrets ADD COLUMN description TEXT`,\n );\n } catch {\n // Column already exists — expected\n }\n\n // Additive migration: url_allowlist column\n try {\n await client.execute(\n `ALTER TABLE app_secrets ADD COLUMN url_allowlist TEXT`,\n );\n } catch {\n // Column already exists — expected\n }\n\n // Additive migration: workspace-shared ciphertext. Keep the legacy\n // encrypted_value column so older app versions remain readable.\n try {\n await client.execute(\n `ALTER TABLE app_secrets ADD COLUMN shared_encrypted_value TEXT`,\n );\n } catch {\n // Column already exists — expected\n }\n })().catch((err) => {\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\n// ---------------------------------------------------------------------------\n// Encryption — see ./crypto.ts. Keep encrypted_value on the legacy app-key\n// format for mixed-version deployments, and add shared_encrypted_value when a\n// stable workspace key is configured so sibling apps can read the same row.\n// ---------------------------------------------------------------------------\n\n/**\n * Return the last 4 characters of a secret, with any leading characters\n * masked. Used to show a preview without leaking the value.\n */\nexport function last4(value: string): string {\n if (!value) return \"\";\n if (value.length <= 4) return \"••••\";\n return \"••••\" + value.slice(-4);\n}\n\n// ---------------------------------------------------------------------------\n// CRUD\n// ---------------------------------------------------------------------------\n\nexport interface SecretRef {\n key: string;\n scope: SecretScope;\n scopeId: string;\n}\n\nexport interface WriteSecretArgs extends SecretRef {\n value: string;\n /** Optional human-readable description (used for ad-hoc keys). */\n description?: string;\n /** Optional JSON-stringified array of allowed URL origins. */\n urlAllowlist?: string;\n}\n\n/**\n * Write (insert or update) a secret. The value is encrypted before being\n * stored — the caller's plaintext is never persisted. Returns the new\n * record's id.\n */\nexport async function writeAppSecret(args: WriteSecretArgs): Promise<string> {\n await ensureTable();\n const { key, value, scope, scopeId, description, urlAllowlist } = args;\n if (!key || !value || !scope || !scopeId) {\n throw new Error(\n \"writeAppSecret: key, value, scope, and scopeId are all required\",\n );\n }\n const client = getDbExec();\n const now = Date.now();\n // Dual-write during rollout: old readers continue using encrypted_value,\n // while new readers prefer the nullable shared ciphertext. An app-only\n // deployment leaves the shared column null; on an update, a writer without\n // shared key material clears any existing shared ciphertext rather than\n // preserving it (see the upsert SQL below for why).\n const encrypted = encryptLegacyValue(value);\n const sharedEncrypted = hasSharedSecretEncryptionKeyMaterial()\n ? encryptValue(value)\n : null;\n const id = randomUUID();\n\n // Atomic upsert by (scope, scope_id, key). Previously this was a\n // SELECT-then-branch (UPDATE if found, else INSERT): under concurrent\n // writers for the same key both could see \"no row\" and both attempt\n // INSERT, and the loser threw a raw UNIQUE(scope, scope_id, key)\n // constraint violation (a user-facing 500) instead of updating. A single\n // `INSERT ... ON CONFLICT DO UPDATE` closes that window — it's one\n // statement, so there's no gap between \"check\" and \"act\". `id` is\n // deliberately left out of the `DO UPDATE SET` list so an existing row\n // keeps its original id (any stored references stay stable); only a\n // genuinely new row gets the freshly generated `id`. This syntax is\n // portable across SQLite (UPSERT since 3.24) and Postgres.\n //\n // shared_encrypted_value is overwritten with `excluded.shared_encrypted_value`\n // (NULL when this writer lacks shared key material) rather than preserved\n // via COALESCE. Preserving an existing shared ciphertext across a value\n // update would let a sibling app silently decrypt a STALE value after the\n // owner rotates it — a material-less writer has no way to produce the new\n // shared ciphertext, so it must clear the old one instead of leaving it\n // pointing at data that's no longer current. Siblings then get an honest\n // cache miss (falling back to the legacy column or reporting missing) until\n // the owning app's next read repopulates shared_encrypted_value via\n // `populateSharedAppSecret`, which only ever fills a NULL column. A\n // temporary miss is safer than serving rotated-away plaintext.\n const upsertSql = `INSERT INTO app_secrets (id, scope, scope_id, key, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (scope, scope_id, key) DO UPDATE SET\n encrypted_value = excluded.encrypted_value,\n shared_encrypted_value = excluded.shared_encrypted_value,\n description = excluded.description,\n url_allowlist = excluded.url_allowlist,\n updated_at = excluded.updated_at`;\n const upsertArgs = [\n id,\n scope,\n scopeId,\n key,\n encrypted,\n sharedEncrypted,\n description ?? null,\n urlAllowlist ?? null,\n now,\n now,\n ];\n\n if (isPostgres()) {\n const { rows } = await client.execute({\n sql: `${upsertSql} RETURNING id`,\n args: upsertArgs,\n });\n return String(rows[0]?.id ?? id);\n }\n\n // SQLite: RETURNING support varies across better-sqlite3/libsql builds, so\n // (matching the convention elsewhere in this codebase, e.g.\n // integrations/pending-tasks-store.ts) re-read the id afterward instead of\n // relying on it. The row is guaranteed to exist at this point, so this is\n // a plain lookup rather than a TOCTOU-prone gate on the write itself.\n await client.execute({ sql: upsertSql, args: upsertArgs });\n const { rows } = await client.execute({\n sql: `SELECT id FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ? LIMIT 1`,\n args: [scope, scopeId, key],\n });\n return String(rows[0]?.id ?? id);\n}\n\nexport interface ReadSecretResult {\n value: string;\n last4: string;\n updatedAt: number;\n}\n\n/**\n * Read the shared-key format and retain compatibility with rows written before\n * app_secrets moved to its workspace-shared encryption boundary. The legacy\n * fallback is only useful when the current app owns the old row; sibling apps\n * will receive shared-key ciphertext after the next vault sync or update.\n */\ninterface DecryptedAppSecretValue {\n value: string;\n /** True when the app-scoped fallback decrypted encrypted_value. */\n usedLegacyKey: boolean;\n /** True when shared_encrypted_value was not the source of the plaintext. */\n needsSharedCiphertext: boolean;\n}\n\nfunction decryptAppSecretValue(\n encrypted: string,\n sharedEncrypted?: string | null,\n): DecryptedAppSecretValue {\n if (sharedEncrypted) {\n try {\n return {\n value: decryptValue(sharedEncrypted),\n usedLegacyKey: false,\n needsSharedCiphertext: false,\n };\n } catch {\n // Fall through to the legacy column. A partially migrated row may have\n // a stale shared ciphertext while the old app-key value is valid.\n }\n }\n try {\n return {\n value: decryptValue(encrypted),\n usedLegacyKey: false,\n needsSharedCiphertext: true,\n };\n } catch {\n return {\n value: decryptLegacyValue(encrypted),\n usedLegacyKey: true,\n needsSharedCiphertext: true,\n };\n }\n}\n\n/**\n * Populate the shared column without touching encrypted_value. This is\n * intentionally best-effort: a read must still succeed if a deployment's DB\n * role cannot update the row. The NULL predicate prevents a concurrent writer\n * from overwriting newly-populated shared ciphertext, and leaving updated_at\n * untouched preserves the row's user-visible ordering/metadata.\n */\nasync function populateSharedAppSecret(\n id: unknown,\n value: string,\n): Promise<void> {\n if (\n id === undefined ||\n id === null ||\n !hasSharedSecretEncryptionKeyMaterial()\n ) {\n return;\n }\n try {\n await getDbExec().execute({\n sql: `UPDATE app_secrets SET shared_encrypted_value = ? WHERE id = ? AND shared_encrypted_value IS NULL`,\n args: [encryptValue(value), id],\n });\n } catch {\n // Migration is opportunistic. Preserve the successful read if the update\n // is unavailable due to a read-only role, transient DB failure, or race.\n }\n}\n\ntype AppSecretsReadQuery = { sql: string; args: unknown[] };\n\n/**\n * True only when the database says the app_secrets table itself is missing.\n * Other query failures must propagate unchanged: attempting schema bootstrap\n * for connectivity, permission, or syntax errors both hides the real failure\n * and can introduce DDL onto a latency-sensitive read path.\n */\nfunction isMissingAppSecretsTableError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const code = String((error as Error & { code?: unknown }).code ?? \"\");\n const message = error.message.toLowerCase();\n const namesAppSecrets = /(?:app_secrets|\"app_secrets\")/.test(message);\n\n if (code === \"42P01\") return namesAppSecrets;\n return (\n namesAppSecrets &&\n (message.includes(\"no such table\") ||\n (message.includes(\"relation\") && message.includes(\"does not exist\")))\n );\n}\n\n/** Execute a read without schema probes on the normal path. */\nasync function executeAppSecretsRead(query: AppSecretsReadQuery) {\n const client = getDbExec();\n try {\n return await client.execute(query);\n } catch (error) {\n if (!isMissingAppSecretsTableError(error)) throw error;\n await ensureTable();\n return client.execute(query);\n }\n}\n\n/**\n * Read a secret's plaintext value. Returns null when not found. The caller\n * is responsible for never logging the returned value.\n */\nexport async function readAppSecret(\n ref: SecretRef,\n): Promise<ReadSecretResult | null> {\n const { key, scope, scopeId } = ref;\n const { rows } = await executeAppSecretsRead({\n sql: `SELECT encrypted_value, shared_encrypted_value, updated_at, id FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ? LIMIT 1`,\n args: [scope, scopeId, key],\n });\n if (rows.length === 0) return null;\n try {\n const encrypted = rows[0].encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n rows[0].shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(rows[0].id, decrypted.value);\n }\n return {\n value: decrypted.value,\n last4: last4(decrypted.value),\n updatedAt: Number(rows[0].updated_at ?? 0),\n };\n } catch {\n // Decryption failure — key rotated, tampered row, etc. Don't throw up the\n // stack in a way that could leak the ciphertext; just report missing.\n return null;\n }\n}\n\n/** Read several keys from one scope in a single database round trip. */\nexport async function readAppSecrets(args: {\n keys: readonly string[];\n scope: SecretScope;\n scopeId: string;\n}): Promise<Map<string, ReadSecretResult>> {\n const keys = [...new Set(args.keys.filter(Boolean))];\n if (keys.length === 0) return new Map();\n\n const placeholders = keys.map(() => \"?\").join(\", \");\n const { rows } = await executeAppSecretsRead({\n sql: `SELECT key, encrypted_value, shared_encrypted_value, updated_at, id FROM app_secrets WHERE scope = ? AND scope_id = ? AND key IN (${placeholders})`,\n args: [args.scope, args.scopeId, ...keys],\n });\n const results = new Map<string, ReadSecretResult>();\n for (const row of rows) {\n const key = String(row.key ?? \"\");\n if (!key) continue;\n try {\n const encrypted = row.encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n row.shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(row.id, decrypted.value);\n }\n results.set(key, {\n value: decrypted.value,\n last4: last4(decrypted.value),\n updatedAt: Number(row.updated_at ?? 0),\n });\n } catch {\n // Match readAppSecret: corrupted or stale ciphertext behaves as missing.\n }\n }\n return results;\n}\n\n/**\n * Return just the metadata for a secret (no value). Used by the list route so\n * the UI can show the \"Set\" pill and last-4 without the decrypted value going\n * over the wire.\n */\nexport async function getAppSecretMeta(\n ref: SecretRef,\n): Promise<{ last4: string; updatedAt: number } | null> {\n const result = await readAppSecret(ref);\n if (!result) return null;\n return { last4: result.last4, updatedAt: result.updatedAt };\n}\n\nexport interface SecretMeta {\n key: string;\n scope: SecretScope;\n scopeId: string;\n last4: string;\n description: string | null;\n urlAllowlist: string[] | null;\n createdAt: number;\n updatedAt: number;\n}\n\n/**\n * Read a secret's metadata, including ad-hoc fields (description, allowlist),\n * without ever decrypting or returning the plaintext value. Used by the\n * ad-hoc list route and any UI that wants to render a key tile.\n */\nexport async function readAppSecretMeta(\n ref: SecretRef,\n): Promise<SecretMeta | null> {\n await ensureTable();\n const { key, scope, scopeId } = ref;\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ? LIMIT 1`,\n args: [scope, scopeId, key],\n });\n if (rows.length === 0) return null;\n const row = rows[0];\n let last4Value = \"\";\n try {\n const encrypted = row.encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n row.shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(row.id, decrypted.value);\n }\n last4Value = last4(decrypted.value);\n } catch {\n last4Value = \"\";\n }\n return {\n key,\n scope,\n scopeId,\n last4: last4Value,\n description: (row.description as string | null) ?? null,\n urlAllowlist: parseAllowlist(row.url_allowlist as string | null),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\n/**\n * List all secrets for a given scope. Returns metadata only — values are\n * never decrypted or returned. Used by the ad-hoc list route to surface\n * user-created keys.\n */\nexport async function listAppSecretsForScope(\n scope: SecretScope,\n scopeId: string,\n): Promise<SecretMeta[]> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, key, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at FROM app_secrets WHERE scope = ? AND scope_id = ? ORDER BY updated_at DESC`,\n args: [scope, scopeId],\n });\n const results: SecretMeta[] = [];\n for (const row of rows) {\n let last4Value = \"\";\n try {\n const encrypted = row.encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n row.shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(row.id, decrypted.value);\n }\n last4Value = last4(decrypted.value);\n } catch {\n last4Value = \"\";\n }\n results.push({\n key: row.key as string,\n scope,\n scopeId,\n last4: last4Value,\n description: (row.description as string | null) ?? null,\n urlAllowlist: parseAllowlist(row.url_allowlist as string | null),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n });\n }\n return results;\n}\n\nfunction parseAllowlist(raw: string | null): string[] | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed) && parsed.every((v) => typeof v === \"string\")) {\n return parsed;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function deleteAppSecret(ref: SecretRef): Promise<boolean> {\n await ensureTable();\n const { key, scope, scopeId } = ref;\n const client = getDbExec();\n const { rowsAffected } = await client.execute({\n sql: `DELETE FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ?`,\n args: [scope, scopeId, key],\n });\n return rowsAffected > 0;\n}\n"]}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/secrets/storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Storage layer for the framework secrets registry.\n *\n * Values are encrypted at rest with AES-256-GCM. The workspace-shared\n * encryption key prefers `WORKSPACE_SECRETS_ENCRYPTION_KEY`, then the legacy\n * combined `SECRETS_ENCRYPTION_KEY`, then the workspace-wide `A2A_SECRET`.\n * A configured previous workspace key, `BETTER_AUTH_SECRET`, and app-scoped\n * keys remain read fallbacks for rows written before sibling apps converged on\n * the shared key. Successful fallback reads race-safely refresh the shared\n * ciphertext.\n *\n * Secret values are NEVER logged and NEVER returned from any route handler.\n */\n\nimport { randomUUID } from \"node:crypto\";\n\nimport { getDbExec, isPostgres } from \"../db/client.js\";\nimport { ensureColumnExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport {\n encryptSecretValue as encryptLegacyValue,\n encryptSharedSecretValue as encryptValue,\n decryptSharedSecretValueDetailed as decryptValue,\n decryptSecretValue as decryptLegacyValue,\n hasSharedSecretEncryptionKeyMaterial,\n} from \"./crypto.js\";\nimport type { SecretScope } from \"./register.js\";\nimport { APP_SECRETS_CREATE_SQL } from \"./schema.js\";\n\n// ---------------------------------------------------------------------------\n// Table bootstrap\n// ---------------------------------------------------------------------------\n\nlet _initPromise: Promise<void> | undefined;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n // Postgres version of the CREATE TABLE — the generic `INTEGER` maps to\n // BIGINT on Postgres, which we need for millisecond timestamps.\n const createSql = isPostgres()\n ? APP_SECRETS_CREATE_SQL.replace(/\\bINTEGER\\b/g, \"BIGINT\")\n : APP_SECRETS_CREATE_SQL;\n\n if (isPostgres()) {\n // Hot path: in production the table and both additive columns are\n // virtually always already present. Issuing `CREATE`/`ALTER` would\n // still take an ACCESS EXCLUSIVE lock — which, in a fresh background\n // worker process behind a concurrent connection on the shared Neon DB,\n // can block ~indefinitely. `ensureTableExists` / `ensureColumnExists`\n // check `information_schema` first (a plain read, no lock) and run DDL\n // ONLY for what is actually missing, wrapping any DDL that must run in a\n // transaction-scoped `lock_timeout` so a contended lock fails fast. They\n // also re-probe after a swallowed lock-timeout and THROW if the schema\n // is still missing, so a timed-out DDL never poisons this init memo.\n await ensureTableExists(\"app_secrets\", createSql);\n await ensureColumnExists(\n \"app_secrets\",\n \"description\",\n `ALTER TABLE app_secrets ADD COLUMN IF NOT EXISTS description TEXT`,\n );\n await ensureColumnExists(\n \"app_secrets\",\n \"url_allowlist\",\n `ALTER TABLE app_secrets ADD COLUMN IF NOT EXISTS url_allowlist TEXT`,\n );\n await ensureColumnExists(\n \"app_secrets\",\n \"shared_encrypted_value\",\n `ALTER TABLE app_secrets ADD COLUMN IF NOT EXISTS shared_encrypted_value TEXT`,\n );\n return;\n }\n\n // SQLite (local dev): no ACCESS EXCLUSIVE lock problem, keep the original\n // create-then-additive-alter behaviour. SQLite has no\n // `ADD COLUMN IF NOT EXISTS`, so the ALTERs stay wrapped in try/catch.\n await client.execute(createSql);\n\n // Additive migration: description column (for ad-hoc keys)\n try {\n await client.execute(\n `ALTER TABLE app_secrets ADD COLUMN description TEXT`,\n );\n } catch {\n // Column already exists — expected\n }\n\n // Additive migration: url_allowlist column\n try {\n await client.execute(\n `ALTER TABLE app_secrets ADD COLUMN url_allowlist TEXT`,\n );\n } catch {\n // Column already exists — expected\n }\n\n // Additive migration: workspace-shared ciphertext. Keep the legacy\n // encrypted_value column so older app versions remain readable.\n try {\n await client.execute(\n `ALTER TABLE app_secrets ADD COLUMN shared_encrypted_value TEXT`,\n );\n } catch {\n // Column already exists — expected\n }\n })().catch((err) => {\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\n// ---------------------------------------------------------------------------\n// Encryption — see ./crypto.ts. Keep encrypted_value on the legacy app-key\n// format for mixed-version deployments, and add shared_encrypted_value when a\n// stable workspace key is configured so sibling apps can read the same row.\n// ---------------------------------------------------------------------------\n\n/**\n * Return the last 4 characters of a secret, with any leading characters\n * masked. Used to show a preview without leaking the value.\n */\nexport function last4(value: string): string {\n if (!value) return \"\";\n if (value.length <= 4) return \"••••\";\n return \"••••\" + value.slice(-4);\n}\n\n// ---------------------------------------------------------------------------\n// CRUD\n// ---------------------------------------------------------------------------\n\nexport interface SecretRef {\n key: string;\n scope: SecretScope;\n scopeId: string;\n}\n\nexport interface WriteSecretArgs extends SecretRef {\n value: string;\n /** Optional human-readable description (used for ad-hoc keys). */\n description?: string;\n /** Optional JSON-stringified array of allowed URL origins. */\n urlAllowlist?: string;\n}\n\n/**\n * Write (insert or update) a secret. The value is encrypted before being\n * stored — the caller's plaintext is never persisted. Returns the new\n * record's id.\n */\nexport async function writeAppSecret(args: WriteSecretArgs): Promise<string> {\n await ensureTable();\n const { key, value, scope, scopeId, description, urlAllowlist } = args;\n if (!key || !value || !scope || !scopeId) {\n throw new Error(\n \"writeAppSecret: key, value, scope, and scopeId are all required\",\n );\n }\n const client = getDbExec();\n const now = Date.now();\n // Dual-write during rollout: old readers continue using encrypted_value,\n // while new readers prefer the nullable shared ciphertext. An app-only\n // deployment leaves the shared column null; on an update, a writer without\n // shared key material clears any existing shared ciphertext rather than\n // preserving it (see the upsert SQL below for why).\n const encrypted = encryptLegacyValue(value);\n const sharedEncrypted = hasSharedSecretEncryptionKeyMaterial()\n ? encryptValue(value)\n : null;\n const id = randomUUID();\n\n // Atomic upsert by (scope, scope_id, key). Previously this was a\n // SELECT-then-branch (UPDATE if found, else INSERT): under concurrent\n // writers for the same key both could see \"no row\" and both attempt\n // INSERT, and the loser threw a raw UNIQUE(scope, scope_id, key)\n // constraint violation (a user-facing 500) instead of updating. A single\n // `INSERT ... ON CONFLICT DO UPDATE` closes that window — it's one\n // statement, so there's no gap between \"check\" and \"act\". `id` is\n // deliberately left out of the `DO UPDATE SET` list so an existing row\n // keeps its original id (any stored references stay stable); only a\n // genuinely new row gets the freshly generated `id`. This syntax is\n // portable across SQLite (UPSERT since 3.24) and Postgres.\n //\n // shared_encrypted_value is overwritten with `excluded.shared_encrypted_value`\n // (NULL when this writer lacks shared key material) rather than preserved\n // via COALESCE. Preserving an existing shared ciphertext across a value\n // update would let a sibling app silently decrypt a STALE value after the\n // owner rotates it — a material-less writer has no way to produce the new\n // shared ciphertext, so it must clear the old one instead of leaving it\n // pointing at data that's no longer current. Siblings then get an honest\n // cache miss (falling back to the legacy column or reporting missing) until\n // the owning app's next read repopulates shared_encrypted_value via\n // `populateSharedAppSecret`, which fills a NULL column or compare-and-swap\n // replaces the exact legacy ciphertext it just decrypted. A temporary miss\n // is safer than serving rotated-away plaintext.\n const upsertSql = `INSERT INTO app_secrets (id, scope, scope_id, key, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (scope, scope_id, key) DO UPDATE SET\n encrypted_value = excluded.encrypted_value,\n shared_encrypted_value = excluded.shared_encrypted_value,\n description = excluded.description,\n url_allowlist = excluded.url_allowlist,\n updated_at = excluded.updated_at`;\n const upsertArgs = [\n id,\n scope,\n scopeId,\n key,\n encrypted,\n sharedEncrypted,\n description ?? null,\n urlAllowlist ?? null,\n now,\n now,\n ];\n\n if (isPostgres()) {\n const { rows } = await client.execute({\n sql: `${upsertSql} RETURNING id`,\n args: upsertArgs,\n });\n return String(rows[0]?.id ?? id);\n }\n\n // SQLite: RETURNING support varies across better-sqlite3/libsql builds, so\n // (matching the convention elsewhere in this codebase, e.g.\n // integrations/pending-tasks-store.ts) re-read the id afterward instead of\n // relying on it. The row is guaranteed to exist at this point, so this is\n // a plain lookup rather than a TOCTOU-prone gate on the write itself.\n await client.execute({ sql: upsertSql, args: upsertArgs });\n const { rows } = await client.execute({\n sql: `SELECT id FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ? LIMIT 1`,\n args: [scope, scopeId, key],\n });\n return String(rows[0]?.id ?? id);\n}\n\nexport interface ReadSecretResult {\n value: string;\n last4: string;\n updatedAt: number;\n}\n\n/**\n * Read the shared-key format and retain compatibility with rows written before\n * app_secrets moved to its workspace-shared encryption boundary. The legacy\n * fallback is only useful when the current app owns the old row; sibling apps\n * will receive shared-key ciphertext after the next vault sync or update.\n */\ninterface DecryptedAppSecretValue {\n value: string;\n /** True when the app-scoped fallback decrypted encrypted_value. */\n usedLegacyKey: boolean;\n /** True when shared_encrypted_value needs to be created or refreshed. */\n needsSharedCiphertext: boolean;\n /**\n * Existing ciphertext that must still match before a refresh. Null means the\n * migration may only fill an empty shared column.\n */\n sharedCiphertextToReplace?: string | null;\n}\n\nfunction decryptAppSecretValue(\n encrypted: string,\n sharedEncrypted?: string | null,\n): DecryptedAppSecretValue {\n if (sharedEncrypted) {\n try {\n const decrypted = decryptValue(sharedEncrypted);\n return {\n value: decrypted.value,\n usedLegacyKey: false,\n needsSharedCiphertext: decrypted.needsReencrypt,\n sharedCiphertextToReplace: decrypted.needsReencrypt\n ? sharedEncrypted\n : undefined,\n };\n } catch {\n // Fall through to the legacy column. A partially migrated row may have\n // a stale shared ciphertext while the old app-key value is valid.\n }\n }\n try {\n const decrypted = decryptValue(encrypted);\n return {\n value: decrypted.value,\n usedLegacyKey: false,\n needsSharedCiphertext: true,\n sharedCiphertextToReplace: sharedEncrypted ?? null,\n };\n } catch {\n return {\n value: decryptLegacyValue(encrypted),\n usedLegacyKey: true,\n needsSharedCiphertext: true,\n sharedCiphertextToReplace: sharedEncrypted ?? null,\n };\n }\n}\n\n/**\n * Create or refresh the shared column without touching encrypted_value. This\n * is intentionally best-effort: a read must still succeed if a deployment's\n * DB role cannot update the row. The compare-and-swap predicate prevents a\n * concurrent writer from being overwritten, and leaving updated_at untouched\n * preserves the row's user-visible ordering/metadata.\n */\nasync function populateSharedAppSecret(\n id: unknown,\n value: string,\n sharedCiphertextToReplace: string | null,\n): Promise<void> {\n if (\n id === undefined ||\n id === null ||\n !hasSharedSecretEncryptionKeyMaterial()\n ) {\n return;\n }\n try {\n const encrypted = encryptValue(value);\n if (sharedCiphertextToReplace === null) {\n await getDbExec().execute({\n sql: `UPDATE app_secrets SET shared_encrypted_value = ? WHERE id = ? AND shared_encrypted_value IS NULL`,\n args: [encrypted, id],\n });\n } else {\n await getDbExec().execute({\n sql: `UPDATE app_secrets SET shared_encrypted_value = ? WHERE id = ? AND shared_encrypted_value = ?`,\n args: [encrypted, id, sharedCiphertextToReplace],\n });\n }\n } catch {\n // Migration is opportunistic. Preserve the successful read if the update\n // is unavailable due to a read-only role, transient DB failure, or race.\n }\n}\n\ntype AppSecretsReadQuery = { sql: string; args: unknown[] };\n\n/**\n * True only when the database says the app_secrets table itself is missing.\n * Other query failures must propagate unchanged: attempting schema bootstrap\n * for connectivity, permission, or syntax errors both hides the real failure\n * and can introduce DDL onto a latency-sensitive read path.\n */\nfunction isMissingAppSecretsTableError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const code = String((error as Error & { code?: unknown }).code ?? \"\");\n const message = error.message.toLowerCase();\n const namesAppSecrets = /(?:app_secrets|\"app_secrets\")/.test(message);\n\n if (code === \"42P01\") return namesAppSecrets;\n return (\n namesAppSecrets &&\n (message.includes(\"no such table\") ||\n (message.includes(\"relation\") && message.includes(\"does not exist\")))\n );\n}\n\n/** Execute a read without schema probes on the normal path. */\nasync function executeAppSecretsRead(query: AppSecretsReadQuery) {\n const client = getDbExec();\n try {\n return await client.execute(query);\n } catch (error) {\n if (!isMissingAppSecretsTableError(error)) throw error;\n await ensureTable();\n return client.execute(query);\n }\n}\n\n/**\n * Read a secret's plaintext value. Returns null when not found. The caller\n * is responsible for never logging the returned value.\n */\nexport async function readAppSecret(\n ref: SecretRef,\n): Promise<ReadSecretResult | null> {\n const { key, scope, scopeId } = ref;\n const { rows } = await executeAppSecretsRead({\n sql: `SELECT encrypted_value, shared_encrypted_value, updated_at, id FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ? LIMIT 1`,\n args: [scope, scopeId, key],\n });\n if (rows.length === 0) return null;\n try {\n const encrypted = rows[0].encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n rows[0].shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(\n rows[0].id,\n decrypted.value,\n decrypted.sharedCiphertextToReplace ?? null,\n );\n }\n return {\n value: decrypted.value,\n last4: last4(decrypted.value),\n updatedAt: Number(rows[0].updated_at ?? 0),\n };\n } catch {\n // Decryption failure — key rotated, tampered row, etc. Don't throw up the\n // stack in a way that could leak the ciphertext; just report missing.\n return null;\n }\n}\n\n/** Read several keys from one scope in a single database round trip. */\nexport async function readAppSecrets(args: {\n keys: readonly string[];\n scope: SecretScope;\n scopeId: string;\n}): Promise<Map<string, ReadSecretResult>> {\n const keys = [...new Set(args.keys.filter(Boolean))];\n if (keys.length === 0) return new Map();\n\n const placeholders = keys.map(() => \"?\").join(\", \");\n const { rows } = await executeAppSecretsRead({\n sql: `SELECT key, encrypted_value, shared_encrypted_value, updated_at, id FROM app_secrets WHERE scope = ? AND scope_id = ? AND key IN (${placeholders})`,\n args: [args.scope, args.scopeId, ...keys],\n });\n const results = new Map<string, ReadSecretResult>();\n for (const row of rows) {\n const key = String(row.key ?? \"\");\n if (!key) continue;\n try {\n const encrypted = row.encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n row.shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(\n row.id,\n decrypted.value,\n decrypted.sharedCiphertextToReplace ?? null,\n );\n }\n results.set(key, {\n value: decrypted.value,\n last4: last4(decrypted.value),\n updatedAt: Number(row.updated_at ?? 0),\n });\n } catch {\n // Match readAppSecret: corrupted or stale ciphertext behaves as missing.\n }\n }\n return results;\n}\n\n/**\n * Return just the metadata for a secret (no value). Used by the list route so\n * the UI can show the \"Set\" pill and last-4 without the decrypted value going\n * over the wire.\n */\nexport async function getAppSecretMeta(\n ref: SecretRef,\n): Promise<{ last4: string; updatedAt: number } | null> {\n const result = await readAppSecret(ref);\n if (!result) return null;\n return { last4: result.last4, updatedAt: result.updatedAt };\n}\n\nexport interface SecretMeta {\n key: string;\n scope: SecretScope;\n scopeId: string;\n last4: string;\n description: string | null;\n urlAllowlist: string[] | null;\n createdAt: number;\n updatedAt: number;\n}\n\n/**\n * Read a secret's metadata, including ad-hoc fields (description, allowlist),\n * without ever decrypting or returning the plaintext value. Used by the\n * ad-hoc list route and any UI that wants to render a key tile.\n */\nexport async function readAppSecretMeta(\n ref: SecretRef,\n): Promise<SecretMeta | null> {\n await ensureTable();\n const { key, scope, scopeId } = ref;\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ? LIMIT 1`,\n args: [scope, scopeId, key],\n });\n if (rows.length === 0) return null;\n const row = rows[0];\n let last4Value = \"\";\n try {\n const encrypted = row.encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n row.shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(\n row.id,\n decrypted.value,\n decrypted.sharedCiphertextToReplace ?? null,\n );\n }\n last4Value = last4(decrypted.value);\n } catch {\n last4Value = \"\";\n }\n return {\n key,\n scope,\n scopeId,\n last4: last4Value,\n description: (row.description as string | null) ?? null,\n urlAllowlist: parseAllowlist(row.url_allowlist as string | null),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\n/**\n * List all secrets for a given scope. Returns metadata only — values are\n * never decrypted or returned. Used by the ad-hoc list route to surface\n * user-created keys.\n */\nexport async function listAppSecretsForScope(\n scope: SecretScope,\n scopeId: string,\n): Promise<SecretMeta[]> {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, key, encrypted_value, shared_encrypted_value, description, url_allowlist, created_at, updated_at FROM app_secrets WHERE scope = ? AND scope_id = ? ORDER BY updated_at DESC`,\n args: [scope, scopeId],\n });\n const results: SecretMeta[] = [];\n for (const row of rows) {\n let last4Value = \"\";\n try {\n const encrypted = row.encrypted_value as string;\n const decrypted = decryptAppSecretValue(\n encrypted,\n row.shared_encrypted_value as string | null,\n );\n if (decrypted.needsSharedCiphertext) {\n await populateSharedAppSecret(\n row.id,\n decrypted.value,\n decrypted.sharedCiphertextToReplace ?? null,\n );\n }\n last4Value = last4(decrypted.value);\n } catch {\n last4Value = \"\";\n }\n results.push({\n key: row.key as string,\n scope,\n scopeId,\n last4: last4Value,\n description: (row.description as string | null) ?? null,\n urlAllowlist: parseAllowlist(row.url_allowlist as string | null),\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n });\n }\n return results;\n}\n\nfunction parseAllowlist(raw: string | null): string[] | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed) && parsed.every((v) => typeof v === \"string\")) {\n return parsed;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function deleteAppSecret(ref: SecretRef): Promise<boolean> {\n await ensureTable();\n const { key, scope, scopeId } = ref;\n const client = getDbExec();\n const { rowsAffected } = await client.execute({\n sql: `DELETE FROM app_secrets WHERE scope = ? AND scope_id = ? AND key = ?`,\n args: [scope, scopeId, key],\n });\n return rowsAffected > 0;\n}\n"]}
@@ -95,7 +95,7 @@ export function formatCapabilitySummary(peers, truncated, detailHint) {
95
95
  "",
96
96
  lines.join("\n\n"),
97
97
  "",
98
- "Delegate with call-agent: pass action + input for a listed action, or message for open-ended work. Prefer the app that owns the data over rebuilding its capability here.",
98
+ "Delegate with call-agent using a natural-language message by default. The receiving app owns interpretation and its local tools. Use action + input only for an exact bounded read with a fully known schema, never as a workaround for failed delegation. Prefer the app that owns the data over rebuilding its capability here.",
99
99
  ]
100
100
  .filter(Boolean)
101
101
  .join("\n");
@@ -1 +1 @@
1
- {"version":3,"file":"agent-capabilities.js","sourceRoot":"","sources":["../../src/server/agent-capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["import { A2AClient } from \"../a2a/client.js\";\nimport type { AgentCard, AgentSkill } from \"../a2a/types.js\";\nimport { type DiscoveredAgent } from \"./agent-discovery.js\";\nimport { getRequestUserEmail } from \"./request-context.js\";\n\n/** Matches the `<available-apps>` prompt block so both surfaces agree. */\nexport const MAX_APPS = 30;\nconst MAX_SKILLS_IN_SUMMARY = 8;\nconst MAX_SKILLS_IN_DETAIL = 60;\nconst MAX_DESCRIPTION_CHARS = 240;\nconst CARD_TIMEOUT_MS = 6_000;\nconst CARD_CONCURRENCY = 8;\n\nexport interface PeerCapabilities {\n agent: DiscoveredAgent;\n /** null distinguishes an unreachable card from a peer that exposes nothing. */\n skills: AgentSkill[] | null;\n cardDescription?: string;\n error?: string;\n /**\n * The full card from this same fetch, for callers that need more than\n * skills/description (e.g. the peer-probe route's name/securitySchemes).\n * Kept optional so existing consumers of this shape are unaffected.\n */\n card?: AgentCard;\n}\n\nfunction truncate(value: string, max: number): string {\n const collapsed = value.replace(/\\s+/g, \" \").trim();\n return collapsed.length > max ? `${collapsed.slice(0, max - 1)}…` : collapsed;\n}\n\nexport async function loadCapabilities(\n agent: DiscoveredAgent,\n): Promise<PeerCapabilities> {\n try {\n // Discover as ourselves. An anonymous card lists only publicly-safe\n // actions, which never overlap the set `actions/invoke` accepts, so an\n // unauthenticated probe reports every sibling as having no callable\n // actions and pushes the caller into open-ended delegation.\n let token: string | undefined;\n try {\n const { signA2AToken } = await import(\"../a2a/client.js\");\n const email = getRequestUserEmail();\n if (email) {\n token = await signA2AToken(email, undefined, undefined, {\n preferGlobalSecret: true,\n audience: new URL(agent.url).origin,\n });\n }\n } catch {\n // No signable identity (no secret, no session) — fall back to the\n // anonymous card rather than failing discovery outright.\n }\n const card = await new A2AClient(agent.url).getAgentCard({\n timeoutMs: CARD_TIMEOUT_MS,\n ...(token ? { token } : {}),\n });\n return {\n agent,\n skills: Array.isArray(card.skills) ? card.skills : [],\n cardDescription:\n typeof card.description === \"string\" ? card.description : undefined,\n card,\n };\n } catch (error) {\n return {\n agent,\n skills: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function loadAllCapabilities(\n agents: DiscoveredAgent[],\n): Promise<PeerCapabilities[]> {\n const results: PeerCapabilities[] = [];\n for (let i = 0; i < agents.length; i += CARD_CONCURRENCY) {\n results.push(\n ...(await Promise.all(\n agents.slice(i, i + CARD_CONCURRENCY).map(loadCapabilities),\n )),\n );\n }\n return results;\n}\n\nexport function purposeOf(peer: PeerCapabilities): string {\n // The manifest description comes from the app's own package.json and is\n // authored; the card description is a generic template for auto-mounted\n // apps, so it is only a fallback.\n const manifest = peer.agent.description?.trim();\n if (manifest) return truncate(manifest, MAX_DESCRIPTION_CHARS);\n const card = peer.cardDescription?.trim();\n return card\n ? truncate(card, MAX_DESCRIPTION_CHARS)\n : \"(no description published)\";\n}\n\n/**\n * `detailHint` differs per surface: the agent tool tells the model to call\n * itself again with an app id, the CLI tells the reader to pass `--app`.\n */\nexport function formatCapabilitySummary(\n peers: PeerCapabilities[],\n truncated: number,\n detailHint: (appId: string) => string,\n): string {\n const lines = peers.map((peer) => {\n const header = `### ${peer.agent.name} (${peer.agent.id})\\n${purposeOf(peer)}`;\n if (peer.skills === null) {\n return `${header}\\nCapabilities: could not read agent card (${truncate(peer.error ?? \"unreachable\", 120)}). Delegate with a natural-language message instead of a direct action.`;\n }\n if (peer.skills.length === 0) {\n return `${header}\\nCapabilities: exposes no directly callable actions. Delegate with a natural-language message via call-agent.`;\n }\n const shown = peer.skills.slice(0, MAX_SKILLS_IN_SUMMARY);\n const rest = peer.skills.length - shown.length;\n return `${header}\\nCallable actions: ${shown.map((skill) => skill.id).join(\", \")}${\n rest > 0 ? ` (+${rest} more — ${detailHint(peer.agent.id)})` : \"\"\n }`;\n });\n\n return [\n `${peers.length} other app${peers.length === 1 ? \"\" : \"s\"} reachable from this one over A2A.`,\n truncated > 0\n ? `(${truncated} additional app${truncated === 1 ? \"\" : \"s\"} not shown.)`\n : \"\",\n \"\",\n lines.join(\"\\n\\n\"),\n \"\",\n \"Delegate with call-agent: pass action + input for a listed action, or message for open-ended work. Prefer the app that owns the data over rebuilding its capability here.\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\n/**\n * Render a skill's `input` contract as `input: { field*: type, other?: type }`,\n * marking required fields with `*`. Returns undefined when the skill publishes\n * no schema, so callers fall back to the description alone.\n */\nfunction formatSkillInput(skill: AgentSkill): string | undefined {\n const schema = skill.inputSchema as\n | {\n properties?: Record<string, { type?: unknown }>;\n required?: unknown;\n }\n | undefined;\n const properties = schema?.properties;\n if (!properties || typeof properties !== \"object\") return undefined;\n const names = Object.keys(properties);\n if (names.length === 0) return \" — input: {} (no fields)\";\n\n const required = new Set(\n Array.isArray(schema?.required)\n ? schema.required.filter(\n (name): name is string => typeof name === \"string\",\n )\n : [],\n );\n const fields = names.map((name) => {\n const type = properties[name]?.type;\n const rendered = typeof type === \"string\" ? type : \"any\";\n return `${name}${required.has(name) ? \"*\" : \"?\"}: ${rendered}`;\n });\n return ` — input: { ${fields.join(\", \")} } (* = required)`;\n}\n\nexport function formatCapabilityDetail(\n peer: PeerCapabilities,\n callHint: (appId: string) => string,\n): string {\n const header = `## ${peer.agent.name} (${peer.agent.id})\\n${purposeOf(peer)}\\nURL: ${peer.agent.url}`;\n\n if (peer.skills === null) {\n return `${header}\\n\\nIts agent card could not be read (${truncate(peer.error ?? \"unreachable\", 200)}), so its callable actions are unknown. It may still answer a natural-language call-agent message.`;\n }\n if (peer.skills.length === 0) {\n return `${header}\\n\\nIt exposes no directly callable actions. Delegate with a natural-language call-agent message.`;\n }\n\n const shown = peer.skills.slice(0, MAX_SKILLS_IN_DETAIL);\n const rest = peer.skills.length - shown.length;\n const lines = shown.map((skill) => {\n const summary = skill.description\n ? truncate(skill.description, MAX_DESCRIPTION_CHARS)\n : skill.name || \"(no description)\";\n // Naming an action without its parameters is what makes a caller invoke it\n // with `{}` and fail on a required field, which reads as the sibling being\n // broken rather than as a malformed call.\n return `- ${skill.id}${skill.readOnly ? \"\" : \" (mutating)\"}: ${summary}${\n formatSkillInput(skill) ?? \"\"\n }`;\n });\n\n return [\n header,\n \"\",\n \"Callable actions:\",\n lines.join(\"\\n\"),\n rest > 0 ? `(+${rest} more not shown.)` : \"\",\n \"\",\n callHint(peer.agent.id),\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"agent-capabilities.js","sourceRoot":"","sources":["../../src/server/agent-capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["import { A2AClient } from \"../a2a/client.js\";\nimport type { AgentCard, AgentSkill } from \"../a2a/types.js\";\nimport { type DiscoveredAgent } from \"./agent-discovery.js\";\nimport { getRequestUserEmail } from \"./request-context.js\";\n\n/** Matches the `<available-apps>` prompt block so both surfaces agree. */\nexport const MAX_APPS = 30;\nconst MAX_SKILLS_IN_SUMMARY = 8;\nconst MAX_SKILLS_IN_DETAIL = 60;\nconst MAX_DESCRIPTION_CHARS = 240;\nconst CARD_TIMEOUT_MS = 6_000;\nconst CARD_CONCURRENCY = 8;\n\nexport interface PeerCapabilities {\n agent: DiscoveredAgent;\n /** null distinguishes an unreachable card from a peer that exposes nothing. */\n skills: AgentSkill[] | null;\n cardDescription?: string;\n error?: string;\n /**\n * The full card from this same fetch, for callers that need more than\n * skills/description (e.g. the peer-probe route's name/securitySchemes).\n * Kept optional so existing consumers of this shape are unaffected.\n */\n card?: AgentCard;\n}\n\nfunction truncate(value: string, max: number): string {\n const collapsed = value.replace(/\\s+/g, \" \").trim();\n return collapsed.length > max ? `${collapsed.slice(0, max - 1)}…` : collapsed;\n}\n\nexport async function loadCapabilities(\n agent: DiscoveredAgent,\n): Promise<PeerCapabilities> {\n try {\n // Discover as ourselves. An anonymous card lists only publicly-safe\n // actions, which never overlap the set `actions/invoke` accepts, so an\n // unauthenticated probe reports every sibling as having no callable\n // actions and pushes the caller into open-ended delegation.\n let token: string | undefined;\n try {\n const { signA2AToken } = await import(\"../a2a/client.js\");\n const email = getRequestUserEmail();\n if (email) {\n token = await signA2AToken(email, undefined, undefined, {\n preferGlobalSecret: true,\n audience: new URL(agent.url).origin,\n });\n }\n } catch {\n // No signable identity (no secret, no session) — fall back to the\n // anonymous card rather than failing discovery outright.\n }\n const card = await new A2AClient(agent.url).getAgentCard({\n timeoutMs: CARD_TIMEOUT_MS,\n ...(token ? { token } : {}),\n });\n return {\n agent,\n skills: Array.isArray(card.skills) ? card.skills : [],\n cardDescription:\n typeof card.description === \"string\" ? card.description : undefined,\n card,\n };\n } catch (error) {\n return {\n agent,\n skills: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function loadAllCapabilities(\n agents: DiscoveredAgent[],\n): Promise<PeerCapabilities[]> {\n const results: PeerCapabilities[] = [];\n for (let i = 0; i < agents.length; i += CARD_CONCURRENCY) {\n results.push(\n ...(await Promise.all(\n agents.slice(i, i + CARD_CONCURRENCY).map(loadCapabilities),\n )),\n );\n }\n return results;\n}\n\nexport function purposeOf(peer: PeerCapabilities): string {\n // The manifest description comes from the app's own package.json and is\n // authored; the card description is a generic template for auto-mounted\n // apps, so it is only a fallback.\n const manifest = peer.agent.description?.trim();\n if (manifest) return truncate(manifest, MAX_DESCRIPTION_CHARS);\n const card = peer.cardDescription?.trim();\n return card\n ? truncate(card, MAX_DESCRIPTION_CHARS)\n : \"(no description published)\";\n}\n\n/**\n * `detailHint` differs per surface: the agent tool tells the model to call\n * itself again with an app id, the CLI tells the reader to pass `--app`.\n */\nexport function formatCapabilitySummary(\n peers: PeerCapabilities[],\n truncated: number,\n detailHint: (appId: string) => string,\n): string {\n const lines = peers.map((peer) => {\n const header = `### ${peer.agent.name} (${peer.agent.id})\\n${purposeOf(peer)}`;\n if (peer.skills === null) {\n return `${header}\\nCapabilities: could not read agent card (${truncate(peer.error ?? \"unreachable\", 120)}). Delegate with a natural-language message instead of a direct action.`;\n }\n if (peer.skills.length === 0) {\n return `${header}\\nCapabilities: exposes no directly callable actions. Delegate with a natural-language message via call-agent.`;\n }\n const shown = peer.skills.slice(0, MAX_SKILLS_IN_SUMMARY);\n const rest = peer.skills.length - shown.length;\n return `${header}\\nCallable actions: ${shown.map((skill) => skill.id).join(\", \")}${\n rest > 0 ? ` (+${rest} more — ${detailHint(peer.agent.id)})` : \"\"\n }`;\n });\n\n return [\n `${peers.length} other app${peers.length === 1 ? \"\" : \"s\"} reachable from this one over A2A.`,\n truncated > 0\n ? `(${truncated} additional app${truncated === 1 ? \"\" : \"s\"} not shown.)`\n : \"\",\n \"\",\n lines.join(\"\\n\\n\"),\n \"\",\n \"Delegate with call-agent using a natural-language message by default. The receiving app owns interpretation and its local tools. Use action + input only for an exact bounded read with a fully known schema, never as a workaround for failed delegation. Prefer the app that owns the data over rebuilding its capability here.\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\n/**\n * Render a skill's `input` contract as `input: { field*: type, other?: type }`,\n * marking required fields with `*`. Returns undefined when the skill publishes\n * no schema, so callers fall back to the description alone.\n */\nfunction formatSkillInput(skill: AgentSkill): string | undefined {\n const schema = skill.inputSchema as\n | {\n properties?: Record<string, { type?: unknown }>;\n required?: unknown;\n }\n | undefined;\n const properties = schema?.properties;\n if (!properties || typeof properties !== \"object\") return undefined;\n const names = Object.keys(properties);\n if (names.length === 0) return \" — input: {} (no fields)\";\n\n const required = new Set(\n Array.isArray(schema?.required)\n ? schema.required.filter(\n (name): name is string => typeof name === \"string\",\n )\n : [],\n );\n const fields = names.map((name) => {\n const type = properties[name]?.type;\n const rendered = typeof type === \"string\" ? type : \"any\";\n return `${name}${required.has(name) ? \"*\" : \"?\"}: ${rendered}`;\n });\n return ` — input: { ${fields.join(\", \")} } (* = required)`;\n}\n\nexport function formatCapabilityDetail(\n peer: PeerCapabilities,\n callHint: (appId: string) => string,\n): string {\n const header = `## ${peer.agent.name} (${peer.agent.id})\\n${purposeOf(peer)}\\nURL: ${peer.agent.url}`;\n\n if (peer.skills === null) {\n return `${header}\\n\\nIts agent card could not be read (${truncate(peer.error ?? \"unreachable\", 200)}), so its callable actions are unknown. It may still answer a natural-language call-agent message.`;\n }\n if (peer.skills.length === 0) {\n return `${header}\\n\\nIt exposes no directly callable actions. Delegate with a natural-language call-agent message.`;\n }\n\n const shown = peer.skills.slice(0, MAX_SKILLS_IN_DETAIL);\n const rest = peer.skills.length - shown.length;\n const lines = shown.map((skill) => {\n const summary = skill.description\n ? truncate(skill.description, MAX_DESCRIPTION_CHARS)\n : skill.name || \"(no description)\";\n // Naming an action without its parameters is what makes a caller invoke it\n // with `{}` and fail on a required field, which reads as the sibling being\n // broken rather than as a malformed call.\n return `- ${skill.id}${skill.readOnly ? \"\" : \" (mutating)\"}: ${summary}${\n formatSkillInput(skill) ?? \"\"\n }`;\n });\n\n return [\n header,\n \"\",\n \"Callable actions:\",\n lines.join(\"\\n\"),\n rest > 0 ? `(+${rest} more not shown.)` : \"\",\n \"\",\n callHint(peer.agent.id),\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { type A2AArtifactResponseOptions, type A2AToolResultSummary } from "../../a2a/artifact-response.js";
2
2
  import type { EngineTool } from "../../agent/engine/types.js";
3
- import { type ActionEntry } from "../../agent/production-agent.js";
3
+ import { type ActionEntry, type AgentLoopOutcome } from "../../agent/production-agent.js";
4
4
  import { runAgentLoopDirectWithSoftTimeout } from "../../agent/run-loop-with-resume.js";
5
5
  import type { AgentChatEvent } from "../../agent/types.js";
6
6
  import type { AgentChatPluginOptions } from "./plugin-options.js";
@@ -57,11 +57,25 @@ export declare function buildAuthenticatedAgentA2ASkills(actions: Record<string,
57
57
  export declare function resolveArtifactBaseUrl(event: any | undefined): string | undefined;
58
58
  export declare function assembleA2AFinalResponse(events: readonly AgentChatEvent[], toolResults: readonly A2AToolResultSummary[], options?: A2AArtifactResponseOptions & {
59
59
  event?: any;
60
+ outcome?: AgentLoopOutcome;
60
61
  }): {
61
62
  responseText: string;
62
63
  finalText: string;
63
64
  };
64
65
  type A2AAgentLoopRunner = typeof runAgentLoopDirectWithSoftTimeout;
66
+ /**
67
+ * Delegated turns should do specialist work with the receiver's own tools,
68
+ * but must return a bounded caller-ready result. Interactive defaults allow
69
+ * extremely deep work (400 iterations / 20M cumulative input tokens), which
70
+ * made healthy Slides -> Analytics calls take 4-13 minutes and consume up to
71
+ * millions of input tokens as tool results accumulated. These defaults leave
72
+ * ample room for multi-source analysis while failing before a delegated turn
73
+ * can silently become an unbounded research session.
74
+ */
75
+ export declare const DEFAULT_DELEGATED_MAX_ITERATIONS = 80;
76
+ export declare const DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS = 750000;
77
+ export declare const DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS = 20000;
78
+ export declare const DELEGATED_AGENT_EXECUTION_CONTRACT = "\n<delegated-agent-contract>\nThis request was delegated by another app. You are the specialist owner of the work.\n- Interpret the caller's natural-language objective using your own instructions, skills, data dictionary, credentials, and tools. Choose providers, schemas, queries, and joins here; never ask the caller to invent SQL or source-specific implementation details for you.\n- Finish the objective autonomously in this delegated turn whenever a safe, reasonable default exists. Do not bounce the work back with UI-navigation requests, implementation questions, or intermediate status. Ask for input only when authorization, missing credentials, or a consequential user choice truly blocks progress.\n- When evidence is incomplete, return the best grounded partial answer with explicit coverage gaps instead of refusing or asking the caller to choose your source, filter, dashboard, or workflow.\n- Minimize round trips. Filter, join, aggregate, paginate, stage, and reduce large datasets inside your own tools rather than returning raw records or transcripts.\n- Return a concise caller-ready result with the answer, source and coverage details, relevant counts or IDs, caveats/partial gaps, and exact artifact URLs. Do not return tool transcripts or large raw payloads.\n</delegated-agent-contract>";
65
79
  export interface DelegatedAgentLoopTelemetry {
66
80
  runId: string;
67
81
  threadId: string | null;
@@ -86,13 +100,13 @@ interface DelegatedAgentLoopOptions {
86
100
  * template guarantees such as Analytics' requirement to query real data
87
101
  * before presenting metrics or exhaustive provider conclusions.
88
102
  */
89
- export declare function runA2AAgentLoop(runOptions: Parameters<A2AAgentLoopRunner>[0], pluginOptions: Pick<AgentChatPluginOptions, "finalResponseGuard" | "runSoftTimeoutMs">, timeoutOptions: Parameters<A2AAgentLoopRunner>[2], options?: DelegatedAgentLoopOptions): Promise<import("../../agent/production-agent.js").AgentLoopUsage>;
103
+ export declare function runA2AAgentLoop(runOptions: Parameters<A2AAgentLoopRunner>[0], pluginOptions: Pick<AgentChatPluginOptions, "delegatedRunPolicy" | "finalResponseGuard" | "runSoftTimeoutMs">, timeoutOptions: Parameters<A2AAgentLoopRunner>[2], options?: DelegatedAgentLoopOptions): Promise<import("../../agent/production-agent.js").AgentLoopUsage>;
90
104
  /**
91
105
  * Run the MCP-local ask_app turn with the same app-level response guard as
92
106
  * A2A. Keeping this seam shared prevents hosted MCP callers from bypassing
93
107
  * template guarantees when the request cannot use the self-A2A route.
94
108
  */
95
- export declare function runMCPAgentLoop(runOptions: Parameters<A2AAgentLoopRunner>[0], pluginOptions: Pick<AgentChatPluginOptions, "finalResponseGuard" | "runSoftTimeoutMs">, timeoutOptions: Parameters<A2AAgentLoopRunner>[2], options?: DelegatedAgentLoopOptions): Promise<import("../../agent/production-agent.js").AgentLoopUsage>;
109
+ export declare function runMCPAgentLoop(runOptions: Parameters<A2AAgentLoopRunner>[0], pluginOptions: Pick<AgentChatPluginOptions, "delegatedRunPolicy" | "finalResponseGuard" | "runSoftTimeoutMs">, timeoutOptions: Parameters<A2AAgentLoopRunner>[2], options?: DelegatedAgentLoopOptions): Promise<import("../../agent/production-agent.js").AgentLoopUsage>;
96
110
  /**
97
111
  * Keep delegated A2A turns on the same compact initial tool surface as
98
112
  * interactive chat. `tool-search` remains in the initial set, while the
@@ -1 +1 @@
1
- {"version":3,"file":"action-filters-a2a.d.ts","sourceRoot":"","sources":["../../../src/server/agent-chat/action-filters-a2a.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action-filters-a2a.d.ts","sourceRoot":"","sources":["../../../src/server/agent-chat/action-filters-a2a.ts"],"names":[],"mappings":"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"}
@@ -121,6 +121,10 @@ export function buildAuthenticatedAgentA2ASkills(actions, options) {
121
121
  name,
122
122
  description: entry.tool.description,
123
123
  publicAgent: entry.publicAgent,
124
+ // Every action in this set is read-only by construction. Omitting the
125
+ // flag made discovery label all of them "(mutating)", which pushes a
126
+ // caller away from invoking them and back into open-ended delegation.
127
+ readOnly: true,
124
128
  // Naming an action without its parameters is what makes a caller invoke
125
129
  // it with `{}` and fail on a required field.
126
130
  ...(entry.tool.parameters
@@ -147,7 +151,9 @@ export function resolveArtifactBaseUrl(event) {
147
151
  return undefined;
148
152
  }
149
153
  export function assembleA2AFinalResponse(events, toolResults, options = {}) {
150
- const terminalError = getA2ATerminalErrorEvent(events);
154
+ const terminalError = options.outcome
155
+ ? terminalErrorFromOutcome(options.outcome)
156
+ : getA2ATerminalErrorEvent(events);
151
157
  const responseText = collectFinalResponseTextFromAgentEvents(events, {
152
158
  fallbackToPreToolText: !terminalError,
153
159
  });
@@ -156,11 +162,43 @@ export function assembleA2AFinalResponse(events, toolResults, options = {}) {
156
162
  includeReferencedArtifacts: true,
157
163
  includePersistedArtifactMarker: true,
158
164
  });
159
- if (terminalError && !finalText.trim()) {
160
- throw new Error(formatA2ATerminalError(terminalError));
165
+ if (terminalError) {
166
+ const partialResult = finalText.trim()
167
+ ? `\n\nPartial verified results before the failure:\n${finalText.trim()}`
168
+ : "";
169
+ throw new Error(formatA2ATerminalError(terminalError) + partialResult);
170
+ }
171
+ if (!finalText.trim()) {
172
+ throw new Error("Agent completed without a response or verified artifact.\ncode: empty_agent_response");
161
173
  }
162
174
  return { responseText, finalText };
163
175
  }
176
+ function terminalErrorFromOutcome(outcome) {
177
+ if (outcome.state === "completed")
178
+ return null;
179
+ if (outcome.state === "failed") {
180
+ return {
181
+ type: "error",
182
+ error: outcome.message,
183
+ errorCode: outcome.code,
184
+ recoverable: outcome.retryable,
185
+ };
186
+ }
187
+ if (outcome.state === "input_required") {
188
+ return {
189
+ type: "error",
190
+ error: outcome.message,
191
+ errorCode: outcome.code,
192
+ recoverable: true,
193
+ };
194
+ }
195
+ return {
196
+ type: "error",
197
+ error: outcome.message ?? "Agent run was canceled.",
198
+ errorCode: "canceled",
199
+ recoverable: false,
200
+ };
201
+ }
164
202
  function getA2ATerminalErrorEvent(events) {
165
203
  for (let i = events.length - 1; i >= 0; i--) {
166
204
  const event = events[i];
@@ -170,6 +208,22 @@ function getA2ATerminalErrorEvent(events) {
170
208
  return null;
171
209
  if (event.type === "error")
172
210
  return event;
211
+ if (event.type === "tripwire") {
212
+ return {
213
+ type: "error",
214
+ error: event.reason || "Agent stopped at a delegated-run guardrail.",
215
+ errorCode: event.processor ? `tripwire:${event.processor}` : "tripwire",
216
+ recoverable: true,
217
+ };
218
+ }
219
+ if (event.type === "loop_limit") {
220
+ return {
221
+ type: "error",
222
+ error: "Agent stopped before finishing at the delegated-run step limit.",
223
+ errorCode: "loop_limit",
224
+ recoverable: true,
225
+ };
226
+ }
173
227
  if (event.type === "auto_continue") {
174
228
  return {
175
229
  type: "error",
@@ -189,10 +243,35 @@ function formatA2ATerminalError(event) {
189
243
  ].filter(Boolean);
190
244
  return parts.join("\n");
191
245
  }
246
+ /**
247
+ * Delegated turns should do specialist work with the receiver's own tools,
248
+ * but must return a bounded caller-ready result. Interactive defaults allow
249
+ * extremely deep work (400 iterations / 20M cumulative input tokens), which
250
+ * made healthy Slides -> Analytics calls take 4-13 minutes and consume up to
251
+ * millions of input tokens as tool results accumulated. These defaults leave
252
+ * ample room for multi-source analysis while failing before a delegated turn
253
+ * can silently become an unbounded research session.
254
+ */
255
+ export const DEFAULT_DELEGATED_MAX_ITERATIONS = 80;
256
+ export const DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS = 750_000;
257
+ export const DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS = 20_000;
258
+ export const DELEGATED_AGENT_EXECUTION_CONTRACT = `
259
+ <delegated-agent-contract>
260
+ This request was delegated by another app. You are the specialist owner of the work.
261
+ - Interpret the caller's natural-language objective using your own instructions, skills, data dictionary, credentials, and tools. Choose providers, schemas, queries, and joins here; never ask the caller to invent SQL or source-specific implementation details for you.
262
+ - Finish the objective autonomously in this delegated turn whenever a safe, reasonable default exists. Do not bounce the work back with UI-navigation requests, implementation questions, or intermediate status. Ask for input only when authorization, missing credentials, or a consequential user choice truly blocks progress.
263
+ - When evidence is incomplete, return the best grounded partial answer with explicit coverage gaps instead of refusing or asking the caller to choose your source, filter, dashboard, or workflow.
264
+ - Minimize round trips. Filter, join, aggregate, paginate, stage, and reduce large datasets inside your own tools rather than returning raw records or transcripts.
265
+ - Return a concise caller-ready result with the answer, source and coverage details, relevant counts or IDs, caveats/partial gaps, and exact artifact URLs. Do not return tool transcripts or large raw payloads.
266
+ </delegated-agent-contract>`;
192
267
  async function runDelegatedAgentLoop(runOptions, pluginOptions, timeoutOptions, options) {
193
268
  const runner = options.runner ?? runAgentLoopDirectWithSoftTimeout;
269
+ const policy = pluginOptions.delegatedRunPolicy;
270
+ const configuredHardToolResultCap = runOptions.toolLimits?.hardMaxResultChars;
271
+ const delegatedHardToolResultCap = policy?.maxToolResultChars ?? DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS;
194
272
  const resolvedRunOptions = {
195
273
  ...runOptions,
274
+ systemPrompt: runOptions.systemPrompt + DELEGATED_AGENT_EXECUTION_CONTRACT,
196
275
  // Delegated runs resolve their own model and do not pass through the
197
276
  // interactive request handler's output-token setup. Use the same
198
277
  // model-aware headroom here so reasoning models (notably GPT-5.x) do
@@ -202,6 +281,18 @@ async function runDelegatedAgentLoop(runOptions, pluginOptions, timeoutOptions,
202
281
  resolveMainChatMaxOutputTokens(runOptions.model),
203
282
  reasoningEffort: runOptions.reasoningEffort ??
204
283
  resolveAgentRequestReasoningEffort({ model: runOptions.model }),
284
+ maxIterations: runOptions.maxIterations ??
285
+ policy?.maxIterations ??
286
+ DEFAULT_DELEGATED_MAX_ITERATIONS,
287
+ maxRunInputTokens: runOptions.maxRunInputTokens ??
288
+ policy?.maxRunInputTokens ??
289
+ DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS,
290
+ toolLimits: {
291
+ ...(runOptions.toolLimits ?? {}),
292
+ hardMaxResultChars: typeof configuredHardToolResultCap === "number"
293
+ ? Math.min(configuredHardToolResultCap, delegatedHardToolResultCap)
294
+ : delegatedHardToolResultCap,
295
+ },
205
296
  finalResponseGuard: pluginOptions.finalResponseGuard,
206
297
  };
207
298
  const execute = (loopOptions = resolvedRunOptions) => runner(loopOptions, pluginOptions.runSoftTimeoutMs, timeoutOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"action-filters-a2a.js","sourceRoot":"","sources":["../../../src/server/agent-chat/action-filters-a2a.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EACL,sBAAsB,GAGvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,uCAAuC,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EACL,wBAAwB,EACxB,kCAAkC,GAEnC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,iCAAiC,EAAE,MAAM,qCAAqC,CAAC;AAExF,OAAO,EACL,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,8EAA8E;AAC9E,4EAA4E;AAC5E,uEAAuE;AACvE,oCAAoC;AACpC,8EAA8E;AAE9E,MAAM,UAAU,qBAAqB,CACnC,OAAoC;IAEpC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CACvE,CAAC;AACJ,CAAC;AAED;;;;2DAI2D;AAC3D,MAAM,UAAU,gBAAgB,CAC9B,OAAoC;IAEpC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,CACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,OAAoC;IAEpC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;QACjC,OAAO,CACL,MAAM,EAAE,MAAM,KAAK,IAAI;YACvB,MAAM,CAAC,QAAQ,KAAK,IAAI;YACxB,MAAM,CAAC,YAAY,KAAK,IAAI;YAC5B,MAAM,CAAC,eAAe,KAAK,IAAI,CAChC,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IACjD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,UAElB,CAAC;IACd,MAAM,UAAU,GAAG,UAAU,EAAE,UAAU,CAAC;IAC1C,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE;QACzD,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;QAC1B,MAAM,aAAa,GACjB,IAAI,KAAK,QAAQ;YACjB,IAAI,KAAK,SAAS;YAClB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnD,OAAO,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,aAAa,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAoC,EACpC,OAA4E;IAE5E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,kBAAkB,KAAK,MAAM,CAAC;IAExE,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC;QACnC,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YACjB,CAAC,SAAS;gBACR,yBAAyB,CAAC,KAAK,CAAC;gBAChC,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,MAAM,eAAe,GACnB,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;QACpE,OAAO,CACL,QAAQ;YACR,eAAe;YACf,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YACjB,KAAK,CAAC,SAAS,KAAK,KAAK;YACzB,KAAK,CAAC,QAAQ,KAAK,IAAI;YACvB,QAAQ,EAAE,MAAM,KAAK,IAAI;YACzB,QAAQ,CAAC,QAAQ,KAAK,IAAI;YAC1B,QAAQ,CAAC,YAAY,KAAK,IAAI;YAC9B,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC;YACpE,QAAQ,CAAC,eAAe,KAAK,IAAI,CAClC,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAAoC;IAQpC,OAAO,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAC1D,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAClB,EAAE,EAAE,IAAI;QACR,IAAI;QACJ,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW;QACnC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU;YACvB,CAAC,CAAC;gBACE,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,UAGvB;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gCAAgC,CAC9C,OAAoC,EACpC,OAA4E;IAQ5E,OAAO,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CACjE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAClB,EAAE,EAAE,IAAI;QACR,IAAI;QACJ,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW;QACnC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,wEAAwE;QACxE,6CAA6C;QAC7C,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU;YACvB,CAAC,CAAC;gBACE,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,UAGvB;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAsB;IAEtB,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,OAAO;QACnB,OAAO,CAAC,GAAG,CAAC,GAAG;QACf,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9B,IAAI,OAAO;QAAE,OAAO,yBAAyB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,mBAAmB,CAAC,IAAI,OAAO,CAAC;QAC/D,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACtC,IAAI,IAAI;YAAE,OAAO,yBAAyB,CAAC,GAAG,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,MAAiC,EACjC,WAA4C,EAC5C,OAAO,GAAiD,EAAE;IAE1D,MAAM,aAAa,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,YAAY,GAAG,uCAAuC,CAAC,MAAM,EAAE;QACnE,qBAAqB,EAAE,CAAC,aAAa;KACtC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,sBAAsB,CAAC,YAAY,EAAE,CAAC,GAAG,WAAW,CAAC,EAAE;QACvE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC;QACjE,0BAA0B,EAAE,IAAI;QAChC,8BAA8B,EAAE,IAAI;KACrC,CAAC,CAAC;IACH,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,wBAAwB,CAC/B,MAAiC;IAEjC,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QACrC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACnC,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,mCAAmC,KAAK,CAAC,MAAM,IAAI;gBAC1D,SAAS,EAAE,KAAK,CAAC,MAAM;gBACvB,WAAW,EAAE,IAAI;aAClB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAAiD;IAEjD,MAAM,KAAK,GAAG;QACZ,KAAK,CAAC,KAAK,IAAI,iDAAiD;QAChE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;QACjD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;KACjD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAsBD,KAAK,UAAU,qBAAqB,CAClC,UAA6C,EAC7C,aAGC,EACD,cAAiD,EACjD,OAAkC;IAElC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,iCAAiC,CAAC;IACnE,MAAM,kBAAkB,GAAG;QACzB,GAAG,UAAU;QACb,qEAAqE;QACrE,iEAAiE;QACjE,qEAAqE;QACrE,oEAAoE;QACpE,wEAAwE;QACxE,eAAe,EACb,UAAU,CAAC,eAAe;YAC1B,8BAA8B,CAAC,UAAU,CAAC,KAAK,CAAC;QAClD,eAAe,EACb,UAAU,CAAC,eAAe;YAC1B,kCAAkC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC;QACjE,kBAAkB,EAAE,aAAa,CAAC,kBAAkB;KACrD,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,WAAW,GAAG,kBAAkB,EAAE,EAAE,CACnD,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;IAEtE,IAAI,CAAC,OAAO,CAAC,SAAS;QAAE,OAAO,OAAO,EAAE,CAAC;IAEzC,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,GACnD,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC;YACpB,OAAO,MAAM,mBAAmB,CAAC;gBAC/B,YAAY,EAAE,CAAC,WAAW,EAAE,EAAE,CAC5B,OAAO,CACL,WAC2B,CAC5B;gBACH,QAAQ,EAAE,kBAAkB;gBAC5B,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK;gBAC9B,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ;gBACpC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM;gBAChC,MAAM;gBACN,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,UAAU;aACzC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,0EAA0E;QAC1E,IAAI,YAAY;YAAE,MAAM,KAAK,CAAC;IAChC,CAAC;IACD,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,UAA6C,EAC7C,aAGC,EACD,cAAiD,EACjD,OAAO,GAA8B,EAAE;IAEvC,OAAO,qBAAqB,CAC1B,UAAU,EACV,aAAa,EACb,cAAc,EACd,OAAO,CACR,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,UAA6C,EAC7C,aAGC,EACD,cAAiD,EACjD,OAAO,GAA8B,EAAE;IAEvC,OAAO,qBAAqB,CAC1B,UAAU,EACV,aAAa,EACb,cAAc,EACd,OAAO,CACR,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,cAA4B,EAC5B,gBAA2B;IAE3B,OAAO;QACL,KAAK,EAAE,wBAAwB,CAAC,cAAc,EAAE,gBAAgB,CAAC;QACjE,cAAc;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,eAA4C,EAC5C,UAAqB;IAErB,OAAO,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AACpD,CAAC","sourcesContent":["import { getHeader } from \"h3\";\n\nimport {\n appendA2AArtifactLinks,\n type A2AArtifactResponseOptions,\n type A2AToolResultSummary,\n} from \"../../a2a/artifact-response.js\";\nimport { collectFinalResponseTextFromAgentEvents } from \"../../a2a/response-text.js\";\nimport { resolveMainChatMaxOutputTokens } from \"../../agent/engine/output-tokens.js\";\nimport type { EngineTool } from \"../../agent/engine/types.js\";\nimport {\n filterInitialEngineTools,\n resolveAgentRequestReasoningEffort,\n type ActionEntry,\n} from \"../../agent/production-agent.js\";\nimport { runAgentLoopDirectWithSoftTimeout } from \"../../agent/run-loop-with-resume.js\";\nimport type { AgentChatEvent } from \"../../agent/types.js\";\nimport {\n isAuthenticatedReadAction,\n isAutoReadExcludedActionName,\n} from \"../../mcp/build-server.js\";\nimport { withConfiguredAppBasePath } from \"../app-base-path.js\";\nimport type { AgentChatPluginOptions } from \"./plugin-options.js\";\n\n// ---------------------------------------------------------------------------\n// Action-visibility filters (read-only / agent-exposed / public-agent-safe)\n// and the A2A (agent-to-agent) final-response assembly + delegated-run\n// helpers that share those filters.\n// ---------------------------------------------------------------------------\n\nexport function filterReadOnlyActions(\n actions: Record<string, ActionEntry>,\n): Record<string, ActionEntry> {\n return Object.fromEntries(\n Object.entries(actions).filter(([, entry]) => entry.readOnly === true),\n );\n}\n\n/** Drop actions that opted out of agent exposure via `agentTool: false`. They\n * remain callable from the frontend / HTTP (mounted separately from this\n * agent tool surface — see `httpActions`) but never appear in any agent tool\n * list (in-app assistant, MCP, A2A, job/trigger runners) or actions prompt.\n * Default-allow: only an explicit `false` is excluded. */\nexport function filterAgentTools(\n actions: Record<string, ActionEntry>,\n): Record<string, ActionEntry> {\n return Object.fromEntries(\n Object.entries(actions).filter(([, entry]) => entry.agentTool !== false),\n );\n}\n\nexport function filterPublicAgentActions(\n actions: Record<string, ActionEntry>,\n): Record<string, ActionEntry> {\n return Object.fromEntries(\n Object.entries(actions).filter(([, entry]) => {\n const config = entry.publicAgent;\n return (\n config?.expose === true &&\n config.readOnly === true &&\n config.requiresAuth !== true &&\n config.isConsequential !== true\n );\n }),\n );\n}\n\n/**\n * Input fields that unambiguously carry a program the receiver executes.\n *\n * Deliberately excludes `query`: across the templates that field is nearly\n * always natural-language search text (Brain's `search-everything`,\n * `search-knowledge`), and blocking it would break exactly the ask-don't-instruct\n * calls this rule exists to encourage.\n */\nconst RAW_QUERY_INPUT_FIELDS = new Set([\"sql\", \"code\", \"script\", \"expression\"]);\n\n/**\n * True when an action takes a free-form query or program as input — raw SQL, a\n * code body, an arbitrary expression.\n *\n * Such an action must not be sibling-invocable over A2A. The app that owns the\n * data owns its schema, data dictionary, skills, and reference queries; a\n * calling app has none of that, so letting it pass SQL means every caller\n * reimplements the owner's schema knowledge badly and silently rots when the\n * owner's shape changes. Callers ask the owning app a question; the owner\n * forms the query. Set `publicAgent.allowRawQueryInput` to opt a specific\n * action out of this rule.\n */\nexport function hasRawQueryInput(entry: ActionEntry): boolean {\n const parameters = entry.tool?.parameters as\n | { properties?: Record<string, { type?: unknown }> }\n | undefined;\n const properties = parameters?.properties;\n if (!properties || typeof properties !== \"object\") return false;\n return Object.entries(properties).some(([field, schema]) => {\n const type = schema?.type;\n const acceptsString =\n type === \"string\" ||\n type === undefined ||\n (Array.isArray(type) && type.includes(\"string\"));\n return RAW_QUERY_INPUT_FIELDS.has(field.toLowerCase()) && acceptsString;\n });\n}\n\n/**\n * Direct A2A action calls share the authenticated external-agent policy with\n * MCP, but remain stricter: only explicitly exposed, authenticated read-only\n * actions can skip the receiver's model loop, and never one that takes a raw\n * query the caller wrote.\n */\nexport function filterDirectA2AActions(\n actions: Record<string, ActionEntry>,\n options: Pick<AgentChatPluginOptions, \"connectorCatalog\" | \"externalAgents\">,\n): Record<string, ActionEntry> {\n const catalog = new Set(options.connectorCatalog ?? []);\n const denied = new Set(options.externalAgents?.denyActions ?? []);\n const autoReads = options.externalAgents?.authenticatedReads === \"auto\";\n\n return Object.fromEntries(\n Object.entries(actions).filter(([name, entry]) => {\n const exposure = entry.publicAgent;\n const selected =\n catalog.has(name) ||\n (autoReads &&\n isAuthenticatedReadAction(entry) &&\n !isAutoReadExcludedActionName(name));\n const rawQueryAllowed =\n !hasRawQueryInput(entry) || exposure?.allowRawQueryInput === true;\n return (\n selected &&\n rawQueryAllowed &&\n !denied.has(name) &&\n entry.agentTool !== false &&\n entry.readOnly === true &&\n exposure?.expose === true &&\n exposure.readOnly === true &&\n exposure.requiresAuth === true &&\n (entry.needsApproval === undefined || entry.needsApproval === false) &&\n exposure.isConsequential !== true\n );\n }),\n );\n}\n\nexport function buildPublicAgentA2ASkills(\n actions: Record<string, ActionEntry>,\n): Array<{\n id: string;\n name: string;\n description: string;\n publicAgent: ActionEntry[\"publicAgent\"];\n inputSchema?: Record<string, unknown>;\n}> {\n return Object.entries(filterPublicAgentActions(actions)).map(\n ([name, entry]) => ({\n id: name,\n name,\n description: entry.tool.description,\n publicAgent: entry.publicAgent,\n ...(entry.tool.parameters\n ? {\n inputSchema: entry.tool.parameters as unknown as Record<\n string,\n unknown\n >,\n }\n : {}),\n }),\n );\n}\n\n/**\n * Skills for a caller with a verified A2A identity: exactly what\n * `filterDirectA2AActions` will execute. Kept separate from\n * `buildPublicAgentA2ASkills` because the public card may only name actions\n * with `requiresAuth !== true` while direct invocation requires\n * `requiresAuth === true` — advertising the public set alone tells siblings\n * an app has nothing callable when it does.\n */\nexport function buildAuthenticatedAgentA2ASkills(\n actions: Record<string, ActionEntry>,\n options: Pick<AgentChatPluginOptions, \"connectorCatalog\" | \"externalAgents\">,\n): Array<{\n id: string;\n name: string;\n description: string;\n publicAgent: ActionEntry[\"publicAgent\"];\n inputSchema?: Record<string, unknown>;\n}> {\n return Object.entries(filterDirectA2AActions(actions, options)).map(\n ([name, entry]) => ({\n id: name,\n name,\n description: entry.tool.description,\n publicAgent: entry.publicAgent,\n // Naming an action without its parameters is what makes a caller invoke\n // it with `{}` and fail on a required field.\n ...(entry.tool.parameters\n ? {\n inputSchema: entry.tool.parameters as unknown as Record<\n string,\n unknown\n >,\n }\n : {}),\n }),\n );\n}\n\nexport function resolveArtifactBaseUrl(\n event: any | undefined,\n): string | undefined {\n const fromEnv =\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n process.env.BETTER_AUTH_URL;\n if (fromEnv) return withConfiguredAppBasePath(String(fromEnv));\n\n try {\n const proto = getHeader(event, \"x-forwarded-proto\") || \"https\";\n const host = getHeader(event, \"host\");\n if (host) return withConfiguredAppBasePath(`${proto}://${host}`);\n } catch {}\n\n return undefined;\n}\n\nexport function assembleA2AFinalResponse(\n events: readonly AgentChatEvent[],\n toolResults: readonly A2AToolResultSummary[],\n options: A2AArtifactResponseOptions & { event?: any } = {},\n): { responseText: string; finalText: string } {\n const terminalError = getA2ATerminalErrorEvent(events);\n const responseText = collectFinalResponseTextFromAgentEvents(events, {\n fallbackToPreToolText: !terminalError,\n });\n const finalText = appendA2AArtifactLinks(responseText, [...toolResults], {\n baseUrl: options.baseUrl ?? resolveArtifactBaseUrl(options.event),\n includeReferencedArtifacts: true,\n includePersistedArtifactMarker: true,\n });\n if (terminalError && !finalText.trim()) {\n throw new Error(formatA2ATerminalError(terminalError));\n }\n return { responseText, finalText };\n}\n\nfunction getA2ATerminalErrorEvent(\n events: readonly AgentChatEvent[],\n): Extract<AgentChatEvent, { type: \"error\" }> | null {\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.type === \"clear\") continue;\n if (event.type === \"done\") return null;\n if (event.type === \"error\") return event;\n if (event.type === \"auto_continue\") {\n return {\n type: \"error\",\n error: `Agent stopped before finishing (${event.reason}).`,\n errorCode: event.reason,\n recoverable: true,\n };\n }\n }\n return null;\n}\n\nfunction formatA2ATerminalError(\n event: Extract<AgentChatEvent, { type: \"error\" }>,\n): string {\n const parts = [\n event.error || \"Agent failed before producing a final response.\",\n event.errorCode ? `code: ${event.errorCode}` : \"\",\n event.details ? `details: ${event.details}` : \"\",\n ].filter(Boolean);\n return parts.join(\"\\n\");\n}\n\ntype A2AAgentLoopRunner = typeof runAgentLoopDirectWithSoftTimeout;\n\nexport interface DelegatedAgentLoopTelemetry {\n runId: string;\n threadId: string | null;\n userId: string | null;\n delegation: {\n protocol: \"a2a\" | \"mcp\";\n callerApp?: string;\n taskId?: string;\n parentRunId?: string;\n parentTurnId?: string;\n };\n}\n\ninterface DelegatedAgentLoopOptions {\n runner?: A2AAgentLoopRunner;\n telemetry?: DelegatedAgentLoopTelemetry;\n}\n\nasync function runDelegatedAgentLoop(\n runOptions: Parameters<A2AAgentLoopRunner>[0],\n pluginOptions: Pick<\n AgentChatPluginOptions,\n \"finalResponseGuard\" | \"runSoftTimeoutMs\"\n >,\n timeoutOptions: Parameters<A2AAgentLoopRunner>[2],\n options: DelegatedAgentLoopOptions,\n) {\n const runner = options.runner ?? runAgentLoopDirectWithSoftTimeout;\n const resolvedRunOptions = {\n ...runOptions,\n // Delegated runs resolve their own model and do not pass through the\n // interactive request handler's output-token setup. Use the same\n // model-aware headroom here so reasoning models (notably GPT-5.x) do\n // not spend the small internal default entirely on reasoning before\n // emitting a tool call or answer. Preserve explicit test/caller values.\n maxOutputTokens:\n runOptions.maxOutputTokens ??\n resolveMainChatMaxOutputTokens(runOptions.model),\n reasoningEffort:\n runOptions.reasoningEffort ??\n resolveAgentRequestReasoningEffort({ model: runOptions.model }),\n finalResponseGuard: pluginOptions.finalResponseGuard,\n };\n const execute = (loopOptions = resolvedRunOptions) =>\n runner(loopOptions, pluginOptions.runSoftTimeoutMs, timeoutOptions);\n\n if (!options.telemetry) return execute();\n\n let instrumented = false;\n try {\n const { getObservabilityConfig, instrumentAgentLoop } =\n await import(\"../../observability/traces.js\");\n const config = await getObservabilityConfig();\n if (config.enabled) {\n instrumented = true;\n return await instrumentAgentLoop({\n runAgentLoop: (loopOptions) =>\n execute(\n loopOptions as Parameters<A2AAgentLoopRunner>[0] &\n typeof resolvedRunOptions,\n ),\n loopOpts: resolvedRunOptions,\n runId: options.telemetry.runId,\n threadId: options.telemetry.threadId,\n userId: options.telemetry.userId,\n config,\n delegation: options.telemetry.delegation,\n });\n }\n } catch (error) {\n // Match interactive chat: setup failures fall through, but a failure from\n // inside an instrumented agent loop is the real run failure and rethrows.\n if (instrumented) throw error;\n }\n return execute();\n}\n\n/**\n * Run an A2A-delegated agent turn with the same final-response guard used by\n * the app's interactive chat surface.\n *\n * Keeping this in one helper prevents delegated calls from silently bypassing\n * template guarantees such as Analytics' requirement to query real data\n * before presenting metrics or exhaustive provider conclusions.\n */\nexport function runA2AAgentLoop(\n runOptions: Parameters<A2AAgentLoopRunner>[0],\n pluginOptions: Pick<\n AgentChatPluginOptions,\n \"finalResponseGuard\" | \"runSoftTimeoutMs\"\n >,\n timeoutOptions: Parameters<A2AAgentLoopRunner>[2],\n options: DelegatedAgentLoopOptions = {},\n) {\n return runDelegatedAgentLoop(\n runOptions,\n pluginOptions,\n timeoutOptions,\n options,\n );\n}\n\n/**\n * Run the MCP-local ask_app turn with the same app-level response guard as\n * A2A. Keeping this seam shared prevents hosted MCP callers from bypassing\n * template guarantees when the request cannot use the self-A2A route.\n */\nexport function runMCPAgentLoop(\n runOptions: Parameters<A2AAgentLoopRunner>[0],\n pluginOptions: Pick<\n AgentChatPluginOptions,\n \"finalResponseGuard\" | \"runSoftTimeoutMs\"\n >,\n timeoutOptions: Parameters<A2AAgentLoopRunner>[2],\n options: DelegatedAgentLoopOptions = {},\n) {\n return runDelegatedAgentLoop(\n runOptions,\n pluginOptions,\n timeoutOptions,\n options,\n );\n}\n\n/**\n * Keep delegated A2A turns on the same compact initial tool surface as\n * interactive chat. `tool-search` remains in the initial set, while the\n * complete registry is supplied separately so the run loop can load a matched\n * schema after a tool-search result.\n */\nexport function createA2AEngineToolSurface(\n availableTools: EngineTool[],\n initialToolNames?: string[],\n): { tools: EngineTool[]; availableTools: EngineTool[] } {\n return {\n tools: filterInitialEngineTools(availableTools, initialToolNames),\n availableTools,\n };\n}\n\nexport function resolveInitialToolNames(\n templateActions: Record<string, ActionEntry>,\n configured?: string[],\n): string[] {\n return configured ?? Object.keys(templateActions);\n}\n"]}
1
+ {"version":3,"file":"action-filters-a2a.js","sourceRoot":"","sources":["../../../src/server/agent-chat/action-filters-a2a.ts"],"names":[],"mappings":"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","sourcesContent":["import { getHeader } from \"h3\";\n\nimport {\n appendA2AArtifactLinks,\n type A2AArtifactResponseOptions,\n type A2AToolResultSummary,\n} from \"../../a2a/artifact-response.js\";\nimport { collectFinalResponseTextFromAgentEvents } from \"../../a2a/response-text.js\";\nimport { resolveMainChatMaxOutputTokens } from \"../../agent/engine/output-tokens.js\";\nimport type { EngineTool } from \"../../agent/engine/types.js\";\nimport {\n filterInitialEngineTools,\n resolveAgentRequestReasoningEffort,\n type ActionEntry,\n type AgentLoopOutcome,\n} from \"../../agent/production-agent.js\";\nimport { runAgentLoopDirectWithSoftTimeout } from \"../../agent/run-loop-with-resume.js\";\nimport type { AgentChatEvent } from \"../../agent/types.js\";\nimport {\n isAuthenticatedReadAction,\n isAutoReadExcludedActionName,\n} from \"../../mcp/build-server.js\";\nimport { withConfiguredAppBasePath } from \"../app-base-path.js\";\nimport type { AgentChatPluginOptions } from \"./plugin-options.js\";\n\n// ---------------------------------------------------------------------------\n// Action-visibility filters (read-only / agent-exposed / public-agent-safe)\n// and the A2A (agent-to-agent) final-response assembly + delegated-run\n// helpers that share those filters.\n// ---------------------------------------------------------------------------\n\nexport function filterReadOnlyActions(\n actions: Record<string, ActionEntry>,\n): Record<string, ActionEntry> {\n return Object.fromEntries(\n Object.entries(actions).filter(([, entry]) => entry.readOnly === true),\n );\n}\n\n/** Drop actions that opted out of agent exposure via `agentTool: false`. They\n * remain callable from the frontend / HTTP (mounted separately from this\n * agent tool surface — see `httpActions`) but never appear in any agent tool\n * list (in-app assistant, MCP, A2A, job/trigger runners) or actions prompt.\n * Default-allow: only an explicit `false` is excluded. */\nexport function filterAgentTools(\n actions: Record<string, ActionEntry>,\n): Record<string, ActionEntry> {\n return Object.fromEntries(\n Object.entries(actions).filter(([, entry]) => entry.agentTool !== false),\n );\n}\n\nexport function filterPublicAgentActions(\n actions: Record<string, ActionEntry>,\n): Record<string, ActionEntry> {\n return Object.fromEntries(\n Object.entries(actions).filter(([, entry]) => {\n const config = entry.publicAgent;\n return (\n config?.expose === true &&\n config.readOnly === true &&\n config.requiresAuth !== true &&\n config.isConsequential !== true\n );\n }),\n );\n}\n\n/**\n * Input fields that unambiguously carry a program the receiver executes.\n *\n * Deliberately excludes `query`: across the templates that field is nearly\n * always natural-language search text (Brain's `search-everything`,\n * `search-knowledge`), and blocking it would break exactly the ask-don't-instruct\n * calls this rule exists to encourage.\n */\nconst RAW_QUERY_INPUT_FIELDS = new Set([\"sql\", \"code\", \"script\", \"expression\"]);\n\n/**\n * True when an action takes a free-form query or program as input — raw SQL, a\n * code body, an arbitrary expression.\n *\n * Such an action must not be sibling-invocable over A2A. The app that owns the\n * data owns its schema, data dictionary, skills, and reference queries; a\n * calling app has none of that, so letting it pass SQL means every caller\n * reimplements the owner's schema knowledge badly and silently rots when the\n * owner's shape changes. Callers ask the owning app a question; the owner\n * forms the query. Set `publicAgent.allowRawQueryInput` to opt a specific\n * action out of this rule.\n */\nexport function hasRawQueryInput(entry: ActionEntry): boolean {\n const parameters = entry.tool?.parameters as\n | { properties?: Record<string, { type?: unknown }> }\n | undefined;\n const properties = parameters?.properties;\n if (!properties || typeof properties !== \"object\") return false;\n return Object.entries(properties).some(([field, schema]) => {\n const type = schema?.type;\n const acceptsString =\n type === \"string\" ||\n type === undefined ||\n (Array.isArray(type) && type.includes(\"string\"));\n return RAW_QUERY_INPUT_FIELDS.has(field.toLowerCase()) && acceptsString;\n });\n}\n\n/**\n * Direct A2A action calls share the authenticated external-agent policy with\n * MCP, but remain stricter: only explicitly exposed, authenticated read-only\n * actions can skip the receiver's model loop, and never one that takes a raw\n * query the caller wrote.\n */\nexport function filterDirectA2AActions(\n actions: Record<string, ActionEntry>,\n options: Pick<AgentChatPluginOptions, \"connectorCatalog\" | \"externalAgents\">,\n): Record<string, ActionEntry> {\n const catalog = new Set(options.connectorCatalog ?? []);\n const denied = new Set(options.externalAgents?.denyActions ?? []);\n const autoReads = options.externalAgents?.authenticatedReads === \"auto\";\n\n return Object.fromEntries(\n Object.entries(actions).filter(([name, entry]) => {\n const exposure = entry.publicAgent;\n const selected =\n catalog.has(name) ||\n (autoReads &&\n isAuthenticatedReadAction(entry) &&\n !isAutoReadExcludedActionName(name));\n const rawQueryAllowed =\n !hasRawQueryInput(entry) || exposure?.allowRawQueryInput === true;\n return (\n selected &&\n rawQueryAllowed &&\n !denied.has(name) &&\n entry.agentTool !== false &&\n entry.readOnly === true &&\n exposure?.expose === true &&\n exposure.readOnly === true &&\n exposure.requiresAuth === true &&\n (entry.needsApproval === undefined || entry.needsApproval === false) &&\n exposure.isConsequential !== true\n );\n }),\n );\n}\n\nexport function buildPublicAgentA2ASkills(\n actions: Record<string, ActionEntry>,\n): Array<{\n id: string;\n name: string;\n description: string;\n publicAgent: ActionEntry[\"publicAgent\"];\n inputSchema?: Record<string, unknown>;\n}> {\n return Object.entries(filterPublicAgentActions(actions)).map(\n ([name, entry]) => ({\n id: name,\n name,\n description: entry.tool.description,\n publicAgent: entry.publicAgent,\n ...(entry.tool.parameters\n ? {\n inputSchema: entry.tool.parameters as unknown as Record<\n string,\n unknown\n >,\n }\n : {}),\n }),\n );\n}\n\n/**\n * Skills for a caller with a verified A2A identity: exactly what\n * `filterDirectA2AActions` will execute. Kept separate from\n * `buildPublicAgentA2ASkills` because the public card may only name actions\n * with `requiresAuth !== true` while direct invocation requires\n * `requiresAuth === true` — advertising the public set alone tells siblings\n * an app has nothing callable when it does.\n */\nexport function buildAuthenticatedAgentA2ASkills(\n actions: Record<string, ActionEntry>,\n options: Pick<AgentChatPluginOptions, \"connectorCatalog\" | \"externalAgents\">,\n): Array<{\n id: string;\n name: string;\n description: string;\n publicAgent: ActionEntry[\"publicAgent\"];\n inputSchema?: Record<string, unknown>;\n}> {\n return Object.entries(filterDirectA2AActions(actions, options)).map(\n ([name, entry]) => ({\n id: name,\n name,\n description: entry.tool.description,\n publicAgent: entry.publicAgent,\n // Every action in this set is read-only by construction. Omitting the\n // flag made discovery label all of them \"(mutating)\", which pushes a\n // caller away from invoking them and back into open-ended delegation.\n readOnly: true,\n // Naming an action without its parameters is what makes a caller invoke\n // it with `{}` and fail on a required field.\n ...(entry.tool.parameters\n ? {\n inputSchema: entry.tool.parameters as unknown as Record<\n string,\n unknown\n >,\n }\n : {}),\n }),\n );\n}\n\nexport function resolveArtifactBaseUrl(\n event: any | undefined,\n): string | undefined {\n const fromEnv =\n process.env.APP_URL ||\n process.env.URL ||\n process.env.DEPLOY_URL ||\n process.env.BETTER_AUTH_URL;\n if (fromEnv) return withConfiguredAppBasePath(String(fromEnv));\n\n try {\n const proto = getHeader(event, \"x-forwarded-proto\") || \"https\";\n const host = getHeader(event, \"host\");\n if (host) return withConfiguredAppBasePath(`${proto}://${host}`);\n } catch {}\n\n return undefined;\n}\n\nexport function assembleA2AFinalResponse(\n events: readonly AgentChatEvent[],\n toolResults: readonly A2AToolResultSummary[],\n options: A2AArtifactResponseOptions & {\n event?: any;\n outcome?: AgentLoopOutcome;\n } = {},\n): { responseText: string; finalText: string } {\n const terminalError = options.outcome\n ? terminalErrorFromOutcome(options.outcome)\n : getA2ATerminalErrorEvent(events);\n const responseText = collectFinalResponseTextFromAgentEvents(events, {\n fallbackToPreToolText: !terminalError,\n });\n const finalText = appendA2AArtifactLinks(responseText, [...toolResults], {\n baseUrl: options.baseUrl ?? resolveArtifactBaseUrl(options.event),\n includeReferencedArtifacts: true,\n includePersistedArtifactMarker: true,\n });\n if (terminalError) {\n const partialResult = finalText.trim()\n ? `\\n\\nPartial verified results before the failure:\\n${finalText.trim()}`\n : \"\";\n throw new Error(formatA2ATerminalError(terminalError) + partialResult);\n }\n if (!finalText.trim()) {\n throw new Error(\n \"Agent completed without a response or verified artifact.\\ncode: empty_agent_response\",\n );\n }\n return { responseText, finalText };\n}\n\nfunction terminalErrorFromOutcome(\n outcome: AgentLoopOutcome,\n): Extract<AgentChatEvent, { type: \"error\" }> | null {\n if (outcome.state === \"completed\") return null;\n if (outcome.state === \"failed\") {\n return {\n type: \"error\",\n error: outcome.message,\n errorCode: outcome.code,\n recoverable: outcome.retryable,\n };\n }\n if (outcome.state === \"input_required\") {\n return {\n type: \"error\",\n error: outcome.message,\n errorCode: outcome.code,\n recoverable: true,\n };\n }\n return {\n type: \"error\",\n error: outcome.message ?? \"Agent run was canceled.\",\n errorCode: \"canceled\",\n recoverable: false,\n };\n}\n\nfunction getA2ATerminalErrorEvent(\n events: readonly AgentChatEvent[],\n): Extract<AgentChatEvent, { type: \"error\" }> | null {\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.type === \"clear\") continue;\n if (event.type === \"done\") return null;\n if (event.type === \"error\") return event;\n if (event.type === \"tripwire\") {\n return {\n type: \"error\",\n error: event.reason || \"Agent stopped at a delegated-run guardrail.\",\n errorCode: event.processor ? `tripwire:${event.processor}` : \"tripwire\",\n recoverable: true,\n };\n }\n if (event.type === \"loop_limit\") {\n return {\n type: \"error\",\n error:\n \"Agent stopped before finishing at the delegated-run step limit.\",\n errorCode: \"loop_limit\",\n recoverable: true,\n };\n }\n if (event.type === \"auto_continue\") {\n return {\n type: \"error\",\n error: `Agent stopped before finishing (${event.reason}).`,\n errorCode: event.reason,\n recoverable: true,\n };\n }\n }\n return null;\n}\n\nfunction formatA2ATerminalError(\n event: Extract<AgentChatEvent, { type: \"error\" }>,\n): string {\n const parts = [\n event.error || \"Agent failed before producing a final response.\",\n event.errorCode ? `code: ${event.errorCode}` : \"\",\n event.details ? `details: ${event.details}` : \"\",\n ].filter(Boolean);\n return parts.join(\"\\n\");\n}\n\ntype A2AAgentLoopRunner = typeof runAgentLoopDirectWithSoftTimeout;\n\n/**\n * Delegated turns should do specialist work with the receiver's own tools,\n * but must return a bounded caller-ready result. Interactive defaults allow\n * extremely deep work (400 iterations / 20M cumulative input tokens), which\n * made healthy Slides -> Analytics calls take 4-13 minutes and consume up to\n * millions of input tokens as tool results accumulated. These defaults leave\n * ample room for multi-source analysis while failing before a delegated turn\n * can silently become an unbounded research session.\n */\nexport const DEFAULT_DELEGATED_MAX_ITERATIONS = 80;\nexport const DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS = 750_000;\nexport const DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS = 20_000;\n\nexport const DELEGATED_AGENT_EXECUTION_CONTRACT = `\n<delegated-agent-contract>\nThis request was delegated by another app. You are the specialist owner of the work.\n- Interpret the caller's natural-language objective using your own instructions, skills, data dictionary, credentials, and tools. Choose providers, schemas, queries, and joins here; never ask the caller to invent SQL or source-specific implementation details for you.\n- Finish the objective autonomously in this delegated turn whenever a safe, reasonable default exists. Do not bounce the work back with UI-navigation requests, implementation questions, or intermediate status. Ask for input only when authorization, missing credentials, or a consequential user choice truly blocks progress.\n- When evidence is incomplete, return the best grounded partial answer with explicit coverage gaps instead of refusing or asking the caller to choose your source, filter, dashboard, or workflow.\n- Minimize round trips. Filter, join, aggregate, paginate, stage, and reduce large datasets inside your own tools rather than returning raw records or transcripts.\n- Return a concise caller-ready result with the answer, source and coverage details, relevant counts or IDs, caveats/partial gaps, and exact artifact URLs. Do not return tool transcripts or large raw payloads.\n</delegated-agent-contract>`;\n\nexport interface DelegatedAgentLoopTelemetry {\n runId: string;\n threadId: string | null;\n userId: string | null;\n delegation: {\n protocol: \"a2a\" | \"mcp\";\n callerApp?: string;\n taskId?: string;\n parentRunId?: string;\n parentTurnId?: string;\n };\n}\n\ninterface DelegatedAgentLoopOptions {\n runner?: A2AAgentLoopRunner;\n telemetry?: DelegatedAgentLoopTelemetry;\n}\n\nasync function runDelegatedAgentLoop(\n runOptions: Parameters<A2AAgentLoopRunner>[0],\n pluginOptions: Pick<\n AgentChatPluginOptions,\n \"delegatedRunPolicy\" | \"finalResponseGuard\" | \"runSoftTimeoutMs\"\n >,\n timeoutOptions: Parameters<A2AAgentLoopRunner>[2],\n options: DelegatedAgentLoopOptions,\n) {\n const runner = options.runner ?? runAgentLoopDirectWithSoftTimeout;\n const policy = pluginOptions.delegatedRunPolicy;\n const configuredHardToolResultCap = runOptions.toolLimits?.hardMaxResultChars;\n const delegatedHardToolResultCap =\n policy?.maxToolResultChars ?? DEFAULT_DELEGATED_MAX_TOOL_RESULT_CHARS;\n const resolvedRunOptions = {\n ...runOptions,\n systemPrompt: runOptions.systemPrompt + DELEGATED_AGENT_EXECUTION_CONTRACT,\n // Delegated runs resolve their own model and do not pass through the\n // interactive request handler's output-token setup. Use the same\n // model-aware headroom here so reasoning models (notably GPT-5.x) do\n // not spend the small internal default entirely on reasoning before\n // emitting a tool call or answer. Preserve explicit test/caller values.\n maxOutputTokens:\n runOptions.maxOutputTokens ??\n resolveMainChatMaxOutputTokens(runOptions.model),\n reasoningEffort:\n runOptions.reasoningEffort ??\n resolveAgentRequestReasoningEffort({ model: runOptions.model }),\n maxIterations:\n runOptions.maxIterations ??\n policy?.maxIterations ??\n DEFAULT_DELEGATED_MAX_ITERATIONS,\n maxRunInputTokens:\n runOptions.maxRunInputTokens ??\n policy?.maxRunInputTokens ??\n DEFAULT_DELEGATED_MAX_RUN_INPUT_TOKENS,\n toolLimits: {\n ...(runOptions.toolLimits ?? {}),\n hardMaxResultChars:\n typeof configuredHardToolResultCap === \"number\"\n ? Math.min(configuredHardToolResultCap, delegatedHardToolResultCap)\n : delegatedHardToolResultCap,\n },\n finalResponseGuard: pluginOptions.finalResponseGuard,\n };\n const execute = (loopOptions = resolvedRunOptions) =>\n runner(loopOptions, pluginOptions.runSoftTimeoutMs, timeoutOptions);\n\n if (!options.telemetry) return execute();\n\n let instrumented = false;\n try {\n const { getObservabilityConfig, instrumentAgentLoop } =\n await import(\"../../observability/traces.js\");\n const config = await getObservabilityConfig();\n if (config.enabled) {\n instrumented = true;\n return await instrumentAgentLoop({\n runAgentLoop: (loopOptions) =>\n execute(\n loopOptions as Parameters<A2AAgentLoopRunner>[0] &\n typeof resolvedRunOptions,\n ),\n loopOpts: resolvedRunOptions,\n runId: options.telemetry.runId,\n threadId: options.telemetry.threadId,\n userId: options.telemetry.userId,\n config,\n delegation: options.telemetry.delegation,\n });\n }\n } catch (error) {\n // Match interactive chat: setup failures fall through, but a failure from\n // inside an instrumented agent loop is the real run failure and rethrows.\n if (instrumented) throw error;\n }\n return execute();\n}\n\n/**\n * Run an A2A-delegated agent turn with the same final-response guard used by\n * the app's interactive chat surface.\n *\n * Keeping this in one helper prevents delegated calls from silently bypassing\n * template guarantees such as Analytics' requirement to query real data\n * before presenting metrics or exhaustive provider conclusions.\n */\nexport function runA2AAgentLoop(\n runOptions: Parameters<A2AAgentLoopRunner>[0],\n pluginOptions: Pick<\n AgentChatPluginOptions,\n \"delegatedRunPolicy\" | \"finalResponseGuard\" | \"runSoftTimeoutMs\"\n >,\n timeoutOptions: Parameters<A2AAgentLoopRunner>[2],\n options: DelegatedAgentLoopOptions = {},\n) {\n return runDelegatedAgentLoop(\n runOptions,\n pluginOptions,\n timeoutOptions,\n options,\n );\n}\n\n/**\n * Run the MCP-local ask_app turn with the same app-level response guard as\n * A2A. Keeping this seam shared prevents hosted MCP callers from bypassing\n * template guarantees when the request cannot use the self-A2A route.\n */\nexport function runMCPAgentLoop(\n runOptions: Parameters<A2AAgentLoopRunner>[0],\n pluginOptions: Pick<\n AgentChatPluginOptions,\n \"delegatedRunPolicy\" | \"finalResponseGuard\" | \"runSoftTimeoutMs\"\n >,\n timeoutOptions: Parameters<A2AAgentLoopRunner>[2],\n options: DelegatedAgentLoopOptions = {},\n) {\n return runDelegatedAgentLoop(\n runOptions,\n pluginOptions,\n timeoutOptions,\n options,\n );\n}\n\n/**\n * Keep delegated A2A turns on the same compact initial tool surface as\n * interactive chat. `tool-search` remains in the initial set, while the\n * complete registry is supplied separately so the run loop can load a matched\n * schema after a tool-search result.\n */\nexport function createA2AEngineToolSurface(\n availableTools: EngineTool[],\n initialToolNames?: string[],\n): { tools: EngineTool[]; availableTools: EngineTool[] } {\n return {\n tools: filterInitialEngineTools(availableTools, initialToolNames),\n availableTools,\n };\n}\n\nexport function resolveInitialToolNames(\n templateActions: Record<string, ActionEntry>,\n configured?: string[],\n): string[] {\n return configured ?? Object.keys(templateActions);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../../src/server/agent-chat/context-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAgBnE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuL7D,CAAC;AAEF,wBAAgB,2BAA2B,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA+BzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAsCtE;AAMD,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,OAAO,GACpB,MAAM,CAIR;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAgP5D;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAyD3E"}
1
+ {"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../../src/server/agent-chat/context-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAgBnE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyL7D,CAAC;AAEF,wBAAgB,2BAA2B,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA+BzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAsCtE;AAMD,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,OAAO,GACpB,MAAM,CAIR;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAgP5D;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAyD3E"}
@@ -138,6 +138,8 @@ Prefer \`web-request\` for simple API calls and static pages. Use browser automa
138
138
 
139
139
  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.
140
140
 
141
+ Use a natural-language \`message\` by default. The receiving app owns interpretation and runs with its own instructions, skills, connected sources, data dictionary, and tools. Do not choose its provider, schema, query, joins, or SQL for it. A direct \`action\` + \`input\` call is only for an exact bounded read whose complete contract is already known; it is never a workaround for unreliable delegation.
142
+
141
143
  **NEVER use \`call-agent\` to:**
142
144
  - Call your own app by name
143
145
  - Perform tasks you can accomplish with your own registered tools