@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
@@ -22,6 +22,7 @@ describe("MemoryV3ConfigSchema", () => {
22
22
  needleK: 100,
23
23
  denseK: 100,
24
24
  replyQueryK: 12,
25
+ spanQueryK: 0,
25
26
  selectorEnabled: true,
26
27
  selectorPromptPath: null,
27
28
  edge: { hubDegree: 30, seedCount: 18, perSeed: 6, cap: 45 },
@@ -79,7 +79,31 @@ export const LiveVoiceProgressConfigSchema = z
79
79
  )
80
80
  .default(5_000)
81
81
  .describe(
82
- "Narrate after this much silence (ms) with the turn still running",
82
+ "How often (ms) a running turn's silence is checked, and so the soonest new tool activity is narrated",
83
+ ),
84
+ maxSilenceMs: z
85
+ .number({
86
+ error: "liveVoice.frontModel.progress.maxSilenceMs must be a number",
87
+ })
88
+ .int("liveVoice.frontModel.progress.maxSilenceMs must be an integer")
89
+ .positive(
90
+ "liveVoice.frontModel.progress.maxSilenceMs must be a positive integer",
91
+ )
92
+ .default(35_000)
93
+ .describe(
94
+ "Heartbeat ceiling (ms): narrate after this much unbroken silence even when nothing new has happened. Evaluated on the idle tick, so its resolution is idleIntervalMs and it must be at least that long",
95
+ ),
96
+ longOpMs: z
97
+ .number({
98
+ error: "liveVoice.frontModel.progress.longOpMs must be a number",
99
+ })
100
+ .int("liveVoice.frontModel.progress.longOpMs must be an integer")
101
+ .positive(
102
+ "liveVoice.frontModel.progress.longOpMs must be a positive integer",
103
+ )
104
+ .default(15_000)
105
+ .describe(
106
+ "A tool operation that ran at least this long (ms) narrates the moment it completes, without waiting for opsThreshold",
83
107
  ),
84
108
  minGapMs: z
85
109
  .number({
@@ -109,6 +133,14 @@ export const LiveVoiceProgressConfigSchema = z
109
133
  "Budget (ms) for LLM-generated progress text — not latency-critical: it speaks into dead air",
110
134
  ),
111
135
  })
136
+ // The heartbeat is checked when the idle tick finds the turn silent, so a
137
+ // ceiling shorter than the tick interval would be missed by up to a full
138
+ // interval — a promise the cadence cannot keep. Rejecting the combination
139
+ // beats silently overshooting it.
140
+ .refine((progress) => progress.maxSilenceMs >= progress.idleIntervalMs, {
141
+ error:
142
+ "liveVoice.frontModel.progress.maxSilenceMs must be at least idleIntervalMs — the heartbeat is evaluated on the idle tick",
143
+ })
112
144
  .describe(
113
145
  "Progress-narration tuning for live voice sessions (spoken updates during long-running turns)",
114
146
  );
@@ -172,12 +204,6 @@ export const LiveVoiceFrontModelConfigSchema = z
172
204
  )
173
205
  .default(600)
174
206
  .describe("Budget (ms) for LLM-generated ack text"),
175
- llmAckText: z
176
- .boolean({ error: "liveVoice.frontModel.llmAckText must be a boolean" })
177
- .default(false)
178
- .describe(
179
- "Use the front model to phrase spoken acks; static phrases otherwise",
180
- ),
181
207
  progress: LiveVoiceProgressConfigSchema.default(
182
208
  LiveVoiceProgressConfigSchema.parse({}),
183
209
  ),
@@ -39,6 +39,7 @@ export const LLMProvider = z
39
39
  "together",
40
40
  "litellm",
41
41
  "baseten",
42
+ "poolside",
42
43
  // Routing identities rather than adapters: "vellum" = the platform-managed
43
44
  // route (upstream derived from the model at dispatch), "chatgpt" = the
44
45
  // subscription route to OpenAI. Neither has a PROVIDER_CATALOG entry;
@@ -52,6 +52,19 @@ export const MemoryRetrospectiveConfigSchema = z
52
52
  "Cadence of the scheduled retrospective sweep, the timer-driven backstop that re-scans conversations for unprocessed messages the event-driven triggers missed (e.g. a turn that ended in a crash or IPC drop before the post-turn hooks ran). A conversation is only swept when its last retrospective attempt is at least this old, so the sweep never competes with the responsive interval/message_count triggers on active conversations.",
