@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
@@ -8,6 +8,12 @@
8
8
 
9
9
  import { v7 as uuidv7 } from "uuid";
10
10
 
11
+ import type {
12
+ AssistantEvent,
13
+ AssistantTextDeltaEvent,
14
+ GenerationCancelledEvent,
15
+ MessageCompleteEvent,
16
+ } from "../api/index.js";
11
17
  import { consumeGrantForInvocation } from "../approvals/approval-primitive.js";
12
18
  import type {
13
19
  ChannelId,
@@ -20,7 +26,6 @@ import { ABORT_WATCHDOG_MS } from "../daemon/abort-watchdog.js";
20
26
  import { CONVERSATION_BUSY_MESSAGE } from "../daemon/conversation-messaging.js";
21
27
  import { resolveChannelCapabilities } from "../daemon/conversation-runtime-assembly.js";
22
28
  import { getOrCreateConversation } from "../daemon/conversation-store.js";
23
- import type { ServerMessage } from "../daemon/message-protocol.js";
24
29
  import type { TrustContext } from "../daemon/trust-context-types.js";
25
30
  import {
26
31
  deleteMessageById,
@@ -43,6 +48,7 @@ import {
43
48
  CALL_VERIFICATION_COMPLETE_MARKER,
44
49
  ESCALATE_VERDICT_TOKEN,
45
50
  HOLD_VERDICT_TOKEN,
51
+ MINIMIZE_ROOM_MARKER,
46
52
  stripInternalSpeechMarkers,
47
53
  } from "./voice-control-protocol.js";
48
54
  import {
@@ -216,15 +222,8 @@ export interface VoiceToolResultEvent {
216
222
  * standard channel path.
217
223
  */
218
224
  export interface VoiceRunEventSink {
219
- onTextDelta(
220
- msg: Extract<ServerMessage, { type: "assistant_text_delta" }>,
221
- ): void;
222
- onMessageComplete(
223
- msg: Extract<
224
- ServerMessage,
225
- { type: "message_complete" } | { type: "generation_cancelled" }
226
- >,
227
- ): void;
225
+ onTextDelta(msg: AssistantTextDeltaEvent): void;
226
+ onMessageComplete(msg: MessageCompleteEvent | GenerationCancelledEvent): void;
228
227
  onError(message: string): void;
229
228
  onToolUse(
230
229
  toolName: string,
@@ -235,14 +234,9 @@ export interface VoiceRunEventSink {
235
234
  }
236
235
 
237
236
  export interface VoiceTurnCallbacks {
238
- assistant_text_delta?: (
239
- msg: Extract<ServerMessage, { type: "assistant_text_delta" }>,
240
- ) => void;
237
+ assistant_text_delta?: (msg: AssistantTextDeltaEvent) => void;
241
238
  message_complete?: (
242
- msg: Extract<
243
- ServerMessage,
244
- { type: "message_complete" } | { type: "generation_cancelled" }
245
- >,
239
+ msg: MessageCompleteEvent | GenerationCancelledEvent,
246
240
  ) => void;
247
241
  persisted_user_message_id?: (messageId: string) => void;
248
242
  persisted_assistant_message_id?: (messageId: string) => void;
@@ -466,9 +460,9 @@ function buildVoiceCallControlPrompt(opts: {
466
460
  `12. ${VOICE_NO_SETUP_FLOWS_RULE}`,
467
461
  );
468
462
 
469
- // Triage-and-escalate routing rules (gated by the voice-mode flag). The
470
- // front-door leg decides and may hand off; the escalated leg continues the
471
- // answer after a holding phrase was already spoken.
463
+ // Triage-and-escalate routing rules. The front-door leg decides and may
464
+ // hand off; the escalated leg continues the answer after a holding phrase
465
+ // was already spoken.
472
466
  if (opts.routingLeg === "front-door") {
473
467
  lines.push(`13. ${frontDoorRuleWithDigest(opts.unifiedVerdict === true)}`);
474
468
  } else if (opts.routingLeg === "escalated") {
@@ -481,9 +475,85 @@ function buildVoiceCallControlPrompt(opts: {
481
475
  }
482
476
 
483
477
  // ---------------------------------------------------------------------------
484
- // Front-door transcript hygiene
478
+ // Transcript hygiene
485
479
  // ---------------------------------------------------------------------------
486
480
 
481
+ /** The concatenated text of a row's text blocks. */
482
+ function joinedTextOfBlocks(blocks: ContentBlock[]): string {
483
+ return blocks
484
+ .map((block) => (block.type === "text" ? block.text : ""))
485
+ .join("");
486
+ }
487
+
488
+ /**
489
+ * Strip internal speech markers from every text block, dropping text blocks
490
+ * the strip leaves empty; non-text blocks pass through untouched. Shared by
491
+ * the front-door stray-token rewrite and the main-leg minimize-marker
492
+ * rewrite.
493
+ */
494
+ function stripMarkersFromBlocks(blocks: ContentBlock[]): ContentBlock[] {
495
+ const kept: ContentBlock[] = [];
496
+ for (const block of blocks) {
497
+ if (block.type !== "text") {
498
+ kept.push(block);
499
+ continue;
500
+ }
501
+ const cleaned = stripInternalSpeechMarkers(block.text);
502
+ if (cleaned.trim().length > 0) {
503
+ kept.push({ ...block, text: cleaned });
504
+ }
505
+ }
506
+ return kept;
507
+ }
508
+
509
+ /**
510
+ * Remove the terminal MINIMIZE_ROOM_MARKER from the end of a row's text,
511
+ * walking text blocks from the last one backward so a marker split across
512
+ * block boundaries (e.g. `"Done [-"` + `"1]"`) is removed whole — the
513
+ * per-block strip in {@link stripMarkersFromBlocks} only sees fragments and
514
+ * would leave both halves in place. Callers must have established that the
515
+ * row's joined text ends with the marker after trimming trailing whitespace.
516
+ */
517
+ function stripTerminalMinimizeMarker(blocks: ContentBlock[]): ContentBlock[] {
518
+ const result = blocks.map((block) => ({ ...block }));
519
+ const joined = joinedTextOfBlocks(result);
520
+ const cutAt = joined.trimEnd().length - MINIMIZE_ROOM_MARKER.length;
521
+ let blockEnd = joined.length;
522
+ for (let i = result.length - 1; i >= 0 && blockEnd > cutAt; i--) {
523
+ const block = result[i]!;
524
+ if (block.type !== "text") {
525
+ continue;
526
+ }
527
+ const blockStart = blockEnd - block.text.length;
528
+ block.text = block.text.slice(0, Math.max(0, cutAt - blockStart));
529
+ blockEnd = blockStart;
530
+ }
531
+ return result;
532
+ }
533
+
534
+ /**
535
+ * Trim whitespace stranded at a rewritten row's outer edges by a stripped
536
+ * edge marker (e.g. "Done, take a look [-1]"), leaving inter-block spacing
537
+ * untouched.
538
+ */
539
+ function trimOuterTextEdges(blocks: ContentBlock[]): ContentBlock[] {
540
+ const result = blocks.map((block) => ({ ...block }));
541
+ for (const block of result) {
542
+ if (block.type === "text") {
543
+ block.text = block.text.trimStart();
544
+ break;
545
+ }
546
+ }
547
+ for (let i = result.length - 1; i >= 0; i--) {
548
+ const block = result[i]!;
549
+ if (block.type === "text") {
550
+ block.text = block.text.trimEnd();
551
+ break;
552
+ }
553
+ }
554
+ return result;
555
+ }
556
+
487
557
  /**
488
558
  * Reduce a front-door leg's persisted content to what was actually spoken
489
559
  * under the verdict-first protocol.
@@ -500,9 +570,7 @@ function buildVoiceCallControlPrompt(opts: {
500
570
  export function cutFrontDoorContentAtVerdict(
501
571
  blocks: ContentBlock[],
502
572
  ): { blocks: ContentBlock[]; spokenText: string } | null {
503
- const joinedText = blocks
504
- .map((block) => (block.type === "text" ? block.text : ""))
505
- .join("");
573
+ const joinedText = joinedTextOfBlocks(blocks);
506
574
  if (joinedText.trimStart().startsWith(ESCALATE_VERDICT_TOKEN)) {
507
575
  const spokenText = spokenBridgeText(joinedText);
508
576
  return {
@@ -516,21 +584,8 @@ export function cutFrontDoorContentAtVerdict(
516
584
  ) {
517
585
  return null;
518
586
  }
519
- const kept: ContentBlock[] = [];
520
- for (const block of blocks) {
521
- if (block.type !== "text") {
522
- kept.push(block);
523
- continue;
524
- }
525
- const cleaned = stripInternalSpeechMarkers(block.text);
526
- if (cleaned.trim().length > 0) {
527
- kept.push({ ...block, text: cleaned });
528
- }
529
- }
530
- const spokenText = kept
531
- .map((block) => (block.type === "text" ? block.text : ""))
532
- .join("")
533
- .trim();
587
+ const kept = stripMarkersFromBlocks(blocks);
588
+ const spokenText = joinedTextOfBlocks(kept).trim();
534
589
  return { blocks: kept, spokenText };
535
590
  }
536
591
 
@@ -1034,7 +1089,7 @@ export async function startVoiceTurn(
1034
1089
  // Hook into conversation to intercept confirmation_request and secret_request events.
1035
1090
  // Voice auto-denies/auto-allows/auto-resolves these since there's no interactive UI.
1036
1091
  let lastError: string | null = null;
1037
- conversation.updateClient(async (msg: ServerMessage) => {
1092
+ conversation.updateClient(async (msg: AssistantEvent) => {
1038
1093
  if (msg.type === "confirmation_request") {
1039
1094
  // Broadcast the request BEFORE resolving it: resolution synchronously
1040
1095
  // broadcasts `interaction_resolved` (handleConfirmationResponse →
@@ -1178,6 +1233,14 @@ export async function startVoiceTurn(
1178
1233
  * never the verdict token or the text streamed past the cap (issue
1179
1234
  * #37850). A row with no spoken bridge (canned-fallback case — that
1180
1235
  * bridge is audio-only) is deleted.
1236
+ * - Any leg whose row ENDS with the `[-1]` minimize marker (swallowed
1237
+ * before TTS on the live path) has its text blocks rewritten through
1238
+ * `stripInternalSpeechMarkers` so the marker never renders in the chat
1239
+ * transcript. This covers front-door answers too: that leg is never
1240
+ * taught the marker, but it can parrot one from visible conversation
1241
+ * history, and the parroted marker is never spoken and never minimizes
1242
+ * the room. Deliberately scoped to that marker: rows without it
1243
+ * persist byte-identical.
1181
1244
  *
1182
1245
  * After a rewrite, in-memory history is reloaded from the clean DB before
1183
1246
  * the escalated leg — blocked on this turn's teardown — snapshots it, so
@@ -1198,9 +1261,6 @@ export async function startVoiceTurn(
1198
1261
  }
1199
1262
  return;
1200
1263
  }
1201
- if (!discarded && opts.routingLeg !== "front-door") {
1202
- return;
1203
- }
1204
1264
  try {
1205
1265
  let action = "none";
1206
1266
  if (discarded) {
@@ -1208,8 +1268,13 @@ export async function startVoiceTurn(
1208
1268
  action = "delete_discarded";
1209
1269
  } else {
1210
1270
  const row = getMessageById(reservedAssistantRowId, opts.conversationId);
1211
- const cut = row ? cutFrontDoorContentAtVerdict(row.content) : null;
1212
- if (cut) {
1271
+ const cut =
1272
+ row && opts.routingLeg === "front-door"
1273
+ ? cutFrontDoorContentAtVerdict(row.content)
1274
+ : null;
1275
+ if (!row) {
1276
+ action = "row_missing";
1277
+ } else if (cut) {
1213
1278
  if (cut.spokenText.length > 0) {
1214
1279
  updateMessageContent(
1215
1280
  reservedAssistantRowId,
@@ -1220,20 +1285,53 @@ export async function startVoiceTurn(
1220
1285
  deleteMessageById(reservedAssistantRowId);
1221
1286
  action = "delete_empty";
1222
1287
  }
1223
- } else if (!row) {
1224
- action = "row_missing";
1288
+ } else if (
1289
+ // Terminal position only — mirrors the live latch in
1290
+ // createControlMarkerHoldback: a reply whose CONTENT contains
1291
+ // "[-1]" mid-text never minimized the room, so its transcript
1292
+ // keeps that content untouched too. Front-door answer rows (no
1293
+ // verdict token to cut) take this branch as well.
1294
+ joinedTextOfBlocks(row.content)
1295
+ .trimEnd()
1296
+ .endsWith(MINIMIZE_ROOM_MARKER)
1297
+ ) {
1298
+ // Terminal marker first (boundary-aware — it may span text blocks),
1299
+ // then the per-block strip for any interior complete markers.
1300
+ const cleaned = trimOuterTextEdges(
1301
+ stripMarkersFromBlocks(stripTerminalMinimizeMarker(row.content)),
1302
+ );
1303
+ // A marker-only reply (the model said nothing beyond "[-1]") strips
1304
+ // to nothing at all; keeping the row would render a blank assistant
1305
+ // bubble, so delete it like the front-door empty case. Any surviving
1306
+ // block — including non-text blocks like tool_use — keeps the row.
1307
+ if (cleaned.length === 0) {
1308
+ deleteMessageById(reservedAssistantRowId);
1309
+ action = "delete_empty";
1310
+ } else {
1311
+ updateMessageContent(
1312
+ reservedAssistantRowId,
1313
+ JSON.stringify(cleaned),
1314
+ );
1315
+ action = "strip_minimize_marker";
1316
+ }
1225
1317
  }
1226
1318
  }
1227
- log.info(
1228
- {
1229
- turnId,
1230
- messageId: reservedAssistantRowId,
1231
- routingLeg: opts.routingLeg ?? null,
1232
- discarded,
1233
- action,
1234
- },
1235
- "Voice leg transcript hygiene",
1236
- );
1319
+ // Main legs run the pass on every voice turn; keep the no-op case
1320
+ // out of the logs.
1321
+ const isMainLegNoOp =
1322
+ action === "none" && !discarded && opts.routingLeg !== "front-door";
1323
+ if (!isMainLegNoOp) {
1324
+ log.info(
1325
+ {
1326
+ turnId,
1327
+ messageId: reservedAssistantRowId,
1328
+ routingLeg: opts.routingLeg ?? null,
1329
+ discarded,
1330
+ action,
1331
+ },
1332
+ "Voice leg transcript hygiene",
1333
+ );
1334
+ }
1237
1335
  if (action !== "none" && action !== "row_missing") {
1238
1336
  await conversation.loadFromDb();
1239
1337
  publishConversationMessagesChanged(opts.conversationId);
@@ -1283,7 +1381,7 @@ export async function startVoiceTurn(
1283
1381
  frontDoorToolsSuppressed = true;
1284
1382
  }
1285
1383
  await conversation.runAgentLoop(persistedContent, messageId, {
1286
- onEvent: (msg: ServerMessage) => {
1384
+ onEvent: (msg: AssistantEvent) => {
1287
1385
  if (msg.type === "assistant_turn_start") {
1288
1386
  reservedAssistantRowId = msg.messageId;
1289
1387
  } else if (msg.type === "error") {
@@ -23,8 +23,7 @@
23
23
  *
24
24
  * This module owns the routing policy in one place: the profile key, the
25
25
  * leg-specific prompt rules, the leading-token classifier, and the bridge
26
- * cap/fallback policy. The gate itself is the `voice-mode` flag, read by the
27
- * LiveVoiceSession that drives the routing.
26
+ * cap/fallback policy. LiveVoiceSession drives the routing.
28
27
  */
29
28
 
30
29
  import {
@@ -296,6 +295,6 @@ export function escalatedContinuationRule(spokenBridge?: string): string {
296
295
  'Do NOT greet again, do NOT say things like "as I was saying", and do NOT repeat, paraphrase, or re-announce that holding phrase —',
297
296
  'opening with another "Let me check", "One moment", or any restatement of what you are about to do sounds broken, because the caller just heard that.',
298
297
  "Your first words must carry new substance: the answer itself, what you found, or a question you genuinely need answered.",
299
- `Never output ${ESCALATE_VERDICT_TOKEN} or any other verdict token — you are the model that finishes the answer.`,
298
+ `Never output ${ESCALATE_VERDICT_TOKEN} or any other front-door verdict token — you are the model that finishes the answer. (The [-1] room-minimize marker from your call instructions is not a verdict token and stays allowed.)`,
300
299
  ].join(" ");
301
300
  }
@@ -73,6 +73,14 @@ const CHANNEL_POLICIES = {
73
73
  conversationStrategy: "continue_existing_conversation",
74
74
  },
75
75
  },
76
+ discord: {
77
+ notification: {
78
+ // Discord has no outbound transport, so enabling delivery would route
79
+ // notifications at a callback no transport owns.
80
+ deliveryEnabled: false,
81
+ conversationStrategy: "continue_existing_conversation",
82
+ },
83
+ },
76
84
  } as const satisfies Record<ChannelId, ChannelNotificationPolicy>;
77
85
 
78
86
  export type ChannelPolicies = typeof CHANNEL_POLICIES;
@@ -150,6 +150,7 @@ export const INTERFACE_IDS = [
150
150
  "email",
151
151
  "chrome-extension",
152
152
  "a2a",
153
+ "discord",
153
154
  // Turns injected by workspace custom routes (webhook receivers, cron jobs,
154
155
  // device/service callbacks). Non-interactive — permission prompts route
155
156
  // through the guardian system, not an interactive client — and non-host-proxy.
@@ -30,9 +30,27 @@ function flattenConfig(
30
30
  return result;
31
31
  }
32
32
 
33
- /** Matches config paths like `services.image-generation.mode`, `services.web-search.mode`, etc. */
33
+ /** Matches config paths like `services.google-oauth.mode` (mode-based services). */
34
34
  const SERVICE_MODE_PATH_RE = /^services\.[^.]+\.mode$/;
35
35
 
36
+ /**
37
+ * Services configured by provider alone: their schemas strip a raw `mode`
38
+ * write, so the CLI rejects it with the provider-based replacement instead
39
+ * of printing success on a no-op.
40
+ */
41
+ const REMOVED_MODE_PATHS: Record<string, string> = {
42
+ "services.web-search.mode":
43
+ "services.web-search.mode does not exist; web search is configured by provider alone. For managed search run `config set services.web-search.provider vellum`.",
44
+ "services.image-generation.mode":
45
+ "services.image-generation.mode does not exist; image generation is configured by provider alone. For managed image generation run `config set services.image-generation.provider vellum`.",
46
+ };
47
+
48
+ /** Provider paths whose "vellum" value requires a platform connection. */
49
+ const VELLUM_PROVIDER_PATHS = new Set([
50
+ "services.web-search.provider",
51
+ "services.image-generation.provider",
52
+ ]);
53
+
36
54
  /**
37
55
  * Fetch the full raw config from the assistant via IPC.
38
56
  * On transport / connection error, prints a helpful message and exits.
@@ -69,13 +87,10 @@ export function registerConfigCommand(program: Command): void {
69
87
  // Web-search has no mode field: the schema strips it, so a write
70
88
  // here would print success while changing nothing. Reject it with
71
89
  // the provider-based replacement instead.
72
- if (key === "services.web-search.mode") {
90
+ const removedModePath = REMOVED_MODE_PATHS[key];
91
+ if (removedModePath) {
73
92
  const { writeOutput } = await import("../output.js");
74
- writeOutput(cmd, {
75
- ok: false,
76
- error:
77
- "services.web-search.mode does not exist; web search is configured by provider alone. For managed search run `config set services.web-search.provider vellum`.",
78
- });
93
+ writeOutput(cmd, { ok: false, error: removedModePath });
79
94
  process.exitCode = 1;
80
95
  return;
81
96
  }
@@ -85,7 +100,7 @@ export function registerConfigCommand(program: Command): void {
85
100
  // web search.
86
101
  const requiresPlatform =
87
102
  (SERVICE_MODE_PATH_RE.test(key) && parsed === "managed") ||
88
- (key === "services.web-search.provider" && parsed === "vellum");
103
+ (VELLUM_PROVIDER_PATHS.has(key) && parsed === "vellum");
89
104
  if (requiresPlatform) {
90
105
  const { requirePlatformConnection } =
91
106
  await import("./oauth/shared.js");
@@ -98,21 +113,31 @@ export function registerConfigCommand(program: Command): void {
98
113
  // Direct-replacement set semantics (preserves null, replaces objects).
99
114
  // See conversation-query-routes.ts:handleSetConfig for why this is a
100
115
  // separate route from config_patch.
101
- const result = await cliIpcCall("config_set", {
102
- body: { path: key, value: parsed },
103
- });
116
+ const result = await cliIpcCall<{ ok: boolean; warning?: string }>(
117
+ "config_set",
118
+ { body: { path: key, value: parsed } },
119
+ );
104
120
  if (!result.ok) {
105
121
  exitFromIpcResult(result, cmd);
106
122
  return;
107
123
  }
108
124
  log.info(`Set ${key} = ${JSON.stringify(parsed)}`);
125
+ // A write the daemon accepted but that another namespace overrides
126
+ // is reported alongside the success, so a no-op set never reads as
127
+ // an effective one.
128
+ const warning = result.result?.warning;
129
+ if (warning) {
130
+ log.warn(`Warning: ${warning}`);
131
+ }
109
132
  },
110
133
  );
111
134
 
112
135
  subcommand(config, "get").action(
113
136
  async (key: string, _opts: unknown, cmd: Command) => {
114
137
  const raw = await fetchRawConfig(cmd);
115
- if (!raw) return;
138
+ if (!raw) {
139
+ return;
140
+ }
116
141
  const value = getNestedValue(raw, key);
117
142
  if (value === undefined) {
118
143
  log.info(`(not set)`);
@@ -123,6 +148,15 @@ export function registerConfigCommand(program: Command): void {
123
148
  : String(value),
124
149
  );
125
150
  }
151
+ // A `memory.v2` substrate tunable whose `memory.substrate` twin is
152
+ // set has a second reader — print which key the runtime consults so
153
+ // the value above cannot be mistaken for the effective one.
154
+ const { describeShadowedConfigGet, findSubstrateShadowing } =
155
+ await import("../../config/substrate-twin-shadowing.js");
156
+ const shadowing = findSubstrateShadowing(raw, key);
157
+ if (shadowing) {
158
+ log.warn(describeShadowedConfigGet(shadowing, key));
159
+ }
126
160
  },
127
161
  );
128
162
 
@@ -143,7 +177,9 @@ export function registerConfigCommand(program: Command): void {
143
177
  subcommand(config, "list").action(
144
178
  async (opts: { search?: string }, cmd: Command) => {
145
179
  const raw = await fetchRawConfig(cmd);
146
- if (!raw) return;
180
+ if (!raw) {
181
+ return;
182
+ }
147
183
  if (Object.keys(raw).length === 0) {
148
184
  log.info("No configuration set");
149
185
  return;
@@ -15,7 +15,8 @@ export const memoryHelp: CliCommandHelp = {
15
15
  "Manage memory items and maintain the assistant memory subsystem",
16
16
  helpText: `
17
17
  The 'nodes' subgroup provides content-based list, delete, and update over
18
- memory v2 graph nodes — address facts by text, not UUID (requires memory v2).
18
+ memory graph nodes — address facts by text, not UUID (requires concept-page
19
+ memory: memory.v3.live or memory.v2.enabled).
19
20
 
20
21
  The 'items' subgroup exposes full CRUD over individual memory items
21
22
  (remembered facts) — list, get, create, update, delete.
@@ -46,7 +47,8 @@ memory v2 subsystem. Unlike 'memory items', which addresses nodes by UUID, these
46
47
  commands address nodes by content text — matching the way an operator refers to
47
48
  a remembered fact without first looking up its ID.
48
49
 
49
- All subcommands require memory v2 to be enabled and the assistant to be running.
50
+ All subcommands require concept-page memory (memory.v3.live or
51
+ memory.v2.enabled) and the assistant to be running.
50
52
 
51
53
  Examples:
52
54
  $ assistant memory nodes stats
@@ -135,6 +135,11 @@ function renderOutcome(outcome: MemoryRetrospectiveOutcome): void {
135
135
  case "no_new_messages":
136
136
  log.info("No new messages to review since the last retrospective.");
137
137
  break;
138
+ case "source_dormant":
139
+ log.info(
140
+ "Source conversation is dormant beyond the sweep lookback; skipping.",
141
+ );
142
+ break;
138
143
  case "source_processing":
139
144
  log.info(
140
145
  "Source conversation is mid-turn; skipping (will retry next trigger).",
@@ -474,6 +474,18 @@
474
474
  "homepage": "https://github.com/vellum-ai/battleship",
475
475
  "license": "MIT",
476
476
  "icon": "⚓"
477
+ },
478
+ {
479
+ "name": "octolens",
480
+ "source": {
481
+ "source": "github",
482
+ "repo": "vellum-ai/octolens",
483
+ "ref": "d9117f5c6b97b3bff75dec1a04bedc32571c6538"
484
+ },
485
+ "description": "Social listening plugin for Octolens. Monitor brand mentions, competitor activity, and industry conversations across 13+ platforms. Query mentions, run analytics, manage keywords and feeds via REST API tools, or connect the Octolens MCP server for natural-language workflows.",
486
+ "category": "growth",
487
+ "homepage": "https://github.com/vellum-ai/octolens",
488
+ "license": "MIT"
477
489
  }
478
490
  ]
479
491
  }
package/src/cli.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  import { dirname, join } from "node:path";
12
12
  import * as readline from "node:readline";
13
13
 
14
+ import type { AssistantEvent } from "./api/index.js";
14
15
  import {
15
16
  type MainScreenLayout,
16
17
  renderMainScreen,
@@ -18,7 +19,6 @@ import {
18
19
  updateStatusText,
19
20
  } from "./cli/main-screen.jsx";
20
21
  import { renderHistoryContent } from "./daemon/handlers/shared.js";
21
- import type { ServerMessage } from "./daemon/message-protocol.js";
22
22
  import {
23
23
  getConversation,
24
24
  getMessages,
@@ -64,7 +64,6 @@ export function sanitizeUrlForDisplay(rawUrl: unknown): string {
64
64
  export async function startCli(): Promise<void> {
65
65
  let conversationKey = CLI_CONVERSATION_KEY;
66
66
  let conversationId = "";
67
- let pendingUserContent: string | null = null;
68
67
  let generating = false;
69
68
  let lastUsage: {
70
69
  inputTokens: number;
@@ -290,54 +289,8 @@ export async function startCli(): Promise<void> {
290
289
  });
291
290
  }
292
291
 
293
- function handleMessage(msg: ServerMessage): void {
292
+ function handleMessage(msg: AssistantEvent): void {
294
293
  switch (msg.type) {
295
- case "conversation_info":
296
- pendingSessionPick = false;
297
- conversationId = msg.conversationId;
298
- process.stdout.write(
299
- `\n Conversation: ${msg.title}\n Type your message. Ctrl+D to detach.\n\n`,
300
- );
301
- if (pendingUserContent) {
302
- const content = pendingUserContent;
303
- pendingUserContent = null;
304
- sendUserMessage(content).then((result) => {
305
- if (result.ok) {
306
- generating = true;
307
- spinner.start("Thinking...");
308
- } else {
309
- if (result.error === "secret_blocked" && result.message) {
310
- process.stdout.write(`${result.message}\n`);
311
- rl.question("Send anyway? (y/N): ", (answer) => {
312
- if (answer.trim().toLowerCase() === "y") {
313
- sendUserMessage(content, {
314
- bypassSecretCheck: true,
315
- }).then((retryResult) => {
316
- if (retryResult.ok) {
317
- generating = true;
318
- spinner.start("Thinking...");
319
- } else {
320
- process.stdout.write(
321
- "[Not connected — message not sent]\n",
322
- );
323
- prompt();
324
- }
325
- });
326
- } else {
327
- prompt();
328
- }
329
- });
330
- } else {
331
- process.stdout.write("[Not connected — message not sent]\n");
332
- prompt();
333
- }
334
- }
335
- });
336
- } else {
337
- prompt();
338
- }
339
- break;
340
-
341
294
  case "assistant_text_delta":
342
295
  spinner.stop();
343
296
  process.stdout.write(msg.text);
@@ -507,70 +460,10 @@ export async function startCli(): Promise<void> {
507
460
  prompt();
508
461
  break;
509
462
 
510
- case "conversation_list_response":
511
- if (pendingSessionPick) {
512
- renderConversationPicker(msg.conversations);
513
- } else {
514
- for (const conversation of msg.conversations) {
515
- process.stdout.write(
516
- ` ${conversation.id} ${conversation.title}\n`,
517
- );
518
- }
519
- prompt();
520
- }
521
- break;
522
-
523
463
  case "model_info":
524
464
  process.stdout.write(`\n Model: ${msg.model} (${msg.provider})\n\n`);
525
465
  prompt();
526
466
  break;
527
-
528
- case "history_response":
529
- process.stdout.write("\n");
530
- if (msg.messages.length === 0) {
531
- process.stdout.write(" No messages in this conversation.\n");
532
- } else {
533
- for (const m of msg.messages) {
534
- const label = m.role === "user" ? "you" : "assistant";
535
- const preview = truncate(m.text, 120);
536
- process.stdout.write(
537
- ` ${label}> ${preview.replace(/\n/g, " ")}\n`,
538
- );
539
- }
540
- }
541
- process.stdout.write("\n");
542
- prompt();
543
- break;
544
-
545
- case "undo_complete":
546
- if (msg.removedCount === 0) {
547
- process.stdout.write("\n Nothing to undo.\n\n");
548
- } else {
549
- process.stdout.write(
550
- `\n Removed last exchange (${msg.removedCount} messages).\n\n`,
551
- );
552
- }
553
- prompt();
554
- break;
555
-
556
- case "usage_response": {
557
- process.stdout.write("\n");
558
- process.stdout.write(` Model: ${msg.model}\n`);
559
- process.stdout.write(
560
- ` Input tokens: ${msg.totalInputTokens.toLocaleString()}\n`,
561
- );
562
- process.stdout.write(
563
- ` Output tokens: ${msg.totalOutputTokens.toLocaleString()}\n`,
564
- );
565
- const costStr =
566
- msg.estimatedCost > 0
567
- ? `$${msg.estimatedCost.toFixed(4)}`
568
- : "N/A (unknown model pricing)";
569
- process.stdout.write(` Estimated cost: ${costStr}\n`);
570
- process.stdout.write("\n");
571
- prompt();
572
- break;
573
- }
574
467
  }
575
468
  }
576
469