@vellumai/assistant 0.10.12 → 0.11.0-staging.1

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 (776) hide show
  1. package/AGENTS.md +1 -1
  2. package/ARCHITECTURE.md +4 -5
  3. package/README.md +1 -1
  4. package/docs/architecture/memory.md +60 -23
  5. package/docs/error-handling.md +3 -3
  6. package/docs/guardian-request-flow.md +112 -0
  7. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  8. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  9. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  10. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  11. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  12. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
  13. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
  14. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
  15. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
  16. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
  17. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
  18. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
  19. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
  20. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  21. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  22. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  23. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  24. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  25. package/node_modules/@vellumai/gateway-client/package.json +1 -1
  26. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
  27. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
  28. package/node_modules/@vellumai/service-contracts/package.json +1 -0
  29. package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  30. package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  31. package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  32. package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  33. package/openapi.yaml +246 -10
  34. package/package.json +2 -2
  35. package/src/__tests__/acp-session.test.ts +3 -3
  36. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
  37. package/src/__tests__/anthropic-provider.test.ts +40 -0
  38. package/src/__tests__/approval-cascade.test.ts +5 -5
  39. package/src/__tests__/approval-routes-http.test.ts +3 -3
  40. package/src/__tests__/ask-question-resolver.test.ts +207 -0
  41. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
  42. package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
  43. package/src/__tests__/assistant-event-hub.test.ts +13 -11
  44. package/src/__tests__/assistant-event.test.ts +12 -9
  45. package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
  46. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
  47. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
  48. package/src/__tests__/assistant-stream-state.test.ts +17 -7
  49. package/src/__tests__/avatar-identity-sync.test.ts +3 -3
  50. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  51. package/src/__tests__/call-conversation-messages.test.ts +134 -18
  52. package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
  53. package/src/__tests__/channel-approvals.test.ts +0 -27
  54. package/src/__tests__/channel-guardian.test.ts +85 -512
  55. package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
  56. package/src/__tests__/channel-retry-sweep.test.ts +88 -1
  57. package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
  58. package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
  59. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  60. package/src/__tests__/compaction-events.test.ts +8 -8
  61. package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
  62. package/src/__tests__/config-model-image-provider.test.ts +20 -0
  63. package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
  64. package/src/__tests__/config-schema.test.ts +14 -2
  65. package/src/__tests__/config-set-platform-guard.test.ts +11 -12
  66. package/src/__tests__/config-sounds-sync.test.ts +4 -4
  67. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
  68. package/src/__tests__/context-search-memory-source.test.ts +1 -1
  69. package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
  70. package/src/__tests__/context-token-estimator.test.ts +54 -1
  71. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
  72. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
  73. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
  74. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
  75. package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
  76. package/src/__tests__/conversation-agent-loop.test.ts +39 -30
  77. package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
  78. package/src/__tests__/conversation-evictor.test.ts +49 -0
  79. package/src/__tests__/conversation-fork-crud.test.ts +1 -1
  80. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  81. package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
  82. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
  83. package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
  84. package/src/__tests__/conversation-queue.test.ts +81 -81
  85. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
  86. package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
  89. package/src/__tests__/conversation-slash-queue.test.ts +11 -11
  90. package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
  91. package/src/__tests__/conversation-speed-override.test.ts +2 -2
  92. package/src/__tests__/conversation-summarize-route.test.ts +9 -0
  93. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
  94. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
  95. package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
  96. package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
  97. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
  98. package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
  99. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  100. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
  101. package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
  102. package/src/__tests__/conversation-sync-tags.test.ts +5 -5
  103. package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  105. package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
  107. package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
  108. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  109. package/src/__tests__/daemon-assistant-events.test.ts +14 -15
  110. package/src/__tests__/db-test-helpers.ts +13 -27
  111. package/src/__tests__/disk-pressure-routes.test.ts +12 -3
  112. package/src/__tests__/document-tool-security.test.ts +95 -0
  113. package/src/__tests__/drain-kick-guard.test.ts +232 -0
  114. package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
  115. package/src/__tests__/emit-event-signal.test.ts +5 -6
  116. package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
  117. package/src/__tests__/events-tail-route.test.ts +6 -4
  118. package/src/__tests__/feature-flag-test-helpers.ts +10 -20
  119. package/src/__tests__/file-edit-tool.test.ts +24 -4
  120. package/src/__tests__/file-list-tool.test.ts +2 -1
  121. package/src/__tests__/file-read-tool.test.ts +62 -10
  122. package/src/__tests__/file-write-tool.test.ts +24 -5
  123. package/src/__tests__/followup-tools.test.ts +58 -0
  124. package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
  125. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  126. package/src/__tests__/guardian-question-mode.test.ts +42 -3
  127. package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
  128. package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
  129. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  130. package/src/__tests__/heartbeat-service.test.ts +1 -0
  131. package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
  132. package/src/__tests__/host-browser-proxy.test.ts +1 -1
  133. package/src/__tests__/host-file-edit-tool.test.ts +3 -3
  134. package/src/__tests__/host-file-read-tool.test.ts +2 -2
  135. package/src/__tests__/host-file-write-tool.test.ts +7 -3
  136. package/src/__tests__/host-shell-tool.test.ts +17 -5
  137. package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
  138. package/src/__tests__/image-credentials.test.ts +65 -8
  139. package/src/__tests__/injection-block.test.ts +4 -4
  140. package/src/__tests__/injector-chain.test.ts +1 -1
  141. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  142. package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
  143. package/src/__tests__/injector-v3-suppression.test.ts +6 -4
  144. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
  145. package/src/__tests__/list-messages-page-latest.test.ts +2 -2
  146. package/src/__tests__/llm-usage-store.test.ts +67 -4
  147. package/src/__tests__/log-redact.test.ts +18 -0
  148. package/src/__tests__/managed-profile-guard.test.ts +27 -0
  149. package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
  150. package/src/__tests__/media-generate-image.test.ts +62 -11
  151. package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
  153. package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
  154. package/src/__tests__/notification-decision-strategy.test.ts +115 -11
  155. package/src/__tests__/notification-deep-link.test.ts +12 -12
  156. package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
  157. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  158. package/src/__tests__/path-policy.test.ts +315 -0
  159. package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
  160. package/src/__tests__/persistence-layering-guard.test.ts +2 -2
  161. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  162. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
  163. package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
  164. package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
  165. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
  166. package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
  167. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  168. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
  169. package/src/__tests__/require-fresh-approval.test.ts +38 -38
  170. package/src/__tests__/run-due-schedules.test.ts +72 -1
  171. package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
  172. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  173. package/src/__tests__/schedule-routes.test.ts +44 -5
  174. package/src/__tests__/schedule-store.test.ts +3 -3
  175. package/src/__tests__/schedule-tools.test.ts +176 -0
  176. package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
  177. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
  178. package/src/__tests__/secret-response-routing.test.ts +3 -3
  179. package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
  180. package/src/__tests__/secret-scanner.test.ts +36 -0
  181. package/src/__tests__/send-endpoint-busy.test.ts +7 -7
  182. package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
  183. package/src/__tests__/starter-task-flow.test.ts +6 -3
  184. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  185. package/src/__tests__/subagent-disposal.test.ts +40 -11
  186. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  187. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
  188. package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
  189. package/src/__tests__/subagent-manager-notify.test.ts +73 -14
  190. package/src/__tests__/subagent-notify-parent.test.ts +48 -4
  191. package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
  192. package/src/__tests__/subagent-tools.test.ts +64 -0
  193. package/src/__tests__/sync-message-contract.test.ts +3 -3
  194. package/src/__tests__/terminal-tools.test.ts +12 -3
  195. package/src/__tests__/test-preload.ts +9 -0
  196. package/src/__tests__/tool-approval-handler.test.ts +583 -43
  197. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
  198. package/src/__tests__/tool-executor.test.ts +116 -0
  199. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
  200. package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
  201. package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
  202. package/src/__tests__/tool-start-timestamp.test.ts +4 -4
  203. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
  204. package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
  205. package/src/__tests__/ui-work-result-surface.test.ts +3 -3
  206. package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
  207. package/src/__tests__/voice-session-bridge.test.ts +44 -44
  208. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
  209. package/src/__tests__/workspace-policy.test.ts +399 -0
  210. package/src/acp/__tests__/client-handler.test.ts +3 -3
  211. package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
  212. package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
  213. package/src/acp/client-handler.ts +3 -3
  214. package/src/acp/session-manager.ts +8 -8
  215. package/src/api/events/subagent-event.ts +2 -2
  216. package/src/api/responses/memory-v2-activation-log.ts +2 -2
  217. package/src/approvals/AGENTS.md +2 -0
  218. package/src/approvals/guardian-request-resolvers.ts +118 -24
  219. package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
  220. package/src/calls/__tests__/voice-session-bridge.test.ts +158 -4
  221. package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
  222. package/src/calls/call-controller.ts +27 -27
  223. package/src/calls/call-conversation-messages.ts +58 -18
  224. package/src/calls/voice-control-protocol.ts +56 -0
  225. package/src/calls/voice-session-bridge.ts +156 -58
  226. package/src/calls/voice-triage-escalate.ts +2 -3
  227. package/src/channels/config.ts +8 -0
  228. package/src/channels/types.ts +1 -0
  229. package/src/cli/commands/config.ts +49 -13
  230. package/src/cli/commands/memory/index.help.ts +4 -2
  231. package/src/cli/commands/memory/memory-retrospective.ts +5 -0
  232. package/src/cli/lib/bundled-marketplace.json +12 -0
  233. package/src/cli.ts +2 -109
  234. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
  235. package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
  236. package/src/config/assistant-feature-flags.ts +1 -1
  237. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
  238. package/src/config/feature-flag-cache.ts +6 -16
  239. package/src/config/feature-flag-registry.json +14 -30
  240. package/src/config/loader.ts +7 -1
  241. package/src/config/memory-tier.ts +15 -10
  242. package/src/config/memory-v3-gate.test.ts +278 -1
  243. package/src/config/memory-v3-gate.ts +88 -26
  244. package/src/config/raw-config-utils.ts +1 -1
  245. package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
  246. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  247. package/src/config/schemas/live-voice.ts +33 -7
  248. package/src/config/schemas/llm.ts +1 -0
  249. package/src/config/schemas/memory-retrospective.ts +13 -0
  250. package/src/config/schemas/memory-substrate.ts +183 -0
  251. package/src/config/schemas/memory-v2.ts +3 -2
  252. package/src/config/schemas/memory-v3.ts +11 -4
  253. package/src/config/schemas/memory.ts +35 -1
  254. package/src/config/schemas/services.ts +10 -2
  255. package/src/config/substrate-twin-shadowing.ts +195 -0
  256. package/src/config/webhook-routing.ts +67 -0
  257. package/src/context/compactor.ts +10 -3
  258. package/src/context/token-estimator.ts +21 -0
  259. package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
  260. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
  261. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
  262. package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
  263. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
  264. package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
  265. package/src/daemon/channel-ui-capability.ts +70 -1
  266. package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
  267. package/src/daemon/conversation-agent-loop.ts +12 -5
  268. package/src/daemon/conversation-evictor.ts +26 -4
  269. package/src/daemon/conversation-launch.ts +11 -14
  270. package/src/daemon/conversation-messaging.ts +14 -14
  271. package/src/daemon/conversation-notifiers.ts +2 -2
  272. package/src/daemon/conversation-process.ts +133 -21
  273. package/src/daemon/conversation-queue-manager.ts +7 -7
  274. package/src/daemon/conversation-runtime-assembly.ts +16 -0
  275. package/src/daemon/conversation-store.ts +11 -3
  276. package/src/daemon/conversation-surfaces.ts +4 -4
  277. package/src/daemon/conversation-tool-setup.ts +13 -7
  278. package/src/daemon/conversation-usage.ts +12 -11
  279. package/src/daemon/conversation.ts +38 -15
  280. package/src/daemon/disk-pressure-guard.ts +5 -12
  281. package/src/daemon/embedding-reconcile.ts +14 -9
  282. package/src/daemon/handlers/config-channels.ts +40 -134
  283. package/src/daemon/handlers/config-model.ts +15 -7
  284. package/src/daemon/handlers/conversations.ts +4 -2
  285. package/src/daemon/handlers/shared.ts +29 -0
  286. package/src/daemon/host-proxy-base.ts +4 -4
  287. package/src/daemon/lifecycle.ts +13 -0
  288. package/src/daemon/message-protocol.ts +8 -144
  289. package/src/daemon/message-types/computer-use.ts +0 -12
  290. package/src/daemon/message-types/conversations.ts +9 -345
  291. package/src/daemon/message-types/host-app-control.ts +0 -9
  292. package/src/daemon/message-types/host-browser.ts +0 -7
  293. package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
  294. package/src/daemon/message-types/messages.ts +0 -48
  295. package/src/daemon/message-types/notifications.ts +0 -7
  296. package/src/daemon/message-types/skills.ts +0 -5
  297. package/src/daemon/message-types/surfaces.ts +0 -9
  298. package/src/daemon/message-types/sync.ts +0 -2
  299. package/src/daemon/process-message.ts +5 -5
  300. package/src/daemon/skill-memory-refresh.ts +5 -5
  301. package/src/daemon/tool-side-effects.ts +13 -13
  302. package/src/daemon/trust-context.ts +1 -1
  303. package/src/daemon/wake-conversation-ops.ts +4 -4
  304. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
  305. package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
  306. package/src/heartbeat/heartbeat-run-store.ts +81 -4
  307. package/src/heartbeat/heartbeat-service.ts +32 -1
  308. package/src/home/__tests__/feed-writer.test.ts +7 -7
  309. package/src/home/__tests__/home-content-refresh.test.ts +3 -0
  310. package/src/home/__tests__/suggested-prompts.test.ts +1 -0
  311. package/src/home/feed-writer.ts +6 -13
  312. package/src/home/home-content-refresh.ts +6 -9
  313. package/src/home/relationship-state-writer.ts +5 -12
  314. package/src/home/suggested-prompts-cache.ts +6 -19
  315. package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
  316. package/src/ipc/events-publish-client.ts +44 -0
  317. package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
  318. package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
  319. package/src/ipc/routes/events-ipc-routes.ts +11 -31
  320. package/src/live-voice/__tests__/front-decision.test.ts +4 -176
  321. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
  322. package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
  323. package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
  324. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
  325. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
  326. package/src/live-voice/__tests__/live-voice-vad.test.ts +218 -422
  327. package/src/live-voice/front-decision.ts +5 -155
  328. package/src/live-voice/live-voice-metrics.ts +4 -1
  329. package/src/live-voice/live-voice-session.ts +650 -333
  330. package/src/live-voice/progress-phrases.ts +17 -0
  331. package/src/live-voice/protocol.ts +15 -0
  332. package/src/media/app-icon-generator.ts +15 -8
  333. package/src/media/avatar-router.ts +9 -5
  334. package/src/media/image-credentials.ts +42 -10
  335. package/src/media/image-service.ts +1 -13
  336. package/src/media/types.ts +26 -3
  337. package/src/notifications/AGENTS.md +2 -0
  338. package/src/notifications/__tests__/broadcaster.test.ts +95 -0
  339. package/src/notifications/adapters/macos.ts +3 -3
  340. package/src/notifications/broadcaster.ts +57 -0
  341. package/src/notifications/copy-composer.ts +0 -15
  342. package/src/notifications/decision-engine.ts +21 -22
  343. package/src/notifications/guardian-question-mode.ts +57 -2
  344. package/src/notifications/home-feed-side-effect.ts +4 -0
  345. package/src/notifications/signal.ts +6 -4
  346. package/src/notifications/trusted-contact-payloads.ts +3 -4
  347. package/src/notifications/vellum-card-affinity.ts +39 -0
  348. package/src/oauth/AGENTS.md +1 -1
  349. package/src/permissions/channel-permission-query.test.ts +69 -0
  350. package/src/permissions/channel-permission-query.ts +73 -1
  351. package/src/permissions/checker.test.ts +85 -9
  352. package/src/permissions/checker.ts +17 -22
  353. package/src/permissions/confirmation-guardian-request.test.ts +2 -2
  354. package/src/permissions/confirmation-guardian-request.ts +2 -2
  355. package/src/permissions/gateway-threshold-reader.test.ts +224 -17
  356. package/src/permissions/gateway-threshold-reader.ts +82 -10
  357. package/src/permissions/ipc-risk-types.ts +8 -0
  358. package/src/permissions/prompter.ts +5 -5
  359. package/src/permissions/question-guardian-request.test.ts +222 -0
  360. package/src/permissions/question-guardian-request.ts +179 -0
  361. package/src/permissions/question-prompter.test.ts +8 -8
  362. package/src/permissions/question-prompter.ts +18 -0
  363. package/src/permissions/secret-prompter.ts +2 -4
  364. package/src/permissions/workspace-policy.ts +236 -34
  365. package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
  366. package/src/persistence/__tests__/message-content-file.test.ts +58 -3
  367. package/src/persistence/conversation-crud.ts +93 -0
  368. package/src/persistence/conversation-key-store.ts +63 -0
  369. package/src/persistence/db-async-query.ts +1 -1
  370. package/src/persistence/db-singleton.ts +14 -27
  371. package/src/persistence/delivery-crud.ts +45 -0
  372. package/src/persistence/embeddings/embedding-backend.ts +2 -1
  373. package/src/persistence/embeddings/embedding-identity.ts +7 -3
  374. package/src/persistence/job-utils.ts +32 -27
  375. package/src/persistence/jobs-store.ts +92 -3
  376. package/src/persistence/lifecycle-quiesce.ts +80 -0
  377. package/src/persistence/llm-usage-store.ts +45 -8
  378. package/src/persistence/message-content-file.ts +4 -4
  379. package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
  380. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
  381. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
  382. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
  383. package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
  384. package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
  385. package/src/persistence/schema/infrastructure.ts +11 -0
  386. package/src/persistence/steps.ts +7 -1
  387. package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
  388. package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
  389. package/src/plugin-api/conversation-turn.ts +4 -4
  390. package/src/plugin-api/event-hub-facade.ts +15 -6
  391. package/src/plugin-api/index.ts +10 -4
  392. package/src/plugin-api/publish-event.ts +36 -0
  393. package/src/plugins/AGENTS.md +2 -0
  394. package/src/plugins/defaults/compaction/window-manager.ts +9 -0
  395. package/src/plugins/defaults/index.ts +9 -13
  396. package/src/plugins/defaults/memory/AGENTS.md +775 -0
  397. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
  398. package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
  399. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
  400. package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
  401. package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
  402. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
  403. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
  404. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
  405. package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
  406. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
  407. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
  408. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
  409. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  410. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
  411. package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
  412. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
  413. package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
  414. package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
  415. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
  416. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
  417. package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
  418. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
  419. package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
  420. package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
  421. package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
  422. package/src/plugins/defaults/memory/graph/store.ts +1 -0
  423. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
  424. package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
  425. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
  426. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
  427. package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
  428. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
  429. package/src/plugins/defaults/memory/indexer.ts +146 -89
  430. package/src/plugins/defaults/memory/injectors.ts +86 -41
  431. package/src/plugins/defaults/memory/job-handlers.ts +130 -39
  432. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  433. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
  434. package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
  435. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
  436. package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
  437. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
  438. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
  439. package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
  440. package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
  441. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
  442. package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
  443. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
  444. package/src/plugins/defaults/memory/startup.ts +58 -21
  445. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
  446. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
  447. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
  448. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
  449. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
  450. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
  451. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
  452. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
  453. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
  454. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
  455. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
  456. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
  457. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
  458. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
  459. package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
  460. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
  461. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
  462. package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
  463. package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
  464. package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
  465. package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
  466. package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
  467. package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
  468. package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
  469. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
  470. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
  471. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
  472. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
  473. package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
  474. package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
  475. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
  476. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
  477. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
  478. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
  479. package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
  480. package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
  481. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
  482. package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
  483. package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
  484. package/src/plugins/defaults/memory/tools.test.ts +1 -1
  485. package/src/plugins/defaults/memory/tools.ts +1 -1
  486. package/src/plugins/defaults/memory/v1/README.md +5 -0
  487. package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
  488. package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
  489. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
  490. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
  491. package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
  492. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
  493. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
  494. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
  495. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
  496. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
  497. package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
  498. package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
  499. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
  500. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
  501. package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
  502. package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
  503. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
  504. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
  505. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
  506. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
  507. package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
  508. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
  509. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
  510. package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
  511. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
  512. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
  513. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
  514. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
  515. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
  516. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
  517. package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
  518. package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
  519. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
  520. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
  521. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
  522. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
  523. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
  524. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
  525. package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
  526. package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
  527. package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
  528. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
  529. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
  530. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
  531. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
  532. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  533. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  534. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
  535. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
  536. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
  537. package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
  538. package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
  539. package/src/plugins/defaults/memory/v2/activation.ts +30 -163
  540. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
  541. package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
  542. package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
  543. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
  544. package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
  545. package/src/plugins/defaults/memory/v2/injection.ts +36 -26
  546. package/src/plugins/defaults/memory/v2/migration.ts +2 -2
  547. package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
  548. package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
  549. package/src/plugins/defaults/memory/v2/router.ts +38 -15
  550. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
  551. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
  552. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
  553. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
  554. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
  555. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
  556. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
  557. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
  558. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
  559. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
  560. package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
  561. package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
  562. package/src/plugins/defaults/memory/v3/card.ts +25 -9
  563. package/src/plugins/defaults/memory/v3/edge.ts +52 -18
  564. package/src/plugins/defaults/memory/v3/gate.ts +4 -4
  565. package/src/plugins/defaults/memory/v3/injector.ts +10 -3
  566. package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
  567. package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
  568. package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
  569. package/src/plugins/defaults/memory/v3/prune.ts +40 -16
  570. package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
  571. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
  572. package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
  573. package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
  574. package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
  575. package/src/plugins/defaults/memory/v3/types.ts +4 -1
  576. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
  577. package/src/plugins/defaults/memory/validation.ts +1 -1
  578. package/src/plugins/defaults/memory/worker.ts +2 -1
  579. package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
  580. package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
  581. package/src/plugins/types.ts +2 -2
  582. package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
  583. package/src/providers/anthropic/client.ts +15 -6
  584. package/src/providers/content-block-schema.ts +26 -0
  585. package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
  586. package/src/providers/inference/adapter-factory.ts +6 -0
  587. package/src/providers/inference/connections.ts +30 -14
  588. package/src/providers/model-catalog.ts +77 -0
  589. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
  590. package/src/providers/openai/chat-completions-provider.ts +65 -17
  591. package/src/providers/openai/input-audio.ts +76 -0
  592. package/src/providers/openrouter/client.ts +0 -2
  593. package/src/providers/platform-proxy/constants.ts +4 -0
  594. package/src/providers/poolside/client.ts +42 -0
  595. package/src/providers/registry.ts +40 -8
  596. package/src/providers/retry.ts +2 -0
  597. package/src/providers/types.ts +39 -1
  598. package/src/providers/vercel-ai-gateway/client.ts +0 -2
  599. package/src/runtime/AGENTS.md +7 -5
  600. package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
  601. package/src/runtime/__tests__/question-resolution.test.ts +111 -0
  602. package/src/runtime/access-request-helper.ts +7 -15
  603. package/src/runtime/assistant-event-hub.ts +43 -31
  604. package/src/runtime/assistant-event-publish-options.ts +31 -0
  605. package/src/runtime/assistant-event.ts +19 -30
  606. package/src/runtime/assistant-stream-state.ts +4 -4
  607. package/src/runtime/channel-approvals.ts +0 -25
  608. package/src/runtime/channel-readiness-service.ts +99 -40
  609. package/src/runtime/channel-retry-sweep.ts +38 -15
  610. package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
  611. package/src/runtime/guardian-reply-router.ts +108 -0
  612. package/src/runtime/http-server.ts +8 -0
  613. package/src/runtime/http-types.ts +2 -2
  614. package/src/runtime/process-role.ts +42 -0
  615. package/src/runtime/question-request-guardian-bridge.ts +184 -0
  616. package/src/runtime/question-resolution.ts +153 -0
  617. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
  618. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
  619. package/src/runtime/routes/acp-routes.ts +2 -2
  620. package/src/runtime/routes/bookmark-routes.ts +3 -15
  621. package/src/runtime/routes/canned-message-complete.ts +2 -2
  622. package/src/runtime/routes/consolidation-routes.ts +8 -2
  623. package/src/runtime/routes/conversation-list-routes.ts +3 -19
  624. package/src/runtime/routes/conversation-management-routes.ts +1 -5
  625. package/src/runtime/routes/conversation-query-routes.ts +52 -8
  626. package/src/runtime/routes/conversation-routes.ts +36 -22
  627. package/src/runtime/routes/credential-request-routes.ts +0 -1
  628. package/src/runtime/routes/filing-routes.ts +7 -7
  629. package/src/runtime/routes/global-search-routes.ts +1 -1
  630. package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
  631. package/src/runtime/routes/image-generation-routes.ts +12 -9
  632. package/src/runtime/routes/inbound-message-handler.ts +17 -0
  633. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
  634. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
  635. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
  636. package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
  637. package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
  638. package/src/runtime/routes/index.ts +2 -0
  639. package/src/runtime/routes/lifecycle-routes.ts +199 -0
  640. package/src/runtime/routes/platform-routes.ts +3 -8
  641. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
  642. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
  643. package/src/runtime/routes/question-routes.ts +34 -87
  644. package/src/runtime/routes/secret-routes.ts +11 -1
  645. package/src/runtime/routes/settings-routes.ts +8 -18
  646. package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
  647. package/src/runtime/routes/workspace-routes.test.ts +7 -4
  648. package/src/runtime/slack-reply-session.test.ts +12 -12
  649. package/src/runtime/slack-reply-session.ts +17 -17
  650. package/src/runtime/sync/sync-publisher.test.ts +7 -5
  651. package/src/runtime/tool-grant-request-helper.ts +4 -0
  652. package/src/schedule/schedule-store.ts +70 -0
  653. package/src/schedule/scheduler.ts +27 -0
  654. package/src/security/AGENTS.md +1 -1
  655. package/src/security/credential-key.ts +17 -0
  656. package/src/security/secret-ingress.ts +14 -105
  657. package/src/security/secret-patterns.ts +8 -139
  658. package/src/security/secret-scanner.ts +8 -3
  659. package/src/security/store-path-override.ts +6 -16
  660. package/src/sequence/store.ts +8 -0
  661. package/src/signals/emit-event.ts +5 -10
  662. package/src/signals/event-stream.ts +20 -10
  663. package/src/subagent/manager.ts +76 -25
  664. package/src/subagent/notify.ts +8 -0
  665. package/src/subagent/types.ts +13 -3
  666. package/src/telegram/__tests__/webhook-health.test.ts +442 -0
  667. package/src/telegram/webhook-health.ts +478 -0
  668. package/src/telemetry/AGENTS.md +6 -0
  669. package/src/telemetry/memory-corpus-size.test.ts +129 -0
  670. package/src/telemetry/memory-corpus-size.ts +184 -0
  671. package/src/telemetry/memory-tier-reporter.test.ts +67 -2
  672. package/src/telemetry/memory-tier-reporter.ts +30 -3
  673. package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
  674. package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
  675. package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
  676. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
  677. package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
  678. package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
  679. package/src/tools/acp/abort.ts +21 -1
  680. package/src/tools/acp/context.ts +5 -5
  681. package/src/tools/acp/spawn.test.ts +15 -5
  682. package/src/tools/acp/spawn.ts +26 -3
  683. package/src/tools/acp/status.ts +20 -1
  684. package/src/tools/acp/steer.test.ts +20 -0
  685. package/src/tools/acp/steer.ts +23 -2
  686. package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
  687. package/src/tools/ask-question/ask-question-tool.ts +68 -92
  688. package/src/tools/browser/browser-screencast.ts +6 -6
  689. package/src/tools/calls/call-end.ts +24 -3
  690. package/src/tools/calls/call-start.ts +35 -11
  691. package/src/tools/calls/call-status.ts +20 -1
  692. package/src/tools/document/document-comment-tool.test.ts +49 -0
  693. package/src/tools/document/document-comment-tool.ts +45 -6
  694. package/src/tools/document/document-tool.ts +142 -24
  695. package/src/tools/executor.ts +27 -13
  696. package/src/tools/filesystem/edit.ts +62 -60
  697. package/src/tools/filesystem/list.ts +36 -29
  698. package/src/tools/filesystem/read.ts +56 -39
  699. package/src/tools/filesystem/write.ts +44 -38
  700. package/src/tools/followups/followup_create.ts +41 -12
  701. package/src/tools/followups/followup_list.ts +34 -6
  702. package/src/tools/followups/followup_resolve.ts +26 -4
  703. package/src/tools/host-filesystem/edit.ts +50 -60
  704. package/src/tools/host-filesystem/read.ts +45 -39
  705. package/src/tools/host-filesystem/write.ts +31 -36
  706. package/src/tools/host-terminal/host-shell.ts +76 -62
  707. package/src/tools/policy-context.ts +27 -10
  708. package/src/tools/schedule/create.ts +76 -33
  709. package/src/tools/schedule/delete.ts +21 -2
  710. package/src/tools/schedule/list.ts +25 -3
  711. package/src/tools/schedule/update.ts +105 -48
  712. package/src/tools/shared/filesystem/path-policy.ts +246 -40
  713. package/src/tools/shared/zod-tool-schema.ts +117 -0
  714. package/src/tools/subagent/abort.ts +12 -4
  715. package/src/tools/subagent/consult-deadline.ts +9 -3
  716. package/src/tools/subagent/message.ts +21 -5
  717. package/src/tools/subagent/notify-parent.ts +44 -23
  718. package/src/tools/subagent/read.ts +15 -4
  719. package/src/tools/subagent/resolve.ts +26 -4
  720. package/src/tools/subagent/spawn.ts +37 -13
  721. package/src/tools/subagent/status.ts +12 -4
  722. package/src/tools/system/request-permission.ts +35 -26
  723. package/src/tools/terminal/shell.ts +68 -55
  724. package/src/tools/tool-approval-handler.ts +327 -53
  725. package/src/tools/tool-input-schemas.ts +85 -0
  726. package/src/tools/tool-types.ts +7 -0
  727. package/src/tools/types.ts +8 -0
  728. package/src/tools/workflows/manage-workflows.ts +30 -2
  729. package/src/tools/workflows/run-workflow.test.ts +54 -2
  730. package/src/tools/workflows/run-workflow.ts +32 -4
  731. package/src/util/fs-symlinks.ts +30 -0
  732. package/src/util/log-redact.ts +7 -3
  733. package/src/vellum-assistant-namespace.d.ts +80 -0
  734. package/src/watcher/watcher-store.ts +8 -0
  735. package/src/workflows/leaf-runner.test.ts +104 -2
  736. package/src/workflows/leaf-runner.ts +31 -6
  737. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
  738. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
  739. package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
  740. package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
  741. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
  742. package/src/workspace/migrations/registry.ts +4 -0
  743. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  744. package/src/__tests__/secret-patterns.test.ts +0 -27
  745. package/src/config/__tests__/proc-to-skills.test.ts +0 -21
  746. package/src/config/memory-tier.test.ts +0 -44
  747. package/src/daemon/message-types/acp.ts +0 -20
  748. package/src/daemon/message-types/apps.ts +0 -11
  749. package/src/daemon/message-types/background-tools.ts +0 -14
  750. package/src/daemon/message-types/bookmarks.ts +0 -13
  751. package/src/daemon/message-types/contacts.ts +0 -13
  752. package/src/daemon/message-types/document-comments.ts +0 -14
  753. package/src/daemon/message-types/documents.ts +0 -13
  754. package/src/daemon/message-types/home.ts +0 -15
  755. package/src/daemon/message-types/host-bash.ts +0 -12
  756. package/src/daemon/message-types/host-cu.ts +0 -10
  757. package/src/daemon/message-types/host-file.ts +0 -12
  758. package/src/daemon/message-types/host-transfer.ts +0 -12
  759. package/src/daemon/message-types/integrations.ts +0 -90
  760. package/src/daemon/message-types/memory.ts +0 -10
  761. package/src/daemon/message-types/schedules.ts +0 -14
  762. package/src/daemon/message-types/settings.ts +0 -17
  763. package/src/daemon/message-types/subagents.ts +0 -63
  764. package/src/daemon/message-types/upgrades.ts +0 -14
  765. package/src/daemon/message-types/workflows.ts +0 -25
  766. package/src/daemon/message-types/workspace.ts +0 -137
  767. package/src/live-voice/ack-phrases.ts +0 -58
  768. package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
  769. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  770. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  771. package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
  772. package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
  773. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  774. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
  775. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
  776. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
