@vellumai/assistant 0.10.12 → 0.11.0-staging.2

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 (809) 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 +264 -14
  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__/app-conversation-ids-backfill.test.ts +33 -2
  39. package/src/__tests__/app-conversation-ids.test.ts +204 -0
  40. package/src/__tests__/approval-cascade.test.ts +5 -5
  41. package/src/__tests__/approval-routes-http.test.ts +3 -3
  42. package/src/__tests__/ask-question-resolver.test.ts +207 -0
  43. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
  44. package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
  45. package/src/__tests__/assistant-event-hub.test.ts +13 -11
  46. package/src/__tests__/assistant-event.test.ts +12 -9
  47. package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
  48. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
  49. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
  50. package/src/__tests__/assistant-stream-state.test.ts +17 -7
  51. package/src/__tests__/avatar-identity-sync.test.ts +3 -3
  52. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  53. package/src/__tests__/call-conversation-messages.test.ts +134 -18
  54. package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
  55. package/src/__tests__/channel-approvals.test.ts +0 -27
  56. package/src/__tests__/channel-guardian.test.ts +85 -512
  57. package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
  58. package/src/__tests__/channel-retry-sweep.test.ts +88 -1
  59. package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
  60. package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
  61. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  62. package/src/__tests__/compaction-events.test.ts +8 -8
  63. package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
  64. package/src/__tests__/config-model-image-provider.test.ts +20 -0
  65. package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
  66. package/src/__tests__/config-schema.test.ts +14 -2
  67. package/src/__tests__/config-set-platform-guard.test.ts +11 -12
  68. package/src/__tests__/config-sounds-sync.test.ts +4 -4
  69. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
  70. package/src/__tests__/context-search-memory-source.test.ts +1 -1
  71. package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
  72. package/src/__tests__/context-token-estimator.test.ts +54 -1
  73. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
  74. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
  75. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
  76. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
  77. package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
  78. package/src/__tests__/conversation-agent-loop.test.ts +39 -30
  79. package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
  80. package/src/__tests__/conversation-evictor.test.ts +49 -0
  81. package/src/__tests__/conversation-fork-crud.test.ts +1 -1
  82. package/src/__tests__/conversation-group-tools.test.ts +279 -0
  83. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  84. package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
  85. package/src/__tests__/conversation-lineage.test.ts +235 -0
  86. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
  87. package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
  88. package/src/__tests__/conversation-queue.test.ts +81 -81
  89. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
  90. package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
  91. package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
  92. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
  93. package/src/__tests__/conversation-slash-queue.test.ts +11 -11
  94. package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
  95. package/src/__tests__/conversation-speed-override.test.ts +2 -2
  96. package/src/__tests__/conversation-summarize-route.test.ts +9 -0
  97. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
  98. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
  99. package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
  100. package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
  101. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
  102. package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
  103. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  104. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
  105. package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
  106. package/src/__tests__/conversation-sync-tags.test.ts +5 -5
  107. package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
  108. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  109. package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
  110. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
  111. package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
  112. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  113. package/src/__tests__/daemon-assistant-events.test.ts +14 -15
  114. package/src/__tests__/db-test-helpers.ts +13 -27
  115. package/src/__tests__/disk-pressure-routes.test.ts +12 -3
  116. package/src/__tests__/document-tool-security.test.ts +95 -0
  117. package/src/__tests__/drain-kick-guard.test.ts +232 -0
  118. package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
  119. package/src/__tests__/emit-event-signal.test.ts +5 -6
  120. package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
  121. package/src/__tests__/events-tail-route.test.ts +6 -4
  122. package/src/__tests__/feature-flag-test-helpers.ts +10 -20
  123. package/src/__tests__/file-edit-tool.test.ts +24 -4
  124. package/src/__tests__/file-list-tool.test.ts +2 -1
  125. package/src/__tests__/file-read-tool.test.ts +62 -10
  126. package/src/__tests__/file-write-tool.test.ts +24 -5
  127. package/src/__tests__/followup-tools.test.ts +58 -0
  128. package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
  129. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  130. package/src/__tests__/guardian-question-mode.test.ts +42 -3
  131. package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
  132. package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
  133. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  134. package/src/__tests__/heartbeat-service.test.ts +1 -0
  135. package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
  136. package/src/__tests__/host-browser-proxy.test.ts +1 -1
  137. package/src/__tests__/host-file-edit-tool.test.ts +3 -3
  138. package/src/__tests__/host-file-read-tool.test.ts +2 -2
  139. package/src/__tests__/host-file-write-tool.test.ts +7 -3
  140. package/src/__tests__/host-shell-tool.test.ts +17 -5
  141. package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
  142. package/src/__tests__/image-credentials.test.ts +65 -8
  143. package/src/__tests__/injection-block.test.ts +4 -4
  144. package/src/__tests__/injector-chain.test.ts +1 -1
  145. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  146. package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
  147. package/src/__tests__/injector-v3-suppression.test.ts +6 -4
  148. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
  149. package/src/__tests__/list-messages-page-latest.test.ts +2 -2
  150. package/src/__tests__/llm-usage-store.test.ts +67 -4
  151. package/src/__tests__/log-redact.test.ts +18 -0
  152. package/src/__tests__/managed-profile-guard.test.ts +27 -0
  153. package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
  154. package/src/__tests__/media-generate-image.test.ts +62 -11
  155. package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
  156. package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
  157. package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
  158. package/src/__tests__/notification-decision-strategy.test.ts +115 -11
  159. package/src/__tests__/notification-deep-link.test.ts +12 -12
  160. package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
  161. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  162. package/src/__tests__/path-policy.test.ts +315 -0
  163. package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
  164. package/src/__tests__/persistence-layering-guard.test.ts +2 -2
  165. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  166. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
  167. package/src/__tests__/platform-callback-registration.test.ts +10 -10
  168. package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
  169. package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
  170. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
  171. package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
  172. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  173. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
  174. package/src/__tests__/require-fresh-approval.test.ts +38 -38
  175. package/src/__tests__/resolve-app-id.test.ts +32 -0
  176. package/src/__tests__/run-due-schedules.test.ts +72 -1
  177. package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
  178. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  179. package/src/__tests__/schedule-routes.test.ts +44 -5
  180. package/src/__tests__/schedule-store.test.ts +3 -3
  181. package/src/__tests__/schedule-tools.test.ts +176 -0
  182. package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
  183. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
  184. package/src/__tests__/secret-response-routing.test.ts +3 -3
  185. package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
  186. package/src/__tests__/secret-scanner.test.ts +36 -0
  187. package/src/__tests__/send-endpoint-busy.test.ts +7 -7
  188. package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
  189. package/src/__tests__/starter-task-flow.test.ts +26 -3
  190. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  191. package/src/__tests__/subagent-disposal.test.ts +40 -11
  192. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  193. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
  194. package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
  195. package/src/__tests__/subagent-manager-notify.test.ts +73 -14
  196. package/src/__tests__/subagent-notify-parent.test.ts +48 -4
  197. package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
  198. package/src/__tests__/subagent-tools.test.ts +64 -0
  199. package/src/__tests__/sync-message-contract.test.ts +3 -3
  200. package/src/__tests__/terminal-tools.test.ts +12 -3
  201. package/src/__tests__/test-preload.ts +9 -0
  202. package/src/__tests__/tool-approval-handler.test.ts +587 -43
  203. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
  204. package/src/__tests__/tool-executor.test.ts +116 -0
  205. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
  206. package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
  207. package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
  208. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  209. package/src/__tests__/tool-start-timestamp.test.ts +4 -4
  210. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
  211. package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
  212. package/src/__tests__/ui-work-result-surface.test.ts +3 -3
  213. package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
  214. package/src/__tests__/voice-session-bridge.test.ts +44 -44
  215. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
  216. package/src/__tests__/workspace-policy.test.ts +482 -2
  217. package/src/acp/__tests__/client-handler.test.ts +3 -3
  218. package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
  219. package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
  220. package/src/acp/client-handler.ts +3 -3
  221. package/src/acp/session-manager.ts +8 -8
  222. package/src/api/events/subagent-event.ts +2 -2
  223. package/src/api/responses/memory-v2-activation-log.ts +2 -2
  224. package/src/api/responses/subagent-detail.ts +13 -0
  225. package/src/approvals/AGENTS.md +2 -0
  226. package/src/approvals/guardian-request-resolvers.ts +118 -24
  227. package/src/apps/app-store.ts +95 -4
  228. package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
  229. package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
  230. package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
  231. package/src/calls/call-controller.ts +27 -27
  232. package/src/calls/call-conversation-messages.ts +58 -18
  233. package/src/calls/voice-control-protocol.ts +56 -0
  234. package/src/calls/voice-session-bridge.ts +178 -65
  235. package/src/calls/voice-triage-escalate.ts +2 -3
  236. package/src/channels/config.ts +8 -0
  237. package/src/channels/types.ts +1 -0
  238. package/src/cli/commands/config.ts +49 -13
  239. package/src/cli/commands/memory/index.help.ts +4 -2
  240. package/src/cli/commands/memory/memory-retrospective.ts +5 -0
  241. package/src/cli/commands/webhooks.help.ts +9 -4
  242. package/src/cli/lib/bundled-marketplace.json +12 -0
  243. package/src/cli.ts +2 -109
  244. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
  245. package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
  246. package/src/config/assistant-feature-flags.ts +1 -1
  247. package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
  248. package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
  249. package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
  250. package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
  251. package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
  252. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
  253. package/src/config/bundled-skills/schedule/SKILL.md +2 -0
  254. package/src/config/feature-flag-cache.ts +6 -16
  255. package/src/config/feature-flag-registry.json +14 -38
  256. package/src/config/loader.ts +7 -1
  257. package/src/config/memory-tier.ts +15 -10
  258. package/src/config/memory-v3-gate.test.ts +278 -1
  259. package/src/config/memory-v3-gate.ts +88 -26
  260. package/src/config/raw-config-utils.ts +1 -1
  261. package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
  262. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  263. package/src/config/schemas/live-voice.ts +33 -7
  264. package/src/config/schemas/llm.ts +1 -0
  265. package/src/config/schemas/memory-retrospective.ts +13 -0
  266. package/src/config/schemas/memory-substrate.ts +183 -0
  267. package/src/config/schemas/memory-v2.ts +3 -2
  268. package/src/config/schemas/memory-v3.ts +11 -4
  269. package/src/config/schemas/memory.ts +35 -1
  270. package/src/config/schemas/services.ts +10 -2
  271. package/src/config/substrate-twin-shadowing.ts +195 -0
  272. package/src/config/webhook-routing.ts +67 -0
  273. package/src/context/compactor.ts +10 -3
  274. package/src/context/token-estimator.ts +21 -0
  275. package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
  276. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
  277. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
  278. package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
  279. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
  280. package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
  281. package/src/daemon/channel-ui-capability.ts +70 -1
  282. package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
  283. package/src/daemon/conversation-agent-loop.ts +12 -5
  284. package/src/daemon/conversation-evictor.ts +26 -4
  285. package/src/daemon/conversation-launch.ts +11 -14
  286. package/src/daemon/conversation-lineage.ts +76 -0
  287. package/src/daemon/conversation-messaging.ts +14 -14
  288. package/src/daemon/conversation-notifiers.ts +2 -2
  289. package/src/daemon/conversation-process.ts +133 -21
  290. package/src/daemon/conversation-queue-manager.ts +7 -7
  291. package/src/daemon/conversation-runtime-assembly.ts +16 -0
  292. package/src/daemon/conversation-store.ts +11 -3
  293. package/src/daemon/conversation-surfaces.ts +8 -14
  294. package/src/daemon/conversation-tool-setup.ts +13 -7
  295. package/src/daemon/conversation-usage.ts +12 -11
  296. package/src/daemon/conversation.ts +38 -15
  297. package/src/daemon/disk-pressure-guard.ts +5 -12
  298. package/src/daemon/embedding-reconcile.ts +14 -9
  299. package/src/daemon/handlers/config-channels.ts +40 -134
  300. package/src/daemon/handlers/config-model.ts +15 -7
  301. package/src/daemon/handlers/conversations.ts +4 -2
  302. package/src/daemon/handlers/shared.ts +29 -0
  303. package/src/daemon/host-proxy-base.ts +4 -4
  304. package/src/daemon/lifecycle.ts +13 -0
  305. package/src/daemon/message-protocol.ts +8 -144
  306. package/src/daemon/message-types/computer-use.ts +0 -12
  307. package/src/daemon/message-types/conversations.ts +9 -345
  308. package/src/daemon/message-types/host-app-control.ts +0 -9
  309. package/src/daemon/message-types/host-browser.ts +0 -7
  310. package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
  311. package/src/daemon/message-types/messages.ts +0 -48
  312. package/src/daemon/message-types/notifications.ts +0 -7
  313. package/src/daemon/message-types/skills.ts +0 -5
  314. package/src/daemon/message-types/surfaces.ts +0 -9
  315. package/src/daemon/message-types/sync.ts +0 -2
  316. package/src/daemon/process-message.ts +5 -5
  317. package/src/daemon/skill-memory-refresh.ts +5 -5
  318. package/src/daemon/tool-side-effects.ts +32 -16
  319. package/src/daemon/trust-context.ts +1 -1
  320. package/src/daemon/wake-conversation-ops.ts +4 -4
  321. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
  322. package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
  323. package/src/heartbeat/heartbeat-run-store.ts +81 -4
  324. package/src/heartbeat/heartbeat-service.ts +32 -1
  325. package/src/home/__tests__/feed-writer.test.ts +7 -7
  326. package/src/home/__tests__/home-content-refresh.test.ts +3 -0
  327. package/src/home/__tests__/suggested-prompts.test.ts +1 -0
  328. package/src/home/feed-writer.ts +6 -13
  329. package/src/home/home-content-refresh.ts +6 -9
  330. package/src/home/relationship-state-writer.ts +5 -12
  331. package/src/home/suggested-prompts-cache.ts +6 -19
  332. package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
  333. package/src/ipc/events-publish-client.ts +44 -0
  334. package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
  335. package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
  336. package/src/ipc/routes/events-ipc-routes.ts +11 -31
  337. package/src/live-voice/__tests__/front-decision.test.ts +4 -176
  338. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
  339. package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
  340. package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
  341. package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
  342. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
  343. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
  344. package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
  345. package/src/live-voice/front-decision.ts +5 -155
  346. package/src/live-voice/live-voice-metrics.ts +4 -1
  347. package/src/live-voice/live-voice-session.ts +1288 -439
  348. package/src/live-voice/progress-phrases.ts +17 -0
  349. package/src/live-voice/protocol.ts +15 -0
  350. package/src/media/app-icon-generator.ts +15 -8
  351. package/src/media/avatar-router.ts +9 -5
  352. package/src/media/image-credentials.ts +42 -10
  353. package/src/media/image-service.ts +1 -13
  354. package/src/media/types.ts +26 -3
  355. package/src/notifications/AGENTS.md +2 -0
  356. package/src/notifications/__tests__/broadcaster.test.ts +95 -0
  357. package/src/notifications/adapters/macos.ts +3 -3
  358. package/src/notifications/broadcaster.ts +57 -0
  359. package/src/notifications/copy-composer.ts +0 -15
  360. package/src/notifications/decision-engine.ts +21 -22
  361. package/src/notifications/guardian-question-mode.ts +57 -2
  362. package/src/notifications/home-feed-side-effect.ts +4 -0
  363. package/src/notifications/signal.ts +6 -4
  364. package/src/notifications/trusted-contact-payloads.ts +3 -4
  365. package/src/notifications/vellum-card-affinity.ts +39 -0
  366. package/src/oauth/AGENTS.md +1 -1
  367. package/src/permissions/channel-permission-query.test.ts +69 -0
  368. package/src/permissions/channel-permission-query.ts +73 -1
  369. package/src/permissions/checker.test.ts +298 -15
  370. package/src/permissions/checker.ts +102 -36
  371. package/src/permissions/confirmation-guardian-request.test.ts +2 -2
  372. package/src/permissions/confirmation-guardian-request.ts +2 -2
  373. package/src/permissions/gateway-threshold-reader.test.ts +224 -17
  374. package/src/permissions/gateway-threshold-reader.ts +82 -10
  375. package/src/permissions/ipc-risk-types.ts +8 -0
  376. package/src/permissions/prompter.ts +5 -5
  377. package/src/permissions/question-guardian-request.test.ts +222 -0
  378. package/src/permissions/question-guardian-request.ts +179 -0
  379. package/src/permissions/question-prompter.test.ts +8 -8
  380. package/src/permissions/question-prompter.ts +18 -0
  381. package/src/permissions/secret-prompter.ts +2 -4
  382. package/src/permissions/workspace-policy.ts +269 -34
  383. package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
  384. package/src/persistence/__tests__/message-content-file.test.ts +58 -3
  385. package/src/persistence/conversation-crud.ts +93 -0
  386. package/src/persistence/conversation-key-store.ts +63 -0
  387. package/src/persistence/conversation-parent.ts +27 -0
  388. package/src/persistence/db-async-query.ts +1 -1
  389. package/src/persistence/db-singleton.ts +14 -27
  390. package/src/persistence/delivery-crud.ts +45 -0
  391. package/src/persistence/embeddings/embedding-backend.ts +2 -1
  392. package/src/persistence/embeddings/embedding-identity.ts +7 -3
  393. package/src/persistence/job-utils.ts +32 -27
  394. package/src/persistence/jobs-store.ts +92 -3
  395. package/src/persistence/lifecycle-quiesce.ts +80 -0
  396. package/src/persistence/llm-usage-store.ts +45 -8
  397. package/src/persistence/message-content-file.ts +4 -4
  398. package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
  399. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
  400. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
  401. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
  402. package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
  403. package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
  404. package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
  405. package/src/persistence/schema/infrastructure.ts +11 -0
  406. package/src/persistence/steps.ts +9 -1
  407. package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
  408. package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
  409. package/src/plugin-api/conversation-turn.ts +4 -4
  410. package/src/plugin-api/event-hub-facade.ts +15 -6
  411. package/src/plugin-api/index.ts +10 -4
  412. package/src/plugin-api/publish-event.ts +36 -0
  413. package/src/plugins/AGENTS.md +2 -0
  414. package/src/plugins/defaults/compaction/window-manager.ts +9 -0
  415. package/src/plugins/defaults/index.ts +9 -13
  416. package/src/plugins/defaults/memory/AGENTS.md +775 -0
  417. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
  418. package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
  419. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
  420. package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
  421. package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
  422. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
  423. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
  424. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
  425. package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
  426. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
  427. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
  428. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
  429. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  430. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
  431. package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
  432. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
  433. package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
  434. package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
  435. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
  436. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
  437. package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
  438. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
  439. package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
  440. package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
  441. package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
  442. package/src/plugins/defaults/memory/graph/store.ts +1 -0
  443. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
  444. package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
  445. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
  446. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
  447. package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
  448. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
  449. package/src/plugins/defaults/memory/indexer.ts +146 -89
  450. package/src/plugins/defaults/memory/injectors.ts +86 -41
  451. package/src/plugins/defaults/memory/job-handlers.ts +130 -39
  452. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  453. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
  454. package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
  455. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
  456. package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
  457. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
  458. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
  459. package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
  460. package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
  461. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
  462. package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
  463. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
  464. package/src/plugins/defaults/memory/startup.ts +58 -21
  465. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
  466. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
  467. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
  468. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
  469. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
  470. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
  471. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
  472. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
  473. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
  474. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
  475. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
  476. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
  477. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
  478. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
  479. package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
  480. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
  481. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
  482. package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
  483. package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
  484. package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
  485. package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
  486. package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
  487. package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
  488. package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
  489. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
  490. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
  491. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
  492. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
  493. package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
  494. package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
  495. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
  496. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
  497. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
  498. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
  499. package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
  500. package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
  501. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
  502. package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
  503. package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
  504. package/src/plugins/defaults/memory/tools.test.ts +1 -1
  505. package/src/plugins/defaults/memory/tools.ts +1 -1
  506. package/src/plugins/defaults/memory/v1/README.md +5 -0
  507. package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
  508. package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
  509. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
  510. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
  511. package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
  512. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
  513. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
  514. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
  515. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
  516. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
  517. package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
  518. package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
  519. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
  520. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
  521. package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
  522. package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
  523. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
  524. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
  525. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
  526. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
  527. package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
  528. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
  529. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
  530. package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
  531. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
  532. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
  533. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
  534. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
  535. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
  536. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
  537. package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
  538. package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
  539. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
  540. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
  541. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
  542. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
  543. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
  544. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
  545. package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
  546. package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
  547. package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
  548. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
  549. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
  550. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
  551. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
  552. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  553. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  554. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
  555. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
  556. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
  557. package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
  558. package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
  559. package/src/plugins/defaults/memory/v2/activation.ts +30 -163
  560. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
  561. package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
  562. package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
  563. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
  564. package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
  565. package/src/plugins/defaults/memory/v2/injection.ts +36 -26
  566. package/src/plugins/defaults/memory/v2/migration.ts +2 -2
  567. package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
  568. package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
  569. package/src/plugins/defaults/memory/v2/router.ts +38 -15
  570. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
  571. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
  572. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
  573. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
  574. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
  575. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
  576. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
  577. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
  578. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
  579. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
  580. package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
  581. package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
  582. package/src/plugins/defaults/memory/v3/card.ts +25 -9
  583. package/src/plugins/defaults/memory/v3/edge.ts +52 -18
  584. package/src/plugins/defaults/memory/v3/gate.ts +4 -4
  585. package/src/plugins/defaults/memory/v3/injector.ts +10 -3
  586. package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
  587. package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
  588. package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
  589. package/src/plugins/defaults/memory/v3/prune.ts +40 -16
  590. package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
  591. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
  592. package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
  593. package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
  594. package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
  595. package/src/plugins/defaults/memory/v3/types.ts +4 -1
  596. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
  597. package/src/plugins/defaults/memory/validation.ts +1 -1
  598. package/src/plugins/defaults/memory/worker.ts +2 -1
  599. package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
  600. package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
  601. package/src/plugins/types.ts +2 -2
  602. package/src/prompts/sections.ts +4 -16
  603. package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
  604. package/src/providers/anthropic/client.ts +15 -6
  605. package/src/providers/content-block-schema.ts +26 -0
  606. package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
  607. package/src/providers/inference/adapter-factory.ts +6 -0
  608. package/src/providers/inference/connections.ts +30 -14
  609. package/src/providers/model-catalog.ts +77 -0
  610. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
  611. package/src/providers/openai/chat-completions-provider.ts +65 -17
  612. package/src/providers/openai/input-audio.ts +76 -0
  613. package/src/providers/openrouter/client.ts +0 -2
  614. package/src/providers/platform-proxy/constants.ts +4 -0
  615. package/src/providers/poolside/client.ts +42 -0
  616. package/src/providers/registry.ts +40 -8
  617. package/src/providers/retry.ts +2 -0
  618. package/src/providers/types.ts +39 -1
  619. package/src/providers/vercel-ai-gateway/client.ts +0 -2
  620. package/src/runtime/AGENTS.md +7 -5
  621. package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
  622. package/src/runtime/__tests__/question-resolution.test.ts +111 -0
  623. package/src/runtime/access-request-helper.ts +7 -15
  624. package/src/runtime/assistant-event-hub.ts +43 -31
  625. package/src/runtime/assistant-event-publish-options.ts +31 -0
  626. package/src/runtime/assistant-event.ts +19 -30
  627. package/src/runtime/assistant-stream-state.ts +4 -4
  628. package/src/runtime/channel-approvals.ts +0 -25
  629. package/src/runtime/channel-readiness-service.ts +99 -40
  630. package/src/runtime/channel-retry-sweep.ts +38 -15
  631. package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
  632. package/src/runtime/guardian-reply-router.ts +108 -0
  633. package/src/runtime/http-server.ts +8 -0
  634. package/src/runtime/http-types.ts +2 -2
  635. package/src/runtime/process-role.ts +42 -0
  636. package/src/runtime/question-request-guardian-bridge.ts +184 -0
  637. package/src/runtime/question-resolution.ts +153 -0
  638. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
  639. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
  640. package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
  641. package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
  642. package/src/runtime/routes/acp-routes.ts +2 -2
  643. package/src/runtime/routes/bookmark-routes.ts +3 -15
  644. package/src/runtime/routes/canned-message-complete.ts +2 -2
  645. package/src/runtime/routes/consolidation-routes.ts +8 -2
  646. package/src/runtime/routes/conversation-list-routes.ts +3 -19
  647. package/src/runtime/routes/conversation-management-routes.ts +1 -5
  648. package/src/runtime/routes/conversation-query-routes.ts +52 -8
  649. package/src/runtime/routes/conversation-routes.ts +36 -22
  650. package/src/runtime/routes/credential-request-routes.ts +0 -1
  651. package/src/runtime/routes/filing-routes.ts +7 -7
  652. package/src/runtime/routes/global-search-routes.ts +1 -1
  653. package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
  654. package/src/runtime/routes/image-generation-routes.ts +12 -9
  655. package/src/runtime/routes/inbound-message-handler.ts +17 -0
  656. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
  657. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
  658. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
  659. package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
  660. package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
  661. package/src/runtime/routes/index.ts +2 -0
  662. package/src/runtime/routes/lifecycle-routes.ts +199 -0
  663. package/src/runtime/routes/platform-routes.ts +3 -8
  664. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
  665. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
  666. package/src/runtime/routes/question-routes.ts +34 -87
  667. package/src/runtime/routes/secret-routes.ts +11 -1
  668. package/src/runtime/routes/settings-routes.ts +8 -18
  669. package/src/runtime/routes/subagents-routes.ts +35 -8
  670. package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
  671. package/src/runtime/routes/webhook-routes.ts +89 -30
  672. package/src/runtime/routes/workspace-routes.test.ts +7 -4
  673. package/src/runtime/slack-reply-session.test.ts +12 -12
  674. package/src/runtime/slack-reply-session.ts +17 -17
  675. package/src/runtime/sync/sync-publisher.test.ts +7 -5
  676. package/src/runtime/tool-grant-request-helper.ts +4 -0
  677. package/src/schedule/schedule-store.ts +70 -0
  678. package/src/schedule/scheduler.ts +27 -0
  679. package/src/security/AGENTS.md +1 -1
  680. package/src/security/credential-key.ts +17 -0
  681. package/src/security/secret-ingress.ts +14 -105
  682. package/src/security/secret-patterns.ts +8 -139
  683. package/src/security/secret-scanner.ts +8 -3
  684. package/src/security/store-path-override.ts +6 -16
  685. package/src/sequence/store.ts +8 -0
  686. package/src/signals/emit-event.ts +5 -10
  687. package/src/signals/event-stream.ts +20 -10
  688. package/src/subagent/manager.ts +76 -25
  689. package/src/subagent/notify.ts +8 -0
  690. package/src/subagent/types.ts +13 -3
  691. package/src/telegram/__tests__/webhook-health.test.ts +442 -0
  692. package/src/telegram/webhook-health.ts +478 -0
  693. package/src/telemetry/AGENTS.md +6 -0
  694. package/src/telemetry/memory-corpus-size.test.ts +129 -0
  695. package/src/telemetry/memory-corpus-size.ts +184 -0
  696. package/src/telemetry/memory-tier-reporter.test.ts +67 -2
  697. package/src/telemetry/memory-tier-reporter.ts +30 -3
  698. package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
  699. package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
  700. package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
  701. package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
  702. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
  703. package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
  704. package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
  705. package/src/tools/acp/abort.ts +21 -1
  706. package/src/tools/acp/context.ts +5 -5
  707. package/src/tools/acp/spawn.test.ts +15 -5
  708. package/src/tools/acp/spawn.ts +26 -3
  709. package/src/tools/acp/status.ts +20 -1
  710. package/src/tools/acp/steer.test.ts +20 -0
  711. package/src/tools/acp/steer.ts +23 -2
  712. package/src/tools/apps/resolve-app-id.ts +15 -3
  713. package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
  714. package/src/tools/ask-question/ask-question-tool.ts +68 -92
  715. package/src/tools/browser/browser-screencast.ts +6 -6
  716. package/src/tools/calls/call-end.ts +24 -3
  717. package/src/tools/calls/call-start.ts +35 -11
  718. package/src/tools/calls/call-status.ts +20 -1
  719. package/src/tools/conversation-groups/group_create.ts +63 -0
  720. package/src/tools/conversation-groups/group_list.ts +20 -0
  721. package/src/tools/conversation-groups/group_shared.ts +52 -0
  722. package/src/tools/conversation-groups/move_to_group.ts +106 -0
  723. package/src/tools/document/document-comment-tool.test.ts +49 -0
  724. package/src/tools/document/document-comment-tool.ts +45 -6
  725. package/src/tools/document/document-tool.ts +142 -24
  726. package/src/tools/executor.ts +27 -13
  727. package/src/tools/filesystem/edit.ts +62 -60
  728. package/src/tools/filesystem/list.ts +36 -29
  729. package/src/tools/filesystem/read.ts +56 -39
  730. package/src/tools/filesystem/write.ts +44 -38
  731. package/src/tools/followups/followup_create.ts +41 -12
  732. package/src/tools/followups/followup_list.ts +34 -6
  733. package/src/tools/followups/followup_resolve.ts +26 -4
  734. package/src/tools/host-filesystem/edit.ts +50 -60
  735. package/src/tools/host-filesystem/read.ts +45 -39
  736. package/src/tools/host-filesystem/write.ts +31 -36
  737. package/src/tools/host-terminal/host-shell.ts +76 -62
  738. package/src/tools/policy-context.ts +27 -10
  739. package/src/tools/schedule/create.ts +76 -33
  740. package/src/tools/schedule/delete.ts +21 -2
  741. package/src/tools/schedule/list.ts +25 -3
  742. package/src/tools/schedule/update.ts +105 -48
  743. package/src/tools/shared/filesystem/path-policy.ts +246 -40
  744. package/src/tools/shared/zod-tool-schema.ts +117 -0
  745. package/src/tools/subagent/abort.ts +12 -4
  746. package/src/tools/subagent/consult-deadline.ts +9 -3
  747. package/src/tools/subagent/message.ts +21 -5
  748. package/src/tools/subagent/notify-parent.ts +44 -23
  749. package/src/tools/subagent/read.ts +15 -4
  750. package/src/tools/subagent/resolve.ts +26 -4
  751. package/src/tools/subagent/spawn.ts +37 -13
  752. package/src/tools/subagent/status.ts +12 -4
  753. package/src/tools/system/request-permission.ts +35 -26
  754. package/src/tools/terminal/shell.ts +68 -55
  755. package/src/tools/tool-approval-handler.ts +327 -53
  756. package/src/tools/tool-input-schemas.ts +85 -0
  757. package/src/tools/tool-types.ts +7 -0
  758. package/src/tools/types.ts +8 -0
  759. package/src/tools/workflows/manage-workflows.ts +30 -2
  760. package/src/tools/workflows/run-workflow.test.ts +54 -2
  761. package/src/tools/workflows/run-workflow.ts +32 -4
  762. package/src/util/fs-symlinks.ts +30 -0
  763. package/src/util/log-redact.ts +7 -3
  764. package/src/util/platform.ts +15 -0
  765. package/src/vellum-assistant-namespace.d.ts +80 -0
  766. package/src/watcher/watcher-store.ts +8 -0
  767. package/src/workflows/leaf-runner.test.ts +104 -2
  768. package/src/workflows/leaf-runner.ts +31 -6
  769. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
  770. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
  771. package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
  772. package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
  773. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
  774. package/src/workspace/migrations/registry.ts +4 -0
  775. package/tsconfig.plugin-api.json +1 -1
  776. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  777. package/src/__tests__/secret-patterns.test.ts +0 -27
  778. package/src/config/__tests__/proc-to-skills.test.ts +0 -21
  779. package/src/config/memory-tier.test.ts +0 -44
  780. package/src/daemon/message-types/acp.ts +0 -20
  781. package/src/daemon/message-types/apps.ts +0 -11
  782. package/src/daemon/message-types/background-tools.ts +0 -14
  783. package/src/daemon/message-types/bookmarks.ts +0 -13
  784. package/src/daemon/message-types/contacts.ts +0 -13
  785. package/src/daemon/message-types/document-comments.ts +0 -14
  786. package/src/daemon/message-types/documents.ts +0 -13
  787. package/src/daemon/message-types/home.ts +0 -15
  788. package/src/daemon/message-types/host-bash.ts +0 -12
  789. package/src/daemon/message-types/host-cu.ts +0 -10
  790. package/src/daemon/message-types/host-file.ts +0 -12
  791. package/src/daemon/message-types/host-transfer.ts +0 -12
  792. package/src/daemon/message-types/integrations.ts +0 -90
  793. package/src/daemon/message-types/memory.ts +0 -10
  794. package/src/daemon/message-types/schedules.ts +0 -14
  795. package/src/daemon/message-types/settings.ts +0 -17
  796. package/src/daemon/message-types/subagents.ts +0 -63
  797. package/src/daemon/message-types/upgrades.ts +0 -14
  798. package/src/daemon/message-types/workflows.ts +0 -25
  799. package/src/daemon/message-types/workspace.ts +0 -137
  800. package/src/live-voice/ack-phrases.ts +0 -58
  801. package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
  802. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  803. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  804. package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
  805. package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
  806. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  807. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
  808. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
  809. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
