@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
@@ -295,12 +295,13 @@ Clips, or external workspace data.
295
295
  ## Generic ingest payload validation
296
296
 
297
297
  The signed ingest webhook at `/api/_agent-native/brain/ingest` accepts a
298
- `RawCapturePayload`. Create a source with a `sourceKey` to receive a bearer
299
- token, set `Authorization: Bearer <ingestToken>` on the request, and send the
300
- payload shape below. Clips can export to that endpoint without Brain reading the
301
- Clips database directly. Generic sources use the same payload shape for call
302
- transcripts, customer research, imported notes, or any other source that can
303
- produce a bounded capture.
298
+ normalized capture envelope. Create a source with a `sourceKey` to receive a
299
+ bearer token, set `Authorization: Bearer <ingestToken>` on the request, and
300
+ send one of the payload shapes below. Clips can export to that endpoint without
301
+ Brain reading the Clips database directly. Generic sources use the same
302
+ contract for call transcripts, customer research, approved FAQs/docs, imported
303
+ notes, or any other source that can produce a bounded capture. Successful
304
+ creates and updates automatically create or reuse a distillation queue item.
304
305
 
305
306
  ```json
306
307
  {
@@ -315,3 +316,50 @@ produce a bounded capture.
315
316
  "raw": {}
316
317
  }
317
318
  ```
319
+
320
+ For a blessed document publisher, create a generic source with an explicit
321
+ answer policy:
322
+
323
+ ```bash
324
+ pnpm --filter brain action create-source \
325
+ --title "Blessed Agent Native docs" \
326
+ --provider generic \
327
+ --sourceKey agent-native-docs \
328
+ --policy '{"trustTier":"blessed","answerEligible":true,"authority":100,"freshnessWindowDays":null,"reviewRequired":false,"conflictBehavior":"prefer-higher-authority"}' \
329
+ --visibility org
330
+ ```
331
+
332
+ Then publish one stable upstream record per `externalId`:
333
+
334
+ ```json
335
+ {
336
+ "sourceKey": "agent-native-docs",
337
+ "externalId": "what-is-agent-native",
338
+ "title": "What is Agent Native?",
339
+ "kind": "document",
340
+ "content": "Agent Native is ...",
341
+ "capturedAt": "2026-07-30T12:00:00.000Z",
342
+ "sourceUrl": "https://docs.example.com/what-is-agent-native",
343
+ "tags": ["faq", "agent-native"],
344
+ "metadata": {
345
+ "slug": "what-is-agent-native",
346
+ "owner": "product"
347
+ }
348
+ }
349
+ ```
350
+
351
+ Reusing the same `sourceKey` and `externalId` updates the capture and
352
+ invalidates its derived knowledge/search artifacts before re-distillation.
353
+ When the upstream record is deleted or unblessed, send a content-free
354
+ tombstone:
355
+
356
+ ```json
357
+ {
358
+ "sourceKey": "agent-native-docs",
359
+ "externalId": "what-is-agent-native",
360
+ "deleted": true
361
+ }
362
+ ```
363
+
364
+ Tombstones retire the capture, remove its derived knowledge and published
365
+ canonical resource, and prevent a stale retry from silently recreating it.
@@ -10,12 +10,13 @@ Use Brain actions rather than raw SQL.
10
10
  1. Call `get-brain-settings` before answering, searching broadly, or distilling when current settings are not already in context. Apply the returned guidance for assistant name, company name, tone, source policy, citation requirements, publish tier, redaction, and distillation instructions.
11
11
  2. Import raw material with `import-capture` (generic) or `import-transcript`
12
12
  (meeting-shaped: participants, `sourceUrl`, tags). Both default