@@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import type { SessionNotification } from "@agentclientprotocol/sdk";
4
4
 
5
- import type { ServerMessage } from "../../daemon/message-protocol.js";
5
+ import type { AssistantEvent } from "../../api/index.js";
6
6
  import { VellumAcpClientHandler } from "../client-handler.js";
7
7
 
8
8
  const ACP_SESSION_ID = "acp-session-abc";
@@ -10,9 +10,9 @@ const PARENT_CONVERSATION_ID = "conv-xyz";
10
10
 
11
11
  function makeHandler(): {
12
12
  handler: VellumAcpClientHandler;
13
- sent: ServerMessage[];
13
+ sent: AssistantEvent[];
14
14
  } {
15
- const sent: ServerMessage[] = [];
15
+ const sent: AssistantEvent[] = [];
16
16
  const handler = new VellumAcpClientHandler(
17
17
  ACP_SESSION_ID,
18
18
  (msg) => {
@@ -11,7 +11,7 @@
11
11
  import { beforeEach, describe, expect, test } from "bun:test";
12
12
 
13
13
  import type { AcpSessionUpdateEvent } from "../../api/events/acp-session-update.js";
14
- import type { ServerMessage } from "../../daemon/message-protocol.js";
14
+ import type { AssistantEvent } from "../../api/index.js";
15
15
  import { getSqlite } from "../../persistence/db-connection.js";
16
16
  import { initializeDb } from "../../persistence/db-init.js";
17
17
  import { VellumAcpClientHandler } from "../client-handler.js";
@@ -47,8 +47,8 @@ function buildSessionWithFakeProcess(opts: {
47
47
  emitUpdate: (update: AcpSessionUpdateEvent) => void;
48
48
  } {
49
49
  const manager = new AcpSessionManager(1);
50
- const sent: ServerMessage[] = [];
51
- const sendToVellum = (msg: ServerMessage) => sent.push(msg);
50
+ const sent: AssistantEvent[] = [];
51
+ const sendToVellum = (msg: AssistantEvent) => sent.push(msg);
52
52
 
53
53
  type PromptResolution = {
54
54
  stopReason: string;
@@ -81,7 +81,7 @@ function buildSessionWithFakeProcess(opts: {
81
81
  ).eventBuffers;
82
82
  eventBuffers.set(opts.id, []);
83
83
 
84
- const wrappedSend = (msg: ServerMessage) => {
84
+ const wrappedSend = (msg: AssistantEvent) => {
85
85
  if (msg.type === "acp_session_update") {
86
86
  (
87
87
  manager as unknown as {
@@ -464,7 +464,7 @@ describe("AcpSessionManager — terminal persistence", () => {
464
464
 
465
465
  test("emits acp_session_usage and persists input/output tokens from PromptResponse.usage", async () => {
466
466
  const id = "session-io-usage-1";
467
- const sent: ServerMessage[] = [];
467
+ const sent: AssistantEvent[] = [];
468
468
  const handles = buildSessionWithFakeProcess({
469
469
  id,
470
470
  agentId: "agent-io",
@@ -478,11 +478,11 @@ describe("AcpSessionManager — terminal persistence", () => {
478
478
  // Capture the usage event emitted at turn end.
479
479
  const captureSend = (
480
480
  handles.manager as unknown as {
481
- sessions: Map<string, { sendToVellum: (m: ServerMessage) => void }>;
481
+ sessions: Map<string, { sendToVellum: (m: AssistantEvent) => void }>;
482
482
  }
483
483
  ).sessions.get(id);
484
484
  const originalSend = captureSend!.sendToVellum;
485
- captureSend!.sendToVellum = (msg: ServerMessage) => {
485
+ captureSend!.sendToVellum = (msg: AssistantEvent) => {
486
486
  sent.push(msg);
487
487
  originalSend(msg);
488
488
  };
@@ -515,7 +515,7 @@ describe("AcpSessionManager — terminal persistence", () => {
515
515
 
516
516
  test("does not emit usage or write token columns when PromptResponse carries no usage", async () => {
517
517
  const id = "session-io-no-usage-1";
518
- const sent: ServerMessage[] = [];
518
+ const sent: AssistantEvent[] = [];
519
519
  const handles = buildSessionWithFakeProcess({
520
520
  id,
521
521
  agentId: "agent-io-none",
@@ -525,11 +525,11 @@ describe("AcpSessionManager — terminal persistence", () => {
525
525
 
526
526
  const entry = (
527
527
  handles.manager as unknown as {
528
- sessions: Map<string, { sendToVellum: (m: ServerMessage) => void }>;
528
+ sessions: Map<string, { sendToVellum: (m: AssistantEvent) => void }>;
529
529
  }
530
530
  ).sessions.get(id);
531
531
  const originalSend = entry!.sendToVellum;
532
- entry!.sendToVellum = (msg: ServerMessage) => {
532
+ entry!.sendToVellum = (msg: AssistantEvent) => {
533
533
  sent.push(msg);
534
534
  originalSend(msg);
535
535
  };
@@ -208,7 +208,7 @@ const BUN_BIN = "/usr/local/bin/bun";
208
208
  const BUN_ADD_KEY = `${BUN_BIN} add`;
209
209
 
210
210
  import type { AcpSessionUpdateEvent } from "../../api/events/acp-session-update.js";
211
- import type { ServerMessage } from "../../daemon/message-protocol.js";
211
+ import type { AssistantEvent } from "../../api/index.js";
212
212
  import { getSqlite } from "../../persistence/db-connection.js";
213
213
  import { initializeDb } from "../../persistence/db-init.js";
214
214
  import type { AcpSessionState } from "../types.js";
@@ -292,7 +292,7 @@ describe("AcpSessionManager.resumeFromHistory", () => {
292
292
  });
293
293
 
294
294
  const manager = new AcpSessionManager(4);
295
- const sent: ServerMessage[] = [];
295
+ const sent: AssistantEvent[] = [];
296
296
  await manager.resumeFromHistory("resume-1", (msg) => sent.push(msg));
297
297
 
298
298
  const fake = fakeInstances[0]!;
@@ -355,7 +355,7 @@ describe("AcpSessionManager.resumeFromHistory", () => {
355
355
  });
356
356
 
357
357
  const manager = new AcpSessionManager(4);
358
- const sent: ServerMessage[] = [];
358
+ const sent: AssistantEvent[] = [];
359
359
  await manager.resumeFromHistory("resume-seq-1", (msg) => sent.push(msg));
360
360
 
361
361
  const fake = fakeInstances[0]!;
@@ -716,7 +716,7 @@ describe("AcpSessionManager.resumeFromHistory", () => {
716
716
  insertHistoryRow({ id: "race-1" });
717
717
 
718
718
  const manager = new AcpSessionManager(4);
719
- const sent: ServerMessage[] = [];
719
+ const sent: AssistantEvent[] = [];
720
720
  const [a, b] = await Promise.allSettled([
721
721
  manager.resumeFromHistory("race-1", (msg) => sent.push(msg)),
722
722
  manager.resumeFromHistory("race-1", (msg) => sent.push(msg)),
@@ -862,7 +862,7 @@ describe("AcpSessionManager.steerOrResume", () => {
862
862
  insertHistoryRow({ id: "sor-resume-1" });
863
863
 
864
864
  const manager = new AcpSessionManager(4);
865
- const sent: ServerMessage[] = [];
865
+ const sent: AssistantEvent[] = [];
866
866
  const result = await manager.steerOrResume(
867
867
  "sor-resume-1",
868
868
  "continue the work",
@@ -904,7 +904,7 @@ describe("AcpSessionManager.steerOrResume", () => {
904
904
  insertHistoryRow({ id: "sor-race-1" });
905
905
 
906
906
  const manager = new AcpSessionManager(4);
907
- const sent: ServerMessage[] = [];
907
+ const sent: AssistantEvent[] = [];
908
908
  const [a, b] = await Promise.all([
909
909
  manager.steerOrResume("sor-race-1", "first instruction", (msg) =>
910
910
  sent.push(msg),
@@ -943,7 +943,7 @@ describe("AcpSessionManager.steerOrResume", () => {
943
943
  });
944
944
 
945
945
  const manager = new AcpSessionManager(4);
946
- const sent: ServerMessage[] = [];
946
+ const sent: AssistantEvent[] = [];
947
947
  const first = manager.steerOrResume(
948
948
  "sor-init-1",
949
949
  "first instruction",
@@ -32,7 +32,7 @@ import type {
32
32
  } from "@agentclientprotocol/sdk";
33
33
 
34
34
  import type { AcpSessionUpdateEvent } from "../api/events/acp-session-update.js";
35
- import type { ServerMessage } from "../daemon/message-protocol.js";
35
+ import type { AssistantEvent } from "../api/index.js";
36
36
  import { redactJsonStringLeaves } from "../security/redact-json.js";
37
37
  import { redactSensitiveFields } from "../security/redaction.js";
38
38
  import { redactSecrets } from "../security/secret-scanner.js";
@@ -72,7 +72,7 @@ interface TerminalState {
72
72
 
73
73
  /**
74
74
  * Vellum's ACP Client handler. Receives events from an ACP agent and
75
- * forwards them as ServerMessage objects to connected Vellum clients.
75
+ * forwards them as AssistantEvent objects to connected Vellum clients.
76
76
  */
77
77
  export class VellumAcpClientHandler implements Client {
78
78
  private terminals = new Map<string, TerminalState>();
@@ -101,7 +101,7 @@ export class VellumAcpClientHandler implements Client {
101
101
 
102
102
  constructor(
103
103
  private readonly acpSessionId: string,
104
- private readonly sendToVellum: (msg: ServerMessage) => void,
104
+ private readonly sendToVellum: (msg: AssistantEvent) => void,
105
105
  private readonly parentConversationId: string,
106
106
  ) {}
107
107
 
@@ -9,8 +9,8 @@ import { basename } from "node:path";
9
9
  import { eq, inArray } from "drizzle-orm";
10
10
 
11
11
  import type { AcpSessionUpdateEvent } from "../api/events/acp-session-update.js";
12
+ import type { AssistantEvent } from "../api/index.js";
12
13
  import { findConversation } from "../daemon/conversation-registry.js";
13
- import type { ServerMessage } from "../daemon/message-protocol.js";
14
14
  import { getDb } from "../persistence/db-connection.js";
15
15
  import { acpSessionHistory } from "../persistence/schema/index.js";
16
16
  import * as pendingInteractions from "../runtime/pending-interactions.js";
@@ -69,7 +69,7 @@ interface SessionEntry {
69
69
  state: AcpSessionState;
70
70
  clientHandler: VellumAcpClientHandler;
71
71
  /** Wrapped sender that also appends to the ring buffer. */
72
- sendToVellum: (msg: ServerMessage) => void;
72
+ sendToVellum: (msg: AssistantEvent) => void;
73
73
  currentPrompt: Promise<unknown> | null;
74
74
  parentConversationId: string;
75
75
  cwd: string;
@@ -195,7 +195,7 @@ export class AcpSessionManager {
195
195
  task: string,
196
196
  cwd: string,
197
197
  parentConversationId: string,
198
- sendToVellum: (msg: ServerMessage) => void,
198
+ sendToVellum: (msg: AssistantEvent) => void,
199
199
  parentToolUseId?: string,
200
200
  ): Promise<{ acpSessionId: string; protocolSessionId: string }> {
201
201
  this.assertCapacity();
@@ -275,7 +275,7 @@ export class AcpSessionManager {
275
275
  parentConversationId: string;
276
276
  cwd: string;
277
277
  startedAt: number;
278
- sendToVellum: (msg: ServerMessage) => void;
278
+ sendToVellum: (msg: AssistantEvent) => void;
279
279
  parentToolUseId?: string;
280
280
  task?: string;
281
281
  }): SessionEntry {
@@ -287,7 +287,7 @@ export class AcpSessionManager {
287
287
  // Wrap the sender so every emitted message is mirrored into the buffer
288
288
  // when it's an `acp_session_update`. The wrapper preserves the original
289
289
  // call semantics: it forwards every message unchanged.
290
- const wrappedSend = (msg: ServerMessage) => {
290
+ const wrappedSend = (msg: AssistantEvent) => {
291
291
  if (msg.type === "acp_session_update") {
292
292
  this.appendToBuffer(acpSessionId, msg);
293
293
  } else if (msg.type === "acp_session_usage") {
@@ -383,7 +383,7 @@ export class AcpSessionManager {
383
383
  */
384
384
  async resumeFromHistory(
385
385
  acpSessionId: string,
386
- sendToVellum: (msg: ServerMessage) => void,
386
+ sendToVellum: (msg: AssistantEvent) => void,
387
387
  ): Promise<void> {
388
388
  if (
389
389
  this.sessions.has(acpSessionId) ||
@@ -448,7 +448,7 @@ export class AcpSessionManager {
448
448
  private async performResume(
449
449
  acpSessionId: string,
450
450
  row: ResumableHistoryRow,
451
- sendToVellum: (msg: ServerMessage) => void,
451
+ sendToVellum: (msg: AssistantEvent) => void,
452
452
  ): Promise<void> {
453
453
  // Resolve the adapter, silently auto-installing a missing allowlisted
454
454
  // binary via the same sandboxed `bun` path as spawn (see
@@ -658,7 +658,7 @@ export class AcpSessionManager {
658
658
  async steerOrResume(
659
659
  acpSessionId: string,
660
660
  instruction: string,
661
- sendToVellum: (msg: ServerMessage) => void,
661
+ sendToVellum: (msg: AssistantEvent) => void,
662
662
  ): Promise<{ resumed: boolean }> {
663
663
  try {
664
664
  await this.steer(acpSessionId, instruction);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `subagent_event` SSE event.
3
3
  *
4
- * Server → client envelope wrapping any inner `ServerMessage`
4
+ * Server → client envelope wrapping any inner `AssistantEvent`
5
5
  * emitted by a subagent's conversation. The daemon's subagent
6
6
  * manager rebroadcasts the subagent's own stream through the
7
7
  * parent conversation's `sendToClient`, tagged with the subagent's
@@ -9,7 +9,7 @@
9
9
  * to route inner events to the appropriate inline subagent surface.
10
10
  *
11
11
  * The inner `event` is opaque on the wire — it is itself a fully
12
- * structured `ServerMessage` (any member of the canonical event
12
+ * structured `AssistantEvent` (any member of the canonical event
13
13
  * union) and re-validating it here would duplicate work and
14
14
  * tightly couple subagent canonicalization to every other event
15
15
  * schema. Clients re-parse `event` through the same event parser
@@ -2,7 +2,7 @@
2
2
  * Wire contract for the memory v2 activation log surfaced in the
3
3
  * inspector's Memory tab. Mirrors the return value of
4
4
  * `getMemoryV2ActivationLogByMessageIds` in
5
- * `assistant/src/memory/memory-v2-activation-log-store.ts`.
5
+ * `assistant/src/plugins/defaults/memory/v2/activation-log-store.ts`.
6
6
  *
7
7
  * Canonical wire-contract source. Assistant code imports the types
8
8
  * directly from this file via relative paths; external consumers
@@ -20,7 +20,7 @@ import { z } from "zod";
20
20
  /**
21
21
  * One concept row in the V2 activation log. Mirrors
22
22
  * `MemoryV2ConceptRowRecord` from
23
- * `assistant/src/memory/memory-v2-activation-log-store.ts`.
23
+ * `assistant/src/plugins/defaults/memory/v2/activation-log-store.ts`.
24
24
  *
25
25
  * `source` and `status` are open-ended strings on the wire — the
26
26
  * daemon emits known values like `prior_state`, `ann_top50`, `both`
@@ -1,5 +1,7 @@
1
1
  # Approvals & Guardian Rules
2
2
 
3
+ The end-to-end lifecycle of interactive guardian requests (approvals, questions) — promotion, notification cards, reply routing, resolution — is mapped in [docs/guardian-request-flow.md](../../docs/guardian-request-flow.md). Read it before extending any decision or card-delivery path.
4
+
3
5
  ## Approval Flow Resilience
4
6
 
5
7
  - **Rich delivery failures must degrade gracefully.** If delivering a rich approval prompt (e.g., Telegram inline buttons) fails, fall back to plain text with instructions (e.g., `Reply "yes" to approve`) — never auto-deny.
@@ -26,6 +26,7 @@ import { getGuardianRequestOrNull } from "../channels/gateway-guardian-requests.
26
26
  import { findContactChannel } from "../contacts/contact-store.js";
27
27
  import { findConversation } from "../daemon/conversation-registry.js";
28
28
  import { emitNotificationSignal } from "../notifications/emit-signal.js";
29
+ import { parseQuestionAnswerActionId } from "../notifications/guardian-question-mode.js";
29
30
  import {
30
31
  isNotificationSourceChannel,
31
32
  type NotificationSourceChannel,
@@ -34,6 +35,7 @@ import type {
34
35
  TrustedContactDecisionPayload,
35
36
  TrustedContactVerificationSentPayload,
36
37
  } from "../notifications/trusted-contact-payloads.js";
38
+ import type { QuestionBatchSubmission } from "../permissions/question-prompter.js";
37
39
  import type { UserDecision } from "../permissions/types.js";
38
40
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
39
41
  import {
@@ -48,6 +50,10 @@ import {
48
50
  resolveTrustBinding,
49
51
  } from "../runtime/introduction-policy.js";
50
52
  import * as pendingInteractions from "../runtime/pending-interactions.js";
53
+ import {
54
+ readBatchMetadata,
55
+ resolvePendingQuestion,
56
+ } from "../runtime/question-resolution.js";
51
57
  import { TC_GRANT_WAIT_MAX_MS } from "../tools/tool-approval-handler.js";
52
58
  import { getLogger } from "../util/logger.js";
53
59
  import { resolveDeliverCallbackUrlForChannel } from "./guardian-channel-delivery.js";
@@ -409,11 +415,16 @@ const pendingInteractionResolver: GuardianRequestResolver = {
409
415
  };
410
416
 
411
417
  /**
412
- * Resolves `pending_question` requests — the voice call question path.
418
+ * Resolves `pending_question` requests. Two variants share the kind,
419
+ * distinguished by provenance fields:
420
+ *
421
+ * - Voice-call questions carry a `callSessionId` (+ `pendingQuestionId`);
422
+ * the answer is delivered to the live call session via `answerCall`.
423
+ * - `ask_question` prompts carry neither — the request id IS the pending
424
+ * `question` interaction's requestId (mirroring `tool_approval` rows), and
425
+ * the answer resolves that interaction so the parked tool call returns.
413
426
  *
414
- * Validates that voice-specific fields (callSessionId, pendingQuestionId)
415
- * are present and delivers the answer to the live call session. An
416
- * `answerCall` failure surfaces as `resolverFailed` — the committed decision
427
+ * Side-effect failures surface as `resolverFailed` — the committed decision
417
428
  * stands (no reopen).
418
429
  */
419
430
  const pendingQuestionResolver: GuardianRequestResolver = {
@@ -423,10 +434,7 @@ const pendingQuestionResolver: GuardianRequestResolver = {
423
434
  const { request, decision, actor: _actor } = ctx;
424
435
 
425
436
  if (!request.callSessionId) {
426
- return {
427
- ok: false,
428
- reason: "pending_question request missing callSessionId",
429
- };
437
+ return resolveAskQuestionInteraction(request, decision);
430
438
  }
431
439
 
432
440
  if (!request.pendingQuestionId) {
@@ -487,6 +495,100 @@ const pendingQuestionResolver: GuardianRequestResolver = {
487
495
  },
488
496
  };
489
497
 
498
+ /**
499
+ * Resolve an `ask_question` pending interaction from a guardian decision.
500
+ *
501
+ * The decision's `userText` carries either an answer-option token
502
+ * (`answer_<idx>` / `answer_skip`, from a tapped card button — see
503
+ * {@link parseQuestionAnswerActionId}) or the guardian's free-typed answer.
504
+ * A reject decision with no text is an explicit skip. Submission validation
505
+ * and the prompter hand-off go through the shared
506
+ * {@link resolvePendingQuestion}, the same core `/v1/question-response` uses,
507
+ * so an app-card answer and a channel answer resolve identically.
508
+ */
509
+ async function resolveAskQuestionInteraction(
510
+ request: GuardianRequestWire,
511
+ decision: ResolverDecision,
512
+ ): Promise<ResolverResult> {
513
+ const interaction = pendingInteractions.get(request.id);
514
+ if (!interaction || interaction.kind !== "question") {
515
+ // The parked prompt is gone (answered elsewhere, timed out, or the daemon
516
+ // restarted). The committed decision stands; there is just nothing left to
517
+ // resume.
518
+ return { ok: false, reason: "no_pending_question_interaction" };
519
+ }
520
+
521
+ const { orderedIds, optionsById } = readBatchMetadata(interaction);
522
+ if (orderedIds.length !== 1) {
523
+ // Channel cards are only created for single-question batches (the
524
+ // promotion gate enforces it); a multi-question interaction cannot be
525
+ // answered by one decision.
526
+ return { ok: false, reason: "question_batch_not_single" };
527
+ }
528
+ const questionId = orderedIds[0]!;
529
+
530
+ let submission: QuestionBatchSubmission;
531
+ const answerSelection = decision.userText
532
+ ? parseQuestionAnswerActionId(decision.userText.trim())
533
+ : null;
534
+ if (answerSelection?.kind === "skip") {
535
+ submission = { questionId, kind: "skip" };
536
+ } else if (answerSelection?.kind === "option") {
537
+ const optionId = (optionsById[questionId] ?? [])[answerSelection.index];
538
+ if (!optionId) {
539
+ return { ok: false, reason: "question_option_index_out_of_range" };
540
+ }
541
+ submission = { questionId, kind: "option", optionId };
542
+ } else if (decision.userText && decision.userText.trim().length > 0) {
543
+ submission = {
544
+ questionId,
545
+ kind: "free_text",
546
+ text: decision.userText.trim(),
547
+ };
548
+ } else if (DENYING_ACTION_SET.has(decision.action)) {
549
+ submission = { questionId, kind: "skip" };
550
+ } else {
551
+ // Bare approval with no text (e.g. "CODE approve") — affirm without
552
+ // inventing content; the model reads the affirmation in context.
553
+ submission = { questionId, kind: "free_text", text: "Yes" };
554
+ }
555
+
556
+ const outcome = resolvePendingQuestion(request.id, {
557
+ kind: "submit",
558
+ submissions: [submission],
559
+ });
560
+ if (outcome.status !== "resolved") {
561
+ log.warn(
562
+ {
563
+ event: "resolver_ask_question_not_resolved",
564
+ requestId: request.id,
565
+ outcome: outcome.status,
566
+ ...(outcome.status === "invalid" ? { message: outcome.message } : {}),
567
+ },
568
+ "Ask-question resolver: pending interaction did not resolve",
569
+ );
570
+ return {
571
+ ok: false,
572
+ reason:
573
+ outcome.status === "invalid"
574
+ ? "question_submission_invalid"
575
+ : "no_pending_question_interaction",
576
+ };
577
+ }
578
+
579
+ log.info(
580
+ {
581
+ event: "resolver_ask_question_applied",
582
+ requestId: request.id,
583
+ action: decision.action,
584
+ submissionKind: submission.kind,
585
+ conversationId: outcome.conversationId,
586
+ },
587
+ "Ask-question resolver: pending interaction resolved",
588
+ );
589
+ return { ok: true, applied: true };
590
+ }
591
+
490
592
  /**
491
593
  * The four introduction-card outcomes for an access request. The generic
492
594
  * decision pair maps onto them: `approve_once` → `verify_code` (handshake),
@@ -658,9 +760,9 @@ async function deliverRequesterNotice(params: {
658
760
  }
659
761
 
660
762
  /**
661
- * Emit the guardian-facing denial lifecycle signals and, unless suppressed,
763
+ * Emit the guardian-facing denial lifecycle signal and, unless suppressed,
662
764
  * deliver the "declined" notice to the requester. Both the `leave_unverified`
663
- * and `block` outcomes call this for the lifecycle signals, but the requester
765
+ * and `block` outcomes call this for the lifecycle signal, but the requester
664
766
  * notice is delivered only for `block` (in denied mode) — `leave_unverified`
665
767
  * always passes `suppressRequesterNotice: true`, staying a silent park at
666
768
  * `unverified`. The notice text is a plain decline that does not reveal whether
@@ -712,6 +814,12 @@ async function notifyRequesterOfDenial(params: {
712
814
  });
713
815
  }
714
816
 
817
+ // Exactly one signal per denial: the payload's `decision: "denied"`
818
+ // carries the verdict, and the pipeline can only dedupe within a single
819
+ // event stream — a second event name would materialize a second
820
+ // conversation for the same decision. The approve path holds the same
821
+ // one-signal invariant via `verification_sent` standing in for
822
+ // `guardian_decision`.
715
823
  if (channelDeliveryContext) {
716
824
  void emitNotificationSignal({
717
825
  sourceEventName: "ingress.trusted_contact.guardian_decision",
@@ -726,20 +834,6 @@ async function notifyRequesterOfDenial(params: {
726
834
  contextPayload: deniedPayload,
727
835
  dedupeKey: `trusted-contact:guardian-decision:${requestId}`,
728
836
  });
729
-
730
- void emitNotificationSignal({
731
- sourceEventName: "ingress.trusted_contact.denied",
732
- sourceChannel: channel,
733
- sourceContextId: conversationId ?? "",
734
- attentionHints: {
735
- requiresAction: false,
736
- urgency: "low",
737
- isAsyncBackground: false,
738
- visibleInSourceNow: false,
739
- },
740
- contextPayload: deniedPayload,
741
- dedupeKey: `trusted-contact:denied:${requestId}`,
742
- });
743
837
  }
744
838
  }
745
839
 
@@ -4,6 +4,8 @@ import {
4
4
  couldBeControlMarker,
5
5
  ESCALATE_VERDICT_TOKEN,
6
6
  HOLD_VERDICT_TOKEN,
7
+ isIncompleteControlMarkerTail,
8
+ MINIMIZE_ROOM_MARKER,
7
9
  stripInternalSpeechMarkers,
8
10
  } from "../voice-control-protocol.js";
9
11
 
@@ -46,3 +48,58 @@ describe("front-door verdict tokens", () => {
46
48
  );
47
49
  });
48
50
  });
51
+
52
+ describe("minimize-room marker", () => {
53
+ test("marker constant is the expected bracketed form", () => {
54
+ expect(MINIMIZE_ROOM_MARKER).toBe("[-1]");
55
+ });
56
+
57
+ test("stripInternalSpeechMarkers removes the marker so it is never spoken", () => {
58
+ expect(
59
+ stripInternalSpeechMarkers("Done [-1] here").replace(/\s+/g, " "),
60
+ ).toBe("Done here");
61
+ });
62
+
63
+ test("couldBeControlMarker holds the marker and its streaming prefixes", () => {
64
+ for (const text of ["[", "[-", "[-1", "[-1]", "[-1] trailing"]) {
65
+ expect(couldBeControlMarker(text)).toBe(true);
66
+ }
67
+ });
68
+
69
+ test("a bracket prefix that disproves the marker is not held", () => {
70
+ expect(couldBeControlMarker("[- something else")).toBe(false);
71
+ });
72
+ });
73
+
74
+ describe("isIncompleteControlMarkerTail", () => {
75
+ test("strict prefixes of any marker are incomplete", () => {
76
+ for (const tail of ["[", "[-", "[-1", "[END_CAL", "[ASK_GUARDIAN_APPRO"]) {
77
+ expect(isIncompleteControlMarkerTail(tail)).toBe(true);
78
+ }
79
+ });
80
+
81
+ test("complete literal markers are not held", () => {
82
+ for (const tail of ["[-1]", "[END_CALL]", "[0] answer", "[-1] look here"]) {
83
+ expect(isIncompleteControlMarkerTail(tail)).toBe(false);
84
+ }
85
+ });
86
+
87
+ test("guardian-approval is judged by the balanced parser, not the first bracket", () => {
88
+ const streaming =
89
+ '[ASK_GUARDIAN_APPROVAL: {"question": "ok]?", "options": ["a", "b"';
90
+ expect(isIncompleteControlMarkerTail(streaming)).toBe(true);
91
+ expect(isIncompleteControlMarkerTail(`${streaming}]}]`)).toBe(false);
92
+ });
93
+
94
+ test("colon-style markers terminate at their first bracket", () => {
95
+ expect(isIncompleteControlMarkerTail("[ASK_GUARDIAN: may I")).toBe(true);
96
+ expect(isIncompleteControlMarkerTail("[ASK_GUARDIAN: may I?]")).toBe(false);
97
+ expect(isIncompleteControlMarkerTail("[USER_ANSWERED: yes")).toBe(true);
98
+ });
99
+
100
+ test("non-marker bracket text is not held", () => {
101
+ for (const tail of ["[- something else", "[sic]", '["a", "b"]']) {
102
+ expect(isIncompleteControlMarkerTail(tail)).toBe(false);
103
+ }
104
+ });
105
+ });