@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
@@ -1,18 +1,29 @@
1
1
  // ---------------------------------------------------------------------------
2
2
  // Memory Graph — Conversation-level memory integration
3
3
  //
4
- // Replaces the old `prepareMemoryContext` from conversation-memory.ts.
5
- // Manages the InContextTracker lifecycle and dispatches to the correct
6
- // retrieval mode based on conversation state.
4
+ // `graph/` is the all-tier legacy-graph store + tier dispatcher: `store.ts`,
5
+ // `capability-seed.ts`, and `tool-handlers.ts` are written on every tier
6
+ // (capability nodes feed `list_memory`), while the read ENGINE lives in
7
+ // `../v1/graph/`. This class manages the InContextTracker lifecycle,
8
+ // dispatches retrieval to the active tier's engine, and owns compaction
9
+ // eviction of v2/v3 per-conversation state.
7
10
  // ---------------------------------------------------------------------------
8
11
 
9
- import type { ContentBlock, ImageContent, Message } from "@vellumai/plugin-api";
12
+ import type {
13
+ AssistantEvent,
14
+ ContentBlock,
15
+ ImageContent,
16
+ Message,
17
+ } from "@vellumai/plugin-api";
10
18
  import { and, desc, eq, inArray, ne, notInArray } from "drizzle-orm";
11
19
  import { z } from "zod";
12
20
 
21
+ import {
22
+ isMemoryEnabled,
23
+ isV2InjectionEngineActive,
24
+ } from "../../../../config/memory-v3-gate.js";
13
25
  import type { AssistantConfig } from "../../../../config/types.js";
14
26
  import { estimateTextTokens } from "../../../../context/token-estimator.js";
15
- import type { ServerMessage } from "../../../../daemon/message-protocol.js";
16
27
  import { getDb } from "../../../../persistence/db-connection.js";
17
28
  import { embedWithRetry } from "../../../../persistence/embeddings/embed.js";
18
29
  import { generateSparseEmbedding } from "../../../../persistence/embeddings/embedding-backend.js";
@@ -22,6 +33,19 @@ import { memorySummaries } from "../../../../persistence/schema/index.js";
22
33
  import { getLogger } from "../logging.js";
23
34
  import { wrapMemoryBlock } from "../memory-marker.js";
24
35
  import { getWorkspaceDir } from "../paths.js";
36
+ // V1 — delete with v1. The v1 read engine: legacy-graph retrieval and block
37
+ // assembly, feeding the v1 fallback arms of `loadContextMemory` /
38
+ // `retrieveForTurn` below.
39
+ import {
40
+ assembleContextBlock,
41
+ assembleInjectionBlock,
42
+ MAX_CONTEXT_LOAD_IMAGES,
43
+ MAX_PER_TURN_IMAGES,
44
+ type ResolvedImage,
45
+ resolveInjectionImages,
46
+ } from "../v1/graph/injection.js";
47
+ import { loadContextMemory, retrieveForTurn } from "../v1/graph/retriever.js";
48
+ // v2 injection engine — turn-time selection over the concept-page substrate
25
49
  import {
26
50
  clearEverInjected as clearV2EverInjected,
27
51
  hydrate as hydrateV2State,
@@ -33,22 +57,16 @@ import {
33
57
  } from "../v2/injection.js";
34
58
  import { loadNowText } from "../v2/now-text.js";
35
59
  import type { RouterTurnPair } from "../v2/router.js";
60
+ // v3 per-conversation state — evicted here on compaction
36
61
  import { clearConversation as clearV3EverInjected } from "../v3/ever-injected-store.js";
37
62
  import {
38
63
  loadGraphMemoryState,
39
64
  saveGraphMemoryState,
40
65
  } from "./graph-memory-state-store.js";
41
66
  import {
42
- assembleContextBlock,
43
- assembleInjectionBlock,
44
67
  InContextTracker,
45
68
  type InContextTrackerSnapshot,
46
- MAX_CONTEXT_LOAD_IMAGES,
47
- MAX_PER_TURN_IMAGES,
48
- type ResolvedImage,
49
- resolveInjectionImages,
50
- } from "./injection.js";
51
- import { loadContextMemory, retrieveForTurn } from "./retriever.js";
69
+ } from "./in-context-tracker.js";
52
70
  import type { RetrievalMetrics } from "./types.js";
53
71
 
54
72
  const log = getLogger("graph-conversation-memory");