@@ -6,7 +6,7 @@
6
6
  "scope": "client",
7
7
  "key": "in-chat-onboarding-tour",
8
8
  "label": "In-Chat Onboarding Tour",
9
- "description": "Multivariate experiment for the eyes-led in-chat onboarding tour. control = straight to chat after research onboarding (current behavior); tour = the extended tour auto-plays on first workspace entry, and the header replay button shows. Desktop-only: phone-width viewports and the native shell get neither the tour nor its telemetry (not even the exposure event), so the funnel measures desktop sessions exclusively. Targeted via LaunchDarkly (planned 70% tour / 30% control).",
9
+ "description": "Multivariate experiment for the eyes-led in-chat onboarding tour. control = straight to chat after research onboarding (current behavior); tour = the extended tour auto-plays on first workspace entry. Desktop-only: phone-width viewports and the native shell get neither the tour nor its telemetry (not even the exposure event), so the funnel measures desktop sessions exclusively. Targeted via LaunchDarkly (70% tour / 30% control).",
10
10
  "defaultEnabled": "control",
11
11
  "values": ["control", "tour"]
12
12
  },
@@ -117,22 +117,6 @@
117
117
  "description": "Show older versions in the version picker, allowing rollback to previous releases",
118
118
  "defaultEnabled": false