53
53
  ),
54
54
 
55
+ sweepLookbackMs: z
56
+ .number({
57
+ error: "memory.retrospective.sweepLookbackMs must be a number",
58
+ })
59
+ .int("memory.retrospective.sweepLookbackMs must be an integer")
60
+ .positive(
61
+ "memory.retrospective.sweepLookbackMs must be a positive integer",
62
+ )
63
+ .default(7 * 24 * 60 * 60 * 1000)
64
+ .describe(
65
+ "How far back the scheduled retrospective sweep looks for stalled work. The sweep backstops turns that ended abnormally (crash / IPC drop), and such turns are by definition recent — so only conversations whose last message falls inside this window are scanned, and the retrospective job re-applies the same window at execution time so a stale queued backlog is skipped instead of run. Conversations dormant beyond the window are outside the sweep's scope entirely: their unprocessed tails are ordinary end-of-conversation remainders, not stalled work. Values below twice memory.retrospective.sweepIntervalMs are clamped up to that floor — scheduler and queue delay stretch the gap between consecutive scans past the nominal cadence, so a window at or under one interval would leave a permanent blind span between passes.",
66
+ ),
67
+
55
68
  keepSupersededRuns: z
56
69
  .boolean({
57
70
  error: "memory.retrospective.keepSupersededRuns must be a boolean",
@@ -0,0 +1,183 @@
1
+ import { z } from "zod";
2
+
3
+ import { WEIGHT_SUM_TOLERANCE } from "./memory-v2.js";
4
+
5
+ /**
6
+ * Memory substrate (shared concept-page infrastructure) tuning.
7
+ *
8
+ * Every key is optional with no default: an unset key resolves to its
9
+ * historical `memory.v2` counterpart via `resolveSubstrateTuning` (the
10
+ * substrate's single config choke point), so the v2 schema keeps supplying
11
+ * the effective defaults. `spread_k`, `spread_hops`, and
12
+ * `ann_candidate_limit` map onto `memory.v2.k`, `memory.v2.hops`, and
13
+ * `memory.v2.ann_candidate_limit` respectively; every other key shares its
14
+ * name with its `memory.v2` twin.
15
+ */
16
+ export const MemorySubstrateConfigSchema = z
17
+ .object({
18
+ sweep_enabled: z
19
+ .boolean({ error: "memory.substrate.sweep_enabled must be a boolean" })
20
+ .optional()
21
+ .describe(
22
+ "Whether the idle-debounced memory sweep job is enabled. `remember()` is the primary capture path; opt in only when the model is missing entries the sweep would have caught.",
23
+ ),
24
+ dense_weight: z
25
+ .number({ error: "memory.substrate.dense_weight must be a number" })
26
+ .min(0, "memory.substrate.dense_weight must be >= 0")
27
+ .max(1, "memory.substrate.dense_weight must be <= 1")
28
+ .optional()
29
+ .describe(
30
+ "Weight on dense (cosine) similarity in the hybrid retrieval score.",
31
+ ),
32
+ sparse_weight: z
33
+ .number({ error: "memory.substrate.sparse_weight must be a number" })
34
+ .min(0, "memory.substrate.sparse_weight must be >= 0")
35
+ .max(1, "memory.substrate.sparse_weight must be <= 1")
36
+ .optional()
37
+ .describe(
38
+ "Weight on sparse (BM25-style) similarity in the hybrid retrieval score — sparse acts as a discriminator for keyword-rich queries.",
39
+ ),
40
+ min_sparse_spread: z
41
+ .number({ error: "memory.substrate.min_sparse_spread must be a number" })
42
+ .min(0, "memory.substrate.min_sparse_spread must be >= 0")
43
+ .max(1, "memory.substrate.min_sparse_spread must be <= 1")
44
+ .optional()
45
+ .describe(
46
+ "Adaptive sparse weighting: when the spread (max - min) of normalized sparse scores across the candidate hit set falls below this, sparse contribution collapses to 0. Linear interpolation between this and `full_sparse_spread`. Optional escape hatch — leave unset to use the built-in default.",
47
+ ),
48
+ full_sparse_spread: z
49
+ .number({ error: "memory.substrate.full_sparse_spread must be a number" })
50
+ .min(0, "memory.substrate.full_sparse_spread must be >= 0")
51
+ .max(1, "memory.substrate.full_sparse_spread must be <= 1")
52
+ .optional()
53
+ .describe(
54
+ "Adaptive sparse weighting: at or above this spread, sparse weight stays at the configured `sparse_weight`. Optional escape hatch — leave unset to use the built-in default.",
55
+ ),
56
+ bm25_k1: z
57
+ .number({ error: "memory.substrate.bm25_k1 must be a number" })
58
+ .min(0, "memory.substrate.bm25_k1 must be >= 0")
59
+ .optional()
60
+ .describe(
61
+ "BM25 term-frequency saturation parameter. Increase to make repeated mentions of a term matter more, decrease to flatten the curve.",
62
+ ),
63
+ bm25_b: z
64
+ .number({ error: "memory.substrate.bm25_b must be a number" })
65
+ .min(0, "memory.substrate.bm25_b must be >= 0")
66
+ .max(1, "memory.substrate.bm25_b must be <= 1")
67
+ .optional()
68
+ .describe(
69
+ "BM25 document-length normalization. 0 disables length normalization, 1 fully normalizes. Concept-page collections include structured list pages with high information density per word, so values below Lucene's 0.75 default avoid over-penalizing them.",
70
+ ),
71
+ consolidation_interval_hours: z
72
+ .number({
73
+ error: "memory.substrate.consolidation_interval_hours must be a number",
74
+ })
75
+ .int("memory.substrate.consolidation_interval_hours must be an integer")
76
+ .positive(
77
+ "memory.substrate.consolidation_interval_hours must be a positive integer",
78
+ )
79
+ .optional()
80
+ .describe(
81
+ "Hours between scheduled consolidation runs that synthesize buffered memories into concept pages",
82
+ ),
83
+ consolidation_max_buffer_lines: z
84
+ .number({
85
+ error:
86
+ "memory.substrate.consolidation_max_buffer_lines must be a number",
87
+ })
88
+ .int("memory.substrate.consolidation_max_buffer_lines must be an integer")
89
+ .positive(
90
+ "memory.substrate.consolidation_max_buffer_lines must be a positive integer",
91
+ )
92
+ .nullable()
93
+ .optional()
94
+ .describe(
95
+ "Size-based trigger for consolidation. When `memory/buffer.md` reaches this many non-empty lines, consolidation runs even if the time-based interval hasn't elapsed. Set to `null` to disable the size trigger and rely solely on `consolidation_interval_hours`.",
96
+ ),
97
+ consolidation_max_entries_per_run: z
98
+ .number({
99
+ error:
100
+ "memory.substrate.consolidation_max_entries_per_run must be a number",
101
+ })
102
+ .int(
103
+ "memory.substrate.consolidation_max_entries_per_run must be an integer",
104
+ )
105
+ .positive(
106
+ "memory.substrate.consolidation_max_entries_per_run must be a positive integer",
107
+ )
108
+ .nullable()
109
+ .optional()
110
+ .describe(
111
+ "Upper bound on buffer entries one consolidation run may process. When the buffer holds more, the run's cutoff is moved back to the first over-cap entry's timestamp so the overflow is deferred to a follow-up pass. Bounds the context a single agentic run must read after a backlog. Set to `null` to always process the full buffer.",
112
+ ),
113
+ max_page_chars: z
114
+ .number({ error: "memory.substrate.max_page_chars must be a number" })
115
+ .int("memory.substrate.max_page_chars must be an integer")
116
+ .positive("memory.substrate.max_page_chars must be a positive integer")
117
+ .optional()
118
+ .describe(
119
+ "Soft upper bound on concept-page body length — pages exceeding this are flagged for split during consolidation",
120
+ ),
121
+ consolidation_prompt_path: z
122
+ .string({
123
+ error: "memory.substrate.consolidation_prompt_path must be a string",
124
+ })
125
+ .nullable()
126
+ .optional()
127
+ .describe(
128
+ "Optional path to a file whose contents replace the bundled consolidation prompt. Relative paths resolve under the workspace root; absolute paths and a leading `~/` (expanded to the home directory) are honored only when they still resolve inside the workspace root — a path that lands outside the workspace (including via symlinks) is rejected. The loaded contents may include `{{CUTOFF}}`, which is substituted with the run's ISO-8601 cutoff timestamp. If the file is rejected, missing, unreadable, or empty, the bundled prompt is used and a warning is logged.",
129
+ ),
130
+ spread_k: z
131
+ .number({ error: "memory.substrate.spread_k must be a number" })
132
+ .min(0, "memory.substrate.spread_k must be >= 0")
133
+ .max(1, "memory.substrate.spread_k must be <= 1")
134
+ .optional()
135
+ .describe(
136
+ "Spreading-activation propagation coefficient — fraction of own activation that flows to neighbors per hop. Falls back to `memory.v2.k`.",
137
+ ),
138
+ spread_hops: z
139
+ .number({ error: "memory.substrate.spread_hops must be a number" })
140
+ .int("memory.substrate.spread_hops must be an integer")
141
+ .nonnegative("memory.substrate.spread_hops must be non-negative")
142
+ .optional()
143
+ .describe(
144
+ "Maximum BFS distance for spreading activation across the concept graph. Falls back to `memory.v2.hops`.",
145
+ ),
146
+ ann_candidate_limit: z
147
+ .number({
148
+ error: "memory.substrate.ann_candidate_limit must be a number",
149
+ })
150
+ .int("memory.substrate.ann_candidate_limit must be an integer")
151
+ .positive(
152
+ "memory.substrate.ann_candidate_limit must be a positive integer",
153
+ )
154
+ .nullable()
155
+ .optional()
156
+ .describe(
157
+ "Per-channel cap on the unrestricted ANN candidate query used by memory recall (dense and sparse each return up to this many hits before they are unioned). `null` = unlimited (every page in the concept-page collection is eligible).",
158
+ ),
159
+ })
160
+ .describe(
161
+ "Memory substrate tuning — overrides for the shared concept-page infrastructure (consolidation, hybrid retrieval, BM25 encoding, sweep). Unset keys resolve to their historical `memory.v2` counterparts.",
162
+ )
163
+ .superRefine((config, ctx) => {
164
+ if (
165
+ config.dense_weight === undefined ||
166
+ config.sparse_weight === undefined
167
+ ) {
168
+ return;
169
+ }
170
+ const hybridSum = config.dense_weight + config.sparse_weight;
171
+ if (Math.abs(hybridSum - 1.0) >= WEIGHT_SUM_TOLERANCE) {
172
+ const message = `memory.substrate hybrid weights (dense_weight + sparse_weight) must sum to 1.0 (got ${hybridSum.toFixed(4)})`;
173
+ for (const path of ["dense_weight", "sparse_weight"] as const) {
174
+ ctx.addIssue({
175
+ code: z.ZodIssueCode.custom,
176
+ path: [path],
177
+ message,
178
+ });
179
+ }
180
+ }
181
+ });
182
+
183
+ export type MemorySubstrateConfig = z.infer<typeof MemorySubstrateConfigSchema>;
@@ -3,9 +3,10 @@ import { z } from "zod";
3
3
  /**
4
4
  * Tolerance for floating-point comparisons of weight sums. Using 0.001 lets
5
5
  * users specify weights to three decimal places without spurious rejections,
6
- * while still catching obvious mis-sums.
6
+ * while still catching obvious mis-sums. Shared with the `memory.substrate`
7
+ * schema so both namespaces apply the same hybrid-weight refinement.
7
8
  */
8
- const WEIGHT_SUM_TOLERANCE = 0.001;
9
+ export const WEIGHT_SUM_TOLERANCE = 0.001;
9
10
 
10
11
  /**
11
12
  * Default cross-encoder model for memory v2 reranking.
@@ -252,8 +252,7 @@ export const MemoryV3EntitySchema = z
252
252
  /**
253
253
  * Per-turn injection-gate tuning: thresholds the retrieval signals must clear
254
254
  * for the gate to open and run the selector. The gate runs only when the
255
- * `memory-v3-injection-gate` feature flag (the rollout switch) AND the
256
- * `enabled` kill-switch below are both on.
255
+ * `enabled` kill-switch below is on.
257
256
  */
258
257
  export const MemoryV3GateSchema = z
259
258
  .object({
@@ -261,7 +260,7 @@ export const MemoryV3GateSchema = z
261
260
  .boolean({ error: "memory.v3.gate.enabled must be a boolean" })
262
261
  .default(true)
263
262
  .describe(
264
- "Whether the injection gate may run at all. false forces the full selection process every turn regardless of the `memory-v3-injection-gate` feature flag; true (default) defers to the flag.",
263
+ "Whether the injection gate may run at all. false forces the full selection process every turn; true (default) lets the gate run when the thresholds are met.",
265
264
  ),
266
265
  denseThreshold: z
267
266
  .number({ error: "memory.v3.gate.denseThreshold must be a number" })
@@ -327,7 +326,7 @@ export const MemoryV3GateSchema = z
327
326
  ),
328
327
  })
329
328
  .describe(
330
- "Memory v3 per-turn injection gate tuning (thresholds; the gate runs when the `memory-v3-injection-gate` feature flag AND `enabled` are both on).",
329
+ "Memory v3 per-turn injection gate tuning (thresholds; the gate runs when `enabled` is on).",
331
330
  );
332
331
 
333
332
  // NOTE: a retired `workingSet` sub-config (maxPages/evictWindow for the old
@@ -383,6 +382,14 @@ export const MemoryV3ConfigSchema = z
383
382
  .describe(
384
383
  "Per-lane article budget for the reply-query finder pass: needle and dense each re-run over the assistant's previous message as separate queries (never concatenated with the user's message). 0 disables the pass. Deliberately small next to needleK/denseK — the pass adds the assistant-side retrieval signal, not a second full sweep.",
385
384
  ),
385
+ spanQueryK: z
386
+ .number({ error: "memory.v3.spanQueryK must be a number" })
387
+ .int("memory.v3.spanQueryK must be an integer")
388
+ .nonnegative("memory.v3.spanQueryK must be a non-negative integer")
389
+ .default(0)
390
+ .describe(
391
+ "Per-chunk article budget for the span-query dense pass: the current message's clause spans (merged into at most 8 contiguous chunks) re-run through the dense lane as separate queries, union-additive into the candidate pool. 0 disables the pass; it is also inert when denseK is 0 or the message yields fewer than two chunks. Deliberately small next to denseK — the pass rescues motifs a long message's single query vector averages away, not a second full sweep.",
392
+ ),
386
393
  selectorEnabled: z
387
394
  .boolean({ error: "memory.v3.selectorEnabled must be a boolean" })
388
395
  .default(true)
@@ -17,7 +17,8 @@ import {
17
17
  MemorySegmentationConfigSchema,
18
18
  QdrantConfigSchema,
19
19
  } from "./memory-storage.js";
20
- import { MemoryV2ConfigSchema } from "./memory-v2.js";
20
+ import { MemorySubstrateConfigSchema } from "./memory-substrate.js";
21
+ import { MemoryV2ConfigSchema, WEIGHT_SUM_TOLERANCE } from "./memory-v2.js";
21
22
  import { MemoryV3ConfigSchema } from "./memory-v3.js";
22
23
 
23
24
  export const MemoryConfigSchema = z
@@ -54,6 +55,9 @@ export const MemoryConfigSchema = z
54
55
  summarization: MemorySummarizationConfigSchema.default(
55
56
  MemorySummarizationConfigSchema.parse({}),
56
57
  ),
58
+ substrate: MemorySubstrateConfigSchema.default(
59
+ MemorySubstrateConfigSchema.parse({}),
60
+ ),
57
61
  v2: MemoryV2ConfigSchema.default(MemoryV2ConfigSchema.parse({})),
58
62
  v3: MemoryV3ConfigSchema.default(MemoryV3ConfigSchema.parse({})),
59
63
  retrospective: MemoryRetrospectiveConfigSchema.default(
@@ -118,6 +122,36 @@ export const MemoryConfigSchema = z
118
122
  "memory.retrieval.injection.perTurn.capabilityReserve + serendipitySlots must be less than maxNodes",
119
123
  });
