@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
@@ -1,6 +1,16 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
- import { usesConceptPageMemory } from "./memory-v3-gate.js";
3
+ import { memoryTier } from "./memory-tier.js";
4
+ import {
5
+ isMemoryEnabled,
6
+ isMemoryV1Active,
7
+ isMemoryV2ExplicitlyDisabled,
8
+ isMemoryV3Live,
9
+ isV2InjectionEngineActive,
10
+ isV3TierActive,
11
+ usesConceptPageMemory,
12
+ } from "./memory-v3-gate.js";
13
+ import type { AssistantConfig } from "./schema.js";
4
14
 
5
15
  describe("usesConceptPageMemory", () => {
6
16
  test("false when memory is explicitly disabled, even with v3 live", () => {
@@ -38,3 +48,270 @@ describe("usesConceptPageMemory", () => {
38
48
  expect(usesConceptPageMemory({})).toBe(false);
39
49
  });
40
50
  });
51
+
52
+ type TriState = boolean | undefined;
53
+
54
+ function makeConfig(
55
+ enabled: TriState,
56
+ v2Enabled: TriState,
57
+ v3Live: TriState,
58
+ ): AssistantConfig {
59
+ return {
60
+ memory: {
61
+ ...(enabled === undefined ? {} : { enabled }),
62
+ ...(v2Enabled === undefined ? {} : { v2: { enabled: v2Enabled } }),
63
+ ...(v3Live === undefined ? {} : { v3: { live: v3Live } }),
64
+ },
65
+ } as AssistantConfig;
66
+ }
67
+
68
+ describe("tier predicate truth table", () => {
69
+ // Rows: [enabled, v2.enabled, v3.live] → expected
70
+ // [isMemoryEnabled, isMemoryV1Active, isV2InjectionEngineActive,
71
+ // isMemoryV2ExplicitlyDisabled, isV3TierActive].
72
+ // undefined = key unset. Covers all 27 {enabled, v2.enabled, v3.live}
73
+ // tri-state combinations.
74
+ //
75
+ // The nine `enabled: false` rows are the decided memory-off semantics, and
76
+ // they are what makes the predicates non-interchangeable with the raw
77
+ // substrate/live reads: with memory off NO tier is active — not v1
78
+ // (`isMemoryV1Active` false even though `usesConceptPageMemory` is also
79
+ // false) and not v3 (`isV3TierActive` false even with `memory.v3.live`
80
+ // set). Every tier-scoped code path asks these predicates for that reason.
81
+ const rows: Array<{
82
+ inputs: [TriState, TriState, TriState];
83
+ expected: [boolean, boolean, boolean, boolean, boolean];
84
+ }> = [
85
+ // memory on by default (enabled unset)
86
+ {
87
+ inputs: [undefined, undefined, undefined],
88
+ expected: [true, true, false, false, false],
89
+ },
90
+ {
91
+ inputs: [undefined, undefined, true],
92
+ expected: [true, false, false, false, true],
93
+ },
94
+ {
95
+ inputs: [undefined, undefined, false],
96
+ expected: [true, true, false, false, false],
97
+ },
98
+ {
99
+ inputs: [undefined, true, undefined],
100
+ expected: [true, false, true, false, false],
101
+ },
102
+ {
103
+ inputs: [undefined, true, true],
104
+ expected: [true, false, false, false, true],
105
+ },
106
+ {
107
+ inputs: [undefined, true, false],
108
+ expected: [true, false, true, false, false],
109
+ },
110
+ {
111
+ inputs: [undefined, false, undefined],
112
+ expected: [true, true, false, true, false],
113
+ },
114
+ {
115
+ inputs: [undefined, false, true],
116
+ expected: [true, false, false, true, true],
117
+ },
118
+ {
119
+ inputs: [undefined, false, false],
120
+ expected: [true, true, false, true, false],
121
+ },
122
+ // memory explicitly on
123
+ {
124
+ inputs: [true, undefined, undefined],
125
+ expected: [true, true, false, false, false],
126
+ },
127
+ {
128
+ inputs: [true, undefined, true],
129
+ expected: [true, false, false, false, true],
130
+ },
131
+ {
132
+ inputs: [true, undefined, false],
133
+ expected: [true, true, false, false, false],
134
+ },
135
+ {
136
+ inputs: [true, true, undefined],
137
+ expected: [true, false, true, false, false],
138
+ },
139
+ {
140
+ inputs: [true, true, true],
141
+ expected: [true, false, false, false, true],
142
+ },
143
+ {
144
+ inputs: [true, true, false],
145
+ expected: [true, false, true, false, false],
146
+ },
147
+ {
148
+ inputs: [true, false, undefined],
149
+ expected: [true, true, false, true, false],
150
+ },
151
+ {
152
+ inputs: [true, false, true],
153
+ expected: [true, false, false, true, true],
154
+ },
155
+ {
156
+ inputs: [true, false, false],
157
+ expected: [true, true, false, true, false],
158
+ },
159
+ // memory explicitly off — no tier is active (v3-live included:
160
+ // `isV3TierActive` is false), but the explicit v2 opt-out is still visible
161
+ {
162
+ inputs: [false, undefined, undefined],
163
+ expected: [false, false, false, false, false],
164
+ },
165
+ {
166
+ inputs: [false, undefined, true],
167
+ expected: [false, false, false, false, false],
168
+ },
169
+ {
170
+ inputs: [false, undefined, false],
171
+ expected: [false, false, false, false, false],
172
+ },
173
+ {
174
+ inputs: [false, true, undefined],
175
+ expected: [false, false, false, false, false],
176
+ },
177
+ {
178
+ inputs: [false, true, true],
179
+ expected: [false, false, false, false, false],
180
+ },
181
+ {
182
+ inputs: [false, true, false],
183
+ expected: [false, false, false, false, false],
184
+ },
185
+ {
186
+ inputs: [false, false, undefined],
187
+ expected: [false, false, false, true, false],
188
+ },
189
+ {
190
+ inputs: [false, false, true],
191
+ expected: [false, false, false, true, false],
192
+ },
193
+ {
194
+ inputs: [false, false, false],
195
+ expected: [false, false, false, true, false],
196
+ },
197
+ ];
198
+
199
+ const show = (v: TriState) => (v === undefined ? "unset" : String(v));
200
+
201
+ for (const { inputs, expected } of rows) {
202
+ const [enabled, v2Enabled, v3Live] = inputs;
203
+ const [expEnabled, expV1, expV2Engine, expV2Disabled, expV3Tier] = expected;
204
+ test(`enabled=${show(enabled)} v2.enabled=${show(v2Enabled)} v3.live=${show(v3Live)}`, () => {
205
+ const config = makeConfig(enabled, v2Enabled, v3Live);
206
+ expect(isMemoryEnabled(config)).toBe(expEnabled);
207
+ expect(isMemoryV1Active(config)).toBe(expV1);
208
+ expect(isV2InjectionEngineActive(config)).toBe(expV2Engine);
209
+ expect(isMemoryV2ExplicitlyDisabled(config)).toBe(expV2Disabled);
210
+ expect(isV3TierActive(config)).toBe(expV3Tier);
211
+ // The predicates and memoryTier() share one implementation; assert every
212
+ // tier bucket agrees with the predicates on every combination. This is
213
+ // memoryTier()'s coverage — all four buckets are pinned here, so it needs
214
+ // no separate test file.
215
+ expect(isMemoryEnabled(config)).toBe(memoryTier(config) !== "off");
216
+ expect(isMemoryV1Active(config)).toBe(memoryTier(config) === "v1");
217
+ expect(isV2InjectionEngineActive(config)).toBe(
218
+ memoryTier(config) === "v2",
219
+ );
220
+ // `"off"` outranks `"v3"`, so the v3 bucket is the live-AND-enabled
221
+ // conjunction rather than `isMemoryV3Live` alone — which is exactly what
222
+ // `isV3TierActive` names.
223
+ expect(isV3TierActive(config)).toBe(memoryTier(config) === "v3");
224
+ expect(isV3TierActive(config)).toBe(
225
+ isMemoryV3Live(config) && isMemoryEnabled(config),
226
+ );
227
+ });
228
+ }
229
+
230
+ test("empty config: memory on, v1 is the live tier", () => {
231
+ const config = {} as AssistantConfig;
232
+ expect(isMemoryEnabled(config)).toBe(true);
233
+ expect(isMemoryV1Active(config)).toBe(true);
234
+ expect(isV2InjectionEngineActive(config)).toBe(false);
235
+ expect(isMemoryV2ExplicitlyDisabled(config)).toBe(false);
236
+ });
237
+
238
+ test("v2.enabled stays true on v3-live assistants; the engine predicate still reports inactive", () => {
239
+ // v2.enabled and v3.live may both be true; only the v3 injection engine
240
+ // is active then. A direct `memory.v2.enabled` read says "on"; the
241
+ // predicate must say "off".
242
+ const config = makeConfig(undefined, true, true);
243
+ expect(config.memory?.v2?.enabled).toBe(true);
244
+ expect(isV2InjectionEngineActive(config)).toBe(false);
245
+ // The substrate is still active — v3 is a concept-page consumer.
246
+ expect(usesConceptPageMemory(config.memory)).toBe(true);
247
+ });
248
+ });
249
+
250
+ /**
251
+ * The v1-staleness guard used to have three spellings that disagreed when
252
+ * memory is off: `usesConceptPageMemory(config.memory)` at job dispatch,
253
+ * `!isMemoryV1Active(config)` in the graph handlers, and a re-inlined
254
+ * `usesConceptPageMemory` on the `graph_extract` handler. All three now read
255
+ * `isMemoryV1Active`, and these tests pin both halves of that: the two
256
+ * spellings agree everywhere EXCEPT memory-off, and memory-off skips v1 work.
257
+ */
258
+ describe("v1-staleness guard is one condition", () => {
259
+ const memoryOff = makeConfig(false, undefined, undefined);
260
+ const v1Tier = makeConfig(undefined, false, false);
261
+ const v2Tier = makeConfig(undefined, true, false);
262
+ const v3Tier = makeConfig(undefined, true, true);
263
+
264
+ test("v1 work runs on the v1 tier and nowhere else", () => {
265
+ expect(isMemoryV1Active(v1Tier)).toBe(true);
266
+ expect(isMemoryV1Active(v2Tier)).toBe(false);
267
+ expect(isMemoryV1Active(v3Tier)).toBe(false);
268
+ expect(isMemoryV1Active(memoryOff)).toBe(false);
269
+ });
270
+
271
+ test("memory-off is the one state where the old spellings disagreed", () => {
272
+ // The former dispatch-level spelling. Identical on every tier…
273
+ for (const config of [v1Tier, v2Tier, v3Tier]) {
274
+ expect(isMemoryV1Active(config)).toBe(
275
+ !usesConceptPageMemory(config.memory),
276
+ );
277
+ }
278
+ // …and wrong with memory off: the substrate check reports "not concept
279
+ // pages", which the old guard read as "v1 is live" and kept v1 work
280
+ // running. The named predicate says v1 is not the tier.
281
+ expect(usesConceptPageMemory(memoryOff.memory)).toBe(false);
282
+ expect(isMemoryV1Active(memoryOff)).toBe(false);
283
+ });
284
+
285
+ test("an explicit v2 opt-out with memory off still is not the v1 tier", () => {
286
+ // `memory.v2.enabled: false` puts a memory-ON assistant on v1; memory off
287
+ // outranks that.
288
+ expect(isMemoryV1Active(makeConfig(true, false, false))).toBe(true);
289
+ expect(isMemoryV1Active(makeConfig(false, false, false))).toBe(false);
290
+ });
291
+ });
292
+
293
+ /**
294
+ * `isV3TierActive` replaced two predicates that disagreed on memory-off: the
295
+ * memory-graph capability check (which honored the opt-out) and a
296
+ * proc-to-skills alias of `isMemoryV3Live` (which did not). One predicate now
297
+ * answers for both features.
298
+ */
299
+ describe("v3 tier is one condition", () => {
300
+ test("memory off suppresses the v3 tier even with memory.v3.live set", () => {
301
+ const config = makeConfig(false, undefined, true);
302
+ // The raw key is still set — only the tier predicate accounts for the
303
+ // opt-out, which is why feature gates must not read `isMemoryV3Live`.
304
+ expect(isMemoryV3Live(config)).toBe(true);
305
+ expect(isV3TierActive(config)).toBe(false);
306
+ });
307
+
308
+ test("v3 live with memory on is the v3 tier", () => {
309
+ expect(isV3TierActive(makeConfig(true, undefined, true))).toBe(true);
310
+ expect(isV3TierActive(makeConfig(undefined, undefined, true))).toBe(true);
311
+ });
312
+
313
+ test("false when v3 is not live, and on an empty config", () => {
314
+ expect(isV3TierActive(makeConfig(undefined, undefined, false))).toBe(false);
315
+ expect(isV3TierActive({} as AssistantConfig)).toBe(false);
316
+ });
317
+ });
@@ -1,5 +1,67 @@
1
1
  import type { AssistantConfig } from "./schema.js";
2
2
 
3
+ /**
4
+ * Whether memory as a whole is on — the user-facing master switch. Memory is
5
+ * on unless `memory.enabled` is explicitly set to `false`. Canonical home for
6
+ * the check; the config-singleton `isMemoryEnabled()` in
7
+ * `persistence/jobs-store.ts` delegates here. Accepts any object carrying the
8
+ * `memory` slice, so callers holding only the plugin-resolved slice (e.g. the
9
+ * memory plugin's `getMemoryConfig()`) can gate without the full config.
10
+ */
11
+ export function isMemoryEnabled(
12
+ config: Pick<AssistantConfig, "memory">,
13
+ ): boolean {
14
+ return config.memory?.enabled !== false;
15
+ }
16
+
17
+ /**
18
+ * Whether the legacy graph/PKB memory engine (tier v1) is the live tier:
19
+ * memory is on and no concept-page consumer (v3 live or the v2 injection
20
+ * engine) is. Like {@link isMemoryEnabled}, accepts a `memory`-slice view.
21
+ *
22
+ * THE memory-off semantics for v1, stated once and shared by every v1 path
23
+ * (job dispatch, the job handlers, maintenance scheduling, startup seeding,
24
+ * the filing routes): `memory.enabled === false` means v1 is NOT the live
25
+ * tier, so v1 work is skipped exactly as it is under the concept-page
26
+ * substrate. Turning memory off is a user-facing opt-out — it must never be
27
+ * the one state in which the daemon still LLM-extracts, embeds, or files into
28
+ * the legacy graph. Ask this predicate, never `usesConceptPageMemory` alone:
29
+ * the two agree on every tier EXCEPT memory-off, where the bare substrate
30
+ * check reports "v1" and would keep v1 running.
31
+ */
32
+ export function isMemoryV1Active(
33
+ config: Pick<AssistantConfig, "memory">,
34
+ ): boolean {
35
+ return isMemoryEnabled(config) && !usesConceptPageMemory(config.memory);
36
+ }
37
+
38
+ /**
39
+ * Whether the v2 activation/router engine performs turn-time selection:
40
+ * memory is on, `memory.v2.enabled` is set, and v3 is NOT the live injected
41
+ * source. Distinct from `usesConceptPageMemory`: `memory.v2.enabled` defaults
42
+ * true and typically stays set on v3-live assistants, so this predicate is the
43
+ * ONLY correct way to ask "should v2 select this turn" — a direct
44
+ * `memory.v2.enabled` read misbehaves under v3.
45
+ */
46
+ export function isV2InjectionEngineActive(config: AssistantConfig): boolean {
47
+ return (
48
+ isMemoryEnabled(config) &&
49
+ config.memory?.v2?.enabled === true &&
50
+ !isMemoryV3Live(config)
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Whether `memory.v2.enabled` is explicitly `false` — deliberately NOT the
56
+ * negation of `isV2InjectionEngineActive`, since the key defaults true. Names
57
+ * the explicit-false semantics `daemon/embedding-reconcile.ts` relies on: an
58
+ * explicit opt-out suppresses concept-page reconcile work even where the
59
+ * default would allow it.
60
+ */
61
+ export function isMemoryV2ExplicitlyDisabled(config: AssistantConfig): boolean {
62
+ return config.memory?.v2?.enabled === false;
63
+ }
64
+
3
65
  /**
4
66
  * Whether memory-v3 is the live injected memory source for this assistant,
5
67
  * suppressing v2 injection. Gated by workspace config (`memory.v3.live`): new
@@ -11,34 +73,34 @@ export function isMemoryV3Live(config: AssistantConfig): boolean {
11
73
  }
12
74
 
13
75
  /**
14
- * Whether the memory concept graph is available for this assistant — the single
15
- * source of truth for both `GET /memory-graph` (`supported`) and the cheap
16
- * `graph_supported` bit on `GET /memory/stats`, so the advertised capability
17
- * and the actual build can never drift.
76
+ * Whether memory-v3 is the live TIER: v3 is the live injected source AND
77
+ * memory as a whole is on. Exactly `memoryTier(config) === "v3"` (see
78
+ * `memory-tier.ts`), and the difference from {@link isMemoryV3Live} is the
79
+ * memory-off case — `"off"` outranks `"v3"`, so a `memory.v3.live` assistant
80
+ * whose owner switched Memory off is NOT on the v3 tier. Every v3-tier-scoped
81
+ * FEATURE asks this predicate; only the injection-suppression checks that must
82
+ * mirror the raw `memory.v3.live` key ask {@link isMemoryV3Live} directly.
18
83
  *
19
- * The graph builds off the v3 concept-page substrate, so it requires v3 live.
20
- * It also honors the user-facing Memory opt-out: `memory.enabled === false`
21
- * turns memory off wholesale, so the graph must not be offered even when
22
- * `memory.v3.live` is still set.
23
- */
24
- export function isMemoryGraphSupported(config: AssistantConfig): boolean {
25
- return config.memory?.enabled !== false && isMemoryV3Live(config);
26
- }
27
-
28
- /**
29
- * Whether procedural-memory-as-skills is ACTIVE: it is active whenever
30
- * memory-v3 is the live injected source. The feature is scoped to v3-live
31
- * assistants because skill retrieval rides the v3 lanes and the usage-prune
32
- * stage lives in the v3 maintain job. That prune ships observe-first: with
33
- * `memory.maintenance.skillPruneDays` at its default (`null`) it reports stale
34
- * assistant-authored skills (`prunableSkills`) but deletes none — so a v3-live
35
- * assistant authors skills without an automatic retirement bound until a
36
- * positive `skillPruneDays` is configured. Gating the whole feature (the
37
- * retrospective skill-authoring step and its permission grant) on this named
38
- * predicate keeps it coherently inert on non-v3 assistants.
84
+ * The two features gated on it, and why they must agree:
85
+ *
86
+ * - The memory concept graph — the single source of truth for both
87
+ * `GET /memory-graph` (`supported`) and the cheap `graph_supported` bit on
88
+ * `GET /memory/stats`, so the advertised capability and the actual build can
89
+ * never drift. The graph builds off the v3 concept-page substrate.
90
+ * - Procedural-memory-as-skills — the retrospective's skill-authoring step and
91
+ * its permission grant. Scoped to the v3 tier because skill retrieval rides
92
+ * the v3 lanes and the usage-prune stage lives in the v3 maintain job. That
93
+ * prune ships observe-first: with `memory.maintenance.skillPruneDays` at its
94
+ * default (`null`) it reports stale assistant-authored skills
95
+ * (`prunableSkills`) but deletes none — so a v3-tier assistant authors skills
96
+ * without an automatic retirement bound until a positive `skillPruneDays` is
97
+ * configured.
98
+ *
99
+ * Both write into memory on the user's behalf, so both honor the Memory
100
+ * opt-out identically: one predicate, one answer.
39
101
  */
40
- export function isProcToSkillsActive(config: AssistantConfig): boolean {
41
- return isMemoryV3Live(config);
102
+ export function isV3TierActive(config: AssistantConfig): boolean {
103
+ return isMemoryEnabled(config) && isMemoryV3Live(config);
42
104
  }
43
105
 
44
106
  /**
@@ -4,7 +4,7 @@
4
4
  * Ensures the `services` and service-level objects exist before writing,
5
5
  * so callers don't need to guard against undefined intermediate keys.
6
6
  *
7
- * Example: `setServiceField(raw, "image-generation", "mode", "managed")`
7
+ * Example: `setServiceField(raw, "image-generation", "provider", "vellum")`
8
8
  * produces `raw.services["image-generation"].mode = "managed"`.
9
9
  */
10
10
  export function setServiceField(
@@ -11,6 +11,8 @@ const PROGRESS_DEFAULTS = {
11
11
  enabled: true,
12
12
  opsThreshold: 3,
13
13
  idleIntervalMs: 5_000,
14
+ maxSilenceMs: 35_000,
15
+ longOpMs: 15_000,
14
16
  minGapMs: 6_000,
15
17
  generationTimeoutMs: 1_500,
16
18
  };
@@ -21,7 +23,6 @@ const FRONT_MODEL_DEFAULTS = {
21
23
  endpointMaxExtensions: 2,
22
24
  ackFirstDeltaTimeoutMs: 2500,
23
25
  ackGenerationTimeoutMs: 600,
24
- llmAckText: false,
25
26
  progress: PROGRESS_DEFAULTS,
26
27
  };
27
28
 
@@ -86,11 +87,9 @@ describe("LiveVoiceFrontModelConfigSchema", () => {
86
87
  const parsed = LiveVoiceFrontModelConfigSchema.parse({
87
88
  endpointDecisionTimeoutMs: 400,
88
89
  endpointMaxExtensions: 0,
89
- llmAckText: true,
90
90
  });
91
91
  expect(parsed.endpointDecisionTimeoutMs).toBe(400);
92
92
  expect(parsed.endpointMaxExtensions).toBe(0);
93
- expect(parsed.llmAckText).toBe(true);
94
93
  // Unspecified fields still get defaults
95
94
  expect(parsed.endpointExtensionMs).toBe(1500);
96
95
  expect(parsed.ackFirstDeltaTimeoutMs).toBe(2500);
@@ -111,19 +110,6 @@ describe("LiveVoiceFrontModelConfigSchema", () => {
111
110
  expect(result.success).toBe(false);
112
111
  });
113
112
 
114
- test("rejects a non-boolean llmAckText", () => {
115
- const result = LiveVoiceFrontModelConfigSchema.safeParse({
116
- llmAckText: "yes",
117
- });
118
- expect(result.success).toBe(false);
119
- if (!result.success) {
120
- const msgs = result.error.issues.map((i) => i.message);
121
- expect(
122
- msgs.some((m) => m.includes("liveVoice.frontModel.llmAckText")),
123
- ).toBe(true);
124
- }
125
- });
126
-
127
113
  test("absent progress namespace parses to full progress defaults", () => {
128
114
  const parsed = LiveVoiceFrontModelConfigSchema.parse({});
129
115
  expect(parsed.progress).toEqual(PROGRESS_DEFAULTS);
@@ -137,6 +123,8 @@ describe("LiveVoiceFrontModelConfigSchema", () => {
137
123
  expect(parsed.progress.opsThreshold).toBe(5);
138
124
  // Unspecified progress fields still get defaults
139
125
  expect(parsed.progress.idleIntervalMs).toBe(5_000);
126
+ expect(parsed.progress.maxSilenceMs).toBe(35_000);
127
+ expect(parsed.progress.longOpMs).toBe(15_000);
140
128
  expect(parsed.progress.minGapMs).toBe(6_000);
141
129
  expect(parsed.progress.generationTimeoutMs).toBe(1_500);
142
130
  });
@@ -156,6 +144,29 @@ describe("LiveVoiceFrontModelConfigSchema", () => {
156
144
  expect(result.success).toBe(false);
157
145
  });
158
146
 
147
+ test("rejects a heartbeat ceiling shorter than the idle tick interval", () => {
148
+ // The heartbeat is only checked on the idle tick, so a shorter ceiling
149
+ // could be overshot by a full interval.
150
+ const result = LiveVoiceFrontModelConfigSchema.safeParse({
151
+ progress: { idleIntervalMs: 60_000, maxSilenceMs: 10_000 },
152
+ });
153
+ expect(result.success).toBe(false);
154
+ if (!result.success) {
155
+ const msgs = result.error.issues.map((issue) => issue.message);
156
+ expect(
157
+ msgs.some((msg) =>
158
+ msg.includes("liveVoice.frontModel.progress.maxSilenceMs"),
159
+ ),
160
+ ).toBe(true);
161
+ }
162
+ // The floor itself is allowed: the tick is exactly on the ceiling.
163
+ expect(
164
+ LiveVoiceFrontModelConfigSchema.safeParse({
165
+ progress: { idleIntervalMs: 60_000, maxSilenceMs: 60_000 },
166
+ }).success,
167
+ ).toBe(true);
168
+ });
169
+
159
170
  test("rejects a non-boolean progress.enabled", () => {
160
171
  const result = LiveVoiceFrontModelConfigSchema.safeParse({
161
172
  progress: { enabled: "yes" },
@@ -22,6 +22,7 @@ describe("MemoryV3ConfigSchema", () => {
22
22
  needleK: 100,
23
23
  denseK: 100,
24
24
  replyQueryK: 12,
25
+ spanQueryK: 0,
25
26
  selectorEnabled: true,
26
27
  selectorPromptPath: null,
27
28
  edge: { hubDegree: 30, seedCount: 18, perSeed: 6, cap: 45 },
@@ -79,7 +79,31 @@ export const LiveVoiceProgressConfigSchema = z
79
79
  )
80
80
  .default(5_000)
81
81
  .describe(
82
- "Narrate after this much silence (ms) with the turn still running",
82
+ "How often (ms) a running turn's silence is checked, and so the soonest new tool activity is narrated",
83
+ ),
84
+ maxSilenceMs: z
85
+ .number({
86
+ error: "liveVoice.frontModel.progress.maxSilenceMs must be a number",
87
+ })
88
+ .int("liveVoice.frontModel.progress.maxSilenceMs must be an integer")
89
+ .positive(
90
+ "liveVoice.frontModel.progress.maxSilenceMs must be a positive integer",
91
+ )
92
+ .default(35_000)
93
+ .describe(
94
+ "Heartbeat ceiling (ms): narrate after this much unbroken silence even when nothing new has happened. Evaluated on the idle tick, so its resolution is idleIntervalMs and it must be at least that long",
95
+ ),
96
+ longOpMs: z
97
+ .number({
98
+ error: "liveVoice.frontModel.progress.longOpMs must be a number",
99
+ })
100
+ .int("liveVoice.frontModel.progress.longOpMs must be an integer")
101
+ .positive(
102
+ "liveVoice.frontModel.progress.longOpMs must be a positive integer",
103
+ )
104
+ .default(15_000)
105
+ .describe(
106
+ "A tool operation that ran at least this long (ms) narrates the moment it completes, without waiting for opsThreshold",
83
107
  ),
84
108
  minGapMs: z
85
109
  .number({
@@ -109,6 +133,14 @@ export const LiveVoiceProgressConfigSchema = z
109
133
  "Budget (ms) for LLM-generated progress text — not latency-critical: it speaks into dead air",
110
134
  ),
111
135
  })
136
+ // The heartbeat is checked when the idle tick finds the turn silent, so a
137
+ // ceiling shorter than the tick interval would be missed by up to a full
138
+ // interval — a promise the cadence cannot keep. Rejecting the combination
139
+ // beats silently overshooting it.
140
+ .refine((progress) => progress.maxSilenceMs >= progress.idleIntervalMs, {
141
+ error:
142
+ "liveVoice.frontModel.progress.maxSilenceMs must be at least idleIntervalMs — the heartbeat is evaluated on the idle tick",
143
+ })
112
144
  .describe(
113
145
  "Progress-narration tuning for live voice sessions (spoken updates during long-running turns)",
114
146
  );
@@ -172,12 +204,6 @@ export const LiveVoiceFrontModelConfigSchema = z
172
204
  )
173
205
  .default(600)
174
206
  .describe("Budget (ms) for LLM-generated ack text"),
175
- llmAckText: z
176
- .boolean({ error: "liveVoice.frontModel.llmAckText must be a boolean" })
177
- .default(false)
178
- .describe(
179
- "Use the front model to phrase spoken acks; static phrases otherwise",
180
- ),
181
207
  progress: LiveVoiceProgressConfigSchema.default(
182
208
  LiveVoiceProgressConfigSchema.parse({}),
183
209
  ),
@@ -39,6 +39,7 @@ export const LLMProvider = z
39
39
  "together",
40
40
  "litellm",
41
41
  "baseten",
42
+ "poolside",
42
43
  // Routing identities rather than adapters: "vellum" = the platform-managed
43
44
  // route (upstream derived from the model at dispatch), "chatgpt" = the
44
45
  // subscription route to OpenAI. Neither has a PROVIDER_CATALOG entry;
@@ -52,6 +52,19 @@ export const MemoryRetrospectiveConfigSchema = z
52
52
  "Cadence of the scheduled retrospective sweep, the timer-driven backstop that re-scans conversations for unprocessed messages the event-driven triggers missed (e.g. a turn that ended in a crash or IPC drop before the post-turn hooks ran). A conversation is only swept when its last retrospective attempt is at least this old, so the sweep never competes with the responsive interval/message_count triggers on active conversations.",
53
53
  ),
54
54
 
55
+ sweepLookbackMs: z
56
+ .number({
57
+ error: "memory.retrospective.sweepLookbackMs must be a number",
58
+ })
59
+ .int("memory.retrospective.sweepLookbackMs must be an integer")
60
+ .positive(
61
+ "memory.retrospective.sweepLookbackMs must be a positive integer",
62
+ )
63
+ .default(7 * 24 * 60 * 60 * 1000)
64
+ .describe(
65
+ "How far back the scheduled retrospective sweep looks for stalled work. The sweep backstops turns that ended abnormally (crash / IPC drop), and such turns are by definition recent — so only conversations whose last message falls inside this window are scanned, and the retrospective job re-applies the same window at execution time so a stale queued backlog is skipped instead of run. Conversations dormant beyond the window are outside the sweep's scope entirely: their unprocessed tails are ordinary end-of-conversation remainders, not stalled work. Values below twice memory.retrospective.sweepIntervalMs are clamped up to that floor — scheduler and queue delay stretch the gap between consecutive scans past the nominal cadence, so a window at or under one interval would leave a permanent blind span between passes.",
66
+ ),
67
+
55
68
  keepSupersededRuns: z
56
69
  .boolean({
57
70
  error: "memory.retrospective.keepSupersededRuns must be a boolean",