119
119
  },
120
- {
121
- "id": "voice-mode",
122
- "scope": "assistant",
123
- "key": "voice-mode",
124
- "label": "Voice Mode",
125
- "description": "Show the live voice conversation button in the composer",
126
- "defaultEnabled": false
127
- },
128
- {
129
- "id": "voice-duplex-handoff",
130
- "scope": "assistant",
131
- "key": "voice-duplex-handoff",
132
- "label": "Voice Duplex Handoff",
133
- "description": "When a user barges in during live voice, keep the interrupted turn running as a background subagent instead of discarding it (true-duplex handoff)",
134
- "defaultEnabled": false
135
- },
136
120
  {
137
121
  "id": "fast-mode",
138
122
  "scope": "assistant",
@@ -293,14 +277,6 @@
293
277
  "description": "Expose the developer-only Memory Router Playground tab in macOS Settings and the /assistant/memory-router-playground web page for dry-running v4 router config overrides against the live page index. Dev-only; default off.",
294
278
  "defaultEnabled": false
295
279
  },
296
- {
297
- "id": "memory-v3-injection-gate",
298
- "scope": "assistant",
299
- "key": "memory-v3-injection-gate",
300
- "label": "Memory v3 injection gate",
301
- "description": "Per-turn injection gate for memory v3: after the BM25F needle + dense cosine finder lanes run, skip the selectPool LLM call (inject nothing) when finder-lane scores fall below the configured thresholds (memory.v3.gate). Default on (flipped remotely July 2026); this registry value is the fallback when no platform snapshot is available.",
302
- "defaultEnabled": true
303
- },
304
280
  {
305
281
  "id": "self-intro-greeting",
306
282
  "scope": "both",
@@ -350,27 +326,27 @@
350
326
  "defaultEnabled": false
351
327
  },