13
- `enqueueDistillation: true` and auto-create a `manual` source when
14
- `sourceId` is omitted — don't call `create-source` first just to import one
15
- ad hoc capture.
16
- 3. Call `enqueue-distillation` when a capture needs distillation. Re-running it
17
- for a capture that's already queued/processing refreshes the handoff
18
- instructions instead of creating a duplicate queue row.
13
+ `enqueueDistillation: true`, immediately create or reuse a queue item, and
14
+ auto-create a `manual` source when `sourceId` is omitted — don't call
15
+ `create-source` first just to import one ad hoc capture.
16
+ 3. Call `enqueue-distillation` when an existing capture needs an explicit
17
+ queue/retry handoff. Re-running it for a capture that's already
18
+ queued/processing refreshes the handoff instructions instead of creating a
19
+ duplicate queue row.
19
20
  4. Before writing knowledge, call `get-capture` and copy short exact quotes.
20
21
  Quotes and offsets always reference the persisted safe capture, never an
21
22
  upstream raw payload. `get-capture` redacts `title`/`content`/`metadata` by
@@ -131,13 +132,23 @@ not just documented:
131
132
  returning an answer with no usable citation — it returns a policy-explanation
132
133
  message instead of a bare summary when that happens.
133
134
 
135
+ Each source may also carry an `answerPolicy`, configured through the
136
+ `create-source` / `update-source` `policy` argument. `ask-brain` excludes stale
137
+ or answer-ineligible results, prevents review-required raw captures from
138
+ supporting answers, ranks `blessed` before `standard` before `untrusted`, and
139
+ then ranks by `authority`. It returns the evaluated policy alongside citations
140
+ so external apps can explain why a result was preferred or excluded. Sources
141
+ without this policy retain the compatible `standard`, eligible, authority-50
142
+ behavior.
143
+
134
144
  ## Publish Tiers And Proposal Gating
135
145
 
136
146
  `write-knowledge` writes at a `publishTier`: `private` (draft, private
137
147
  visibility), `team`, or `company` (published, org visibility) — default comes
138
148
  from `settings.defaultPublishTier`. A `company`-tier write becomes a
139
- **proposal** (`mode: "proposal"`, held for human review) instead of publishing
140
- immediately when ALL of:
149
+ **proposal** (`mode: "proposal"`, held for human review) when any cited source
150
+ has `answerPolicy.reviewRequired: true`. Otherwise the workspace approval
151
+ behavior applies when ALL of:
141
152
 
142
153
  - `proposalMode !== "never"`, and
143
154
  - `tier === "company"`, and
@@ -163,7 +174,7 @@ AGENTS.md carries a one-line action index; these are the fuller purposes.
163
174
  | `ask-brain` | Cited-answer endpoint: reviewed knowledge, capped raw-capture fallback, citations, `federatedCoverage`. |
164
175
  | `get-knowledge` / `list-knowledge` | Read one or list distilled knowledge records. |
165
176
  | `get-capture` / `list-captures` | Read one or list raw captures (redacted by default; `includeRawContent` for exact quotes). |
166
- | `import-capture` / `import-transcript` | Ingest a generic capture or a meeting transcript; auto-creates a `manual` source. |
177
+ | `import-capture` / `import-transcript` | Ingest a generic capture or meeting transcript, auto-create a `manual` source when needed, and queue distillation by default. |
167
178
  | `enqueue-distillation` / `mark-capture-distilled` | Queue a capture for distillation; close out the queue row when done. |
168
179
  | `write-knowledge` | Write/update durable knowledge; may return a pending proposal — see Publish Tiers above. |
169
180
  | `review-proposal` / `approve-proposal` / `reject-proposal` / `list-proposals` / `update-proposal` | Human-review workflow for gated writes. |
