@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
@@ -12,7 +12,7 @@ import { describe, expect, mock, test } from "bun:test";
12
12
 
13
13
  import { CompactionCircuit } from "../agent/compaction-circuit.js";
14
14
  import type { AgentEvent } from "../agent/loop.js";
15
- import type { ServerMessage } from "../daemon/message-protocol.js";
15
+ import type { AssistantEvent } from "../api/index.js";
16
16
  import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
17
17
  import type { Message, ProviderResponse } from "../providers/types.js";
18
18
 
@@ -233,7 +233,7 @@ function makeProvider() {
233
233
  }
234
234
 
235
235
  function makeConversation(
236
- collected: ServerMessage[],
236
+ collected: AssistantEvent[],
237
237
  id = "conv-compact-events",
238
238
  ): Conversation {
239
239
  return new Conversation(
@@ -254,7 +254,7 @@ function makeConversation(
254
254
 
255
255
  describe("forceCompact event emission", () => {
256
256
  test("emits context_compacted and a usage_update without contextWindow when compacted", async () => {
257
- const collected: ServerMessage[] = [];
257
+ const collected: AssistantEvent[] = [];
258
258
  mockCompactResult = {
259
259
  messages: [],
260
260
  compacted: true,
@@ -279,7 +279,7 @@ describe("forceCompact event emission", () => {
279
279
  );
280
280
  expect(compactedEvents.length).toBe(1);
281
281
  const compactedEvent = compactedEvents[0] as Extract<
282
- ServerMessage,
282
+ AssistantEvent,
283
283
  { type: "context_compacted" }
284
284
  >;
285
285
  expect(compactedEvent.conversationId).toBe("conv-compact-events");
@@ -298,7 +298,7 @@ describe("forceCompact event emission", () => {
298
298
  const usageEvents = collected.filter((m) => m.type === "usage_update");
299
299
  expect(usageEvents.length).toBe(1);
300
300
  const usageEvent = usageEvents[0] as Extract<
301
- ServerMessage,
301
+ AssistantEvent,
302
302
  { type: "usage_update" }
303
303
  >;
304
304
  // `context_compacted` is now the single source of truth for the UI
@@ -312,7 +312,7 @@ describe("forceCompact event emission", () => {
312
312
  });
313
313
 
314
314
  test("emits context_compacted even when summary LLM was skipped (truncation-only path)", async () => {
315
- const collected: ServerMessage[] = [];
315
+ const collected: AssistantEvent[] = [];
316
316
  mockCompactResult = {
317
317
  messages: [],
318
318
  compacted: true,
@@ -342,7 +342,7 @@ describe("forceCompact event emission", () => {
342
342
  );
343
343
  expect(compactedEvents.length).toBe(1);
344
344
  const compactedEvent = compactedEvents[0] as Extract<
345
- ServerMessage,
345
+ AssistantEvent,
346
346
  { type: "context_compacted" }
347
347
  >;
348
348
  expect(compactedEvent.conversationId).toBe("conv-compact-trunc");
@@ -356,7 +356,7 @@ describe("forceCompact event emission", () => {
356
356
  });
357
357
 
358
358
  test("skips emission when compacted is false", async () => {
359
- const collected: ServerMessage[] = [];
359
+ const collected: AssistantEvent[] = [];
360
360
  mockCompactResult = {
361
361
  messages: [],
362
362
  compacted: false,
@@ -76,9 +76,10 @@ function readConfig(): Record<string, unknown> {
76
76
  // Without IS_PLATFORM, services split by Zod schema default: google/notion-oauth
77
77
  // resolve to "managed" (per JARVIS-966), the rest resolve to "your-own".
78
78
  // web-search is deliberately absent: `provider` is its only axis, so the
79
- // platform context injects no mode for it.
79
+ // platform context injects no mode for it. image-generation is also absent:
80
+ // its managed axis is the provider ("vellum" proxies through the platform),
81
+ // so the platform context fills `provider: "vellum"` rather than a mode.
80
82
  const MANAGED_SERVICES = [
81
- "image-generation",
82
83
  "google-oauth",
83
84
  "outlook-oauth",
84
85
  "linear-oauth",
@@ -101,8 +102,9 @@ const SCHEMA_MANAGED_DEFAULT_SERVICES = [
101
102
  ] as const;
102
103
 
103
104
  // web-search is absent from both lists: it carries no mode at all.
105
+ // image-generation and web-search are absent from both lists: they carry
106
+ // no mode at all.
104
107
  const SCHEMA_YOUR_OWN_DEFAULT_SERVICES = [
105
- "image-generation",
106
108
  "outlook-oauth",
107
109
  "linear-oauth",
108
110
  "github-oauth",
@@ -132,7 +134,7 @@ describe("platform-managed config defaults", () => {
132
134
  }
133
135
  });
134
136
 
135
- test("IS_PLATFORM=true, no config file → all 7 managed service modes written as 'managed'", () => {
137
+ test("IS_PLATFORM=true, no config file → all 6 managed service modes written as 'managed', image-generation provider written as 'vellum'", () => {
136
138
  process.env.IS_PLATFORM = "true";
137
139
 
138
140
  loadConfig();
@@ -147,6 +149,15 @@ describe("platform-managed config defaults", () => {
147
149
  expect((services["web-search"] as { provider?: string })?.provider).toBe(
148
150
  "inference-provider-native",
149
151
  );
152
+ // image-generation's managed axis is its provider: the platform context
153
+ // fills "vellum" and never injects a managed mode (the persisted mode is
154
+ // the schema default).
155
+ const imageGen = services["image-generation"] as {
156
+ provider?: string;
157
+ mode?: string;
158
+ };
159
+ expect(imageGen?.provider).toBe("vellum");
160
+ expect(imageGen?.mode).not.toBe("managed");
150
161
  });
151
162
 
152
163
  test("IS_PLATFORM=false, no config file → service modes follow schema defaults (your-own except google/notion-oauth which are managed)", () => {
@@ -204,13 +215,16 @@ describe("platform-managed config defaults", () => {
204
215
 
205
216
  const written = readConfig() as { services?: Record<string, unknown> };
206
217
  expect(written.services).toBeDefined();
207
- // The existing value must be preserved — backfill path, not fresh-write path
218
+ // The raw value must be preserved — backfill path, not fresh-write path.
219
+ // (Migration 134 rewrites this legacy shape at daemon startup; the loader
220
+ // itself must simply leave it alone.)
208
221
  expect(
209
222
  (written.services!["image-generation"] as { mode?: string })?.mode,
210
223
  ).toBe("your-own");
211
- // ...and the in-memory config must mirror the explicit user choice (the
212
- // fill-defaults pass must not override an explicit "your-own").
213
- expect(config.services["image-generation"].mode).toBe("your-own");
224
+ // The parsed config strips the legacy key and carries the filled
225
+ // provider; no mode survives the schema.
226
+ expect(config.services["image-generation"]).not.toHaveProperty("mode");
227
+ expect(config.services["image-generation"].provider).toBe("vellum");
214
228
  });
215
229
 
216
230
  test("IS_PLATFORM=true, config file with explicit notion-oauth mode='your-own' → preserved (schema default is 'managed')", () => {
@@ -279,6 +293,8 @@ describe("platform-managed config defaults", () => {
279
293
  .mode,
280
294
  ).toBe("managed");
281
295
  }
296
+ // ...and for image-generation's provider, whose fill is "vellum".
297
+ expect(config.services["image-generation"].provider).toBe("vellum");
282
298
 
283
299
  // The on-disk file is NOT modified by the fill pass — disk reflects only
284
300
  // what was already there. Existing-file branch never re-writes config.json.
@@ -286,15 +302,13 @@ describe("platform-managed config defaults", () => {
286
302
  expect(onDisk["services"]).toBeUndefined();
287
303
  });
288
304
 
289
- test("IS_PLATFORM=true, config file exists with a partial service subtree → preserves user fields, fills missing mode", () => {
305
+ test("IS_PLATFORM=true, config file exists with an explicit image-generation provider → provider wins over the vellum fill", () => {
290
306
  process.env.IS_PLATFORM = "true";
291
307
 
292
- // User has an image-generation provider configured but never explicitly
293
- // chose a mode for that service. The fill pass must apply
294
- // `mode: "managed"` without clobbering the user-supplied provider.
295
- // (The inference schema dropped per-service model/provider in
296
- // migration 039 — image-generation still carries them, so it's the
297
- // right schema to exercise the partial-subtree case.)
308
+ // User has an explicit BYOK image-generation provider on disk. The fill
309
+ // pass targets exactly that leaf (`provider: "vellum"`), so the explicit
310
+ // value must win and no mode is injected — the effective mode is the
311
+ // schema default.
298
312
  writeFileSync(
299
313
  CONFIG_PATH,
300
314
  JSON.stringify(
@@ -313,11 +327,11 @@ describe("platform-managed config defaults", () => {
313
327
  const imageGen = (
314
328
  config.services as unknown as Record<
315
329
  string,
316
- { mode: string; provider?: string }
330
+ { mode?: string; provider?: string }
317
331
  >
318
332
  )["image-generation"]!;
319
- expect(imageGen.mode).toBe("managed");
320
333
  expect(imageGen.provider).toBe("openai");
334
+ expect(imageGen).not.toHaveProperty("mode");
321
335
  });
322
336
 
323
337
  test("IS_PLATFORM=false, config file exists without services key → in-memory config keeps schema defaults (your-own except google/notion-oauth which are managed)", () => {
@@ -404,19 +418,27 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
404
418
  string,
405
419
  unknown
406
420
  >;
407
- const services = result["services"] as Record<string, { mode: string }>;
421
+ const services = result["services"] as Record<
422
+ string,
423
+ { mode?: string; provider?: string }
424
+ >;
408
425
  expect(services).toBeDefined();
409
426
  for (const svc of MANAGED_SERVICES) {
410
427
  expect(services[svc]!.mode).toBe("managed");
411
428
  }
429
+ // image-generation is filled by provider, not mode.
430
+ expect(services["image-generation"]!.provider).toBe("vellum");
431
+ expect(services["image-generation"]!.mode).toBeUndefined();
412
432
  });
413
433
 
414
434
  test("IS_PLATFORM=true, raw config has explicit services.image-generation.mode='your-own' → preserved", () => {
415
435
  process.env.IS_PLATFORM = "true";
416
436
 
417
- // User has explicitly chosen "your-own" for image-generation via the macOS
418
- // Save flow. The patch handler persisted that to disk; the fill pass must
419
- // not override an explicit user choice.
437
+ // A legacy raw shape: mode with no provider leaf. Migration 134 rewrites
438
+ // it (pinning provider gemini) before any real request reaches this
439
+ // function, so the fill's only obligation here is to be non-destructive:
440
+ // existing keys pass through untouched, absent leaves get the platform
441
+ // default.
420
442
  const raw: Record<string, unknown> = {
421
443
  services: {
422
444
  "image-generation": { mode: "your-own" },
@@ -427,8 +449,12 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
427
449
  string,
428
450
  unknown
429
451
  >;
430
- const services = result["services"] as Record<string, { mode: string }>;
452
+ const services = result["services"] as Record<
453
+ string,
454
+ { mode?: string; provider?: string }
455
+ >;
431
456
  expect(services["image-generation"]!.mode).toBe("your-own");
457
+ expect(services["image-generation"]!.provider).toBe("vellum");
432
458
  // web-search is not context-filled: a filled `mode` would override BYOK
433
459
  // configs on every load.
434
460
  expect(services["web-search"]).toBeUndefined();
@@ -455,12 +481,12 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
455
481
  expect(result["services"]).toBeUndefined();
456
482
  });
457
483
 
458
- test("IS_PLATFORM=true, raw config has partial services subtree → preserves user fields, fills missing mode", () => {
484
+ test("IS_PLATFORM=true, raw config has an explicit image-generation provider → preserved, no mode injected", () => {
459
485
  process.env.IS_PLATFORM = "true";
460
486
 
461
- // User set image-generation.provider but never chose a mode.
462
- // The fill pass adds the missing mode without clobbering the user-supplied
463
- // provider.
487
+ // User set image-generation.provider explicitly. The fill targets that
488
+ // same leaf (`provider: "vellum"`), so the explicit value wins and no
489
+ // mode is injected.
464
490
  const raw: Record<string, unknown> = {
465
491
  services: {
466
492
  "image-generation": { provider: "openai" },
@@ -473,10 +499,10 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
473
499
  >;
474
500
  const services = result["services"] as Record<
475
501
  string,
476
- { mode: string; provider?: string }
502
+ { mode?: string; provider?: string }
477
503
  >;
478
- expect(services["image-generation"]!.mode).toBe("managed");
479
504
  expect(services["image-generation"]!.provider).toBe("openai");
505
+ expect(services["image-generation"]!.mode).toBeUndefined();
480
506
  // services.inference.mode is synthesized as a legacy wire-only field for
481
507
  // older macOS clients during the rollout window (Phase 1.2 schema removal
482
508
  // landed before the macOS Providers UI ships).
@@ -107,3 +107,23 @@ describe("setImageGenModel — provider derived from model prefix", () => {
107
107
  expect(imageGen?.provider).toBe("openai");
108
108
  });
109
109
  });
110
+
111
+ describe("setImageGenModel with provider vellum", () => {
112
+ test("a model change leaves provider vellum untouched", () => {
113
+ writeConfig({
114
+ services: {
115
+ "image-generation": { provider: "vellum", model: "gpt-image-2" },
116
+ },
117
+ });
118
+
119
+ setImageGenModel("gemini-3-pro-image-preview", makeCtx());
120
+
121
+ const raw = readConfig() as {
122
+ services: { "image-generation": { provider: string; model: string } };
123
+ };
124
+ expect(raw.services["image-generation"].model).toBe(
125
+ "gemini-3-pro-image-preview",
126
+ );
127
+ expect(raw.services["image-generation"].provider).toBe("vellum");
128
+ });
129
+ });
@@ -0,0 +1,306 @@
1
+ /**
2
+ * Tests for the `memory.substrate.*` config namespace and its resolver.
3
+ *
4
+ * The substrate schema mirrors the substrate-consumed subset of `memory.v2.*`
5
+ * with every field optional and no defaults; `resolveSubstrateTuning` is the
6
+ * single choke point that resolves each tunable from `memory.substrate` with
7
+ * fallback to the historical `memory.v2` key. Coverage:
8
+ *
9
+ * - Fallback resolution: substrate unset → v2 value (defaults and explicit
10
+ * values); substrate set → wins; `spread_k`/`spread_hops` map onto
11
+ * `memory.v2.k`/`memory.v2.hops`; explicit `null` on a nullable substrate
12
+ * key wins over a non-null v2 value.
13
+ * - Namespace parsing (LUM-2758 guard): configs carrying only old keys,
14
+ * only new keys, or both parse cleanly with no refinement misfires, both
15
+ * through the memory slice schema and the full assistant schema.
16
+ * - The substrate hybrid-weight refinement fires only when BOTH weights are
17
+ * set and mis-summed.
18
+ * - The parent memory schema validates the RESOLVED weight pair: a single
19
+ * substrate weight is paired with its `memory.v2` twin (schema default
20
+ * applied), and the effective sum must respect the sum-to-one invariant.
21
+ */
22
+ import { describe, expect, test } from "bun:test";
23
+
24
+ import { AssistantConfigSchema } from "../config/schema.js";
25
+ import { MemoryConfigSchema } from "../config/schemas/memory.js";
26
+ import { MemorySubstrateConfigSchema } from "../config/schemas/memory-substrate.js";
27
+ import { resolveSubstrateTuning } from "../plugins/defaults/memory/substrate/tuning.js";
28
+
29
+ describe("memory.substrate schema", () => {
30
+ test("empty object parses and every field stays unset", () => {
31
+ const parsed = MemorySubstrateConfigSchema.parse({});
32
+ expect(parsed).toEqual({});
33
+ });
34
+
35
+ test("memory slice parse mounts substrate as an empty object by default", () => {
36
+ const memory = MemoryConfigSchema.parse({});
37
+ expect(memory.substrate).toEqual({});
38
+ });
39
+
40
+ test("config with only historical memory.v2 keys parses cleanly", () => {
41
+ const memory = MemoryConfigSchema.parse({
42
+ v2: { consolidation_interval_hours: 3, bm25_k1: 1.5 },
43
+ });
44
+ expect(memory.v2.consolidation_interval_hours).toBe(3);
45
+ expect(memory.substrate).toEqual({});
46
+ });
47
+
48
+ test("config with only memory.substrate keys parses cleanly", () => {
49
+ const memory = MemoryConfigSchema.parse({
50
+ substrate: { consolidation_interval_hours: 3, spread_k: 0.4 },
51
+ });
52
+ expect(memory.substrate.consolidation_interval_hours).toBe(3);
53
+ expect(memory.substrate.spread_k).toBe(0.4);
54
+ // v2 defaults are untouched by substrate keys.
55
+ expect(memory.v2.consolidation_interval_hours).toBe(8);
56
+ });
57
+
58
+ test("config with both namespaces parses cleanly", () => {
59
+ const memory = MemoryConfigSchema.parse({
60
+ v2: { consolidation_interval_hours: 3 },
61
+ substrate: { consolidation_interval_hours: 5 },
62
+ });
63
+ expect(memory.v2.consolidation_interval_hours).toBe(3);
64
+ expect(memory.substrate.consolidation_interval_hours).toBe(5);
65
+ });
66
+
67
+ test("full assistant config parse accepts either, both, or neither namespace", () => {
68
+ for (const memory of [
69
+ {},
70
+ { v2: { max_page_chars: 4000 } },
71
+ { substrate: { max_page_chars: 4000 } },
72
+ { v2: { max_page_chars: 4000 }, substrate: { max_page_chars: 6000 } },
73
+ ]) {
74
+ const result = AssistantConfigSchema.safeParse({ memory });
75
+ expect(result.success).toBe(true);
76
+ }
77
+ });
78
+
79
+ test("hybrid-weight refinement fires only when both weights are set and mis-summed", () => {
80
+ // Only one weight set — no refinement at the substrate schema level; the
81
+ // parent memory schema validates the resolved pair against the v2 twin.
82
+ expect(
83
+ MemorySubstrateConfigSchema.safeParse({ dense_weight: 0.5 }).success,
84
+ ).toBe(true);
85
+ expect(
86
+ MemorySubstrateConfigSchema.safeParse({ sparse_weight: 0.5 }).success,
87
+ ).toBe(true);
88
+
89
+ // Both set and summing to 1.0 — valid.
90
+ expect(
91
+ MemorySubstrateConfigSchema.safeParse({
92
+ dense_weight: 0.7,
93
+ sparse_weight: 0.3,
94
+ }).success,
95
+ ).toBe(true);
96
+
97
+ // Both set and mis-summed — one issue per contributing field.
98
+ const bad = MemorySubstrateConfigSchema.safeParse({
99
+ dense_weight: 0.7,
100
+ sparse_weight: 0.7,
101
+ });
102
+ expect(bad.success).toBe(false);
103
+ if (!bad.success) {
104
+ const paths = bad.error.issues.map((issue) => issue.path.join("."));
105
+ expect(paths.sort()).toEqual(["dense_weight", "sparse_weight"]);
106
+ expect(bad.error.issues[0].message).toContain(
107
+ "memory.substrate hybrid weights",
108
+ );
109
+ }
110
+ });
111
+
112
+ describe("resolved hybrid-weight invariant (memory schema level)", () => {
113
+ // Parses `memory` through both entry points that must agree: the memory
114
+ // slice schema and the full assistant config schema.
115
+ const parseBothWays = (memory: unknown) => ({
116
+ slice: MemoryConfigSchema.safeParse(memory),
117
+ full: AssistantConfigSchema.safeParse({ memory }),
118
+ });
119
+
120
+ test("a lone substrate dense_weight that breaks the effective sum is rejected", () => {
121
+ // v2 sparse_weight defaults to 0.15 → effective sum 1.05.
122
+ const { slice, full } = parseBothWays({
123
+ substrate: { dense_weight: 0.9 },
124
+ });
125
+ for (const result of [slice, full]) {
126
+ expect(result.success).toBe(false);
127
+ if (!result.success) {
128
+ const issue = result.error.issues.find((candidate) =>
129
+ candidate.message.includes(
130
+ "memory hybrid weights must sum to 1.0 after memory.substrate → memory.v2 fallback",
131
+ ),
132
+ );
133
+ expect(issue).toBeDefined();
134
+ expect(issue?.message).toContain("0.9000");
135
+ expect(issue?.message).toContain("0.1500");
136
+ expect(issue?.message).toContain("1.0500");
137
+ expect(issue?.path.slice(-2)).toEqual(["substrate", "dense_weight"]);
138
+ }
139
+ }
140
+ });
141
+
142
+ test("a lone substrate sparse_weight that breaks the effective sum is rejected", () => {
143
+ // v2 dense_weight defaults to 0.85 → effective sum 1.35.
144
+ const { slice, full } = parseBothWays({
145
+ substrate: { sparse_weight: 0.5 },
146
+ });
147
+ for (const result of [slice, full]) {
148
+ expect(result.success).toBe(false);
149
+ if (!result.success) {
150
+ const issue = result.error.issues.find((candidate) =>
151
+ candidate.message.includes(
152
+ "memory hybrid weights must sum to 1.0 after memory.substrate → memory.v2 fallback",
153
+ ),
154
+ );
155
+ expect(issue).toBeDefined();
156
+ expect(issue?.path.slice(-2)).toEqual(["substrate", "sparse_weight"]);
157
+ }
158
+ }
159
+ });
160
+
161
+ test("a complete substrate pair summing to 1.0 is accepted", () => {
162
+ const { slice, full } = parseBothWays({
163
+ substrate: { dense_weight: 0.9, sparse_weight: 0.1 },
164
+ });
165
+ expect(slice.success).toBe(true);
166
+ expect(full.success).toBe(true);
167
+ });
168
+
169
+ test("a lone substrate weight matching the v2 default pair is accepted", () => {
170
+ // 0.85 pairs with the v2 sparse_weight default 0.15 → effective sum 1.0.
171
+ const { slice, full } = parseBothWays({
172
+ substrate: { dense_weight: 0.85 },
173
+ });
174
+ expect(slice.success).toBe(true);
175
+ expect(full.success).toBe(true);
176
+ });
177
+
178
+ test("a lone substrate weight pairing with an explicit v2 twin is accepted", () => {
179
+ const { slice, full } = parseBothWays({
180
+ v2: { dense_weight: 0.7, sparse_weight: 0.3 },
181
+ substrate: { sparse_weight: 0.3 },
182
+ });
183
+ expect(slice.success).toBe(true);
184
+ expect(full.success).toBe(true);
185
+ });
186
+
187
+ test("a mis-summed complete substrate pair only fires the substrate refinement", () => {
188
+ // Both substrate weights set → the parent check skips; only the
189
+ // substrate schema's own refinement reports, so the two never
190
+ // contradict each other.
191
+ const { slice, full } = parseBothWays({
192
+ substrate: { dense_weight: 0.7, sparse_weight: 0.7 },
193
+ });
194
+ for (const result of [slice, full]) {
195
+ expect(result.success).toBe(false);
196
+ if (!result.success) {
197
+ const messages = result.error.issues.map((issue) => issue.message);
198
+ expect(
199
+ messages.some((message) =>
200
+ message.includes("memory.substrate hybrid weights"),
201
+ ),
202
+ ).toBe(true);
203
+ expect(
204
+ messages.some((message) =>
205
+ message.includes(
206
+ "memory hybrid weights must sum to 1.0 after memory.substrate → memory.v2 fallback",
207
+ ),
208
+ ),
209
+ ).toBe(false);
210
+ }
211
+ }
212
+ });
213
+ });
214
+ });
215
+
216
+ describe("resolveSubstrateTuning", () => {
217
+ test("substrate unset resolves to the v2 schema defaults", () => {
218
+ const memory = MemoryConfigSchema.parse({});
219
+ const tuning = resolveSubstrateTuning(memory);
220
+ expect(tuning).toEqual({
221
+ sweep_enabled: false,
222
+ dense_weight: 0.85,
223
+ sparse_weight: 0.15,
224
+ min_sparse_spread: undefined,
225
+ full_sparse_spread: undefined,
226
+ bm25_k1: 1.2,
227
+ bm25_b: 0.4,
228
+ consolidation_interval_hours: 8,
229
+ consolidation_max_buffer_lines: 100,
230
+ consolidation_max_entries_per_run: 150,
231
+ max_page_chars: 5000,
232
+ consolidation_prompt_path: null,
233
+ spread_k: 0.5,
234
+ spread_hops: 2,
235
+ ann_candidate_limit: null,
236
+ });
237
+ });
238
+
239
+ test("substrate unset resolves to explicitly-set v2 values", () => {
240
+ const memory = MemoryConfigSchema.parse({
241
+ v2: {
242
+ sweep_enabled: true,
243
+ consolidation_interval_hours: 3,
244
+ consolidation_max_buffer_lines: null,
245
+ bm25_b: 0.9,
246
+ },
247
+ });
248
+ const tuning = resolveSubstrateTuning(memory);
249
+ expect(tuning.sweep_enabled).toBe(true);
250
+ expect(tuning.consolidation_interval_hours).toBe(3);
251
+ expect(tuning.consolidation_max_buffer_lines).toBeNull();
252
+ expect(tuning.bm25_b).toBe(0.9);
253
+ });
254
+
255
+ test("a set substrate key wins over the v2 twin", () => {
256
+ const memory = MemoryConfigSchema.parse({
257
+ v2: {
258
+ consolidation_interval_hours: 3,
259
+ max_page_chars: 4000,
260
+ sweep_enabled: true,
261
+ },
262
+ substrate: {
263
+ consolidation_interval_hours: 12,
264
+ max_page_chars: 9000,
265
+ sweep_enabled: false,
266
+ },
267
+ });
268
+ const tuning = resolveSubstrateTuning(memory);
269
+ expect(tuning.consolidation_interval_hours).toBe(12);
270
+ expect(tuning.max_page_chars).toBe(9000);
271
+ expect(tuning.sweep_enabled).toBe(false);
272
+ });
273
+
274
+ test("spread_k / spread_hops map onto memory.v2.k / memory.v2.hops", () => {
275
+ const fallback = resolveSubstrateTuning(
276
+ MemoryConfigSchema.parse({ v2: { k: 0.7, hops: 4 } }),
277
+ );
278
+ expect(fallback.spread_k).toBe(0.7);
279
+ expect(fallback.spread_hops).toBe(4);
280
+
281
+ const overridden = resolveSubstrateTuning(
282
+ MemoryConfigSchema.parse({
283
+ v2: { k: 0.7, hops: 4 },
284
+ substrate: { spread_k: 0.2, spread_hops: 1 },
285
+ }),
286
+ );
287
+ expect(overridden.spread_k).toBe(0.2);
288
+ expect(overridden.spread_hops).toBe(1);
289
+ });
290
+
291
+ test("an explicit substrate null wins over a non-null v2 value", () => {
292
+ const memory = MemoryConfigSchema.parse({
293
+ v2: {
294
+ ann_candidate_limit: 500,
295
+ consolidation_max_entries_per_run: 50,
296
+ },
297
+ substrate: {
298
+ ann_candidate_limit: null,
299
+ consolidation_max_entries_per_run: null,
300
+ },
301
+ });
302
+ const tuning = resolveSubstrateTuning(memory);
303
+ expect(tuning.ann_candidate_limit).toBeNull();
304
+ expect(tuning.consolidation_max_entries_per_run).toBeNull();
305
+ });
306
+ });
@@ -68,7 +68,7 @@ describe("AssistantConfigSchema", () => {
68
68
  expect(result.services["image-generation"].model).toBe(
69
69
  "gemini-3.1-flash-image-preview",
70
70
  );
71
- expect(result.services["image-generation"].mode).toBe("your-own");
71
+ expect(result.services["image-generation"]).not.toHaveProperty("mode");
72
72
  expect(result.services["web-search"].provider).toBe(
73
73
  "inference-provider-native",
74
74
  );
@@ -99,6 +99,17 @@ describe("AssistantConfigSchema", () => {
99
99
  expect(result.auditLog).toEqual({ retentionDays: 0 });
100
100
  });
101
101
 
102
+ test("accepts vellum as an image generation provider", () => {
103
+ const result = AssistantConfigSchema.parse({
104
+ services: {
105
+ "image-generation": { provider: "vellum", model: "gpt-image-2" },
106
+ },
107
+ });
108
+
109
+ expect(result.services["image-generation"].provider).toBe("vellum");
110
+ expect(result.services["image-generation"].model).toBe("gpt-image-2");
111
+ });
112
+
102
113
  test("accepts Tavily as a web search provider", () => {
103
114
  const result = AssistantConfigSchema.parse({
104
115
  services: {
@@ -928,11 +939,12 @@ describe("AssistantConfigSchema", () => {
928
939
  endpointMaxExtensions: 2,
929
940
  ackFirstDeltaTimeoutMs: 2500,
930
941
  ackGenerationTimeoutMs: 600,
931
- llmAckText: false,
932
942
  progress: {
933
943
  enabled: true,
934
944
  opsThreshold: 3,
935
945
  idleIntervalMs: 5000,
946
+ maxSilenceMs: 35000,
947
+ longOpMs: 15000,
936
948
  minGapMs: 6000,
937
949
  generationTimeoutMs: 1500,
938
950
  },
@@ -174,8 +174,10 @@ describe("config set - platform connection guard for service mode paths", () =>
174
174
  mockIpcResult = { ok: true, result: { ok: true } };
175
175
  });
176
176
 
177
- test("config set services.image-generation.mode your-own - succeeds without platform connection", async () => {
178
- const { exitCode } = await runCli([
177
+ test("config set services.image-generation.mode - rejected with provider guidance, no IPC write emitted", async () => {
178
+ // The image-generation schema has no mode field; a raw write would be
179
+ // stripped at parse while the CLI reported success.
180
+ const { exitCode, stdout } = await runCli([
179
181
  "node",
180
182
  "assistant",
181
183
  "--json",
@@ -185,16 +187,13 @@ describe("config set - platform connection guard for service mode paths", () =>
185
187
  "your-own",
186
188
  ]);
187
189
 
188
- expect(exitCode).toBe(0);
189
- // The CLI should have emitted exactly one config_set IPC call.
190
- const setCalls = mockIpcCalls.filter((c) => c.method === "config_set");
191
- expect(setCalls).toHaveLength(1);
192
- expect(setCalls[0]!.params).toEqual({
193
- body: {
194
- path: "services.image-generation.mode",
195
- value: "your-own",
196
- },
197
- });
190
+ expect(exitCode).toBe(1);
191
+ const parsed = JSON.parse(stdout);
192
+ expect(parsed.ok).toBe(false);
193
+ expect(parsed.error).toContain("services.image-generation.provider vellum");
194
+ expect(mockIpcCalls.filter((c) => c.method === "config_set")).toHaveLength(
195
+ 0,
196
+ );
198
197
  });
199
198
 
200
199
  test("config set calls.enabled true - succeeds without platform connection and parses to boolean", async () => {