@vellumai/assistant 0.8.3 → 0.8.5

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 (665) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/docker-entrypoint.sh +0 -1
  3. package/docs/browser-use-architecture-phase2.md +1 -1
  4. package/knip.json +2 -1
  5. package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
  6. package/openapi.yaml +1492 -100
  7. package/package.json +1 -1
  8. package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
  9. package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
  10. package/src/__tests__/agent-loop.test.ts +88 -3
  11. package/src/__tests__/anthropic-provider.test.ts +302 -33
  12. package/src/__tests__/approval-cascade.test.ts +1 -1
  13. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  14. package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
  15. package/src/__tests__/audit-log-rotation.test.ts +70 -16
  16. package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
  17. package/src/__tests__/btw-routes.test.ts +2 -3
  18. package/src/__tests__/call-controller.test.ts +0 -1
  19. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  20. package/src/__tests__/channel-delivery-store.test.ts +193 -0
  21. package/src/__tests__/channel-guardian.test.ts +3 -3
  22. package/src/__tests__/channel-reply-delivery.test.ts +284 -5
  23. package/src/__tests__/channel-retry-sweep.test.ts +274 -1
  24. package/src/__tests__/checker.test.ts +6 -15
  25. package/src/__tests__/compaction-events.test.ts +2 -1
  26. package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
  27. package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
  28. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
  29. package/src/__tests__/computer-use-tools.test.ts +2 -4
  30. package/src/__tests__/config-watcher.test.ts +1 -1
  31. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  32. package/src/__tests__/context-token-estimator.test.ts +91 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  34. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
  35. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
  37. package/src/__tests__/conversation-agent-loop.test.ts +188 -129
  38. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
  39. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  40. package/src/__tests__/conversation-clean-command.test.ts +137 -0
  41. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  42. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
  43. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  44. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  45. package/src/__tests__/conversation-error.test.ts +31 -0
  46. package/src/__tests__/conversation-fork-crud.test.ts +324 -0
  47. package/src/__tests__/conversation-lifecycle.test.ts +53 -12
  48. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  49. package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
  50. package/src/__tests__/conversation-pairing.test.ts +2 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +1 -1
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
  53. package/src/__tests__/conversation-queue.test.ts +1 -1
  54. package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
  57. package/src/__tests__/conversation-seed-composer.test.ts +66 -4
  58. package/src/__tests__/conversation-skill-tools.test.ts +2 -5
  59. package/src/__tests__/conversation-slash-commands.test.ts +36 -8
  60. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  61. package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
  62. package/src/__tests__/conversation-speed-override.test.ts +1 -1
  63. package/src/__tests__/conversation-store.test.ts +1 -1
  64. package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
  65. package/src/__tests__/conversation-sync-tags.test.ts +99 -32
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
  67. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  69. package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
  70. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  71. package/src/__tests__/credential-security-invariants.test.ts +7 -0
  72. package/src/__tests__/credential-vault-unit.test.ts +2 -2
  73. package/src/__tests__/cu-unified-flow.test.ts +10 -1
  74. package/src/__tests__/dm-backfill.test.ts +64 -0
  75. package/src/__tests__/dm-persistence.test.ts +33 -0
  76. package/src/__tests__/document-find-replace.test.ts +501 -0
  77. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  78. package/src/__tests__/email-html-renderer.test.ts +12 -0
  79. package/src/__tests__/first-greeting.test.ts +23 -2
  80. package/src/__tests__/gateway-flag-listener.test.ts +237 -0
  81. package/src/__tests__/gemini-provider.test.ts +78 -0
  82. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  83. package/src/__tests__/guardian-outbound-http.test.ts +7 -5
  84. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  85. package/src/__tests__/headless-browser-navigate.test.ts +172 -0
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  87. package/src/__tests__/heartbeat-service.test.ts +4 -0
  88. package/src/__tests__/host-bash-proxy.test.ts +6 -0
  89. package/src/__tests__/host-browser-proxy.test.ts +10 -0
  90. package/src/__tests__/host-cu-proxy.test.ts +8 -1
  91. package/src/__tests__/host-file-proxy.test.ts +8 -1
  92. package/src/__tests__/host-shell-tool.test.ts +1 -1
  93. package/src/__tests__/host-transfer-proxy.test.ts +8 -1
  94. package/src/__tests__/identity-routes.test.ts +57 -0
  95. package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
  96. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  97. package/src/__tests__/injector-chain.test.ts +2 -0
  98. package/src/__tests__/injector-document-comments.test.ts +378 -0
  99. package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
  100. package/src/__tests__/list-messages-attachments.test.ts +21 -17
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
  102. package/src/__tests__/list-messages-page-latest.test.ts +130 -14
  103. package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
  104. package/src/__tests__/llm-context-normalization.test.ts +0 -2
  105. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  106. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  107. package/src/__tests__/llm-resolver.test.ts +161 -9
  108. package/src/__tests__/llm-usage-store.test.ts +66 -0
  109. package/src/__tests__/log-export-routes.test.ts +99 -2
  110. package/src/__tests__/logger.test.ts +89 -0
  111. package/src/__tests__/mcp-abort-signal.test.ts +2 -2
  112. package/src/__tests__/media-generate-image.test.ts +31 -0
  113. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  114. package/src/__tests__/message-queue-steer.test.ts +114 -0
  115. package/src/__tests__/model-intents.test.ts +2 -4
  116. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  117. package/src/__tests__/onboarding-template-contract.test.ts +1 -1
  118. package/src/__tests__/openai-provider.test.ts +151 -0
  119. package/src/__tests__/openai-responses-provider.test.ts +118 -16
  120. package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
  121. package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
  122. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  123. package/src/__tests__/platform.test.ts +2 -5
  124. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  125. package/src/__tests__/plugin-bootstrap.test.ts +2 -2
  126. package/src/__tests__/plugin-source-watcher.test.ts +302 -0
  127. package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
  128. package/src/__tests__/plugin-types.test.ts +3 -2
  129. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  130. package/src/__tests__/pricing.test.ts +12 -0
  131. package/src/__tests__/process-message-background-slack.test.ts +1 -51
  132. package/src/__tests__/process-message-display-content.test.ts +21 -16
  133. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  134. package/src/__tests__/registry.test.ts +2 -8
  135. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  136. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  137. package/src/__tests__/server-history-render.test.ts +83 -4
  138. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  139. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  140. package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
  141. package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
  142. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  143. package/src/__tests__/steer-tool-repair.test.ts +249 -0
  144. package/src/__tests__/subagent-notify-parent.test.ts +1 -1
  145. package/src/__tests__/suggestion-routes.test.ts +1 -0
  146. package/src/__tests__/sync-message-contract.test.ts +59 -0
  147. package/src/__tests__/system-prompt.test.ts +161 -124
  148. package/src/__tests__/terminal-tools.test.ts +12 -2
  149. package/src/__tests__/thinking-block-replay.test.ts +113 -0
  150. package/src/__tests__/thread-backfill.test.ts +370 -22
  151. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  152. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  153. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  154. package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
  155. package/src/__tests__/tool-executor.test.ts +89 -53
  156. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  157. package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
  158. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  159. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  160. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  161. package/src/__tests__/twilio-routes.test.ts +1 -1
  162. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  163. package/src/__tests__/usage-routes.test.ts +3 -0
  164. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  165. package/src/__tests__/web-fetch.test.ts +2 -2
  166. package/src/__tests__/workspace-git-service.test.ts +94 -10
  167. package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
  168. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  169. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  170. package/src/acp/prepare-agent-env.ts +78 -0
  171. package/src/acp/session-manager.ts +1 -1
  172. package/src/agent/attachments.ts +1 -0
  173. package/src/agent/loop.ts +65 -20
  174. package/src/api/README.md +5 -0
  175. package/src/api/index.ts +4 -0
  176. package/src/api/package.json +10 -0
  177. package/src/background-wake/background-wake-routes.test.ts +233 -0
  178. package/src/background-wake/next-wake.test.ts +289 -0
  179. package/src/background-wake/next-wake.ts +172 -0
  180. package/src/background-wake/runtime-registry.ts +24 -0
  181. package/src/browser/operations.ts +15 -0
  182. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  183. package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
  184. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  185. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  186. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  187. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  188. package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
  189. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  190. package/src/cli/commands/browser.ts +247 -0
  191. package/src/cli/commands/conversations.ts +128 -1
  192. package/src/cli/commands/domain.ts +91 -41
  193. package/src/cli/commands/inference-providers.ts +147 -1
  194. package/src/cli/commands/inference.ts +93 -40
  195. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  196. package/src/cli/commands/memory-v2.ts +483 -0
  197. package/src/cli/commands/memory-v3-render.ts +344 -0
  198. package/src/cli/commands/memory-v3.ts +316 -0
  199. package/src/cli/commands/notifications.ts +24 -2
  200. package/src/cli/program.ts +2 -0
  201. package/src/cli/utils/conversation-id.ts +17 -5
  202. package/src/config/assistant-feature-flags.ts +21 -9
  203. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  204. package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
  205. package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
  206. package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
  207. package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
  208. package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
  209. package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
  210. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  211. package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
  212. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  213. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  214. package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
  215. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  216. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  217. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  218. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  219. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  220. package/src/config/bundled-skills/schedule/SKILL.md +8 -0
  221. package/src/config/bundled-tool-registry.ts +24 -12
  222. package/src/config/call-site-defaults.ts +20 -0
  223. package/src/config/feature-flag-registry.json +115 -3
  224. package/src/config/llm-resolver.ts +16 -2
  225. package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
  226. package/src/config/schemas/call-site-catalog.ts +35 -0
  227. package/src/config/schemas/llm.ts +14 -0
  228. package/src/config/schemas/memory-v2.ts +294 -1
  229. package/src/config/schemas/memory.ts +2 -1
  230. package/src/context/compactor.ts +60 -1
  231. package/src/context/token-estimator.ts +47 -4
  232. package/src/context/window-manager.ts +25 -0
  233. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  234. package/src/conversations/message-consolidation.ts +404 -0
  235. package/src/credential-health/credential-health-service.ts +34 -19
  236. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
  237. package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
  238. package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
  239. package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
  240. package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
  241. package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
  242. package/src/daemon/conversation-agent-loop.ts +307 -88
  243. package/src/daemon/conversation-error.ts +31 -1
  244. package/src/daemon/conversation-lifecycle.ts +149 -118
  245. package/src/daemon/conversation-messaging.ts +3 -0
  246. package/src/daemon/conversation-process.ts +273 -0
  247. package/src/daemon/conversation-queue-manager.ts +14 -0
  248. package/src/daemon/conversation-runtime-assembly.ts +145 -84
  249. package/src/daemon/conversation-slash.ts +37 -5
  250. package/src/daemon/conversation-surfaces.ts +45 -2
  251. package/src/daemon/conversation-tool-setup.ts +70 -3
  252. package/src/daemon/conversation-usage.ts +2 -0
  253. package/src/daemon/conversation.ts +54 -32
  254. package/src/daemon/disk-pressure-guard.ts +14 -2
  255. package/src/daemon/first-greeting.ts +10 -0
  256. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
  257. package/src/daemon/handlers/config-a2a.ts +160 -0
  258. package/src/daemon/handlers/config-model.test.ts +2 -0
  259. package/src/daemon/handlers/conversations.ts +90 -3
  260. package/src/daemon/handlers/shared.ts +92 -29
  261. package/src/daemon/host-bash-proxy.ts +1 -1
  262. package/src/daemon/host-browser-proxy.ts +5 -5
  263. package/src/daemon/host-cu-proxy.ts +5 -5
  264. package/src/daemon/host-file-proxy.ts +5 -5
  265. package/src/daemon/host-proxy-base.ts +4 -4
  266. package/src/daemon/host-transfer-proxy.ts +11 -11
  267. package/src/daemon/lifecycle.ts +40 -23
  268. package/src/daemon/meet-manifest-loader.ts +1 -7
  269. package/src/daemon/message-protocol.ts +4 -0
  270. package/src/daemon/message-types/conversations.ts +14 -9
  271. package/src/daemon/message-types/document-comments.ts +50 -0
  272. package/src/daemon/message-types/home.ts +1 -13
  273. package/src/daemon/message-types/messages.ts +66 -7
  274. package/src/daemon/message-types/surfaces.ts +3 -1
  275. package/src/daemon/message-types/sync.ts +14 -0
  276. package/src/daemon/message-types/web-activity.ts +57 -0
  277. package/src/daemon/plugin-source-watcher.ts +135 -3
  278. package/src/daemon/process-message.ts +69 -12
  279. package/src/daemon/shutdown-handlers.ts +24 -5
  280. package/src/daemon/switch-inference-profile-tool.ts +52 -0
  281. package/src/daemon/tool-setup-types.ts +13 -0
  282. package/src/daemon/trust-context.ts +6 -0
  283. package/src/documents/document-comments-store.test.ts +338 -0
  284. package/src/documents/document-comments-store.ts +237 -0
  285. package/src/documents/document-store.ts +202 -0
  286. package/src/events/relationship-state-updated.ts +25 -0
  287. package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
  288. package/src/heartbeat/heartbeat-service.ts +1 -0
  289. package/src/home/__tests__/suggested-prompts.test.ts +33 -2
  290. package/src/home/feed-types.ts +6 -1
  291. package/src/home/home-content-refresh.ts +52 -0
  292. package/src/home/home-greeting-cache.ts +69 -0
  293. package/src/home/home-greeting.ts +85 -0
  294. package/src/home/suggested-prompts.ts +168 -9
  295. package/src/ipc/gateway-flag-listener.ts +123 -0
  296. package/src/ipc/skill-routes/registries.ts +8 -12
  297. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  298. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  299. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
  300. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  301. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
  302. package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
  303. package/src/memory/auto-analysis-enqueue.ts +5 -1
  304. package/src/memory/conversation-crud.ts +191 -100
  305. package/src/memory/conversation-starters-cadence.ts +3 -1
  306. package/src/memory/conversation-title-service.ts +19 -3
  307. package/src/memory/db-async-query.ts +214 -0
  308. package/src/memory/db-init.ts +26 -0
  309. package/src/memory/db-maintenance.ts +30 -21
  310. package/src/memory/delivery-crud.ts +41 -0
  311. package/src/memory/delivery-status.ts +141 -15
  312. package/src/memory/external-conversation-store.ts +32 -1
  313. package/src/memory/graph/bootstrap.ts +8 -1
  314. package/src/memory/graph/capability-seed.ts +7 -3
  315. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  316. package/src/memory/graph/extraction.ts +1 -5
  317. package/src/memory/graph/graph-search.ts +7 -1
  318. package/src/memory/indexer.ts +28 -18
  319. package/src/memory/job-handlers/cleanup.ts +76 -18
  320. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  321. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  322. package/src/memory/jobs-store.ts +14 -0
  323. package/src/memory/jobs-worker.ts +68 -15
  324. package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
  325. package/src/memory/llm-request-log-source-local.ts +7 -0
  326. package/src/memory/llm-request-log-source.ts +9 -2
  327. package/src/memory/llm-request-log-store.ts +43 -1
  328. package/src/memory/llm-usage-store.ts +24 -0
  329. package/src/memory/memory-retrospective-constants.ts +28 -0
  330. package/src/memory/memory-retrospective-enqueue.ts +11 -3
  331. package/src/memory/memory-retrospective-job.ts +413 -18
  332. package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
  333. package/src/memory/memory-v2-activation-log-store.ts +41 -14
  334. package/src/memory/migrations/100-core-tables.ts +1 -0
  335. package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
  336. package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
  337. package/src/memory/migrations/253-document-comments.ts +47 -0
  338. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
  339. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
  340. package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
  341. package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
  342. package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
  343. package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
  344. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  345. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  346. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  347. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  348. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  349. package/src/memory/migrations/index.ts +34 -0
  350. package/src/memory/migrations/registry.ts +58 -0
  351. package/src/memory/onboarding-events-store.ts +7 -0
  352. package/src/memory/schema/calls.ts +1 -0
  353. package/src/memory/schema/conversations.ts +3 -0
  354. package/src/memory/schema/infrastructure.ts +22 -0
  355. package/src/memory/tool-usage-store.ts +36 -8
  356. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  357. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  358. package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
  359. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  360. package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
  361. package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
  362. package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
  363. package/src/memory/v2/__tests__/injection.test.ts +158 -112
  364. package/src/memory/v2/__tests__/page-index.test.ts +365 -1
  365. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  366. package/src/memory/v2/__tests__/router.test.ts +660 -4
  367. package/src/memory/v2/consolidation-job.ts +14 -0
  368. package/src/memory/v2/harness/compare.ts +57 -0
  369. package/src/memory/v2/harness/metrics.ts +124 -0
  370. package/src/memory/v2/harness/oracle.ts +145 -0
  371. package/src/memory/v2/harness/replay-input.ts +224 -0
  372. package/src/memory/v2/harness/retriever.ts +74 -0
  373. package/src/memory/v2/harness/router-retriever.ts +43 -0
  374. package/src/memory/v2/harness/runner.ts +106 -0
  375. package/src/memory/v2/harness/trace.ts +58 -0
  376. package/src/memory/v2/injection-events.ts +101 -0
  377. package/src/memory/v2/injection.ts +42 -25
  378. package/src/memory/v2/page-index.ts +209 -7
  379. package/src/memory/v2/page-store.ts +18 -0
  380. package/src/memory/v2/prompts/router.ts +26 -1
  381. package/src/memory/v2/qdrant.ts +14 -2
  382. package/src/memory/v2/router.ts +369 -62
  383. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  384. package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
  385. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  386. package/src/memory/v3/__tests__/edges.test.ts +563 -0
  387. package/src/memory/v3/__tests__/filter.test.ts +512 -0
  388. package/src/memory/v3/__tests__/gate.test.ts +574 -0
  389. package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
  390. package/src/memory/v3/__tests__/loop.test.ts +530 -0
  391. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  392. package/src/memory/v3/__tests__/scouts.test.ts +440 -0
  393. package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
  394. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  395. package/src/memory/v3/__tests__/traversal.test.ts +469 -0
  396. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  397. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  398. package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
  399. package/src/memory/v3/__tests__/validate.test.ts +245 -0
  400. package/src/memory/v3/auto-edges.ts +223 -0
  401. package/src/memory/v3/coactivation-store.ts +124 -0
  402. package/src/memory/v3/consolidation-job.ts +323 -0
  403. package/src/memory/v3/edge-learning-job.ts +160 -0
  404. package/src/memory/v3/edges.ts +249 -0
  405. package/src/memory/v3/filter.ts +281 -0
  406. package/src/memory/v3/gate.ts +334 -0
  407. package/src/memory/v3/index-composition.ts +113 -0
  408. package/src/memory/v3/llm-capture.ts +46 -0
  409. package/src/memory/v3/loop.ts +382 -0
  410. package/src/memory/v3/maintenance.ts +144 -0
  411. package/src/memory/v3/prompt-context.ts +33 -0
  412. package/src/memory/v3/prompts/consolidation.ts +458 -0
  413. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  414. package/src/memory/v3/retriever.ts +33 -0
  415. package/src/memory/v3/scouts.ts +420 -0
  416. package/src/memory/v3/shadow-middleware.ts +305 -0
  417. package/src/memory/v3/traversal.ts +206 -0
  418. package/src/memory/v3/tree-index.ts +237 -0
  419. package/src/memory/v3/tree-store.ts +394 -0
  420. package/src/memory/v3/tree-walk.ts +351 -0
  421. package/src/memory/v3/types.ts +65 -0
  422. package/src/memory/v3/validate.ts +300 -0
  423. package/src/messaging/providers/index.ts +7 -1
  424. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
  425. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
  426. package/src/messaging/providers/slack/adapter.ts +178 -25
  427. package/src/messaging/providers/slack/api.test.ts +54 -0
  428. package/src/messaging/providers/slack/api.ts +119 -3
  429. package/src/messaging/providers/slack/client.ts +12 -0
  430. package/src/messaging/providers/slack/deep-link.ts +20 -1
  431. package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
  432. package/src/messaging/providers/slack/message-metadata.ts +156 -0
  433. package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
  434. package/src/messaging/providers/slack/render-transcript.ts +176 -49
  435. package/src/messaging/providers/slack/send.test.ts +77 -0
  436. package/src/messaging/providers/slack/send.ts +8 -2
  437. package/src/messaging/providers/slack/types.ts +14 -0
  438. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
  439. package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
  440. package/src/notifications/adapters/macos.ts +18 -1
  441. package/src/notifications/adapters/platform.ts +1 -1
  442. package/src/notifications/conversation-seed-composer.ts +14 -2
  443. package/src/notifications/decision-engine.ts +1 -4
  444. package/src/notifications/deferred-emit.ts +135 -0
  445. package/src/notifications/emit-signal.ts +38 -50
  446. package/src/notifications/home-feed-side-effect.ts +60 -30
  447. package/src/oauth/connect-orchestrator.ts +3 -0
  448. package/src/oauth/credential-token-resolver.ts +2 -0
  449. package/src/oauth/manual-token-connection.ts +19 -0
  450. package/src/oauth/oauth-store.ts +12 -0
  451. package/src/oauth/seed-providers.ts +22 -0
  452. package/src/permissions/prompter.ts +8 -5
  453. package/src/permissions/question-prompter.ts +5 -2
  454. package/src/permissions/secret-prompter.ts +6 -3
  455. package/src/plugin-api/index.ts +4 -0
  456. package/src/plugin-api/types.ts +7 -33
  457. package/src/plugins/defaults/index.ts +6 -0
  458. package/src/plugins/defaults/injectors.ts +100 -20
  459. package/src/plugins/external-plugin-loader.ts +5 -68
  460. package/src/plugins/types.ts +11 -16
  461. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  462. package/src/prompts/__tests__/system-prompt.test.ts +46 -2
  463. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  464. package/src/prompts/normalize-onboarding.ts +40 -0
  465. package/src/prompts/persona-resolver.ts +36 -21
  466. package/src/prompts/sections.ts +69 -19
  467. package/src/prompts/system-prompt.ts +118 -216
  468. package/src/prompts/template-detection.ts +37 -0
  469. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
  470. package/src/prompts/templates/BOOTSTRAP.md +10 -2
  471. package/src/prompts/templates/VOICE.md +3 -0
  472. package/src/prompts/templates/system-sections.ts +281 -9
  473. package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
  474. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  475. package/src/providers/anthropic/client.ts +159 -66
  476. package/src/providers/call-site-routing.ts +14 -2
  477. package/src/providers/connection-model-compat.ts +38 -0
  478. package/src/providers/connection-resolution.ts +16 -2
  479. package/src/providers/fireworks/client.ts +20 -2
  480. package/src/providers/gemini/client.ts +49 -6
  481. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
  482. package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
  483. package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
  484. package/src/providers/inference/adapter-factory.ts +18 -1
  485. package/src/providers/inference/auth.ts +3 -3
  486. package/src/providers/inference/codex-token-refresh.ts +128 -0
  487. package/src/providers/inference/resolve-auth.ts +49 -6
  488. package/src/providers/minimax/client.ts +106 -0
  489. package/src/providers/model-catalog.ts +91 -1
  490. package/src/providers/model-intents.ts +1 -1
  491. package/src/providers/openai/chat-completions-provider.ts +63 -23
  492. package/src/providers/openai/codex-models.ts +18 -0
  493. package/src/providers/openai/responses-provider.ts +86 -23
  494. package/src/providers/openrouter/client.ts +5 -1
  495. package/src/providers/provider-send-message.ts +7 -1
  496. package/src/providers/retry.ts +34 -3
  497. package/src/providers/thinking-config.ts +26 -1
  498. package/src/providers/types.ts +25 -0
  499. package/src/providers/usage-tracking.ts +2 -0
  500. package/src/runtime/AGENTS.md +2 -2
  501. package/src/runtime/__tests__/agent-wake.test.ts +214 -0
  502. package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
  503. package/src/runtime/agent-wake.ts +152 -56
  504. package/src/runtime/assistant-event-hub.ts +76 -6
  505. package/src/runtime/auth/route-policy.ts +43 -3
  506. package/src/runtime/background-job-runner.ts +26 -0
  507. package/src/runtime/btw-sidechain.ts +0 -6
  508. package/src/runtime/channel-reply-delivery.ts +182 -47
  509. package/src/runtime/channel-retry-sweep.ts +141 -16
  510. package/src/runtime/http-types.ts +7 -6
  511. package/src/runtime/migrations/vbundle-builder.ts +10 -3
  512. package/src/runtime/pending-interactions.ts +50 -8
  513. package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
  514. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
  515. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
  516. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
  517. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  518. package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
  519. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
  520. package/src/runtime/routes/acp-routes.test.ts +255 -6
  521. package/src/runtime/routes/acp-routes.ts +8 -1
  522. package/src/runtime/routes/approval-routes.ts +4 -1
  523. package/src/runtime/routes/avatar-routes.ts +10 -10
  524. package/src/runtime/routes/background-wake-routes.ts +188 -0
  525. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  526. package/src/runtime/routes/btw-routes.ts +0 -6
  527. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
  528. package/src/runtime/routes/content-source-routes.ts +78 -0
  529. package/src/runtime/routes/conversation-cli-routes.ts +147 -2
  530. package/src/runtime/routes/conversation-list-routes.ts +12 -4
  531. package/src/runtime/routes/conversation-management-routes.ts +77 -20
  532. package/src/runtime/routes/conversation-query-routes.ts +196 -31
  533. package/src/runtime/routes/conversation-routes.ts +472 -425
  534. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  535. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  536. package/src/runtime/routes/document-comments-routes.ts +287 -0
  537. package/src/runtime/routes/documents-routes.ts +33 -0
  538. package/src/runtime/routes/domain-routes.ts +60 -10
  539. package/src/runtime/routes/email-routes.ts +5 -2
  540. package/src/runtime/routes/events-routes.ts +54 -10
  541. package/src/runtime/routes/group-routes.ts +24 -8
  542. package/src/runtime/routes/home-feed-routes.ts +6 -3
  543. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  544. package/src/runtime/routes/host-browser-routes.ts +17 -2
  545. package/src/runtime/routes/host-cu-routes.ts +2 -2
  546. package/src/runtime/routes/identity-routes.ts +21 -0
  547. package/src/runtime/routes/inbound-message-handler.ts +288 -58
  548. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  549. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
  550. package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
  551. package/src/runtime/routes/index.ts +20 -4
  552. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  553. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  554. package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
  555. package/src/runtime/routes/integrations/a2a.ts +60 -1
  556. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  557. package/src/runtime/routes/log-export-routes.ts +39 -0
  558. package/src/runtime/routes/memory-item-routes.ts +8 -3
  559. package/src/runtime/routes/memory-v2-routes.ts +427 -0
  560. package/src/runtime/routes/memory-v3-routes.ts +316 -0
  561. package/src/runtime/routes/migration-routes.ts +21 -24
  562. package/src/runtime/routes/notification-routes.ts +19 -2
  563. package/src/runtime/routes/plugins-routes.ts +337 -0
  564. package/src/runtime/routes/question-routes.ts +4 -1
  565. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  566. package/src/runtime/routes/sanity-routes.ts +159 -0
  567. package/src/runtime/routes/secret-routes.ts +25 -5
  568. package/src/runtime/routes/settings-routes.ts +12 -11
  569. package/src/runtime/routes/slack-channel-routes.ts +188 -0
  570. package/src/runtime/routes/workspace-routes.ts +25 -10
  571. package/src/runtime/services/conversation-serializer.ts +30 -4
  572. package/src/runtime/sync/resource-sync-events.ts +106 -38
  573. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  574. package/src/runtime/sync/sync-publisher.ts +2 -1
  575. package/src/runtime/verification-outbound-actions.ts +73 -1
  576. package/src/schedule/integration-status.ts +3 -1
  577. package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
  578. package/src/security/oauth2-device-code.ts +307 -0
  579. package/src/security/oauth2.ts +26 -9
  580. package/src/security/secure-keys.ts +5 -0
  581. package/src/skills/catalog-install.ts +6 -2
  582. package/src/telemetry/types.ts +12 -0
  583. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  584. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  585. package/src/tools/acp/spawn.test.ts +119 -0
  586. package/src/tools/acp/spawn.ts +15 -2
  587. package/src/tools/apps/definitions.ts +2 -8
  588. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  589. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  590. package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
  591. package/src/tools/browser/browser-execution.ts +106 -0
  592. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  593. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
  594. package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
  595. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
  596. package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
  597. package/src/tools/browser/cdp-client/factory.ts +171 -4
  598. package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
  599. package/src/tools/browser/cdp-client/types.ts +101 -0
  600. package/src/tools/browser/pinned-tabs.ts +146 -0
  601. package/src/tools/computer-use/definitions.ts +22 -78
  602. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  603. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  604. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  605. package/src/tools/credentials/vault.ts +3 -9
  606. package/src/tools/document/document-comment-tool.test.ts +379 -0
  607. package/src/tools/document/document-comment-tool.ts +156 -0
  608. package/src/tools/document/document-tool.ts +187 -2
  609. package/src/tools/execution-target.ts +21 -23
  610. package/src/tools/executor.ts +6 -1
  611. package/src/tools/filesystem/edit.ts +3 -9
  612. package/src/tools/filesystem/list.ts +3 -9
  613. package/src/tools/filesystem/read.ts +3 -9
  614. package/src/tools/filesystem/write.ts +3 -9
  615. package/src/tools/host-filesystem/edit.ts +3 -9
  616. package/src/tools/host-filesystem/read.ts +3 -9
  617. package/src/tools/host-filesystem/transfer.ts +3 -9
  618. package/src/tools/host-filesystem/write.ts +3 -9
  619. package/src/tools/host-terminal/host-shell.ts +3 -9
  620. package/src/tools/mcp/mcp-tool-factory.ts +1 -8
  621. package/src/tools/memory/register.test.ts +1 -1
  622. package/src/tools/memory/register.ts +4 -9
  623. package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
  624. package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
  625. package/src/tools/network/domain-normalize.ts +17 -0
  626. package/src/tools/network/web-fetch.ts +216 -73
  627. package/src/tools/network/web-search.ts +216 -98
  628. package/src/tools/registry.ts +7 -23
  629. package/src/tools/schema-transforms.ts +1 -1
  630. package/src/tools/skills/execute.ts +3 -9
  631. package/src/tools/skills/load.ts +3 -9
  632. package/src/tools/skills/skill-tool-factory.ts +1 -8
  633. package/src/tools/subagent/notify-parent.ts +3 -9
  634. package/src/tools/system/request-permission.ts +3 -9
  635. package/src/tools/terminal/safe-env.ts +3 -2
  636. package/src/tools/terminal/shell.ts +3 -9
  637. package/src/tools/tool-approval-handler.ts +19 -12
  638. package/src/tools/tool-defaults.ts +94 -0
  639. package/src/tools/types.ts +31 -98
  640. package/src/tools/ui-surface/definitions.ts +9 -23
  641. package/src/types/onboarding-context.ts +4 -0
  642. package/src/usage/pricing.ts +23 -0
  643. package/src/usage/types.ts +12 -0
  644. package/src/util/__tests__/favicon.test.ts +84 -0
  645. package/src/util/favicon.ts +40 -0
  646. package/src/util/logger.ts +16 -7
  647. package/src/util/platform.ts +7 -7
  648. package/src/util/sqlite3-runtime.ts +65 -0
  649. package/src/workspace/git-service.ts +75 -4
  650. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  651. package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
  652. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  653. package/src/workspace/migrations/registry.ts +4 -0
  654. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  655. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  656. package/src/config/bundled-skills/document/SKILL.md +0 -54
  657. package/src/config/bundled-skills/document/TOOLS.json +0 -106
  658. package/src/daemon/seed-files.ts +0 -18
  659. package/src/prompts/cache-boundary.ts +0 -8
  660. package/src/runtime/routes/interface-routes.ts +0 -43
  661. /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
  662. /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
  663. /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
  664. /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
  665. /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
