@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
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Bridge a guardian's parked `ask_question` prompt to a `guardian.question`
3
+ * notification.
4
+ *
5
+ * Mirrors `confirmation-request-guardian-bridge.ts` for the question kind:
6
+ * emits the notification signal (the broadcaster renders the options as card
7
+ * actions — see `resolveQuestionOptionsContext`) and records the resulting
8
+ * card deliveries so reply routing can address taps and reactions back to the
9
+ * request.
10
+ *
11
+ * Unlike the confirmation bridge — which escalates a NON-guardian's request TO
12
+ * the guardian — the caller (`question-guardian-request.ts`) has already
13
+ * established that the asking turn belongs to the guardian; this bridge only
14
+ * verifies the channel's guardian binding still matches so a rebind between
15
+ * ingress and prompt emission can't deliver the question card to the wrong
16
+ * recipient.
17
+ */
18
+
19
+ import type { QuestionEntry } from "../api/events/question-request.js";
20
+ import type { GuardianRequestWire } from "../channels/gateway-guardian-requests.js";
21
+ import type { TrustContext } from "../daemon/trust-context-types.js";
22
+ import { emitNotificationSignal } from "../notifications/emit-signal.js";
23
+ import {
24
+ recordApprovalCardDelivery,
25
+ recordGuardianRequestDeliveries,
26
+ } from "../notifications/guardian-delivery-recorder.js";
27
+ import { buildVellumCardAffinity } from "../notifications/vellum-card-affinity.js";
28
+ import { canonicalizeInboundIdentity } from "../util/canonicalize-identity.js";
29
+ import { getLogger } from "../util/logger.js";
30
+ import { DAEMON_INTERNAL_ASSISTANT_ID } from "./assistant-scope.js";
31
+ import { getGuardianBinding } from "./channel-verification-service.js";
32
+
33
+ const log = getLogger("question-request-guardian-bridge");
34
+
35
+ export interface BridgeQuestionRequestParams {
36
+ /** The guardian request already persisted for this question. */
37
+ guardianRequest: GuardianRequestWire;
38
+ /** Trust context snapshot from the asking turn. */
39
+ trustContext: TrustContext;
40
+ /** Conversation the question was asked in. */
41
+ conversationId: string;
42
+ /** The (single) question entry being asked. */
43
+ question: QuestionEntry;
44
+ /** Logical assistant ID (defaults to 'self'). */
45
+ assistantId?: string;
46
+ }
47
+
48
+ export type BridgeQuestionRequestResult =
49
+ | { bridged: true; signalId: string }
50
+ | {
51
+ skipped: true;
52
+ reason: "no_guardian_binding" | "binding_identity_mismatch";
53
+ };
54
+
55
+ /**
56
+ * Emit the `guardian.question` signal for a parked question and record the
57
+ * card deliveries. Fire-and-forget safe: emission errors are logged, never
58
+ * propagated.
59
+ */
60
+ export async function bridgeQuestionRequestToGuardian(
61
+ params: BridgeQuestionRequestParams,
62
+ ): Promise<BridgeQuestionRequestResult> {
63
+ const {
64
+ guardianRequest,
65
+ trustContext,
66
+ conversationId,
67
+ question,
68
+ assistantId = DAEMON_INTERNAL_ASSISTANT_ID,
69
+ } = params;
70
+
71
+ const sourceChannel = trustContext.sourceChannel;
72
+ const binding = await getGuardianBinding(assistantId, sourceChannel);
73
+ if (!binding) {
74
+ log.debug(
75
+ { sourceChannel, conversationId },
76
+ "No guardian binding for question request bridge",
77
+ );
78
+ return { skipped: true, reason: "no_guardian_binding" };
79
+ }
80
+
81
+ // A guardian rebind between ingress and prompt emission would deliver the
82
+ // question card to the wrong recipient — mirror the confirmation bridge's
83
+ // canonicalized identity check.
84
+ const canonicalizedBindingGuardianId = canonicalizeInboundIdentity(
85
+ sourceChannel,
86
+ binding.guardianExternalUserId,
87
+ );
88
+ const canonicalizedRequestGuardianId = guardianRequest.guardianExternalUserId
89
+ ? canonicalizeInboundIdentity(
90
+ sourceChannel,
91
+ guardianRequest.guardianExternalUserId,
92
+ )
93
+ : null;
94
+ if (
95
+ canonicalizedRequestGuardianId &&
96
+ canonicalizedBindingGuardianId !== canonicalizedRequestGuardianId
97
+ ) {
98
+ log.warn(
99
+ {
100
+ sourceChannel,
101
+ requestId: guardianRequest.id,
102
+ },
103
+ "Guardian binding identity does not match the question request guardian — skipping notification to prevent misrouting",
104
+ );
105
+ return { skipped: true, reason: "binding_identity_mismatch" };
106
+ }
107
+
108
+ // The vellum delivery row is created up front in onConversationCreated so
109
+ // the in-app client sees it immediately; the post-resolve recorder reuses it.
110
+ let vellumDeliveryIdPromise: Promise<string | undefined> | undefined;
111
+
112
+ const signalPromise = emitNotificationSignal({
113
+ sourceEventName: "guardian.question",
114
+ sourceChannel,
115
+ sourceContextId: conversationId,
116
+ requiresConversation: true,
117
+ // Pin the in-app (vellum) card to the conversation the question was
118
+ // asked in, so the guardian answers it in context.
119
+ ...(buildVellumCardAffinity(conversationId) ?? {}),
120
+ attentionHints: {
121
+ requiresAction: true,
122
+ urgency: "high",
123
+ isAsyncBackground: false,
124
+ // MUST be false: visibleInSourceNow is a hard suppression pre-gate in
125
+ // emitNotificationSignal (source-active check) — it means "the user can
126
+ // already see this content in the source surface, skip notifying". A
127
+ // parked ask_question renders NOTHING in the source chat by itself; this
128
+ // card IS the prompt, so suppressing it would leave the turn hanging
129
+ // until the prompt timeout.
130
+ visibleInSourceNow: false,
131
+ },
132
+ contextPayload: {
133
+ requestKind: "pending_question",
134
+ requestId: guardianRequest.id,
135
+ requestCode:
136
+ guardianRequest.requestCode ??
137
+ guardianRequest.id.slice(0, 6).toUpperCase(),
138
+ sourceChannel,
139
+ requesterExternalUserId: trustContext.requesterExternalUserId,
140
+ requesterChatId: trustContext.requesterChatId ?? null,
141
+ questionText: question.question,
142
+ options: question.options.map((option) => ({
143
+ id: option.id,
144
+ label: option.label,
145
+ })),
146
+ },
147
+ dedupeKey: `ask-question-request:${guardianRequest.id}`,
148
+ onConversationCreated: (info) => {
149
+ vellumDeliveryIdPromise ??= recordApprovalCardDelivery({
150
+ requestId: guardianRequest.id,
151
+ channel: "vellum",
152
+ conversationId: info.conversationId,
153
+ }).then((delivery) => delivery?.id);
154
+ return vellumDeliveryIdPromise.then(() => undefined);
155
+ },
156
+ });
157
+
158
+ void signalPromise
159
+ .then(async (signalResult) => {
160
+ await recordGuardianRequestDeliveries({
161
+ requestId: guardianRequest.id,
162
+ deliveryResults: signalResult.deliveryResults,
163
+ vellumDeliveryId: await vellumDeliveryIdPromise,
164
+ });
165
+ })
166
+ .catch((err) => {
167
+ log.warn(
168
+ { err, requestId: guardianRequest.id },
169
+ "Failed to record channel deliveries for question bridge",
170
+ );
171
+ });
172
+
173
+ log.info(
174
+ {
175
+ sourceChannel,
176
+ requestId: guardianRequest.id,
177
+ requestCode: guardianRequest.requestCode,
178
+ optionCount: question.options.length,
179
+ },
180
+ "Guardian notified of pending question",
181
+ );
182
+
183
+ return { bridged: true, signalId: guardianRequest.id };
184
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Shared resolution core for pending `ask_question` interactions.
3
+ *
4
+ * A pending `question` interaction (registered by {@link QuestionPrompter}) can
5
+ * be resolved from two places:
6
+ *
7
+ * - `POST /v1/question-response` — an app/web client submits the user's
8
+ * batched selection (see `routes/question-routes.ts`).
9
+ * - the guardian-request pipeline — a channel option tap, request-code reply,
10
+ * or bare-text answer routes through the guardian reply router to the
11
+ * `pending_question` resolver, which builds the submission (see
12
+ * `approvals/guardian-request-resolvers.ts`).
13
+ *
14
+ * Both funnel through {@link resolvePendingQuestion} so the validate → consume
15
+ * → `rpcResolve` sequence has a single implementation. The helper is
16
+ * transport-agnostic: it returns a discriminated outcome rather than throwing
17
+ * route errors, so each caller maps the outcome to its own surface (HTTP status
18
+ * codes for the route; a resolver failure reason for the pipeline).
19
+ */
20
+
21
+ import {
22
+ buildBatchEntries,
23
+ type QuestionBatchMetadata,
24
+ type QuestionBatchSubmission,
25
+ QuestionBatchValidationError,
26
+ type QuestionPromptResult,
27
+ } from "../permissions/question-prompter.js";
28
+ import * as pendingInteractions from "./pending-interactions.js";
29
+
30
+ /**
31
+ * How to resolve a pending question: a batched submission (one entry per
32
+ * question) or a close (every question reported as `skipped`).
33
+ */
34
+ export type QuestionResolutionInput =
35
+ | { kind: "submit"; submissions: QuestionBatchSubmission[] }
36
+ | { kind: "close" };
37
+
38
+ /**
39
+ * Outcome of {@link resolvePendingQuestion}.
40
+ *
41
+ * - `resolved` — the interaction was consumed and the prompter's caller
42
+ * settled. `conversationId` is the owning conversation (absent for
43
+ * conversation-less prompts).
44
+ * - `not_found` — no pending `question` interaction matched the requestId
45
+ * (already answered, timed out, superseded, or wrong kind). Callers treat
46
+ * this as a stale request.
47
+ * - `invalid` — the submission failed validation. The interaction is left
48
+ * intact (timer still running) so the user can submit a correct batch.
49
+ */
50
+ export type QuestionResolutionOutcome =
51
+ | {
52
+ status: "resolved";
53
+ result: QuestionPromptResult;
54
+ conversationId?: string;
55
+ }
56
+ | { status: "not_found" }
57
+ | { status: "invalid"; message: string };
58
+
59
+ /**
60
+ * Resolve a pending `question` interaction with a batched submission or a
61
+ * close. Validation runs BEFORE the interaction is consumed, so an `invalid`
62
+ * outcome leaves the pending prompt (and its timer) intact for a retry.
63
+ */
64
+ export function resolvePendingQuestion(
65
+ requestId: string,
66
+ input: QuestionResolutionInput,
67
+ ): QuestionResolutionOutcome {
68
+ const interaction = pendingInteractions.get(requestId);
69
+ if (!interaction || interaction.kind !== "question") {
70
+ return { status: "not_found" };
71
+ }
72
+
73
+ let result: QuestionPromptResult;
74
+ try {
75
+ if (input.kind === "close") {
76
+ const { orderedIds } = readBatchMetadata(interaction);
77
+ result = {
78
+ entries: orderedIds.map((id) => ({
79
+ questionId: id,
80
+ decision: "skipped" as const,
81
+ })),
82
+ overall: "closed",
83
+ };
84
+ } else {
85
+ result = buildCompletedResult(input.submissions, interaction);
86
+ }
87
+ } catch (err) {
88
+ if (err instanceof QuestionBatchValidationError) {
89
+ return { status: "invalid", message: err.message };
90
+ }
91
+ throw err;
92
+ }
93
+
94
+ // Validation passed — deregister now to clear the prompter timer, then hand
95
+ // the result to the prompter's caller via rpcResolve.
96
+ pendingInteractions.resolve(
97
+ requestId,
98
+ input.kind === "close" ? "cancelled" : "answered",
99
+ );
100
+
101
+ (
102
+ interaction.rpcResolve as
103
+ | ((value: QuestionPromptResult) => void)
104
+ | undefined
105
+ )?.(result);
106
+
107
+ return {
108
+ status: "resolved",
109
+ result,
110
+ conversationId: interaction.conversationId,
111
+ };
112
+ }
113
+
114
+ /**
115
+ * Build a `completed` QuestionPromptResult from a batched submission and the
116
+ * per-question metadata the prompter stashed on the interaction. Delegates the
117
+ * validation + ordering loop to {@link buildBatchEntries} so the prompter, the
118
+ * route, and the channel wizard share a single implementation.
119
+ */
120
+ function buildCompletedResult(
121
+ submissions: QuestionBatchSubmission[],
122
+ interaction: ReturnType<typeof pendingInteractions.get>,
123
+ ): QuestionPromptResult {
124
+ const { orderedIds, optionsById } = readBatchMetadata(interaction);
125
+ if (orderedIds.length === 0) {
126
+ throw new QuestionBatchValidationError(
127
+ "No registered question ids for this batch",
128
+ );
129
+ }
130
+ const entries = buildBatchEntries(
131
+ orderedIds,
132
+ (qid, oid) => (optionsById[qid] ?? []).includes(oid),
133
+ new Set(Object.keys(optionsById)),
134
+ submissions,
135
+ );
136
+ return { entries, overall: "completed" };
137
+ }
138
+
139
+ /**
140
+ * Pull the prompter-stashed batch bookkeeping off a pending interaction.
141
+ * Returns empty defaults if the metadata is absent.
142
+ */
143
+ export function readBatchMetadata(
144
+ interaction: ReturnType<typeof pendingInteractions.get>,
145
+ ): QuestionBatchMetadata {
146
+ const meta = interaction?.metadata as
147
+ | Partial<QuestionBatchMetadata>
148
+ | undefined;
149
+ return {
150
+ orderedIds: meta?.orderedIds ?? [],
151
+ optionsById: meta?.optionsById ?? {},
152
+ };
153
+ }
@@ -22,7 +22,9 @@ mock.module("../../assistant-event-hub.js", () => ({
22
22
  },
23
23
  subscribe: () => () => {},
24
24
  },
25
- broadcastMessage: async () => {},
25
+ broadcastMessage: (message: unknown, conversationId?: string) => {
26
+ publishCalls.push({ message, conversationId });
27
+ },
26
28
  }));