352
328
  {
353
- "id": "credentials-settings",
329
+ "id": "chat-credential-reveal",
354
330
  "scope": "assistant",
355
- "key": "credentials-settings",
356
- "label": "Credentials settings page",
357
- "description": "Show the Credentials page in web settings for listing, adding, and deleting stored credentials.",
331
+ "key": "chat-credential-reveal",
332
+ "label": "Chat Credential Reveal",
333
+ "description": "Persist chat secret redactions as sentinel markers instead of the legacy HTML marker, enriched with the vault identity when the value byte-matches a credential revealed this turn. Also gates the `credentials reveal --for-chat` channel and the live-stream swap that replaces an echoed reveal plaintext with its sentinel before emission. Redaction itself is NOT gated: a route-proven reveal plaintext stays out of persisted rows in both modes. Client chip rendering is gated on daemon version, not on this flag.",
358
334
  "defaultEnabled": false
359
335
  },
360
336
  {
361
- "id": "credential-requests",
337
+ "id": "composer-secret-guard",
362
338
  "scope": "assistant",
363
- "key": "credential-requests",
364
- "label": "One-time credential request links",
365
- "description": "Enable one-time credential-request links: the generate-link action in settings, the public credential entry page, and assistant-initiated links on channels without secure input.",
339
+ "key": "composer-secret-guard",
340
+ "label": "Composer Secret Guard",
341
+ "description": "Detect API keys/secrets typed into the chat composer and offer secure credential storage before send",
366
342
  "defaultEnabled": false
367
343
  },