@@ -14,8 +14,9 @@ import { v4 as uuid } from "uuid";
14
14
  import { getDeliverableChannels } from "../channels/config.js";
15
15
  import { findGuardianForChannel } from "../contacts/contact-store.js";
16
16
  import type { ConversationCreateType } from "../memory/conversation-crud.js";
17
+ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
17
18
  import { getLogger } from "../util/logger.js";
18
- import { type BroadcastFn, VellumAdapter } from "./adapters/macos.js";
19
+ import { VellumAdapter } from "./adapters/macos.js";
19
20
  import { PlatformPushAdapter } from "./adapters/platform.js";
20
21
  import { SlackAdapter } from "./adapters/slack.js";
21
22
  import { TelegramAdapter } from "./adapters/telegram.js";
@@ -49,56 +50,38 @@ const log = getLogger("emit-signal");
49
50
  // ── Broadcaster singleton ──────────────────────────────────────────────
50
51
 
51
52
  let broadcasterInstance: NotificationBroadcaster | null = null;
52
- let registeredBroadcastFn: BroadcastFn | null = null;
53
-
54
- /**
55
- * Register the broadcast function so the vellum adapter can deliver
56
- * notifications to connected clients. Must be called once during
57
- * daemon startup (before any signals are emitted).
58
- */
59
- export function registerBroadcastFn(fn: BroadcastFn): void {
60
- registeredBroadcastFn = fn;
61
- // Reset the broadcaster so it picks up the new broadcast function
62
- broadcasterInstance = null;
63
- }
64
53
 