27
29
 
28
30
  import { getDb } from "../../../persistence/db-connection.js";
@@ -47,7 +49,9 @@ await initializeDb();
47
49
 
48
50
  function findHandler(operationId: string): RouteDefinition["handler"] {
49
51
  const route = BOOKMARK_ROUTES.find((r) => r.operationId === operationId);
50
- if (!route) throw new Error(`Route ${operationId} not found`);
52
+ if (!route) {
53
+ throw new Error(`Route ${operationId} not found`);
54
+ }
51
55
  return route.handler;
52
56
  }
53
57
 
@@ -71,7 +71,7 @@ import {
71
71
  type MemoryV2ConceptRowRecord,
72
72
  type MemoryV2ConfigSnapshot,
73
73
  recordMemoryV2ActivationLog,
74
- } from "../../../plugins/defaults/memory/memory-v2-activation-log-store.js";
74
+ } from "../../../plugins/defaults/memory/v2/activation-log-store.js";
75
75
  import {
76
76
  createConnection,
77
77
  getConnection,
@@ -18,8 +18,8 @@ import {
18
18
  AcpSessionNotFoundError,
19
19
  } from "../../acp/session-manager.js";
20
20
  import type { AcpSessionState } from "../../acp/types.js";
21
+ import type { AssistantEvent } from "../../api/index.js";
21
22
  import { getConfig } from "../../config/loader.js";
22
- import type { ServerMessage } from "../../daemon/message-protocol.js";
23
23
  import { createGuardianRequestForConfirmation } from "../../permissions/confirmation-guardian-request.js";
24
24
  import type { UserDecision } from "../../permissions/types.js";
25
25
  import { getDb } from "../../persistence/db-connection.js";
@@ -159,7 +159,7 @@ function awaitRouteApproval(args: {
159
159
  settle(decision, decision === "allow" ? "approved" : "rejected"),
160
160
  });
161
161
 
162
- const confirmationMsg: ServerMessage & {
162
+ const confirmationMsg: AssistantEvent & {
163
163
  type: "confirmation_request";
164
164
  } = {
165
165
  type: "confirmation_request",
@@ -20,33 +20,21 @@ import {
20
20
  } from "../../persistence/bookmark-crud.js";
21
21
  import { getMessageById } from "../../persistence/conversation-crud.js";
22
22
  import { getDb } from "../../persistence/db-connection.js";
23
- import { getLogger } from "../../util/logger.js";
24
- import { buildAssistantEvent } from "../assistant-event.js";
25
- import { assistantEventHub } from "../assistant-event-hub.js";
23
+ import { broadcastMessage } from "../assistant-event-hub.js";
26
24
  import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
27
25
  import { BadRequestError, NotFoundError } from "./errors.js";
28
26
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
29
27
 
30
- const log = getLogger("bookmark-routes");
31
-
32
28
  // ---------------------------------------------------------------------------
33
29
  // Helpers
34
30
  // ---------------------------------------------------------------------------
35
31
 
36
32
  function publishBookmarkCreated(bookmark: BookmarkSummary): void {
37
- assistantEventHub
38
- .publish(buildAssistantEvent({ type: "bookmark.created", bookmark }))
39
- .catch((err) => {
40
- log.warn({ err }, "Failed to publish bookmark.created");
41
- });
33
+ broadcastMessage({ type: "bookmark.created", bookmark });
42
34
  }
43
35
 
44
36
  function publishBookmarkDeleted(payload: { messageId: string }): void {
45
- assistantEventHub
46
- .publish(buildAssistantEvent({ type: "bookmark.deleted", ...payload }))
47
- .catch((err) => {
48
- log.warn({ err }, "Failed to publish bookmark.deleted");
49
- });
37
+ broadcastMessage({ type: "bookmark.deleted", ...payload });
50
38
  }
51
39
 
52
40
  // ---------------------------------------------------------------------------
@@ -1,5 +1,5 @@
1
1
  import { createAssistantMessage } from "../../agent/message-types.js";
2
- import type { ServerMessage } from "../../daemon/message-protocol.js";
2
+ import type { AssistantEvent } from "../../api/index.js";
3
3
  import {
4
4
  addMessage,
5
5
  recordConversationPersistedSeq,
@@ -28,7 +28,7 @@ import { publishConversationMessagesChanged } from "../sync/resource-sync-events
28
28
  // `state.assistantTurnId` directly, grep for `emitCannedMessageComplete` to
29
29
  // find every call site and inline-then-delete.
30
30
  export function emitCannedMessageComplete(
31
- send: (msg: ServerMessage) => void,
31
+ send: (msg: AssistantEvent) => void,
32
32
  conversationId: string,
33
33
  persistedAssistantId: string,
34
34
  ): void {
@@ -29,7 +29,8 @@ import {
29
29
  } from "../../persistence/jobs-store.js";
30
30
  import { getUsageCostForConversationWindow } from "../../persistence/llm-usage-store.js";
31
31
  import { GRAPH_MAINTENANCE_CHECKPOINTS } from "../../plugins/defaults/memory/jobs-worker.js";
32
- import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../plugins/defaults/memory/v3/substrate/constants.js";
32
+ import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../plugins/defaults/memory/substrate/constants.js";
33
+ import { resolveSubstrateTuning } from "../../plugins/defaults/memory/substrate/tuning.js";
33
34
  import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
34
35
  import { BadRequestError } from "./errors.js";
35
36
  import {
@@ -46,7 +47,12 @@ function isConsolidationAvailable(): boolean {
46
47
  }
47
48
 
48
49
  function consolidationIntervalMs(): number {
49
- return getConfig().memory.v2.consolidation_interval_hours * 60 * 60 * 1000;
50
+ return (
51
+ resolveSubstrateTuning(getConfig().memory).consolidation_interval_hours *
52
+ 60 *
53
+ 60 *
54
+ 1000
55
+ );
50
56
  }
51
57
 
52
58
  function readLastRunAt(): number | null {
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { z } from "zod";
12
12
 
13
+ import { CHANNEL_IDS } from "../../channels/types.js";
13
14
  import { channelBindingSchema } from "../../messaging/channel-binding-schema.js";
14
15
  import {
15
16
  type Confidence,
@@ -57,16 +58,7 @@ const log = getLogger("conversation-list-routes");
57
58
  // Response schemas
58
59
  // ---------------------------------------------------------------------------
59
60
 
60
- const channelIdSchema = z.enum([
61
- "telegram",
62
- "phone",
63
- "vellum",
64
- "whatsapp",
65
- "slack",
66
- "email",
67
- "platform",
68
- "a2a",
69
- ]);
61
+ const channelIdSchema = z.enum(CHANNEL_IDS);
70
62
 
71
63
  const assistantAttentionSchema = z.object({
72
64
  hasUnseenLatestAssistantMessage: z.boolean(),
@@ -453,15 +445,7 @@ export const ROUTES: RouteDefinition[] = [
453
445
  "Filter by origin channel. When provided, only conversations with this exact origin_channel value are returned. Omit to include all channels.",
454
446
  schema: {
455
447
  type: "string",
456
- enum: [
457
- "slack",
458
- "telegram",
459
- "whatsapp",
460
- "email",
461
- "a2a",
462
- "vellum",
463
- "phone",
464
- ],
448
+ enum: [...CHANNEL_IDS],
465
449
  },
466
450
  },
467
451
  ],
@@ -71,7 +71,6 @@ import { deleteSchedule } from "../../schedule/schedule-store.js";
71
71
  import { UserError } from "../../util/errors.js";
72
72
  import { safeParseRecord } from "../../util/json.js";
73
73
  import { getLogger } from "../../util/logger.js";
74
- import { silentlyWithLog } from "../../util/silently.js";
75
74
  import { broadcastMessage } from "../assistant-event-hub.js";
76
75
  import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
77
76
  import { resolveActorPrincipalIdForLocalGuardian } from "../local-actor-identity.js";
@@ -337,10 +336,7 @@ async function handleSummarizeConversation({ body = {} }: RouteHandlerArgs) {
337
336
  conversation.abortController = null;
338
337
  }
339
338
  conversation.setProcessing(false);
340
- silentlyWithLog(
341
- conversation.drainQueue(),
342
- "summarize-command queue drain",
343
- );
339
+ void conversation.kickDrainQueue("loop_complete", "summarize_command");
344
340
  }
345
341
  })();
346
342
 
@@ -55,6 +55,10 @@ import {
55
55
  } from "../../config/schemas/llm.js";
56
56
  import { VALID_MEMORY_EMBEDDING_PROVIDERS } from "../../config/schemas/memory-storage.js";
57
57
  import { ServiceModeSchema } from "../../config/schemas/services.js";
58
+ import {
59
+ describeShadowedConfigSet,
60
+ findSubstrateShadowing,
61
+ } from "../../config/substrate-twin-shadowing.js";
58
62
  import { getConfigWatcher } from "../../daemon/config-watcher.js";
59
63
  import {
60
64
  getEmbeddingConfigInfo,
@@ -88,9 +92,9 @@ import { clearEmbeddingBackendCache } from "../../persistence/embeddings/embeddi
88
92
  import { getLlmRequestLogSource } from "../../persistence/llm-request-log-source.js";
89
93
  import { type LogRow } from "../../persistence/llm-request-log-store.js";
90
94
  import { getMemoryRecallLogByMessageIds } from "../../plugins/defaults/memory/memory-recall-log-store.js";
91
- import { getMemoryV2ActivationLogByMessageIds } from "../../plugins/defaults/memory/memory-v2-activation-log-store.js";
95
+ import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../plugins/defaults/memory/substrate/constants.js";
96
+ import { getMemoryV2ActivationLogByMessageIds } from "../../plugins/defaults/memory/v2/activation-log-store.js";
92
97
  import { getMemoryV3SelectionForInspectorByMessageIds } from "../../plugins/defaults/memory/v3/selection-log-store.js";
93
- import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../plugins/defaults/memory/v3/substrate/constants.js";
94
98
  import { ROUTING_IDENTITY_PROVIDERS } from "../../providers/inference/auth.js";
95
99
  import { PROVIDERS_REQUIRING_BASE_URL_AND_MODELS } from "../../providers/inference/auth.js";
96
100
  import {
@@ -459,10 +463,10 @@ async function handleSetEmbeddingConfig({ body }: RouteHandlerArgs) {
459
463
  * response needs the same treatment so external clients (macOS, web, CLI)
460
464
  * see the effective value rather than `undefined` when the daemon hasn't
461
465
  * persisted an explicit choice yet. For example, on a freshly-hatched
462
- * platform-managed assistant, `services.image-generation.mode` may be absent
463
- * from disk (only `llm.profiles` was written by `seedInferenceProfiles`); the
464
- * fill pass ensures clients receive `"managed"` rather than falling back to
465
- * their own defaults.
466
+ * platform-managed assistant, `services.image-generation.provider` may be
467
+ * absent from disk (only `llm.profiles` was written by
468
+ * `seedInferenceProfiles`); the fill pass ensures clients receive `"vellum"`
469
+ * rather than falling back to their own defaults.
466
470
  *
467
471
  * Guards against `loadRawConfig()` handing us a value that is technically
468
472
  * valid JSON but not a plain object (e.g. literal `null`, a number, or an
@@ -703,7 +707,10 @@ const ConfigGetResponseSchema = z
703
707
  .passthrough()
704
708
  .optional(),
705
709
  "image-generation": z
706
- .object({ mode: ServiceModeSchema.optional() })
710
+ .object({
711
+ provider: z.string().optional(),
712
+ model: z.string().optional(),
713
+ })
707
714
  .passthrough()
708
715
  .optional(),
709
716
  inference: z
@@ -807,7 +814,10 @@ const ConfigPatchRequestSchema = z
807
814
  .nullable()
808
815
  .optional(),
809
816
  "image-generation": z
810
- .object({ mode: ServiceModeSchema.optional() })
817
+ .object({
818
+ provider: z.string().optional(),
819
+ model: z.string().optional(),
820
+ })
811
821
  .passthrough()
812
822
  .nullable()
813
823
  .optional(),
@@ -1449,6 +1459,28 @@ export async function commitConfigWrite(
1449
1459
  }
1450
1460
  }
1451
1461
 
1462
+ /**
1463
+ * Web clients pair provider writes with a legacy `mode` key so their saves
1464
+ * stay valid on daemons whose schemas still carry it. The provider-only
1465
+ * services (web-search, image-generation) parse-strip that key, but the
1466
+ * deep-merge would still persist it to raw config.json on every save —
1467
+ * scrub it so the removed field cannot be resurrected on disk.
1468
+ */
1469
+ function scrubRemovedServiceModes(raw: Record<string, unknown>): void {
1470
+ const services = raw.services as
1471
+ | Record<string, Record<string, unknown> | undefined>
1472
+ | undefined;
1473
+ if (!services) {
1474
+ return;
1475
+ }
1476
+ for (const key of ["web-search", "image-generation"]) {
1477
+ const entry = services[key];
1478
+ if (entry && typeof entry === "object" && "mode" in entry) {
1479
+ delete entry.mode;
1480
+ }
1481
+ }
1482
+ }
1483
+
1452
1484
  async function handlePatchConfig({ body }: RouteHandlerArgs) {
1453
1485
  if (
1454
1486
  !body ||
@@ -1467,6 +1499,7 @@ async function handlePatchConfig({ body }: RouteHandlerArgs) {
1467
1499
  const patch = body as Record<string, unknown>;
1468
1500
  backfillNewCallSiteEntries(raw, patch);
1469
1501
  deepMergeOverwrite(raw, patch);
1502
+ scrubRemovedServiceModes(raw);
1470
1503
 
1471
1504
  await commitConfigWrite(raw, "patch");
1472
1505
 
@@ -1568,6 +1601,17 @@ async function handleSetConfig({ body }: RouteHandlerArgs) {
1568
1601
  }
1569
1602
 
1570
1603
  await commitConfigWrite(raw, "set");
1604
+ // A `memory.v2` substrate tunable whose `memory.substrate` twin is set does
1605
+ // not mean what an unpaired write means: the substrate namespace wins in
1606
+ // `resolveSubstrateTuning`, and for the three twins the v2 injection engine
1607
+ // reads directly the two namespaces diverge instead. Report which case this
1608
+ // is alongside the success so the caller can tell the operator.
1609
+ const shadowing = findSubstrateShadowing(raw, path);
1610
+ if (shadowing) {
1611
+ const warning = describeShadowedConfigSet(shadowing, path);
1612
+ log.warn({ path, substratePath: shadowing.substratePath }, warning);
1613
+ return { ok: true, warning };
1614
+ }
1571
1615
  return { ok: true };
1572
1616
  }
1573
1617