120
124
  }
125
+ // Resolved hybrid-weight invariant. `resolveSubstrateTuning` pairs each
126
+ // `memory.substrate` weight with its `memory.v2` twin on an
127
+ // undefined-only fallback, so a single substrate weight forms its
128
+ // effective pair with the v2 value (schema default applied by now). The
129
+ // substrate schema's own refinement already covers the both-set case, and
130
+ // the v2 schema covers the neither-set case — this check guards the mixed
131
+ // case those local refinements cannot see.
132
+ const substrateDense = config.substrate?.dense_weight;
133
+ const substrateSparse = config.substrate?.sparse_weight;
134
+ const oneSubstrateWeightSet =
135
+ (substrateDense === undefined) !== (substrateSparse === undefined);
136
+ if (oneSubstrateWeightSet) {
137
+ const effectiveDense =
138
+ substrateDense !== undefined ? substrateDense : config.v2.dense_weight;
139
+ const effectiveSparse =
140
+ substrateSparse !== undefined
141
+ ? substrateSparse
142
+ : config.v2.sparse_weight;
143
+ const effectiveSum = effectiveDense + effectiveSparse;
144
+ if (Math.abs(effectiveSum - 1.0) >= WEIGHT_SUM_TOLERANCE) {
145
+ ctx.addIssue({
146
+ code: z.ZodIssueCode.custom,
147
+ path: [
148
+ "substrate",
149
+ substrateDense !== undefined ? "dense_weight" : "sparse_weight",
150
+ ],
151
+ message: `memory hybrid weights must sum to 1.0 after memory.substrate → memory.v2 fallback (effective dense_weight ${effectiveDense.toFixed(4)} + sparse_weight ${effectiveSparse.toFixed(4)} = ${effectiveSum.toFixed(4)})`,
152
+ });
153
+ }
154
+ }
121
155
  });