@@ -35,6 +35,37 @@ retrieved again later. Surface it to the user immediately (e.g. for wiring
35
35
  into an external system's webhook config) rather than assuming you can read
36
36
  it back with `get-source`.
37
37
 
38
+ ## Blessed FAQ And Docs Publishers
39
+
40
+ Approved FAQs, docs, handbooks, and similar owned resources use the same
41
+ `generic` signed source contract. They are not a new provider and do not require
42
+ Brain to crawl the entire upstream system. The source owner publishes only the
43
+ records Brain is allowed to use:
44
+
45
+ ```bash
46
+ pnpm --filter brain action create-source \
47
+ --title "Blessed Agent Native docs" \
48
+ --provider generic \
49
+ --sourceKey agent-native-docs \
50
+ --policy '{"trustTier":"blessed","answerEligible":true,"authority":100,"freshnessWindowDays":null,"reviewRequired":false,"conflictBehavior":"prefer-higher-authority"}' \
51
+ --visibility org
52
+ ```
53
+
54
+ The source answer policy is code-enforced:
55
+
56
+ | Field | Effect |
57
+ | --------------------- | ----------------------------------------------------------------------------------- |
58
+ | `trustTier` | `blessed`, `standard`, or `untrusted`; cited answers rank higher trust first. |
59
+ | `answerEligible` | Excludes the source from `ask-brain` answers when false. |
60
+ | `authority` | Ranks otherwise eligible sources from 0 to 100. |
61
+ | `freshnessWindowDays` | Excludes source-backed results after the configured window; `null` disables expiry. |
62
+ | `reviewRequired` | Raw captures cannot support answers, and company knowledge enters review. |
63
+ | `conflictBehavior` | Prefer higher authority, surface conflicts, or require review before raw support. |
64
+
65
+ Legacy sources remain `standard`, answer-eligible, authority 50, with no
66
+ freshness expiry. Use `update-source --policy ...` to tighten an existing
67
+ source without recreating it.
68
+
38
69
  ## Source Health States
39
70
 
40
71
  `get-brain-health` (`readBrainHealth` in `server/lib/brain-health.ts`) is the
@@ -105,7 +136,8 @@ connection, not creating a new one.
105
136
 
106
137
  ## Editing And Removing Sources
107
138
 
108
- - `update-source` edits title, config, or visibility on an existing source.
139
+ - `update-source` edits title, config, cursor, status, or answer policy on an
140
+ existing source.
109
141
  - `delete-source` is a hard delete — there's no soft-archive alternative
110
142
  exposed as an action; setting `status: "paused"` via `update-source` is the
111
143
  reversible way to stop a source without losing its captures.
@@ -58,6 +58,8 @@ Read the matching skill before deeper work:
58
58
  from `get-capture` output.
59
59
  - Sources support exactly six providers: `manual`, `generic`, `clips`, `slack`,
60
60
  `granola`, `github`. `create-source` rejects anything else.
61
+ - Use a blessed `generic` source for approved FAQs, docs, and handbooks. See
62
+ `ingestion-and-connectors` for answer policy, updates, and deletion semantics.
61
63
  - Reuse existing workspace integration grants (check `list-connection-providers`
62
64
  readiness) instead of duplicating provider tokens into Brain. Source sync
63
65
  actions are convenience readers, not integration limits — for an endpoint,
@@ -87,7 +89,7 @@ Read the matching skill before deeper work:
87
89
  | `ask-brain` | Cited-answer endpoint with `federatedCoverage`. |
88
90
  | `get-knowledge` / `list-knowledge` | Read or list distilled knowledge. |
89
91
  | `get-capture` / `list-captures` | Read or list raw captures (redacted by default). |
90
- | `import-capture` / `import-transcript` | Ingest a capture or meeting transcript. |
92
+ | `import-capture` / `import-transcript` | Ingest and queue a capture or transcript for distillation. |
91
93
  | `enqueue-distillation` / `mark-capture-distilled` | Queue distillation; close the queue row. |
92
94
  | `write-knowledge` | Write/update knowledge; may return a pending proposal. |
93
95
  | `review-proposal` / `approve-proposal` / `reject-proposal` / `list-proposals` / `update-proposal` | Human review of gated writes. |
@@ -15,7 +15,8 @@ attendee-scoped meetings without widening their audience.
15
15
  ## Features
16
16
 
17
17
  - Company chat that answers from cited, reviewed knowledge — not hallucinations.
18
- - Source connectors for Slack, Granola, GitHub, Clips, and generic webhooks.
18
+ - Source connectors for Slack, Granola, GitHub, Clips, and generic webhooks,
19
+ including source-owner-published blessed FAQs and docs.
19
20
  - Deterministic privacy screening before storage, with an optional approved
20
21
  privacy classifier for richer review decisions.
21
22
  - Hybrid full-text and semantic search over allowed captures and knowledge,
@@ -25,6 +26,8 @@ attendee-scoped meetings without widening their audience.
25
26
  - Sensitive sources are suppressed or quarantined before search, citations,
26
27
  distillation, and source editors can see their content.
27
28
  - Read-only, citation-backed retrieval exposed to other apps over A2A.
29
+ - Per-source answer policy for trust, eligibility, authority, freshness,
30
+ review, and conflict handling.
28
31
 
29
32
  ## Privacy posture
30
33
 
@@ -1,5 +1,13 @@
1
1
  import { z } from "zod";
2
2
 
3
+ export const booleanishSchema = z.preprocess((value) => {
4
+ if (typeof value !== "string") return value;
5
+ const normalized = value.trim().toLowerCase();
6
+ if (["true", "1", "yes", "on"].includes(normalized)) return true;
7
+ if (["false", "0", "no", "off"].includes(normalized)) return false;
8
+ return value;
9
+ }, z.boolean());
10
+
3
11
  export const sourceProviderSchema = z.enum([
4
12
  "manual",
5
13
  "generic",
@@ -9,6 +17,28 @@ export const sourceProviderSchema = z.enum([
9
17
  "github",
10
18
  ]);
11
19
 
20
+ export const sourceAnswerPolicySchema = z.preprocess(
21
+ parseJsonCliInput,
22
+ z
23
+ .object({
24
+ trustTier: z.enum(["blessed", "standard", "untrusted"]).optional(),
25
+ answerEligible: booleanishSchema.optional(),
26
+ authority: z.coerce.number().int().min(0).max(100).optional(),
27
+ freshnessWindowDays: z
28
+ .union([z.null(), z.coerce.number().int().min(0).max(3650)])
29
+ .optional(),
30
+ reviewRequired: booleanishSchema.optional(),
31
+ conflictBehavior: z
32
+ .enum([
33
+ "prefer-higher-authority",
34
+ "surface-conflicts",
35
+ "require-review",
36
+ ])
37
+ .optional(),
38
+ })
39
+ .strict(),
40
+ );
41
+
12
42
  export const captureKindSchema = z.enum([
13
43
  "transcript",
14
44
  "note",
@@ -76,14 +106,6 @@ export const optionalJsonRecordSchema = z
76
106
  .preprocess(parseJsonCliInput, z.record(z.string(), z.unknown()).optional())
77
107
  .optional();
78
108
 
79
- export const booleanishSchema = z.preprocess((value) => {
80
- if (typeof value !== "string") return value;
81
- const normalized = value.trim().toLowerCase();
82
- if (["true", "1", "yes", "on"].includes(normalized)) return true;
83
- if (["false", "0", "no", "off"].includes(normalized)) return false;
84
- return value;
85
- }, z.boolean());
86
-
87
109
  export function stringArrayCliSchema({
88
110
  min,
89
111
  max,
@@ -13,6 +13,13 @@ import {
13
13
  searchEverythingRows,
14
14
  type UniversalSearchResult,
15
15
  } from "../server/lib/search.js";
16
+ import {
17
+ compareEvaluatedSourcePolicies,
18
+ evaluateSourceAnswerPolicy,
19
+ loadAccessibleSourcePolicySnapshots,
20
+ type EvaluatedSourceAnswerPolicy,
21
+ type SourcePolicySnapshot,
22
+ } from "../server/lib/source-policy.js";
16
23
 
17
24
  const STOPWORDS = new Set([
18
25
  "about",
@@ -96,7 +103,7 @@ function rankRowsForQuestion(rows: KnowledgeSearchRow[], question: string) {
96
103
  const minimumScore = bestScore >= 3 ? Math.max(2, bestScore - 2) : 0;
97
104
  return ranked
98
105
  .filter((entry) => entry.score >= minimumScore)
99
- .slice(0, 6)
106
+ .slice(0, 24)
100
107
  .map((entry) => entry.row);
101
108
  }
102
109
 
@@ -116,6 +123,54 @@ function captureDeepLink(captureId: string): string {
116
123
  });
117
124
  }
118
125
 
126
+ function knowledgeSourceIds(
127
+ item: ReturnType<typeof serializeKnowledge>,
128
+ ): string[] {
129
+ return Array.from(
130
+ new Set(
131
+ [
132
+ item.sourceId,
133
+ ...item.evidence.map((evidence) => evidence.sourceId),
134
+ ].filter((id): id is string => Boolean(id)),
135
+ ),
136
+ );
137
+ }
138
+
139
+ function sourcePolicyEnforcement(args: {
140
+ policies: Map<string, SourcePolicySnapshot>;
141
+ knowledgeEvaluated: number;
142
+ captureEvaluated: number;
143
+ excludedKnowledge: number;
144
+ excludedCaptures: number;
145
+ }) {
146
+ return {
147
+ enforced: true,
148
+ legacyDefault: {
149
+ trustTier: "standard" as const,
150
+ answerEligible: true,
151
+ authority: 50,
152
+ },
153
+ ranking: ["trustTier", "authority", "relevance"],
154
+ configuredSources: Array.from(args.policies.values()).map((policy) => ({
155
+ sourceId: policy.sourceId,
156
+ trustTier: policy.trustTier,
157
+ answerEligible: policy.answerEligible,
158
+ authority: policy.authority,
159
+ freshnessWindowDays: policy.freshnessWindowDays,
160
+ reviewRequired: policy.reviewRequired,
161
+ conflictBehavior: policy.conflictBehavior,
162
+ })),
163
+ evaluated: {
164
+ knowledge: args.knowledgeEvaluated,
165
+ captures: args.captureEvaluated,
166
+ },
167
+ excluded: {
168
+ knowledge: args.excludedKnowledge,
169
+ captures: args.excludedCaptures,
170
+ },
171
+ };
172
+ }
173
+
119
174
  export default defineAction({
120
175
  description:
121
176
  "Answer a company-knowledge question from published Brain knowledge, falling back to cited raw capture matches when approved knowledge is thin. The external-facing public-agent company lookup: returns a cited answer plus deep links into the Brain knowledge/capture records.",
@@ -137,17 +192,36 @@ export default defineAction({
137
192
  const seen = new Set<string>();
138
193
  const rows = [];
139
194
  for (const facet of facetsFromQuestion(question)) {
140
- const matches = await searchKnowledgeRows({ query: facet, limit: 6 });
195
+ const matches = await searchKnowledgeRows({ query: facet, limit: 24 });
141
196
  for (const row of matches) {
142
197
  if (seen.has(row.id)) continue;
143
198
  seen.add(row.id);
144
199
  rows.push(row);
145
200
  }
146
- if (rows.length >= 6) break;
201
+ if (rows.length >= 24) break;
147
202
  }
148
- const knowledge = rankRowsForQuestion(rows, question).map(
203
+ const knowledgeCandidates = rankRowsForQuestion(rows, question).map(
149
204
  serializeKnowledge,
150
205
  );
206
+ const sourcePolicies = await loadAccessibleSourcePolicySnapshots(
207
+ knowledgeCandidates.flatMap(knowledgeSourceIds),
208
+ );
209
+ const evaluatedKnowledge = knowledgeCandidates.map((item) => ({
210
+ ...item,
211
+ answerPolicy: evaluateSourceAnswerPolicy({
212
+ sourceIds: knowledgeSourceIds(item),
213
+ sourcePolicies,
214
+ contentUpdatedAt: item.updatedAt,
215
+ resultType: "knowledge",
216
+ reviewed: item.status === "published",
217
+ }),
218
+ }));
219
+ const knowledge = evaluatedKnowledge
220
+ .filter((item) => item.answerPolicy.eligible)
221
+ .sort((left, right) =>
222
+ compareEvaluatedSourcePolicies(left.answerPolicy, right.answerPolicy),
223
+ )
224
+ .slice(0, 6);
151
225
  const captureFallback: UniversalSearchResult[] = [];
152
226
  const knowledgeTextLength = knowledge.reduce(
153
227
  (total, item) => total + `${item.summary} ${item.body}`.trim().length,
@@ -163,18 +237,49 @@ export default defineAction({
163
237
  const matches = await searchEverythingRows({
164
238
  query: facet,
165
239
  type: "capture",
166
- limit: 6,
240
+ limit: 24,
167
241
  });
168
242
  for (const match of matches) {
169
243
  if (seenCaptures.has(match.id)) continue;
170
244
  seenCaptures.add(match.id);
171
245
  captureFallback.push(match);
172
246
  }
173
- if (captureFallback.length >= 4) break;
247
+ if (captureFallback.length >= 24) break;
174
248
  }
175
249
  }
250
+ const captureSourcePolicies = await loadAccessibleSourcePolicySnapshots(
251
+ captureFallback.flatMap((item) =>
252
+ item.source?.id ? [item.source.id] : [],
253
+ ),
254
+ );
255
+ for (const [sourceId, policy] of captureSourcePolicies) {
256
+ sourcePolicies.set(sourceId, policy);
257
+ }
258
+ const evaluatedCaptures = captureFallback.map((item) => ({
259
+ ...item,
260
+ answerPolicy: evaluateSourceAnswerPolicy({
261
+ sourceIds: item.source?.id ? [item.source.id] : [],
262
+ sourcePolicies,
263
+ contentUpdatedAt: item.updatedAt,
264
+ resultType: "capture",
265
+ reviewed: false,
266
+ }),
267
+ }));
268
+ const eligibleCaptures = evaluatedCaptures
269
+ .filter((item) => item.answerPolicy.eligible)
270
+ .sort((left, right) =>
271
+ compareEvaluatedSourcePolicies(left.answerPolicy, right.answerPolicy),
272
+ )
273
+ .slice(0, 4);
274
+ const sourcePolicy = sourcePolicyEnforcement({
275
+ policies: sourcePolicies,
276
+ knowledgeEvaluated: evaluatedKnowledge.length,
277
+ captureEvaluated: evaluatedCaptures.length,
278
+ excludedKnowledge: evaluatedKnowledge.length - knowledge.length,
279
+ excludedCaptures: evaluatedCaptures.length - eligibleCaptures.length,
280
+ });
176
281
 
177
- if (!knowledge.length && !captureFallback.length) {
282
+ if (!knowledge.length && !eligibleCaptures.length) {
178
283
  const federatedCoverage = await federatedCoveragePromise;
179
284
  return {
180
285
  answer:
@@ -186,6 +291,7 @@ export default defineAction({
186
291
  captures: [],
187
292
  results: [],
188
293
  policy: guidance.retrieval,
294
+ sourcePolicy,
189
295
  responseGuidance: guidance.response,
190
296
  federatedCoverage,
191
297
  };
@@ -201,9 +307,10 @@ export default defineAction({
201
307
  confidence: item.confidence / 100,
202
308
  url: safeCitationUrl(evidence.sourceUrl ?? evidence.url),
203
309
  deepLink: knowledgeDeepLink(item.id),
310
+ sourcePolicy: item.answerPolicy,
204
311
  })),
205
312
  );
206
- const captureCitations = captureFallback.map((item) => ({
313
+ const captureCitations = eligibleCaptures.map((item) => ({
207
314
  id: item.id,
208
315
  captureId: item.id,
209
316
  title: item.title,
@@ -211,6 +318,7 @@ export default defineAction({
211
318
  excerpt: item.snippet,
212
319
  url: safeCitationUrl(item.sourceUrl),
213
320
  deepLink: captureDeepLink(item.id),
321
+ sourcePolicy: item.answerPolicy,
214
322
  }));
215
323
  const answerParts = [];
216
324
  const hasCitations = knowledgeCitations.length || captureCitations.length;
@@ -221,9 +329,10 @@ export default defineAction({
221
329
  "I found possible Brain context, but workspace settings require citations and these results did not include usable evidence.",
222
330
  citations: [],
223
331
  knowledge,
224
- captures: captureFallback,
225
- results: captureFallback,
332
+ captures: eligibleCaptures,
333
+ results: eligibleCaptures,
226
334
  policy: guidance.retrieval,
335
+ sourcePolicy,
227
336
  responseGuidance: guidance.response,
228
337
  federatedCoverage,
229
338
  };
@@ -235,14 +344,14 @@ export default defineAction({
235
344
  .join("\n\n"),
236
345
  );
237
346
  }
238
- if (captureFallback.length) {
347
+ if (eligibleCaptures.length) {
239
348
  const prefix = knowledge.length
240
349
  ? "Related raw capture matches:"
241
350
  : "I could not find approved Brain knowledge, but I found matching raw captures:";
242
351
  answerParts.push(
243
352
  [
244
353
  prefix,
245
- ...captureFallback.map(
354
+ ...eligibleCaptures.map(
246
355
  (item) =>
247
356
  `${item.title}${item.source?.title ? ` (${item.source.title})` : ""}: ${item.snippet}`,
248
357
  ),
@@ -258,9 +367,10 @@ export default defineAction({
258
367
  citations,
259
368
  deepLink: primary?.deepLink ?? null,
260
369
  knowledge,
261
- captures: captureFallback,
262
- results: captureFallback,
370
+ captures: eligibleCaptures,
371
+ results: eligibleCaptures,
263
372
  policy: guidance.retrieval,
373
+ sourcePolicy,
264
374
  responseGuidance: guidance.response,
265
375
  federatedCoverage,
266
376
  };
@@ -8,7 +8,12 @@ import {
8
8
  sha256Hex,
9
9
  } from "../server/lib/brain.js";
10
10
  import { assertSourceWorkspaceConnectionAvailable } from "../server/lib/source-credentials.js";
11
- import { jsonRecordSchema, sourceProviderSchema } from "./_schemas.js";
11
+ import { withSourceAnswerPolicy } from "../server/lib/source-policy.js";
12
+ import {
13
+ jsonRecordSchema,
14
+ sourceAnswerPolicySchema,
15
+ sourceProviderSchema,
16
+ } from "./_schemas.js";
12
17
 
13
18
  export default defineAction({
14
19
  description:
@@ -27,9 +32,20 @@ export default defineAction({
27
32
  .optional()
28
33
  .describe("Optional signed-ingest bearer token; stored only as a hash"),
29
34
  visibility: z.enum(["private", "org"]).default("org"),
35
+ policy: sourceAnswerPolicySchema
36
+ .optional()
37
+ .describe(
38
+ "Optional answer policy controlling trust, eligibility, authority, freshness, review, and conflicts",
39
+ ),
30
40
  }),
31
41
  run: async (args) => {
32
- const config = { ...args.config };
42
+ let config = { ...args.config };
43
+ if (args.policy !== undefined || config.answerPolicy !== undefined) {
44
+ config = withSourceAnswerPolicy(
45
+ config,
46
+ args.policy ?? config.answerPolicy,
47
+ );
48
+ }
33
49
  const workspaceConnectionId =
34
50
  typeof config.workspaceConnectionId === "string"
35
51
  ? config.workspaceConnectionId.trim()