65
54
  function getBroadcaster(): NotificationBroadcaster {
66
55
  if (!broadcasterInstance) {
67
- const adapters = [
56
+ broadcasterInstance = new NotificationBroadcaster([
57
+ new VellumAdapter(broadcastMessage),
68
58
  new TelegramAdapter(),
69
59
  new SlackAdapter(),
70
60
  new PlatformPushAdapter(),
71
- ];
72
- if (registeredBroadcastFn) {
73
- adapters.unshift(new VellumAdapter(registeredBroadcastFn));
74
- }
75
- broadcasterInstance = new NotificationBroadcaster(adapters);
61
+ ]);
76
62
 
77
63
  // Wire the conversation-created callback so the macOS client is notified
78
64
  // immediately when a vellum notification conversation is paired — before
79
65
  // slower channel deliveries (e.g. Telegram) delay the push.
80
- if (registeredBroadcastFn) {
81
- const broadcastFn = registeredBroadcastFn;
82
- broadcasterInstance.setOnConversationCreated((info) => {
83
- broadcastFn({
84
- type: "notification_conversation_created",
85
- conversationId: info.conversationId,
86
- title: info.title,
87
- sourceEventName: info.sourceEventName,
88
- targetGuardianPrincipalId: info.targetGuardianPrincipalId,
89
- groupId: info.groupId,
90
- source: info.source,
91
- silent: info.silent,
92
- });
93
- log.info(
94
- {
95
- conversationId: info.conversationId,
96
- guardianScoped: info.targetGuardianPrincipalId != null,
97
- },
98
- "Emitted notification_conversation_created push event",
99
- );
66
+ broadcasterInstance.setOnConversationCreated((info) => {
67
+ broadcastMessage({
68
+ type: "notification_conversation_created",
69
+ conversationId: info.conversationId,
70
+ title: info.title,
71
+ sourceEventName: info.sourceEventName,
72
+ targetGuardianPrincipalId: info.targetGuardianPrincipalId,
73
+ groupId: info.groupId,
74
+ source: info.source,
75
+ silent: info.silent,
100
76
  });
101
- }
77
+ log.info(
78
+ {
79
+ conversationId: info.conversationId,
80
+ guardianScoped: info.targetGuardianPrincipalId != null,
81
+ },
82
+ "Emitted notification_conversation_created push event",
83
+ );
84
+ });
102
85
  }
103
86
  return broadcasterInstance;
104
87
  }
@@ -115,18 +98,15 @@ function getConnectedChannels(): NotificationChannel[] {
115
98
  switch (channel) {
116
99
  case "vellum":
117
100
  // Vellum is always considered connected (the local transport is
118
- // always available when the daemon is running).
101
+ // always available when the assistant is running).
119
102
  channels.push(channel);
120
103
  break;
121
104
  case "platform":
122
- // Platform push is connected when the daemon has a registered
123
- // broadcast function i.e., full daemon mode where platform
124
- // credentials are also available. Mirrors the vellum gate so
125
- // the decision engine doesn't route to platform in standalone
126
- // CLI contexts where VellumPlatformClient.create() returns null.
127
- if (registeredBroadcastFn) {
128
- channels.push(channel);
129
- }
105
+ // Platform push is treated as connected at the decision-engine
106
+ // layer; the actual delivery path lazily resolves
107
+ // `VellumPlatformClient.create()` in `PlatformPushAdapter.send()`
108
+ // and reports a delivery failure when credentials are absent.
109
+ channels.push(channel);
130
110
  break;
131
111
  case "telegram": {
132
112
  // A binding-based channel is connected when the guardian has an
@@ -388,10 +368,18 @@ export async function emitNotificationSignal<TEventName extends string>(
388
368
  // Step 5: Mirror background-origin signals into the home activity feed.
389
369
  // The helper itself decides whether to write (background filter); we
390
370
  // catch and log so a feed-write failure cannot poison the dispatch result.
371
+ // Pass the paired vellum delivery conversation as a fallback so producers
372
+ // whose `sourceContextId` is a sentinel string (e.g. heartbeat startup,
373
+ // credential health, watcher emits, scheduler retries-exhausted) still
374
+ // get a "Go to Convo" button — pointing at the conversation the
375
+ // broadcaster paired the notification with.
376
+ const pairedVellumConversationId = dispatchResult.deliveryResults.find(
377
+ (r) => r.channel === "vellum",
378
+ )?.conversationId;
391
379
  await writeHomeFeedItemForSignal(
392
380
  signal,
393
381
  decision,
394
- dispatchResult.deliveryResults,
382
+ pairedVellumConversationId,
395
383
  ).catch((err) => {
396
384
  log.warn({ err, signalId }, "writeHomeFeedItemForSignal threw");
397
385
  });
@@ -22,11 +22,7 @@ import { getConversation } from "../memory/conversation-crud.js";
22
22
  import { isBackgroundConversationType } from "../memory/conversation-types.js";
23
23
  import { getLogger } from "../util/logger.js";
24
24
  import type { NotificationSignal } from "./signal.js";
25
- import type {
26
- NotificationDecision,
27
- NotificationDeliveryResult,
28
- RenderedChannelCopy,
29
- } from "./types.js";
25
+ import type { NotificationDecision, RenderedChannelCopy } from "./types.js";
30
26
 
31
27
  const log = getLogger("home-feed-side-effect");
32
28
 
@@ -41,6 +37,16 @@ const FEED_ITEM_URGENCIES: ReadonlySet<string> = new Set<FeedItemUrgency>([
41
37
  * Append a `FeedItem` for the given notification signal when the
42
38
  * filter criteria pass.
43
39
  *
40
+ * `fallbackConversationId` is used as the feed item's "Go to Convo"
41
+ * navigation target when `signal.sourceContextId` doesn't resolve to a
42
+ * real conversation row. The notification broadcaster pairs the vellum
43
+ * delivery with a conversation (newly created or reused) before this
44
+ * function runs, so callers can thread that paired id through here for
45
+ * producers whose `sourceContextId` is a sentinel (heartbeat startup,
46
+ * credential health, watcher emits, scheduler retries-exhausted) — the
47
+ * feed item will then carry the paired delivery conversation and the
48
+ * "Go to Convo" button can render.
49
+ *
44
50
  * Returns the persisted `FeedItem`, or `null` if the signal does not
45
51
  * qualify for home-feed mirroring (non-background origin AND no
46
52
  * `isAsyncBackground` hint) or if schema validation fails.
@@ -48,9 +54,13 @@ const FEED_ITEM_URGENCIES: ReadonlySet<string> = new Set<FeedItemUrgency>([
48
54
  export async function writeHomeFeedItemForSignal(
49
55
  signal: NotificationSignal,
50
56
  decision: NotificationDecision,
51
- deliveryResults: NotificationDeliveryResult[],
57
+ fallbackConversationId?: string,
52
58
  ): Promise<FeedItem | null> {
53
- if (!shouldMirrorToHomeFeed(signal)) return null;
59
+ const { mirror, sourceConversationId } = resolveHomeFeedMirror(
60
+ signal,
61
+ fallbackConversationId,
62
+ );
63
+ if (!mirror) return null;
54
64
 
55
65
  const renderedCopy =
56
66
  decision.renderedCopy.vellum ??
@@ -77,9 +87,6 @@ export async function writeHomeFeedItemForSignal(
77
87
  return null;
78
88
  }
79
89
 
80
- const conversationId = deliveryResults.find(
81
- (r) => r.channel === "vellum",
82
- )?.conversationId;
83
90
  const urgency = FEED_ITEM_URGENCIES.has(signal.attentionHints.urgency)
84
91
  ? (signal.attentionHints.urgency as FeedItemUrgency)
85
92
  : undefined;
@@ -107,7 +114,7 @@ export async function writeHomeFeedItemForSignal(
107
114
  noteworthy: deriveNoteworthy(signal),
108
115
  fromAssistant: signal.sourceChannel === "assistant_tool",
109
116
  ...(urgency ? { urgency } : {}),
110
- ...(conversationId ? { conversationId } : {}),
117
+ ...(sourceConversationId ? { conversationId: sourceConversationId } : {}),
111
118
  ...(panelKind ? { detailPanel: { kind: panelKind } } : {}),
112
119
  ...(metadata ? { metadata } : {}),
113
120
  };
@@ -166,28 +173,51 @@ function deriveDetailPanelKind(
166
173
  }
167
174
 
168
175
  /**
169
- * `sourceContextId` is best-effort it may not be a conversation id
170
- * (e.g. scheduler job id, watcher event id), so a lookup failure
171
- * falls through to "not a background conversation" rather than throwing.
176
+ * The lookup is best-effort and unified: a single `getConversation` call
177
+ * both gates the "background conversation" mirror branch and populates
178
+ * `sourceConversationId` for the "Go to Thread" navigation target. Misses
179
+ * (scheduler job ids, watcher event ids, CLI tool-call ids) leave
180
+ * `sourceConversationId` undefined so the client hides the affordance.
172
181
  *
173
- * `assistant_tool` is the source channel used by the `notifications send`
174
- * skill (and by background-job failure emits). These signals represent
175
- * the assistant actively choosing to share, so we mirror them into the
176
- * home feed without requiring a background-typed conversation or the
177
- * `isAsyncBackground` hint — the documented (SKILL.md) CLI surface
178
- * intentionally does not expose either; internal call sites that still set
179
- * the hint keep working unchanged.
182
+ * `assistant_tool` mirrors unconditionally because the documented
183
+ * `notifications send` skill (and background-job failure emits) deliberately
184
+ * does not require a background-typed conversation or the
185
+ * `isAsyncBackground` hint.
180
186
  */
181
- function shouldMirrorToHomeFeed(signal: NotificationSignal): boolean {
182
- if (signal.sourceChannel === "assistant_tool") return true;
183
- if (signal.attentionHints.isAsyncBackground) return true;
184
- if (!signal.sourceContextId) return false;
185
- try {
186
- const row = getConversation(signal.sourceContextId);
187
- return isBackgroundConversationType(row?.conversationType);
188
- } catch {
189
- return false;
187
+ function resolveHomeFeedMirror(
188
+ signal: NotificationSignal,
189
+ fallbackConversationId?: string,
190
+ ): {
191
+ mirror: boolean;
192
+ sourceConversationId?: string;
193
+ } {
194
+ let sourceRow: { conversationType?: string } | null = null;
195
+ if (signal.sourceContextId) {
196
+ try {
197
+ sourceRow = getConversation(signal.sourceContextId) ?? null;
198
+ } catch {
199
+ sourceRow = null;
200
+ }
201
+ }
202
+ // Prefer the producer's source context (e.g. the heartbeat / background
203
+ // job conversation that emitted the signal) for the "Go to Convo" target,
204
+ // since that's where the work actually happened. Fall back to the paired
205
+ // delivery conversation only when the source context didn't resolve —
206
+ // covers producers whose `sourceContextId` is a sentinel string.
207
+ const sourceConversationId = sourceRow
208
+ ? signal.sourceContextId
209
+ : fallbackConversationId;
210
+
211
+ if (signal.sourceChannel === "assistant_tool") {
212
+ return { mirror: true, sourceConversationId };
213
+ }
214
+ if (signal.attentionHints.isAsyncBackground) {
215
+ return { mirror: true, sourceConversationId };
216
+ }
217
+ if (isBackgroundConversationType(sourceRow?.conversationType)) {
218
+ return { mirror: true, sourceConversationId };
190
219
  }
220
+ return { mirror: false };
191
221
  }
192
222
 
193
223
  function readPayloadString(payload: unknown, key: string): string | undefined {
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  import { emitPostConnectNudge } from "../home/post-connect-feed.js";
23
+ import { invalidateAssistantSuggestedPromptsCache } from "../home/suggested-prompts.js";
23
24
  import type { TokenEndpointAuthMethod } from "../security/oauth2.js";
24
25
  import { prepareOAuth2Flow, startOAuth2Flow } from "../security/oauth2.js";
25
26
  import { getLogger } from "../util/logger.js";
@@ -252,6 +253,7 @@ export async function orchestrateOAuthConnect(
252
253
  },
253
254
  "Deferred OAuth2 flow completed — tokens stored",
254
255
  );
256
+ invalidateAssistantSuggestedPromptsCache();
255
257
  void emitPostConnectNudge(options.service);
256
258
  options.onDeferredComplete?.({
257
259
  success: true,
@@ -375,6 +377,7 @@ export async function orchestrateOAuthConnect(
375
377
  "orchestrateOAuthConnect: tokens stored, connect complete",
376
378
  );
377
379
 
380
+ invalidateAssistantSuggestedPromptsCache();
378
381
  void emitPostConnectNudge(options.service);
379
382
 
380
383
  return {
@@ -49,6 +49,8 @@ function manualTokenAccessCredentialKey(provider: string): string | null {
49
49
  return credentialKey("slack_channel", "bot_token");
50
50
  case "telegram":
51
51
  return credentialKey("telegram", "bot_token");
52
+ case "sanity":
53
+ return credentialKey("sanity", "api_token");
52
54
  default:
53
55
  return null;
54
56
  }
@@ -122,6 +122,24 @@ export async function syncManualTokenConnection(
122
122
  return;
123
123
  }
124
124
 
125
+ case "sanity": {
126
+ const tokenResult = await getSecureKeyResultAsync(
127
+ credentialKey("sanity", "api_token"),
128
+ );
129
+ if (tokenResult.unreachable) {
130
+ log.warn(
131
+ "Skipping sanity manual-token reconciliation — credential backend unreachable",
132
+ );
133
+ return;
134
+ }
135
+ if (tokenResult.value) {
136
+ await ensureManualTokenConnection(provider, accountInfo);
137
+ } else {
138
+ removeManualTokenConnection(provider);
139
+ }
140
+ return;
141
+ }
142
+
125
143
  default:
126
144
  return;
127
145
  }
@@ -142,4 +160,5 @@ export async function syncManualTokenConnection(
142
160
  export async function backfillManualTokenConnections(): Promise<void> {
143
161
  await syncManualTokenConnection("telegram");
144
162
  await syncManualTokenConnection("slack_channel");
163
+ await syncManualTokenConnection("sanity");
145
164
  }
@@ -1100,5 +1100,17 @@ export async function disconnectOAuthProvider(
1100
1100
 
1101
1101
  deleteConnection(conn.id);
1102
1102
 
1103
+ // Dynamic import: `suggested-prompts.ts` imports from this module, so a
1104
+ // static import here would create a cycle. The cache invalidation is
1105
+ // best-effort — failures must not block disconnect.
1106
+ void import("../home/suggested-prompts.js")
1107
+ .then((m) => m.invalidateAssistantSuggestedPromptsCache())
1108
+ .catch((err) => {
1109
+ log.warn(
1110
+ { err: err instanceof Error ? err.message : String(err) },
1111
+ "Failed to invalidate suggested-prompts cache after disconnect",
1112
+ );
1113
+ });
1114
+
1103
1115
  return "disconnected";
1104
1116
  }
@@ -746,6 +746,28 @@ export const PROVIDER_SEED_DATA: Record<
746
746
  logoUrl: "https://cdn.simpleicons.org/telegram",
747
747
  defaultScopes: [],
748
748
  },
749
+
750
+ sanity: {
751
+ provider: "sanity",
752
+ authorizeUrl: "urn:manual-token",
753
+ tokenExchangeUrl: "urn:manual-token",
754
+ baseUrl: "https://api.sanity.io",
755
+ displayLabel: "Sanity",
756
+ description: "Content management platform",
757
+ dashboardUrl: "https://www.sanity.io/manage",
758
+ clientIdPlaceholder: null,
759
+ requiresClientSecret: false,
760
+ logoUrl: "https://cdn.simpleicons.org/sanity",
761
+ defaultScopes: [],
762
+ injectionTemplates: [
763
+ {
764
+ hostPattern: "*.sanity.io",
765
+ injectionType: "header",
766
+ headerName: "Authorization",
767
+ valuePrefix: "Bearer ",
768
+ },
769
+ ],
770
+ },
749
771
  };
750
772
 
751
773
  export const SEEDED_PROVIDER_KEYS = new Set(Object.keys(PROVIDER_SEED_DATA));
@@ -79,7 +79,7 @@ export class PermissionPrompter {
79
79
  const timeoutMs = getConfig().timeouts.permissionTimeoutSec * 1000;
80
80
 
81
81
  const timer = setTimeout(() => {
82
- const interaction = pendingInteractions.resolve(requestId);
82
+ const interaction = pendingInteractions.resolve(requestId, "cancelled");
83
83
  this.ownedIds.delete(requestId);
84
84
  log.warn(
85
85
  { requestId, toolName },
@@ -130,7 +130,7 @@ export class PermissionPrompter {
130
130
  if (signal) {
131
131
  const onAbort = () => {
132
132
  if (this.ownedIds.has(requestId)) {
133
- pendingInteractions.resolve(requestId);
133
+ pendingInteractions.resolve(requestId, "cancelled");
134
134
  this.ownedIds.delete(requestId);
135
135
  resolve({ decision: "deny", wasAbort: true });
136
136
  }
@@ -196,7 +196,10 @@ export class PermissionPrompter {
196
196
  }
197
197
  // The prompter owns deregistration; all callers use get() to peek before
198
198
  // routing to resolveConfirmation, which fires the rpcResolve callback.
199
- const interaction = pendingInteractions.resolve(requestId);
199
+ const interaction = pendingInteractions.resolve(
200
+ requestId,
201
+ decision === "allow" ? "approved" : "rejected",
202
+ );
200
203
  this.ownedIds.delete(requestId);
201
204
  (interaction?.rpcResolve as ((v: ConfirmResult) => void) | undefined)?.(
202
205
  { decision, selectedPattern, selectedScope, decisionContext },
@@ -210,7 +213,7 @@ export class PermissionPrompter {
210
213
  */
211
214
  denyAllPending(): void {
212
215
  for (const requestId of [...this.ownedIds]) {
213
- const interaction = pendingInteractions.resolve(requestId);
216
+ const interaction = pendingInteractions.resolve(requestId, "superseded");
214
217
  this.ownedIds.delete(requestId);
215
218
  (interaction?.rpcResolve as ((v: ConfirmResult) => void) | undefined)?.(
216
219
  {
@@ -229,7 +232,7 @@ export class PermissionPrompter {
229
232
 
230
233
  dispose(): void {
231
234
  for (const requestId of [...this.ownedIds]) {
232
- const interaction = pendingInteractions.resolve(requestId);
235
+ const interaction = pendingInteractions.resolve(requestId, "cancelled");
233
236
  this.ownedIds.delete(requestId);
234
237
  interaction?.rpcReject?.(
235
238
  new AssistantError("Prompter disposed", ErrorCode.INTERNAL_ERROR),
@@ -223,8 +223,11 @@ export class QuestionPrompter {
223
223
  signal.removeEventListener("abort", onAbort);
224
224
  }
225
225
  // Idempotent: a no-op if the entry was already removed (e.g. by
226
- // `removeByConversation`) or by an earlier path.
227
- pendingInteractions.resolve(requestId);
226
+ // `removeByConversation`) or by an earlier path. The route's
227
+ // success path resolves with "answered" before invoking rpcResolve,
228
+ // so this fallback only fires for timeout / abort / removeByConversation —
229
+ // all cancellation-shaped outcomes.
230
+ pendingInteractions.resolve(requestId, "cancelled");
228
231
  fn();
229
232
  };
230
233
 
@@ -71,7 +71,7 @@ export class SecretPrompter {
71
71
  const timeoutMs = getConfig().timeouts.permissionTimeoutSec * 1000;
72
72
 
73
73
  const timer = setTimeout(() => {
74
- pendingInteractions.resolve(requestId);
74
+ pendingInteractions.resolve(requestId, "cancelled");
75
75
  this.ownedIds.delete(requestId);
76
76
  log.warn({ requestId, service, field }, "Secret prompt timed out");
77
77
  resolve({ value: null, delivery: "store" });
@@ -130,7 +130,10 @@ export class SecretPrompter {
130
130
  }
131
131
  // approval-routes calls pendingInteractions.get() before routing here;
132
132
  // the prompter owns deregistration so it fires the Promise callback cleanly.
133
- const interaction = pendingInteractions.resolve(requestId);
133
+ const interaction = pendingInteractions.resolve(
134
+ requestId,
135
+ value === undefined ? "cancelled" : "answered",
136
+ );
134
137
  this.ownedIds.delete(requestId);
135
138
  (interaction?.rpcResolve as ((v: SecretPromptResult) => void) | undefined)?.(
136
139
  { value: value ?? null, delivery: delivery ?? "store" },
@@ -139,7 +142,7 @@ export class SecretPrompter {
139
142
 
140
143
  dispose(): void {
141
144
  for (const requestId of [...this.ownedIds]) {
142
- const interaction = pendingInteractions.resolve(requestId);
145
+ const interaction = pendingInteractions.resolve(requestId, "cancelled");
143
146
  this.ownedIds.delete(requestId);
144
147
  interaction?.rpcReject?.(
145
148
  new AssistantError("Prompter disposed", ErrorCode.INTERNAL_ERROR),
@@ -25,6 +25,8 @@
25
25
  * - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
26
26
  * fired immediately before the agent loop receives a user's prompt
27
27
  * - {@link PluginLogger} — pino-compatible logger shape on the contexts
28
+ * - {@link ToolDefinition} — author-facing tool spec (default-export shape
29
+ * for both plugin tool files and workspace tool files)
28
30
  * - {@link ToolContext} — passed to a plugin tool's `execute` method
29
31
  * - {@link ToolExecutionResult} — return shape of a plugin tool's `execute`
30
32
  *
@@ -41,6 +43,8 @@ export type {
41
43
  PluginLogger,
42
44
  PluginShutdownContext,
43
45
  ToolContext,
46
+ ToolDefinition,
44
47
  ToolExecutionResult,
45
48
  UserPromptSubmitContext,
46
49
  } from "./types.js";
50
+ export { RiskLevel } from "./types.js";
@@ -1,43 +1,17 @@
1
1
  /**
2
- * Public plugin-API types.
3
- *
4
- * This module is the entry point plugin authors land on when they import
5
- * from `@vellumai/plugin-api`. The shapes here are the canonical public
6
- * contract — anything exported is part of the surface that semver gates.
7
- *
8
- * ## Tool-execution types
9
- *
10
- * `ToolContext` and `ToolExecutionResult` are re-exports of the narrow,
11
- * stable bases defined alongside their daemon-internal counterparts in
12
- * `assistant/src/tools/types.ts`. The daemon-internal `ToolContext` /
13
- * `ToolExecutionResult` (with CES, trust classification, lifecycle
14
- * events, sensitive-output bindings, risk metadata, etc.) `extends`
15
- * the public bases, so the runtime can hand plugins the full value
16
- * without a manual cast and tsc enforces the structural relationship.
17
- * Plugin tools see the narrow surface only — they MUST NOT set fields
18
- * that belong to the daemon-internal extension.
19
- *
20
- * ## Hook contexts
21
- *
22
- * The init / shutdown hook contexts are owned by this module directly.
23
- * They have no daemon-internal extension today (the daemon constructs
24
- * and hands them straight through), so there's nothing to inherit from.
25
- *
26
- * ## Compatibility
27
- *
28
- * Adding fields to any public shape is non-breaking. Renaming or
29
- * removing fields is breaking and gated on a major bump of
30
- * `@vellumai/plugin-api`.
2
+ * Public plugin-API types — the canonical contract for
3
+ * `@vellumai/plugin-api`. Adding fields is non-breaking; renaming /
4
+ * removing is breaking and gated on a major bump.
31
5
  */
32
6
 
33
7
  import type { Message } from "../providers/types.js";
34
8
 
35
- // ─── Tool-execution types (re-exported from daemon source-of-truth) ──────────
36
-
37
9
  export type {
38
- PluginToolContext as ToolContext,
39
- PluginToolExecutionResult as ToolExecutionResult,
10
+ ToolContext,
11
+ ToolDefinition,
12
+ ToolExecutionResult,
40
13
  } from "../tools/types.js";
14
+ export { RiskLevel } from "../tools/types.js";
41
15
 
42
16
  // ─── Logger ──────────────────────────────────────────────────────────────────
43
17
 
@@ -24,6 +24,7 @@
24
24
  * chain) does not trip a TDZ.
25
25
  */
26
26
 
27
+ import { memoryV3ShadowPlugin } from "../../memory/v3/shadow-middleware.js";
27
28
  import { registerPlugin, resetPluginRegistryForTests } from "../registry.js";
28
29
  import { type Plugin, PluginExecutionError } from "../types.js";
29
30
  import { defaultCircuitBreakerPlugin } from "./circuit-breaker.js";
@@ -60,6 +61,11 @@ function getAllDefaultPlugins(): readonly Plugin[] {
60
61
  defaultEmptyResponsePlugin,
61
62
  defaultToolErrorPlugin,
62
63
  defaultMemoryRetrievalPlugin,
64
+ // Live-shadow v3 retrieval. Always registered; inert unless both
65
+ // `memory.v3.enabled` and `memory.v3.shadow` are on (gated inside the
66
+ // middleware). Ordered after the default so the default terminal still
67
+ // produces the injected (v2) `MemoryResult`.
68
+ memoryV3ShadowPlugin,
63
69
  defaultInjectorsPlugin,
64
70
  defaultTokenEstimatePlugin,
65
71
  defaultOverflowReducePlugin,