368
344
  {
369
- "id": "chat-credential-reveal",
370
- "scope": "assistant",
371
- "key": "chat-credential-reveal",
372
- "label": "Chat Credential Reveal",
373
- "description": "Persist chat secret redactions as sentinel markers instead of the legacy HTML marker, enriched with the vault identity when the value byte-matches a credential revealed this turn. Also gates the `credentials reveal --for-chat` channel and the live-stream swap that replaces an echoed reveal plaintext with its sentinel before emission. Redaction itself is NOT gated: a route-proven reveal plaintext stays out of persisted rows in both modes. Client chip rendering is gated on daemon version, not on this flag.",
345
+ "id": "marketing-pricing-takeover",
346
+ "scope": "client",
347
+ "key": "marketing-pricing-takeover",
348
+ "label": "Marketing Pricing Takeover",
349
+ "description": "Gates the marketing pricing takeover page (www.vellum.ai/pricing) and the `/assistant/checkout?package=<slug>` deep link its package CTAs target. One flag covers both halves of the funnel so they can never be enabled independently and strand a CTA. When off, the checkout deep link redirects to the in-app plans takeover.",
374
350
  "defaultEnabled": false
375
351
  }
376
352
  ]
@@ -156,7 +156,13 @@ export function getDeploymentContextDefaults(): Record<string, unknown> {
156
156
  // default (`gemini-embedding-2`).
157
157
  memory: { embeddings: { provider: "gemini" } },
158
158
  services: {
159
- "image-generation": managed,
159
+ // Image-generation is provider-only for the managed axis: `vellum`
160
+ // generates through the platform runtime proxy (the backend derives
161
+ // from the selected model's prefix at request time). Hosted assistants
162
+ // default to it here; fill-only, so an explicit on-disk BYOK provider
163
+ // (gemini/openai) always wins. Filling a `mode` instead would
164
+ // re-manage BYOK configs on every load.
165
+ "image-generation": { provider: "vellum" },
160
166
  "google-oauth": managed,
161
167
  "outlook-oauth": managed,
162
168
  "linear-oauth": managed,
@@ -1,30 +1,35 @@
1
- import { isMemoryV3Live } from "./memory-v3-gate.js";
1
+ import {
2
+ isMemoryEnabled,
3
+ isMemoryV3Live,
4
+ isV2InjectionEngineActive,
5
+ } from "./memory-v3-gate.js";
2
6
  import type { AssistantConfig } from "./schema.js";
3
7
 
4
8
  export type MemoryTier = "off" | "v1" | "v2" | "v3";
5
9
 
6
10
  /**
7
11
  * Derive the coarse memory tier for an assistant, as a single bucket for
8
- * telemetry. Precedence mirrors the runtime memory-source semantics:
12
+ * telemetry. Precedence is defined by the named gate predicates in
13
+ * `memory-v3-gate.ts` — this function is fully derived from them, so the tier
14
+ * buckets and the runtime gates can never disagree:
9
15
  *
10
- * - `"off"` wins over everything: an explicit `memory.enabled === false`
11
- * disables the whole memory system regardless of v2/v3 settings.
16
+ * - `"off"` wins over everything: {@link isMemoryEnabled} is false when an
17
+ * explicit `memory.enabled === false` disables the whole memory system,
18
+ * regardless of v2/v3 settings.
12
19
  * - `"v3"` wins over `"v2"`: when memory-v3 is live it suppresses v2 injection
13
20
  * (see {@link isMemoryV3Live}).
14
- * - `"v2"` when v2 is explicitly enabled and v3 is not live.
21
+ * - `"v2"` when the v2 injection engine performs turn-time selection
22
+ * (see {@link isV2InjectionEngineActive}).
15
23
  * - `"v1"` otherwise (memory on, neither v2 nor v3 selected).
16
- *
17
- * Optional chaining is defensive — a partial config (e.g. a mocked config in
18
- * tests) resolves to the correct bucket rather than throwing.
19
24
  */
20
25
  export function memoryTier(config: AssistantConfig): MemoryTier {
21
- if (config.memory?.enabled === false) {
26
+ if (!isMemoryEnabled(config)) {
22
27
  return "off";
23
28
  }
24
29
  if (isMemoryV3Live(config)) {
25
30
  return "v3";
26
31
  }
27
- if (config.memory?.v2?.enabled === true) {
32
+ if (isV2InjectionEngineActive(config)) {
28
33
  return "v2";
29
34
  }
30
35
  return "v1";
@@ -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" },