@@ -80,7 +98,9 @@ const liveByConversation = new Map<string, ConversationGraphMemory>();
80
98
  export function getLiveGraphMemory(
81
99
  conversationId: string | undefined,
82
100
  ): ConversationGraphMemory | undefined {
83
- if (!conversationId) return undefined;
101
+ if (!conversationId) {
102
+ return undefined;
103
+ }
84
104
  return liveByConversation.get(conversationId);
85
105
  }
86
106
 
@@ -132,7 +152,9 @@ export class ConversationGraphMemory {
132
152
  * Called during conversation disposal.
133
153
  */
134
154
  persistState(): void {
135
- if (!this.initialized) return;
155
+ if (!this.initialized) {
156
+ return;
157
+ }
136
158
  try {
137
159
  const snapshot: InContextTrackerSnapshot & {
138
160
  initialized: boolean;
@@ -156,10 +178,14 @@ export class ConversationGraphMemory {
156
178
  * On failure or missing row, silently falls back to full context-load.
157
179
  */
158
180
  restoreState(): void {
159
- if (this.stateRestored) return;
181
+ if (this.stateRestored) {
182
+ return;
183
+ }
160
184
  try {
161
185
  const json = loadGraphMemoryState(this.conversationId);
162
- if (!json) return;
186
+ if (!json) {
187
+ return;
188
+ }
163
189
 
164
190
  const snapshot = JSON.parse(json) as InContextTrackerSnapshot & {
165
191
  initialized: boolean;
@@ -360,7 +386,9 @@ export class ConversationGraphMemory {
360
386
  * not the original user message.
361
387
  */
362
388
  retrackCachedNodes(): void {
363
- if (this.lastInjectedNodeIds.length === 0) return;
389
+ if (this.lastInjectedNodeIds.length === 0) {
390
+ return;
391
+ }
364
392
  this.tracker.add(this.lastInjectedNodeIds);
365
393
  }
366
394
 
@@ -419,7 +447,7 @@ export class ConversationGraphMemory {
419
447
  messages: Message[],
420
448
  config: AssistantConfig,
421
449
  abortSignal: AbortSignal,
422
- onEvent: (msg: ServerMessage) => void,
450
+ onEvent: (msg: AssistantEvent) => void,
423
451
  ): Promise<{
424
452
  runMessages: Message[];
425
453
  injectedTokens: number;
@@ -467,7 +495,7 @@ export class ConversationGraphMemory {
467
495
  metrics: null as RetrievalMetrics | null,
468
496
  };
469
497
 
470
- if (config.memory.enabled === false) {
498
+ if (!isMemoryEnabled(config)) {
471
499
  // Clear any cached injection so a later overflow-reduction
472
500
  // re-injection via `reinjectCachedMemory()` cannot reintroduce a
473
501
  // stale <memory> block after the user disables memory.
@@ -480,12 +508,15 @@ export class ConversationGraphMemory {
480
508
  // Gate: skip for empty/tool-result-only messages — unless we need to
481
509
  // reload after compaction (needsReload) or haven't initialized yet.
482
510
  const lastMessage = messages[messages.length - 1];
483
- if (!lastMessage || lastMessage.role !== "user") return noopResult;
511
+ if (!lastMessage || lastMessage.role !== "user") {
512
+ return noopResult;
513
+ }
484
514
  const hasUserContent = lastMessage.content.some(
485
515
  (block) => block.type === "text" && block.text.trim().length > 0,
486
516
  );
487
- if (!hasUserContent && this.initialized && !this.needsReload)
517
+ if (!hasUserContent && this.initialized && !this.needsReload) {
488
518
  return noopResult;
519
+ }
489
520
 
490
521
  try {
491
522
  // Decide which retrieval mode to use
@@ -530,7 +561,7 @@ export class ConversationGraphMemory {
530
561
  recentSummaries: string[],
531
562
  userQuery: string | undefined,
532
563
  signal: AbortSignal,
533
- onEvent: (msg: ServerMessage) => void,
564
+ onEvent: (msg: AssistantEvent) => void,
534
565
  ) {
535
566
  // Use the raw user text (no >10-char filter) so even short greetings
536
567
  // ("hi") get a fresh top-K activation dump on the first user message.
@@ -581,7 +612,9 @@ export class ConversationGraphMemory {
581
612
  };
582
613
  }
583
614
 
584
- // v1 fallback — only reached when the v2 flag or workspace config is off.
615
+ // v1 fallback — only reached when the v2 engine is not the live tier (v2
616
+ // disabled, memory off, or v3 live; under the concept-page substrate the
617
+ // retriever short-circuits to zero nodes).
585
618
  const result = await loadContextMemory({
586
619
  recentSummaries,
587
620
  userQuery,
@@ -650,7 +683,7 @@ export class ConversationGraphMemory {
650
683
  type: "memory_status",
651
684
  enabled: true,
652
685
  degraded: false,
653
- } as ServerMessage);
686
+ } as AssistantEvent);
654
687
 
655
688
  this.lastInjectedBlock = contextBlock;
656
689
  this.lastInjectedNodeIds = [
@@ -700,11 +733,13 @@ export class ConversationGraphMemory {
700
733
  } else if (msg.role === "assistant" && !assistantLast) {
701
734
  assistantLast = text;
702
735
  }
703
- if (userLastBlocks.length > 0 && assistantLast) break;
736
+ if (userLastBlocks.length > 0 && assistantLast) {
737
+ break;
738
+ }
704
739
  }
705
740
 
706
- // v2 path — skip v1 retrieval entirely when v2 is enabled. See the
707
- // matching comment in `runContextLoad` for rationale.
741
+ // v2 path — skip v1 retrieval entirely when the v2 engine is the live
742
+ // tier. See the matching comment in `runContextLoad` for rationale.
708
743
  const startedAt = Date.now();
709
744
  const v2 = await this.maybeRouteV2Injection(
710
745
  messages,
@@ -747,7 +782,9 @@ export class ConversationGraphMemory {
747
782
  };
748
783
  }
749
784
 
750
- // v1 path (only reached when the v2 flag or workspace config is off).
785
+ // v1 path (only reached when the v2 engine is not the live tier — v2
786
+ // disabled, memory off, or v3 live; under the concept-page substrate the
787
+ // retriever short-circuits to zero nodes).
751
788
  const result = await retrieveForTurn({
752
789
  assistantLastMessage: assistantLast,
753
790
  userLastMessage: userLast,
@@ -851,11 +888,16 @@ export class ConversationGraphMemory {
851
888
  }
852
889
 
853
890
  /**
854
- * Run the v2 activation pipeline when the workspace config
855
- * (`memory.v2.enabled`) is on.
891
+ * Run the v2 activation pipeline when the v2 injection engine is the live
892
+ * tier ({@link isV2InjectionEngineActive}) — memory on, `memory.v2.enabled`
893
+ * set, and v3 not live. Every `prepareMemory` entry point shares this gate,
894
+ * including callers without their own v3 guard (e.g. the persona
895
+ * workflow-leaf runner), so a v3-live assistant never runs the v2
896
+ * router/activation pipeline or writes its activation/injection logs.
856
897
  *
857
898
  * The two outcomes the caller distinguishes via `routed`:
858
- * - `routed: false` — v2 disabled; caller falls through to the legacy v1
899
+ * - `routed: false` — v2 engine not active (disabled, memory off, or v3
900
+ * live); caller falls through to the legacy v1
859
901
  * retrieval path.
860
902
  * - `routed: true` — v2 ran. `runMessages` is either the v2-prepended
861
903
  * message list (block was non-null) or the input
@@ -880,7 +922,7 @@ export class ConversationGraphMemory {
880
922
  runMessages: Message[];
881
923
  injectedBlockText: string | null;
882
924
  }> {
883
- if (!config.memory.v2.enabled) {
925
+ if (!isV2InjectionEngineActive(config)) {
884
926
  return { routed: false, runMessages: messages, injectedBlockText: null };
885
927
  }
886
928
 
@@ -991,12 +1033,18 @@ export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
991
1033
  * `reinjectCachedMemory` is idempotent — no duplicate images after compaction.
992
1034
  */
993
1035
  export function stripExistingMemoryInjections(messages: Message[]): Message[] {
994
- if (messages.length === 0) return messages;
1036
+ if (messages.length === 0) {
1037
+ return messages;
1038
+ }
995
1039
  const last = messages[messages.length - 1];
996
- if (!last || last.role !== "user") return messages;
1040
+ if (!last || last.role !== "user") {
1041
+ return messages;
1042
+ }
997
1043
 
998
1044
  const stripped = stripMemoryPrefixFromUserMessage(last);
999
- if (stripped === last) return messages;
1045
+ if (stripped === last) {
1046
+ return messages;
1047
+ }
1000
1048
 
1001
1049
  return [...messages.slice(0, -1), stripped];
1002
1050
  }
@@ -1011,9 +1059,13 @@ export function stripExistingMemoryInjections(messages: Message[]): Message[] {
1011
1059
  * assembly strips only the TAIL's fresh v2 prefix when v3 supersedes it.
1012
1060
  */
1013
1061
  function stripMemoryPrefixFromUserMessage(message: Message): Message {
1014
- if (message.role !== "user") return message;
1062
+ if (message.role !== "user") {
1063
+ return message;
1064
+ }
1015
1065
  const firstNonMemory = countMemoryPrefixBlocks(message.content);
1016
- if (firstNonMemory === 0) return message;
1066
+ if (firstNonMemory === 0) {
1067
+ return message;
1068
+ }
1017
1069
  return { ...message, content: message.content.slice(firstNonMemory) };
1018
1070
  }
1019
1071
 
@@ -1024,21 +1076,31 @@ function stripMemoryPrefixFromUserMessage(message: Message): Message {
1024
1076
  * rendering) that otherwise discard the prepended content.
1025
1077
  */
1026
1078
  export function extractMemoryPrefixBlocks(messages: Message[]): ContentBlock[] {
1027
- if (messages.length === 0) return [];
1079
+ if (messages.length === 0) {
1080
+ return [];
1081
+ }
1028
1082
  const last = messages[messages.length - 1];
1029
- if (!last || last.role !== "user") return [];
1083
+ if (!last || last.role !== "user") {
1084
+ return [];
1085
+ }
1030
1086
  const count = countMemoryPrefixBlocks(last.content);
1031
1087
  return count === 0 ? [] : last.content.slice(0, count);
1032
1088
  }
1033
1089
 
1034
1090
  function injectTextBlock(messages: Message[], text: string): Message[] {
1035
- if (text.trim().length === 0) return messages;
1036
- if (messages.length === 0) return messages;
1091
+ if (text.trim().length === 0) {
1092
+ return messages;
1093
+ }
1094
+ if (messages.length === 0) {
1095
+ return messages;
1096
+ }
1037
1097
  // Strip existing memory blocks from the last user message first to prevent
1038
1098
  // duplicates when the message was loaded from DB with a persisted block.
1039
1099
  const cleaned = stripExistingMemoryInjections(messages);
1040
1100
  const userTail = cleaned[cleaned.length - 1];
1041
- if (!userTail || userTail.role !== "user") return messages;
1101
+ if (!userTail || userTail.role !== "user") {
1102
+ return messages;
1103
+ }
1042
1104
  return [
1043
1105
  ...cleaned.slice(0, -1),
1044
1106
  {
@@ -1059,13 +1121,19 @@ function injectMemoryBlock(
1059
1121
  text: string,
1060
1122
  images: Map<string, ResolvedImage>,
1061
1123
  ): Message[] {
1062
- if (text.trim().length === 0 && images.size === 0) return messages;
1063
- if (messages.length === 0) return messages;
1124
+ if (text.trim().length === 0 && images.size === 0) {
1125
+ return messages;
1126
+ }
1127
+ if (messages.length === 0) {
1128
+ return messages;
1129
+ }
1064
1130
  // Strip existing memory blocks from the last user message first to prevent
1065
1131
  // duplicates when the message was loaded from DB with a persisted block.
1066
1132
  const cleaned = stripExistingMemoryInjections(messages);
1067
1133
  const userTail = cleaned[cleaned.length - 1];
1068
- if (!userTail || userTail.role !== "user") return messages;
1134
+ if (!userTail || userTail.role !== "user") {
1135
+ return messages;
1136
+ }
1069
1137
 
1070
1138
  const blocks: ContentBlock[] = [];
1071
1139
 
@@ -1106,7 +1174,9 @@ function injectMemoryBlock(
1106
1174
  */
1107
1175
  function extractUserText(message: Message): string | null {
1108
1176
  const joined = readRawUserText(message);
1109
- if (!joined) return null;
1177
+ if (!joined) {
1178
+ return null;
1179
+ }
1110
1180
  return joined.length > 10 ? joined : null;
1111
1181
  }
1112
1182
 
@@ -1117,12 +1187,16 @@ function extractUserText(message: Message): string | null {
1117
1187
  * v1 needs would unnecessarily starve v2 on short greetings.
1118
1188
  */
1119
1189
  function readRawUserText(message: Message | undefined): string | null {
1120
- if (!message) return null;
1190
+ if (!message) {
1191
+ return null;
1192
+ }
1121
1193
  const texts = message.content
1122
1194
  .filter((b): b is Extract<typeof b, { type: "text" }> => b.type === "text")
1123
1195
  .map((b) => b.text.trim())
1124
1196
  .filter((t) => t.length > 0);
1125
- if (texts.length === 0) return null;
1197
+ if (texts.length === 0) {
1198
+ return null;
1199
+ }
1126
1200
  return texts.join(" ");
1127
1201
  }
1128
1202
 
@@ -1,5 +1,10 @@
1
1
  // ---------------------------------------------------------------------------
2
- // Memory Graph — Qdrant vector search for graph nodes
2
+ // Memory Graph — node/trigger embedding plumbing (all tiers)
3
+ //
4
+ // Capability seeding writes graph nodes on every tier, so the
5
+ // `embed_graph_node` and `graph_trigger_embed` jobs handled here run under
6
+ // the substrate too. The v1 hybrid node SEARCH path lives in
7
+ // `../v1/graph/graph-search.ts`.
3
8
  // ---------------------------------------------------------------------------
4
9
 
5
10
  import {
@@ -7,17 +12,8 @@ import {
7
12
  selectedBackendSupportsMultimodal,
8
13
  } from "@vellumai/plugin-api";
9
14
 
10
- import { getConfig } from "../../../../config/loader.js";
11
- import { usesConceptPageMemory } from "../../../../config/memory-v3-gate.js";
12
15
  import type { AssistantConfig } from "../../../../config/types.js";
13
16
  import type { EmbeddingInput } from "../../../../persistence/embeddings/embedding-types.js";
14
- import { isQdrantBreakerOpen } from "../../../../persistence/embeddings/qdrant-circuit-breaker.js";
15
- import { withQdrantBreaker } from "../../../../persistence/embeddings/qdrant-circuit-breaker.js";
16
- import {
17
- getQdrantClient,
18
- type QdrantSearchResult,
19
- type QdrantSparseVector,
20
- } from "../../../../persistence/embeddings/qdrant-client.js";
21
17
  import { asString } from "../../../../persistence/job-utils.js";
22
18
  import {
23
19
  enqueueMemoryJob,
@@ -31,114 +27,6 @@ import type { MemoryNode } from "./types.js";
31
27
 
32
28
  const log = getLogger("graph-search");
33
29
 
34
- // ---------------------------------------------------------------------------
35
- // Search
36
- // ---------------------------------------------------------------------------
37
-
38
- export interface GraphSearchResult {
39
- nodeId: string;
40
- score: number;
41
- text: string;
42
- }
43
-
44
- /**
45
- * Semantic search across graph nodes in Qdrant. Returns scored node IDs
46
- * that the caller can hydrate from the graph store.
47
- *
48
- * Filters to `target_type: "graph_node"`.
49
- */
50
- export async function searchGraphNodes(
51
- queryVector: number[],
52
- limit: number,
53
- sparseVector?: QdrantSparseVector,
54
- dateRange?: { afterMs?: number; beforeMs?: number },
55
- ): Promise<GraphSearchResult[]> {
56
- // Concept-page memory owns the read path when active. The v1 `memory`
57
- // collection is in active retirement and a corrupted sparse segment can
58
- // OOM-crash the shared Qdrant process — short-circuiting here keeps v1
59
- // background work and stale callers from taking it down.
60
- if (usesConceptPageMemory(getConfig().memory)) {
61
- return [];
62
- }
63
-
64
- if (isQdrantBreakerOpen()) {
65
- log.warn("Qdrant circuit breaker open, skipping graph search");
66
- return [];
67
- }
68
-
69
- const client = getQdrantClient();
70
-
71
- const mustNot: Record<string, unknown>[] = [
72
- { key: "_meta", match: { value: true } },
73
- ];
74
-
75
- // Use hybrid search (dense + sparse with RRF fusion) when a non-empty
76
- // sparse vector is available; otherwise fall back to dense-only search.
77
- if (sparseVector && sparseVector.indices.length > 0) {
78
- const must: Record<string, unknown>[] = [
79
- { key: "target_type", match: { value: "graph_node" } },
80
- ];
81
- if (dateRange?.afterMs != null) {
82
- must.push({ key: "created_at", range: { gte: dateRange.afterMs } });
83
- }
84
- if (dateRange?.beforeMs != null) {
85
- must.push({ key: "created_at", range: { lte: dateRange.beforeMs } });
86
- }
87
- const filter = { must, must_not: mustNot };
88
-
89
- // RRF fuses per-modality top-N. A small prefetch (e.g. limit*3) silently
90
- // truncates good matches when the query is wordy or low-similarity, so
91
- // give RRF a meaningful candidate window with a generous floor.
92
- const prefetchLimit = Math.max(limit * 10, 200);
93
-
94
- const results: QdrantSearchResult[] = await withQdrantBreaker(() =>
95
- client.hybridSearch({
96
- denseVector: queryVector,
97
- sparseVector,
98
- filter,
99
- limit,
100
- prefetchLimit,
101
- }),
102
- );
103
-
104
- return results.map((r) => ({
105
- nodeId: r.payload.target_id,
106
- score: r.score,
107
- text: r.payload.text,
108
- }));
109
- }
110
-
111
- // Dense-only fallback
112
- const denseMusts: Record<string, unknown>[] = [
113
- {
114
- key: "target_type",
115
- match: { value: "graph_node" },
116
- },
117
- ];
118
-
119
- if (dateRange?.afterMs != null) {
120
- denseMusts.push({ key: "created_at", range: { gte: dateRange.afterMs } });
121
- }
122
- if (dateRange?.beforeMs != null) {
123
- denseMusts.push({ key: "created_at", range: { lte: dateRange.beforeMs } });
124
- }
125
-
126
- const filter: Record<string, unknown> = {
127
- must: denseMusts,
128
- must_not: mustNot,
129
- };
130
-
131
- const results: QdrantSearchResult[] = await withQdrantBreaker(async () => {
132
- return client.search(queryVector, limit, filter);
133
- });
134
-
135
- return results.map((r) => ({
136
- nodeId: r.payload.target_id,
137
- score: r.score,
138
- text: r.payload.text,
139
- }));
140
- }
141
-
142
30
  // ---------------------------------------------------------------------------
143
31
  // Embedding job
144
32
  // ---------------------------------------------------------------------------
@@ -0,0 +1,173 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { InContextTracker } from "./in-context-tracker.js";
4
+ import type { MemoryNode, ScoredNode } from "./types.js";
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // Helpers
8
+ // ---------------------------------------------------------------------------
9
+
10
+ const DAY_MS = 1000 * 60 * 60 * 24;
11
+
12
+ function makeNode(overrides: Partial<MemoryNode> = {}): MemoryNode {
13
+ return {
14
+ id: "node-1",
15
+ content: "Test memory content.",
16
+ type: "episodic",
17
+ created: Date.now() - 5 * DAY_MS,
18
+ lastAccessed: Date.now(),
19
+ lastConsolidated: Date.now(),
20
+ eventDate: null,
21
+ emotionalCharge: {
22
+ valence: 0,
23
+ intensity: 0,
24
+ decayCurve: "linear",
25
+ decayRate: 0.05,
26
+ originalIntensity: 0,
27
+ },
28
+ fidelity: "vivid",
29
+ confidence: 0.8,
30
+ significance: 0.5,
31
+ stability: 14,
32
+ reinforcementCount: 0,
33
+ lastReinforced: Date.now(),
34
+ sourceConversations: ["conv-1"],
35
+ sourceType: "direct",
36
+ narrativeRole: null,
37
+ partOfStory: null,
38
+ imageRefs: null,
39
+ ...overrides,
40
+ };
41
+ }
42
+
43
+ function makeScored(nodeOverrides: Partial<MemoryNode> = {}): ScoredNode {
44
+ return {
45
+ node: makeNode(nodeOverrides),
46
+ score: 0.5,
47
+ scoreBreakdown: {
48
+ semanticSimilarity: 0.5,
49
+ effectiveSignificance: 0.5,
50
+ emotionalIntensity: 0,
51
+ temporalBoost: 0,
52
+ recencyBoost: 0.5,
53
+ triggerBoost: 0,
54
+ activationBoost: 0,
55
+ },
56
+ };
57
+ }
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // InContextTracker
61
+ // ---------------------------------------------------------------------------
62
+
63
+ describe("InContextTracker", () => {
64
+ test("tracks added node IDs", () => {
65
+ const tracker = new InContextTracker();
66
+ tracker.add(["a", "b"]);
67
+ expect(tracker.isInContext("a")).toBe(true);
68
+ expect(tracker.isInContext("b")).toBe(true);
69
+ expect(tracker.isInContext("c")).toBe(false);
70
+ });
71
+
72
+ test("filters out nodes already in context", () => {
73
+ const tracker = new InContextTracker();
74
+ tracker.add(["a"]);
75
+
76
+ const candidates: ScoredNode[] = [
77
+ makeScored({ id: "a" }),
78
+ makeScored({ id: "b" }),
79
+ makeScored({ id: "c" }),
80
+ ];
81
+ const filtered = tracker.filterNew(candidates);
82
+ expect(filtered).toHaveLength(2);
83
+ expect(filtered.map((c) => c.node.id)).toEqual(["b", "c"]);
84
+ });
85
+
86
+ test("advances turn counter", () => {
87
+ const tracker = new InContextTracker();
88
+ expect(tracker.getTurn()).toBe(0);
89
+ tracker.advanceTurn();
90
+ expect(tracker.getTurn()).toBe(1);
91
+ tracker.advanceTurn();
92
+ expect(tracker.getTurn()).toBe(2);
93
+ });
94
+
95
+ test("records injection log with turn numbers", () => {
96
+ const tracker = new InContextTracker();
97
+ tracker.add(["a"]);
98
+ tracker.advanceTurn();
99
+ tracker.add(["b"]);
100
+
101
+ const log = tracker.getLog();
102
+ expect(log).toHaveLength(2);
103
+ expect(log[0]).toEqual({ nodeId: "a", turn: 0 });
104
+ expect(log[1]).toEqual({ nodeId: "b", turn: 1 });
105
+ });
106
+
107
+ test("returns all active node IDs", () => {
108
+ const tracker = new InContextTracker();
109
+ tracker.add(["a", "b"]);
110
+ tracker.advanceTurn();
111
+ tracker.add(["c"]);
112
+
113
+ const active = tracker.getActiveNodeIds();
114
+ expect(active.sort()).toEqual(["a", "b", "c"]);
115
+ });
116
+
117
+ test("evicts compacted turns", () => {
118
+ const tracker = new InContextTracker();
119
+ tracker.add(["a"]);
120
+ tracker.advanceTurn();
121
+ tracker.add(["b"]);
122
+ tracker.advanceTurn();
123
+ tracker.add(["c"]);
124
+
125
+ // Evict turns 0 and 1
126
+ tracker.evictCompactedTurns(1);
127
+
128
+ expect(tracker.isInContext("a")).toBe(false);
129
+ expect(tracker.isInContext("b")).toBe(false);
130
+ expect(tracker.isInContext("c")).toBe(true);
131
+ });
132
+
133
+ test("keeps nodes that appear in both compacted and non-compacted turns", () => {
134
+ const tracker = new InContextTracker();
135
+ tracker.add(["a"]);
136
+ tracker.advanceTurn();
137
+ tracker.add(["a"]); // same node re-injected in turn 1
138
+
139
+ // Evict turn 0 only
140
+ tracker.evictCompactedTurns(0);
141
+
142
+ // "a" should still be in context because it was also injected in turn 1
143
+ expect(tracker.isInContext("a")).toBe(true);
144
+ });
145
+
146
+ test("eviction cleans up log entries", () => {
147
+ const tracker = new InContextTracker();
148
+ tracker.add(["a"]);
149
+ tracker.advanceTurn();
150
+ tracker.add(["b"]);
151
+
152
+ tracker.evictCompactedTurns(0);
153
+
154
+ const log = tracker.getLog();
155
+ expect(log).toHaveLength(1);
156
+ expect(log[0].nodeId).toBe("b");
157
+ });
158
+
159
+ test("evicting with upToTurn=0 only evicts turn 0", () => {
160
+ const tracker = new InContextTracker();
161
+ tracker.add(["a"]);
162
+ tracker.advanceTurn();
163
+ tracker.add(["b"]);
164
+ tracker.advanceTurn();
165
+ tracker.add(["c"]);
166
+
167
+ tracker.evictCompactedTurns(0);
168
+
169
+ expect(tracker.isInContext("a")).toBe(false);
170
+ expect(tracker.isInContext("b")).toBe(true);
171
+ expect(tracker.isInContext("c")).toBe(true);
172
+ });
173
+ });