122
156
 
123
157
  export type MemoryConfig = z.infer<typeof MemoryConfigSchema>;
@@ -20,7 +20,9 @@ export const VALID_INFERENCE_PROVIDERS = [
20
20
  "openrouter",
21
21
  ] as const;
22
22
 
23
- const VALID_IMAGE_GEN_PROVIDERS = ["gemini", "openai"] as const;
23
+ // `vellum` generates through the platform runtime proxy; the backend
24
+ // (gemini/openai) derives from the selected model's prefix at request time.
25
+ const VALID_IMAGE_GEN_PROVIDERS = ["vellum", "gemini", "openai"] as const;
24
26
 
25
27
  /**
26
28
  * Derived from `SEARCH_PROVIDER_CATALOG`. Adding a new web-search provider
@@ -51,7 +53,13 @@ const BaseServiceSchema = z.object({
51
53
  */
52
54
  const InferenceServiceSchema = z.object({});
53
55
 
54
- const ImageGenerationServiceSchema = BaseServiceSchema.extend({
56
+ /**
57
+ * Image generation carries no `mode`: `provider` is the only axis. `"vellum"`
58
+ * generates through the platform runtime proxy for the model-appropriate
59
+ * backend, billed to Vellum credits; `"gemini"`/`"openai"` use the user's
60
+ * key. A `mode` key sent by an older client is stripped at parse.
61
+ */
62
+ const ImageGenerationServiceSchema = z.object({
55
63
  provider: z.enum(VALID_IMAGE_GEN_PROVIDERS).default("gemini"),
56
64
  model: z.string().default(DEFAULT_IMAGE_MODEL),
57
65
  });
@@ -0,0 +1,195 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory substrate — twin-namespace shadowing detection
3
+ // ---------------------------------------------------------------------------
4
+
5
+ /** One `memory.v2` tunable's `memory.substrate` twin. */
6
+ interface SubstrateTwin {
7
+ /** The twin's `memory.substrate` key, e.g. `spread_k` for `k`. */
8
+ readonly substrateKey: string;
9
+ /**
10
+ * Whether the v2 injection engine reads the `memory.v2` key straight out of
11
+ * its own namespace (`v2/injection.ts`, `v2/activation.ts`,
12
+ * `v2/backfill-jobs.ts`) rather than through `resolveSubstrateTuning`. For
13
+ * these keys the two namespaces feed two different consumers, so a
14
+ * `memory.v2` write retunes the v2 engine while substrate recall keeps
15
+ * reading the substrate twin — the pair can hold different effective values
16
+ * at once.
17
+ */
18
+ readonly alsoReadByV2Engine: boolean;
19
+ }
20
+
21
+ /**
22
+ * `memory.v2` key → its `memory.substrate` twin, for the fifteen substrate
23
+ * tunables that exist in both namespaces. `k` / `hops` are the historical
24
+ * `memory.v2` names for `spread_k` / `spread_hops`; every other key shares its
25
+ * name with its twin.
26
+ *
27
+ * Substrate precedence lives in `resolveSubstrateTuning`
28
+ * (`plugins/defaults/memory/substrate/tuning.ts`), which resolves each tunable
29
+ * as `memory.substrate.X ?? memory.v2.X`. Twelve keys reach the runtime only
30
+ * through that resolver; the three carrying `alsoReadByV2Engine` are read a
31
+ * second time by the live v2 injection engine off `config.memory.v2` directly.
32
+ *
33
+ * This table is the config surface's view of the same pairing, kept honest by
34
+ * `__tests__/substrate-twin-shadowing.test.ts`, which asserts it covers exactly
35
+ * the `memory.substrate` schema's keys.
36
+ */
37
+ export const SUBSTRATE_TWIN_BY_V2_KEY: Readonly<Record<string, SubstrateTwin>> =
38
+ {
39
+ sweep_enabled: { substrateKey: "sweep_enabled", alsoReadByV2Engine: false },
40
+ dense_weight: { substrateKey: "dense_weight", alsoReadByV2Engine: false },
41
+ sparse_weight: { substrateKey: "sparse_weight", alsoReadByV2Engine: false },
42
+ min_sparse_spread: {
43
+ substrateKey: "min_sparse_spread",
44
+ alsoReadByV2Engine: false,
45
+ },
46
+ full_sparse_spread: {
47
+ substrateKey: "full_sparse_spread",
48
+ alsoReadByV2Engine: false,
49
+ },
50
+ bm25_k1: { substrateKey: "bm25_k1", alsoReadByV2Engine: false },
51
+ bm25_b: { substrateKey: "bm25_b", alsoReadByV2Engine: false },
52
+ consolidation_interval_hours: {
53
+ substrateKey: "consolidation_interval_hours",
54
+ alsoReadByV2Engine: false,
55
+ },
56
+ consolidation_max_buffer_lines: {
57
+ substrateKey: "consolidation_max_buffer_lines",
58
+ alsoReadByV2Engine: false,
59
+ },
60
+ consolidation_max_entries_per_run: {
61
+ substrateKey: "consolidation_max_entries_per_run",
62
+ alsoReadByV2Engine: false,
63
+ },
64
+ max_page_chars: {
65
+ substrateKey: "max_page_chars",
66
+ alsoReadByV2Engine: false,
67
+ },
68
+ consolidation_prompt_path: {
69
+ substrateKey: "consolidation_prompt_path",
70
+ alsoReadByV2Engine: false,
71
+ },
72
+ // The v2 injection engine reads these three off `config.memory.v2`:
73
+ // `k` / `hops` in `v2/injection.ts` and `v2/backfill-jobs.ts`,
74
+ // `ann_candidate_limit` in `v2/activation.ts`.
75
+ k: { substrateKey: "spread_k", alsoReadByV2Engine: true },
76
+ hops: { substrateKey: "spread_hops", alsoReadByV2Engine: true },
77
+ ann_candidate_limit: {
78
+ substrateKey: "ann_candidate_limit",
79
+ alsoReadByV2Engine: true,
80
+ },
81
+ };
82
+
83
+ /** A `memory.substrate` value set on the twin of a given `memory.v2` key. */
84
+ export type SubstrateShadowing = {
85
+ /** Dotted path of the twin, e.g. `memory.substrate.spread_k`. */
86
+ substratePath: string;
87
+ /** The twin's persisted value — what substrate recall resolves to. */
88
+ substrateValue: unknown;
89
+ /**
90
+ * Whether the v2 injection engine also reads the `memory.v2` key directly,
91
+ * so the write is not inert (see {@link SubstrateTwin.alsoReadByV2Engine}).
92
+ */
93
+ alsoReadByV2Engine: boolean;
94
+ };
95
+
96
+ function readPlainObject(value: unknown): Record<string, unknown> | undefined {
97
+ return value != null && typeof value === "object" && !Array.isArray(value)
98
+ ? (value as Record<string, unknown>)
99
+ : undefined;
100
+ }
101
+
102
+ /**
103
+ * The `memory.substrate` twin covering `path`, or `undefined` when `path` is
104
+ * not a shadowable `memory.v2` tunable or its twin is unset.
105
+ *
106
+ * `memory.substrate` is override-only and wins for substrate recall whenever
107
+ * its key is present — including when it holds an explicit `null`, which
108
+ * `resolveSubstrateTuning` treats as present. Detection therefore keys on
109
+ * presence, not truthiness. What that means for the `memory.v2` key depends on
110
+ * `alsoReadByV2Engine`: for a substrate-only twin the `memory.v2` value has no
111
+ * remaining consumer, while for the three engine-read twins it still tunes v2
112
+ * injection.
113
+ *
114
+ * `raw` is the unparsed config object (`loadRawConfig()` / the `config_get`
115
+ * payload), so the check sees exactly what is persisted.
116
+ */
117
+ export function findSubstrateShadowing(
118
+ raw: Record<string, unknown>,
119
+ path: string,
120
+ ): SubstrateShadowing | undefined {
121
+ const segments = path.split(".");
122
+ if (segments.length !== 3 || segments[0] !== "memory") {
123
+ return undefined;
124
+ }
125
+ const [, namespace, key] = segments as [string, string, string];
126
+ if (namespace !== "v2") {
127
+ return undefined;
128
+ }
129
+ const twin = SUBSTRATE_TWIN_BY_V2_KEY[key];
130
+ if (twin === undefined) {
131
+ return undefined;
132
+ }
133
+ const substrate = readPlainObject(readPlainObject(raw.memory)?.substrate);
134
+ if (!substrate || !(twin.substrateKey in substrate)) {
135
+ return undefined;
136
+ }
137
+ return {
138
+ substratePath: `memory.substrate.${twin.substrateKey}`,
139
+ substrateValue: substrate[twin.substrateKey],
140
+ alsoReadByV2Engine: twin.alsoReadByV2Engine,
141
+ };
142
+ }
143
+
144
+ /**
145
+ * Operator-facing warning for a `config set` on a `memory.v2` tunable whose
146
+ * `memory.substrate` twin is set.
147
+ *
148
+ * Two classes, two messages. A substrate-only twin leaves the write with no
149
+ * consumer, so the warning names the winning key and the command that actually
150
+ * retunes it. An engine-read twin (`k`, `hops`, `ann_candidate_limit`) makes
151
+ * the write effective for v2 injection while substrate recall stays on the
152
+ * twin, so the warning reports the split rather than a no-op.
153
+ */
154
+ export function describeShadowedConfigSet(
155
+ shadowing: SubstrateShadowing,
156
+ path: string,
157
+ ): string {
158
+ const value = JSON.stringify(shadowing.substrateValue) ?? "undefined";
159
+ if (shadowing.alsoReadByV2Engine) {
160
+ return (
161
+ `${path} is read directly by the memory-v2 injection engine, so this write ` +
162
+ `does change its behavior. Substrate recall reads ${shadowing.substratePath} ` +
163
+ `(${value}) instead, so the two can diverge. ` +
164
+ `Run 'assistant config set ${shadowing.substratePath} <value>' to move substrate recall with it.`
165
+ );
166
+ }
167
+ return (
168
+ `${shadowing.substratePath} is set (${value}) and takes precedence over ${path}, ` +
169
+ `so this write does not change the effective value. ` +
170
+ `Run 'assistant config set ${shadowing.substratePath} <value>' to retune it.`
171
+ );
172
+ }
173
+
174
+ /**
175
+ * Operator-facing annotation for a `config get` of a `memory.v2` tunable whose
176
+ * `memory.substrate` twin is set — the read-side counterpart of
177
+ * {@link describeShadowedConfigSet}, split along the same two classes so a read
178
+ * never confirms a value the runtime ignores nor denies one it honors.
179
+ */
180
+ export function describeShadowedConfigGet(
181
+ shadowing: SubstrateShadowing,
182
+ path: string,
183
+ ): string {
184
+ const value = JSON.stringify(shadowing.substrateValue) ?? "undefined";
185
+ if (shadowing.alsoReadByV2Engine) {
186
+ return (
187
+ `Split: ${shadowing.substratePath} = ${value} is the effective value for ` +
188
+ `substrate recall, while the memory-v2 injection engine reads ${path} above.`
189
+ );
190
+ }
191
+ return (
192
+ `Shadowed: ${shadowing.substratePath} = ${value} takes precedence and is ` +
193
+ `the effective value.`
194
+ );
195
+ }