@vellumai/assistant 0.10.2-dev.202606250318.5e7cfb0 → 0.10.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 (430) hide show
  1. package/bun.lock +0 -20
  2. package/docs/workspace-tools.md +33 -42
  3. package/eslint-rules/cli-no-daemon-internals.js +0 -6
  4. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +0 -31
  5. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +0 -44
  6. package/node_modules/@vellumai/gateway-client/src/index.ts +0 -14
  7. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +0 -17
  8. package/node_modules/@vellumai/service-contracts/package.json +0 -1
  9. package/node_modules/@vellumai/service-contracts/src/index.ts +0 -1
  10. package/openapi.yaml +0 -155
  11. package/package.json +1 -4
  12. package/scripts/test.sh +15 -36
  13. package/src/__tests__/actor-token-service.test.ts +14 -36
  14. package/src/__tests__/agent-loop-override-profile.test.ts +0 -1
  15. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -2
  16. package/src/__tests__/agent-wake-override-profile.test.ts +0 -2
  17. package/src/__tests__/annotate-activity-metadata.test.ts +0 -2
  18. package/src/__tests__/annotate-risk-options.test.ts +0 -2
  19. package/src/__tests__/approval-cascade.test.ts +0 -2
  20. package/src/__tests__/assistant-attachments.test.ts +0 -42
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
  22. package/src/__tests__/btw-routes.test.ts +0 -2
  23. package/src/__tests__/build-persisted-content.test.ts +0 -2
  24. package/src/__tests__/call-controller.test.ts +0 -19
  25. package/src/__tests__/channel-guardian.test.ts +58 -94
  26. package/src/__tests__/channel-reply-delivery.test.ts +0 -2
  27. package/src/__tests__/compaction-events.test.ts +0 -2
  28. package/src/__tests__/compaction.benchmark.test.ts +0 -2
  29. package/src/__tests__/compactor-call-site-logging.test.ts +0 -2
  30. package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -2
  31. package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -2
  32. package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -2
  33. package/src/__tests__/compactor-web-search-strip.test.ts +0 -2
  34. package/src/__tests__/config-loader-backfill.test.ts +10 -123
  35. package/src/__tests__/config-schema.test.ts +0 -1
  36. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -31
  37. package/src/__tests__/contacts-relay-reads.test.ts +15 -13
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -2
  39. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +0 -2
  40. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -2
  41. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
  42. package/src/__tests__/conversation-agent-loop.test.ts +0 -134
  43. package/src/__tests__/conversation-analysis-routes.test.ts +0 -2
  44. package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -2
  45. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -2
  46. package/src/__tests__/conversation-history-web-search.test.ts +0 -2
  47. package/src/__tests__/conversation-load-history-repair.test.ts +0 -2
  48. package/src/__tests__/conversation-load-history-stripped.test.ts +0 -2
  49. package/src/__tests__/conversation-pairing.test.ts +0 -2
  50. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +0 -2
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -2
  53. package/src/__tests__/conversation-queue.test.ts +0 -91
  54. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -14
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +0 -14
  56. package/src/__tests__/conversation-slash-queue.test.ts +0 -2
  57. package/src/__tests__/conversation-slash-unknown.test.ts +0 -2
  58. package/src/__tests__/conversation-speed-override.test.ts +0 -2
  59. package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -29
  60. package/src/__tests__/conversation-title-service.test.ts +0 -2
  61. package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -47
  62. package/src/__tests__/conversation-usage.test.ts +0 -2
  63. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -2
  64. package/src/__tests__/conversation-workspace-injection.test.ts +0 -2
  65. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -2
  66. package/src/__tests__/credential-security-invariants.test.ts +1 -1
  67. package/src/__tests__/db-migration-rollback.test.ts +171 -205
  68. package/src/__tests__/db-test-helpers.ts +4 -5
  69. package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -4
  70. package/src/__tests__/disk-pressure-guard.test.ts +0 -41
  71. package/src/__tests__/dm-persistence.test.ts +0 -2
  72. package/src/__tests__/emit-signal-routing-intent.test.ts +5 -10
  73. package/src/__tests__/events-dev-bypass-actor.test.ts +1 -7
  74. package/src/__tests__/exploration-drift-hook.test.ts +2 -3
  75. package/src/__tests__/filing-service.test.ts +0 -2
  76. package/src/__tests__/guardian-binding-drift-heal.test.ts +10 -75
  77. package/src/__tests__/guardian-dispatch.test.ts +1 -95
  78. package/src/__tests__/guardian-outbound-http.test.ts +0 -13
  79. package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -2
  80. package/src/__tests__/heartbeat-service.test.ts +0 -2
  81. package/src/__tests__/helpers/channel-test-adapter.ts +7 -1
  82. package/src/__tests__/host-app-control-routes.test.ts +30 -24
  83. package/src/__tests__/host-bash-routes.test.ts +41 -31
  84. package/src/__tests__/host-browser-routes.test.ts +32 -26
  85. package/src/__tests__/host-cu-routes-targeted.test.ts +33 -25
  86. package/src/__tests__/host-file-routes-targeted.test.ts +52 -40
  87. package/src/__tests__/host-transfer-routes-targeted.test.ts +43 -31
  88. package/src/__tests__/http-user-message-parity.test.ts +8 -290
  89. package/src/__tests__/inbound-invite-redemption.test.ts +0 -28
  90. package/src/__tests__/inbound-slack-persistence.test.ts +0 -2
  91. package/src/__tests__/invite-redemption-service.test.ts +0 -198
  92. package/src/__tests__/llm-context-normalization.test.ts +0 -105
  93. package/src/__tests__/llm-request-log-error-payload.test.ts +9 -71
  94. package/src/__tests__/llm-usage-store.test.ts +0 -25
  95. package/src/__tests__/mcp-health-check.test.ts +1 -2
  96. package/src/__tests__/media-stream-server-integration.test.ts +0 -127
  97. package/src/__tests__/memory-retrieval-hook.test.ts +0 -2
  98. package/src/__tests__/messaging-send-tool.test.ts +0 -2
  99. package/src/__tests__/migration-import-from-url.test.ts +2 -2
  100. package/src/__tests__/mtime-cache.test.ts +5 -146
  101. package/src/__tests__/native-web-search.test.ts +0 -2
  102. package/src/__tests__/non-member-access-request.test.ts +17 -189
  103. package/src/__tests__/notification-broadcaster.test.ts +0 -4
  104. package/src/__tests__/notification-decision-recipient-context.test.ts +32 -33
  105. package/src/__tests__/notification-deep-link.test.ts +0 -6
  106. package/src/__tests__/notification-guardian-path.test.ts +0 -19
  107. package/src/__tests__/openai-provider.test.ts +12 -22
  108. package/src/__tests__/openai-responses-provider.test.ts +2 -12
  109. package/src/__tests__/outbound-slack-persistence.test.ts +0 -2
  110. package/src/__tests__/pending-interactions-resolved-event.test.ts +4 -7
  111. package/src/__tests__/persistence-secret-redaction.test.ts +0 -2
  112. package/src/__tests__/plugin-bootstrap.test.ts +73 -3
  113. package/src/__tests__/plugin-route-contribution.test.ts +17 -4
  114. package/src/__tests__/plugin-tool-contribution.test.ts +18 -3
  115. package/src/__tests__/plugin-types.test.ts +2 -0
  116. package/src/__tests__/process-message-background-slack.test.ts +0 -2
  117. package/src/__tests__/process-message-display-content.test.ts +0 -2
  118. package/src/__tests__/provider-error-scenarios.test.ts +4 -5
  119. package/src/__tests__/provider-usage-tracking.test.ts +0 -39
  120. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -2
  121. package/src/__tests__/registry.test.ts +1 -4
  122. package/src/__tests__/relay-server.test.ts +25 -694
  123. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -0
  124. package/src/__tests__/secret-ingress-http.test.ts +0 -14
  125. package/src/__tests__/send-endpoint-busy.test.ts +8 -30
  126. package/src/__tests__/skills.test.ts +0 -44
  127. package/src/__tests__/slack-inbound-verification.test.ts +2 -47
  128. package/src/__tests__/stt-hints.test.ts +13 -44
  129. package/src/__tests__/subagent-detail.test.ts +0 -27
  130. package/src/__tests__/subagent-disposal.test.ts +0 -65
  131. package/src/__tests__/subagent-notify-parent.test.ts +0 -2
  132. package/src/__tests__/subagent-role-registry.test.ts +2 -7
  133. package/src/__tests__/subagent-spawn-tool-fork.test.ts +0 -2
  134. package/src/__tests__/subagent-tools.test.ts +0 -2
  135. package/src/__tests__/suggestion-routes.test.ts +0 -2
  136. package/src/__tests__/title-generate-hook.test.ts +0 -2
  137. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -2
  138. package/src/__tests__/tool-executor.test.ts +11 -16
  139. package/src/__tests__/tool-preview-lifecycle.test.ts +0 -2
  140. package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -2
  141. package/src/__tests__/tool-start-timestamp.test.ts +0 -2
  142. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
  143. package/src/__tests__/twilio-routes.test.ts +0 -96
  144. package/src/__tests__/ui-file-upload-surface.test.ts +0 -86
  145. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  146. package/src/__tests__/voice-invite-redemption.test.ts +0 -33
  147. package/src/__tests__/web-search-backend-failure.test.ts +0 -2
  148. package/src/__tests__/workspace-migration-remove-hooks.test.ts +35 -14
  149. package/src/__tests__/workspace-tool-loader.test.ts +2 -195
  150. package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
  151. package/src/agent/loop.ts +0 -56
  152. package/src/api/index.ts +1 -19
  153. package/src/api/responses/llm-request-log-entry.ts +0 -29
  154. package/src/api/responses/subagent-detail.ts +0 -17
  155. package/src/api/surfaces.ts +3 -39
  156. package/src/approvals/guardian-request-resolvers.ts +11 -1
  157. package/src/calls/__tests__/relay-setup-router.test.ts +4 -262
  158. package/src/calls/call-domain.ts +3 -3
  159. package/src/calls/guardian-dispatch.ts +8 -10
  160. package/src/calls/inbound-trust-reader.ts +1 -17
  161. package/src/calls/media-stream-server.ts +0 -21
  162. package/src/calls/relay-server.ts +50 -167
  163. package/src/calls/relay-setup-router.ts +7 -37
  164. package/src/calls/relay-verification.ts +4 -4
  165. package/src/calls/stt-hints.ts +12 -9
  166. package/src/calls/twilio-routes.ts +4 -14
  167. package/src/channels/types.ts +20 -10
  168. package/src/cli/commands/__tests__/cache.test.ts +1 -8
  169. package/src/cli/commands/cache.ts +181 -194
  170. package/src/cli/commands/db/__tests__/repair.test.ts +5 -6
  171. package/src/cli/commands/db/status.ts +1 -37
  172. package/src/cli/commands/mcp.ts +218 -252
  173. package/src/cli/commands/memory/index.ts +0 -2
  174. package/src/cli/commands/plugins.ts +3 -75
  175. package/src/cli/lib/__tests__/install-from-github.test.ts +0 -102
  176. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +1 -160
  177. package/src/cli/lib/list-installed-plugins.ts +1 -179
  178. package/src/config/__tests__/sync-gated-profiles.test.ts +3 -11
  179. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +17 -27
  180. package/src/config/bundled-skills/contacts/tools/contact-search.ts +3 -13
  181. package/src/config/bundled-skills/subagent/SKILL.md +1 -1
  182. package/src/config/bundled-skills/subagent/TOOLS.json +1 -1
  183. package/src/config/feature-flag-registry.json +13 -5
  184. package/src/config/loader.ts +5 -38
  185. package/src/config/schemas/__tests__/memory-v3.test.ts +0 -1
  186. package/src/config/schemas/memory-lifecycle.ts +0 -12
  187. package/src/config/schemas/memory-v3.ts +0 -7
  188. package/src/config/schemas/memory.ts +0 -4
  189. package/src/config/schemas/timeouts.ts +0 -8
  190. package/src/config/seed-inference-profiles.ts +11 -21
  191. package/src/config/skills.ts +5 -27
  192. package/src/config/sync-gated-profiles.ts +13 -12
  193. package/src/contacts/contacts-write.ts +0 -3
  194. package/src/daemon/assistant-attachments.ts +4 -27
  195. package/src/daemon/conversation-agent-loop.ts +0 -28
  196. package/src/daemon/conversation-process.ts +16 -35
  197. package/src/daemon/conversation-surfaces.ts +38 -111
  198. package/src/daemon/conversation-tool-setup.ts +16 -50
  199. package/src/daemon/conversation.ts +1 -13
  200. package/src/daemon/disk-pressure-guard.ts +2 -12
  201. package/src/daemon/event-loop-watchdog.ts +1 -28
  202. package/src/daemon/external-plugins-bootstrap.ts +34 -4
  203. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -25
  204. package/src/daemon/handlers/config-a2a.ts +14 -6
  205. package/src/daemon/handlers/config-channels.ts +22 -78
  206. package/src/daemon/handlers/conversations.ts +0 -77
  207. package/src/daemon/lifecycle.ts +0 -4
  208. package/src/daemon/mcp-reload-service.ts +0 -10
  209. package/src/daemon/memory-v2-startup.test.ts +0 -72
  210. package/src/daemon/memory-v2-startup.ts +19 -87
  211. package/src/daemon/message-types/conversations.ts +0 -2
  212. package/src/daemon/message-types/surfaces.ts +12 -12
  213. package/src/daemon/server.ts +4 -0
  214. package/src/daemon/shutdown-handlers.ts +0 -20
  215. package/src/daemon/tool-setup-types.ts +0 -9
  216. package/src/daemon/workspace-tools-watcher.ts +328 -0
  217. package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
  218. package/src/ipc/assistant-server.ts +2 -2
  219. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
  220. package/src/mcp/client.ts +1 -15
  221. package/src/mcp/mcp-auth-orchestrator.ts +1 -6
  222. package/src/mcp/mcp-oauth-provider.ts +8 -19
  223. package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -8
  224. package/src/memory/conversation-crud.ts +0 -38
  225. package/src/memory/db-connection.ts +3 -22
  226. package/src/memory/db-init.ts +502 -36
  227. package/src/memory/db-singleton.ts +4 -6
  228. package/src/memory/jobs-worker.ts +0 -58
  229. package/src/memory/llm-request-log-store.ts +1 -26
  230. package/src/memory/llm-usage-store.ts +20 -48
  231. package/src/memory/memory-retrospective-job.ts +8 -9
  232. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +56 -130
  233. package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
  234. package/src/memory/migrations/registry.ts +573 -0
  235. package/src/memory/migrations/run-migrations.ts +6 -90
  236. package/src/memory/migrations/validate-migration-state.ts +66 -101
  237. package/src/memory/schema/conversations.ts +0 -9
  238. package/src/memory/schema/infrastructure.ts +0 -20
  239. package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -25
  240. package/src/memory/v2/__tests__/skill-store.test.ts +0 -80
  241. package/src/memory/v2/cli-command-store.ts +38 -75
  242. package/src/memory/v2/prompts/consolidation.ts +82 -13
  243. package/src/memory/v2/prompts/router.ts +93 -21
  244. package/src/memory/v2/skill-store.ts +31 -68
  245. package/src/notifications/__tests__/broadcaster.test.ts +8 -16
  246. package/src/notifications/__tests__/decision-engine.test.ts +9 -78
  247. package/src/notifications/broadcaster.ts +1 -8
  248. package/src/notifications/decision-engine.ts +7 -15
  249. package/src/notifications/destination-resolver.ts +24 -68
  250. package/src/notifications/emit-signal.ts +14 -39
  251. package/src/permissions/question-prompter.test.ts +1 -1
  252. package/src/permissions/question-prompter.ts +4 -7
  253. package/src/plugin-api/index.ts +6 -6
  254. package/src/plugin-api/types.ts +5 -3
  255. package/src/plugin-api/vision-support.test.ts +4 -28
  256. package/src/plugin-api/vision-support.ts +31 -66
  257. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -161
  258. package/src/plugins/defaults/advisor/consult.ts +6 -110
  259. package/src/plugins/defaults/advisor/steering.ts +2 -14
  260. package/src/plugins/defaults/advisor/tools/advisor.ts +5 -32
  261. package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +1 -2
  262. package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +7 -47
  263. package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +11 -10
  264. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +20 -12
  265. package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +11 -42
  266. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +3 -33
  267. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +4 -48
  268. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +8 -4
  269. package/src/plugins/defaults/memory-v3-shadow/injector.ts +15 -43
  270. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +2 -11
  271. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -77
  272. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +11 -12
  273. package/src/plugins/mtime-cache.ts +291 -76
  274. package/src/plugins/pipeline.ts +13 -111
  275. package/src/plugins/types.ts +2 -0
  276. package/src/providers/anthropic/client.ts +0 -5
  277. package/src/providers/call-site-routing.ts +0 -4
  278. package/src/providers/model-catalog.ts +0 -16
  279. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  280. package/src/providers/openai/chat-completions-provider.ts +83 -37
  281. package/src/providers/openai/responses-provider.ts +46 -50
  282. package/src/providers/openrouter/client.ts +0 -5
  283. package/src/providers/provider-send-message.ts +0 -4
  284. package/src/providers/ratelimit.ts +0 -4
  285. package/src/providers/retry.ts +0 -4
  286. package/src/providers/types.ts +0 -9
  287. package/src/providers/usage-tracking.ts +0 -4
  288. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +3 -335
  289. package/src/runtime/access-request-helper.ts +39 -19
  290. package/src/runtime/actor-trust-resolver.ts +2 -2
  291. package/src/runtime/assistant-event-hub.ts +1 -1
  292. package/src/runtime/assistant-stream-state.ts +2 -9
  293. package/src/runtime/auth/require-bound-guardian.ts +11 -21
  294. package/src/runtime/channel-verification-service.ts +31 -56
  295. package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
  296. package/src/runtime/guardian-vellum-migration.ts +7 -66
  297. package/src/runtime/invite-redemption-service.ts +187 -198
  298. package/src/runtime/local-actor-identity.ts +11 -76
  299. package/src/runtime/pending-interactions.ts +1 -11
  300. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +5 -56
  301. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
  302. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +0 -187
  303. package/src/runtime/routes/browser-routes.ts +1 -1
  304. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -13
  305. package/src/runtime/routes/channel-verification-routes.ts +3 -3
  306. package/src/runtime/routes/contact-routes.ts +32 -8
  307. package/src/runtime/routes/conversation-cli-routes.ts +5 -4
  308. package/src/runtime/routes/conversation-list-routes.ts +7 -4
  309. package/src/runtime/routes/conversation-query-routes.ts +0 -72
  310. package/src/runtime/routes/conversation-routes.ts +85 -84
  311. package/src/runtime/routes/events-routes.ts +2 -2
  312. package/src/runtime/routes/global-search-routes.ts +1 -3
  313. package/src/runtime/routes/guardian-action-routes.ts +5 -4
  314. package/src/runtime/routes/host-app-control-routes.ts +4 -5
  315. package/src/runtime/routes/host-bash-routes.ts +4 -5
  316. package/src/runtime/routes/host-browser-routes.ts +11 -9
  317. package/src/runtime/routes/host-cu-routes.ts +4 -5
  318. package/src/runtime/routes/host-file-routes.ts +4 -5
  319. package/src/runtime/routes/host-transfer-routes.ts +6 -6
  320. package/src/runtime/routes/http-adapter.ts +1 -1
  321. package/src/runtime/routes/identity-routes.ts +2 -3
  322. package/src/runtime/routes/inbound-message-handler.ts +5 -5
  323. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +5 -97
  324. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +49 -61
  325. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -16
  326. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
  327. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +8 -21
  328. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +3 -14
  329. package/src/runtime/routes/index.ts +0 -2
  330. package/src/runtime/routes/llm-context-normalization.ts +0 -83
  331. package/src/runtime/routes/mcp-auth-routes.ts +19 -171
  332. package/src/runtime/routes/migration-rollback-routes.ts +3 -4
  333. package/src/runtime/routes/migration-routes.ts +1 -4
  334. package/src/runtime/routes/subagents-routes.ts +0 -5
  335. package/src/runtime/routes/surface-action-routes.ts +56 -42
  336. package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -1
  337. package/src/runtime/services/conversation-serializer.ts +9 -7
  338. package/src/runtime/tool-grant-request-helper.ts +3 -3
  339. package/src/runtime/trust-verdict-consumer.ts +9 -85
  340. package/src/runtime/verification-outbound-actions.ts +18 -18
  341. package/src/signals/user-message.ts +0 -16
  342. package/src/subagent/manager.ts +0 -9
  343. package/src/subagent/types.ts +3 -3
  344. package/src/telemetry/types.ts +1 -34
  345. package/src/telemetry/usage-telemetry-reporter.test.ts +2 -3
  346. package/src/telemetry/usage-telemetry-reporter.ts +3 -87
  347. package/src/tools/ask-question/ask-question-tool.test.ts +0 -29
  348. package/src/tools/ask-question/ask-question-tool.ts +0 -13
  349. package/src/tools/executor.ts +4 -4
  350. package/src/tools/registry.ts +0 -18
  351. package/src/tools/shared/filesystem/path-policy.ts +5 -12
  352. package/src/tools/tool-approval-handler.ts +1 -1
  353. package/src/tools/tool-defaults.ts +2 -9
  354. package/src/tools/tool-manifest.ts +0 -3
  355. package/src/tools/types.ts +2 -17
  356. package/src/tools/workspace-tools/loader.ts +244 -348
  357. package/src/util/errors.ts +1 -26
  358. package/src/util/platform.ts +0 -5
  359. package/src/workflows/library.test.ts +0 -140
  360. package/src/workflows/library.ts +28 -82
  361. package/src/workspace/migrations/017-seed-persona-dirs.ts +34 -3
  362. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +24 -3
  363. package/src/workspace/migrations/048-remove-workspace-hooks.ts +66 -14
  364. package/src/workspace/migrations/registry.ts +0 -2
  365. package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +0 -91
  366. package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +0 -48
  367. package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +0 -28
  368. package/node_modules/@vellumai/service-contracts/src/channels.ts +0 -41
  369. package/src/__tests__/code-search-tool.test.ts +0 -585
  370. package/src/__tests__/guardian-expiry-notifier.test.ts +0 -282
  371. package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -390
  372. package/src/__tests__/plugin-pipeline.test.ts +0 -96
  373. package/src/__tests__/sse-actor-principal-guardian-source.test.ts +0 -102
  374. package/src/__tests__/steer-on-enqueue-question.test.ts +0 -181
  375. package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +0 -208
  376. package/src/agent/loop-exclusive-tool.test.ts +0 -150
  377. package/src/api/constants/sse-replay.ts +0 -41
  378. package/src/api/events/conversation-notice.ts +0 -26
  379. package/src/approvals/guardian-channel-delivery.ts +0 -30
  380. package/src/approvals/guardian-expiry-notifier.ts +0 -148
  381. package/src/cli/commands/memory/__tests__/worker.test.ts +0 -302
  382. package/src/cli/commands/memory/worker.ts +0 -175
  383. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -143
  384. package/src/config/prune-seeded-callsite-defaults.ts +0 -110
  385. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -129
  386. package/src/contacts/__tests__/guardian-delivery-reader.test.ts +0 -312
  387. package/src/contacts/__tests__/member-write-relay.test.ts +0 -202
  388. package/src/contacts/guardian-delivery-reader.ts +0 -223
  389. package/src/contacts/member-write-relay.ts +0 -189
  390. package/src/daemon/conversation-notices.ts +0 -60
  391. package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -225
  392. package/src/hooks/hook-loader.ts +0 -341
  393. package/src/mcp/mcp-header-store.ts +0 -134
  394. package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
  395. package/src/memory/__tests__/prompt-override.test.ts +0 -192
  396. package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
  397. package/src/memory/migrations/300-add-processing-started-at.ts +0 -30
  398. package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
  399. package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
  400. package/src/memory/prompt-override.ts +0 -129
  401. package/src/memory/steps.ts +0 -573
  402. package/src/memory/watchdog-events-store.ts +0 -87
  403. package/src/memory/worker-control.ts +0 -118
  404. package/src/memory/worker-process.ts +0 -72
  405. package/src/notifications/__tests__/connected-channels.test.ts +0 -114
  406. package/src/notifications/__tests__/destination-resolver.test.ts +0 -256
  407. package/src/onboarding/checkin-event.test.ts +0 -222
  408. package/src/onboarding/checkin-event.ts +0 -321
  409. package/src/onboarding/schedule-checkin.ts +0 -190
  410. package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
  411. package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
  412. package/src/plugins/defaults/advisor/context-pack.ts +0 -288
  413. package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
  414. package/src/plugins/surface-import.ts +0 -121
  415. package/src/providers/openai/__tests__/api-error-normalization.test.ts +0 -321
  416. package/src/providers/openai/api-error-normalization.ts +0 -270
  417. package/src/runtime/__tests__/channel-verification-service.test.ts +0 -133
  418. package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -181
  419. package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +0 -66
  420. package/src/runtime/__tests__/local-principal-trust.test.ts +0 -164
  421. package/src/runtime/anchored-guardian.test.ts +0 -156
  422. package/src/runtime/anchored-guardian.ts +0 -135
  423. package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +0 -99
  424. package/src/runtime/local-principal-trust.ts +0 -52
  425. package/src/runtime/routes/__tests__/contact-routes.test.ts +0 -212
  426. package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -93
  427. package/src/runtime/routes/onboarding-checkin-routes.ts +0 -86
  428. package/src/tools/filesystem/search.ts +0 -543
  429. package/src/util/telemetry-db-path.ts +0 -24
  430. package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +0 -134
@@ -61,36 +61,6 @@ mock.module("../runtime/gateway-client.js", () => ({
61
61
  },
62
62
  }));
63
63
 
64
- // Guardian identity for the access request resolves via the gateway delivery
65
- // reader, not the local contacts DB. Seed it per-test via seedGatewayGuardian.
66
- interface GatewayGuardian {
67
- channelType: string;
68
- contactId: string;
69
- principalId?: string | null;
70
- displayName?: string | null;
71
- address: string;
72
- externalChatId?: string | null;
73
- status: string;
74
- verifiedAt?: number | null;
75
- }
76
- let gatewayGuardians: GatewayGuardian[] = [];
77
- mock.module("../contacts/guardian-delivery-reader.js", () => ({
78
- getGuardianDelivery: async () => gatewayGuardians,
79
- guardianForChannel: (list: GatewayGuardian[], channelType: string) =>
80
- list.find((g) => g.channelType === channelType && g.status === "active"),
81
- }));
82
-
83
- function seedGatewayGuardian(g: Partial<GatewayGuardian> & {
84
- channelType: string;
85
- address: string;
86
- }): void {
87
- gatewayGuardians.push({
88
- contactId: `c-${g.channelType}`,
89
- status: "active",
90
- ...g,
91
- });
92
- }
93
-
94
64
  import {
95
65
  listCanonicalGuardianDeliveries,
96
66
  listCanonicalGuardianRequests,
@@ -125,7 +95,6 @@ function resetState(): string {
125
95
  db.run("DELETE FROM contacts");
126
96
  emitSignalCalls.length = 0;
127
97
  deliverReplyCalls.length = 0;
128
- gatewayGuardians = [];
129
98
  mockEmitResult = {
130
99
  signalId: "mock-signal-id",
131
100
  deduplicated: false,
@@ -133,15 +102,8 @@ function resetState(): string {
133
102
  reason: "mock",
134
103
  deliveryResults: [],
135
104
  };
136
- // Seed the vellum anchor binding in the gateway list (gateway does this at
137
- // startup in production). The DB write mirrors it for any local INFO reads.
105
+ // Seed the vellum anchor binding (gateway does this at startup in production)
138
106
  const principalId = `vellum-principal-${crypto.randomUUID()}`;
139
- seedGatewayGuardian({
140
- channelType: "vellum",
141
- address: principalId,
142
- principalId,
143
- displayName: principalId,
144
- });
145
107
  createGuardianBinding({
146
108
  channel: "vellum",
147
109
  guardianExternalUserId: principalId,
@@ -210,12 +172,6 @@ describe("non-member access request notification", () => {
210
172
 
211
173
  test("guardian is notified when a non-member messages and a guardian binding exists", async () => {
212
174
  // Set up a guardian binding for this channel using the anchor principal
213
- seedGatewayGuardian({
214
- channelType: "telegram",
215
- address: "guardian-user-789",
216
- externalChatId: "guardian-chat-789",
217
- principalId: anchorPrincipalId,
218
- });
219
175
  createGuardianBinding({
220
176
  channel: "telegram",
221
177
  guardianExternalUserId: "guardian-user-789",
@@ -261,12 +217,6 @@ describe("non-member access request notification", () => {
261
217
  });
262
218
 
263
219
  test("no duplicate approval requests for repeated messages from same non-member", async () => {
264
- seedGatewayGuardian({
265
- channelType: "telegram",
266
- address: "guardian-user-789",
267
- externalChatId: "guardian-chat-789",
268
- principalId: anchorPrincipalId,
269
- });
270
220
  createGuardianBinding({
271
221
  channel: "telegram",
272
222
  guardianExternalUserId: "guardian-user-789",
@@ -339,12 +289,6 @@ describe("non-member access request notification", () => {
339
289
  // Only a voice guardian binding exists — no Telegram binding.
340
290
  // Since cross-channel fallback was removed, the access request resolves
341
291
  // to the assistant's vellum anchor identity instead.
342
- seedGatewayGuardian({
343
- channelType: "phone",
344
- address: "guardian-voice-user",
345
- externalChatId: "guardian-voice-chat",
346
- principalId: anchorPrincipalId,
347
- });
348
292
  createGuardianBinding({
349
293
  channel: "phone",
350
294
  guardianExternalUserId: "guardian-voice-user",
@@ -407,8 +351,8 @@ describe("access-request-helper unit tests", () => {
407
351
  anchorPrincipalId = resetState();
408
352
  });
409
353
 
410
- test("notifyGuardianOfAccessRequest returns no_sender_id when actorExternalId is absent", async () => {
411
- const result = await notifyGuardianOfAccessRequest({
354
+ test("notifyGuardianOfAccessRequest returns no_sender_id when actorExternalId is absent", () => {
355
+ const result = notifyGuardianOfAccessRequest({
412
356
  canonicalAssistantId: "self",
413
357
  sourceChannel: "telegram",
414
358
  conversationExternalId: "chat-123",
@@ -428,8 +372,8 @@ describe("access-request-helper unit tests", () => {
428
372
  expect(pending.length).toBe(0);
429
373
  });
430
374
 
431
- test("notifyGuardianOfAccessRequest creates request with self-healed principal when no binding exists", async () => {
432
- const result = await notifyGuardianOfAccessRequest({
375
+ test("notifyGuardianOfAccessRequest creates request with self-healed principal when no binding exists", () => {
376
+ const result = notifyGuardianOfAccessRequest({
433
377
  canonicalAssistantId: "self",
434
378
  sourceChannel: "telegram",
435
379
  conversationExternalId: "chat-123",
@@ -456,14 +400,8 @@ describe("access-request-helper unit tests", () => {
456
400
  expect(emitSignalCalls.length).toBe(1);
457
401
  });
458
402
 
459
- test("notifyGuardianOfAccessRequest falls back to assistant-anchored vellum identity when source-channel binding is missing", async () => {
403
+ test("notifyGuardianOfAccessRequest falls back to assistant-anchored vellum identity when source-channel binding is missing", () => {
460
404
  // Only voice binding exists
461
- seedGatewayGuardian({
462
- channelType: "phone",
463
- address: "guardian-voice",
464
- externalChatId: "voice-chat",
465
- principalId: "test-principal-id",
466
- });
467
405
  createGuardianBinding({
468
406
  channel: "phone",
469
407
  guardianExternalUserId: "guardian-voice",
@@ -472,7 +410,7 @@ describe("access-request-helper unit tests", () => {
472
410
  verifiedVia: "test",
473
411
  });
474
412
 
475
- const result = await notifyGuardianOfAccessRequest({
413
+ const result = notifyGuardianOfAccessRequest({
476
414
  canonicalAssistantId: "self",
477
415
  sourceChannel: "telegram",
478
416
  conversationExternalId: "tg-chat",
@@ -497,20 +435,8 @@ describe("access-request-helper unit tests", () => {
497
435
  expect(payload.guardianBindingChannel).toBe("vellum");
498
436
  });
499
437
 
500
- test("notifyGuardianOfAccessRequest prefers source-channel binding over vellum anchor", async () => {
438
+ test("notifyGuardianOfAccessRequest prefers source-channel binding over vellum anchor", () => {
501
439
  // Both Telegram and voice bindings exist with the anchor principal
502
- seedGatewayGuardian({
503
- channelType: "telegram",
504
- address: "guardian-tg",
505
- externalChatId: "tg-chat",
506
- principalId: anchorPrincipalId,
507
- });
508
- seedGatewayGuardian({
509
- channelType: "phone",
510
- address: "guardian-voice",
511
- externalChatId: "voice-chat",
512
- principalId: anchorPrincipalId,
513
- });
514
440
  createGuardianBinding({
515
441
  channel: "telegram",
516
442
  guardianExternalUserId: "guardian-tg",
@@ -526,7 +452,7 @@ describe("access-request-helper unit tests", () => {
526
452
  verifiedVia: "test",
527
453
  });
528
454
 
529
- const result = await notifyGuardianOfAccessRequest({
455
+ const result = notifyGuardianOfAccessRequest({
530
456
  canonicalAssistantId: "self",
531
457
  sourceChannel: "telegram",
532
458
  conversationExternalId: "chat-123",
@@ -551,100 +477,8 @@ describe("access-request-helper unit tests", () => {
551
477
  expect(payload.guardianBindingChannel).toBe("telegram");
552
478
  });
553
479
 
554
- test("notifyGuardianOfAccessRequest falls back to local source-channel binding when gateway delivery is empty", async () => {
555
- // Gateway delivery read yields nothing (restart/timeout/malformed IPC).
556
- gatewayGuardians = [];
557
- // Local dual-written mirror still has the vellum anchor + telegram binding.
558
- createGuardianBinding({
559
- channel: "telegram",
560
- guardianExternalUserId: "guardian-tg",
561
- guardianDeliveryChatId: "tg-chat",
562
- guardianPrincipalId: anchorPrincipalId,
563
- verifiedVia: "test",
564
- });
565
-
566
- const result = await notifyGuardianOfAccessRequest({
567
- canonicalAssistantId: "self",
568
- sourceChannel: "telegram",
569
- conversationExternalId: "chat-123",
570
- actorExternalId: "unknown-user",
571
- });
572
-
573
- expect(result.notified).toBe(true);
574
-
575
- const pending = listCanonicalGuardianRequests({
576
- status: "pending",
577
- requesterExternalUserId: "unknown-user",
578
- kind: "access_request",
579
- });
580
- expect(pending.length).toBe(1);
581
- // Request is decidable: local read supplied the principal + source binding.
582
- expect(pending[0].guardianPrincipalId).toBe(anchorPrincipalId);
583
- expect(pending[0].guardianExternalUserId).toBe("guardian-tg");
584
-
585
- const payload = emitSignalCalls[0].contextPayload as Record<
586
- string,
587
- unknown
588
- >;
589
- expect(payload.guardianBindingChannel).toBe("telegram");
590
- });
591
-
592
- test("notifyGuardianOfAccessRequest falls back to local vellum anchor when gateway delivery is empty", async () => {
593
- // Gateway empty; only the local vellum anchor from resetState remains.
594
- gatewayGuardians = [];
595
-
596
- const result = await notifyGuardianOfAccessRequest({
597
- canonicalAssistantId: "self",
598
- sourceChannel: "telegram",
599
- conversationExternalId: "chat-123",
600
- actorExternalId: "unknown-user",
601
- });
602
-
603
- expect(result.notified).toBe(true);
604
-
605
- const pending = listCanonicalGuardianRequests({
606
- status: "pending",
607
- requesterExternalUserId: "unknown-user",
608
- kind: "access_request",
609
- });
610
- expect(pending.length).toBe(1);
611
- // Decidable via the local vellum anchor principal.
612
- expect(pending[0].guardianPrincipalId).toBe(anchorPrincipalId);
613
-
614
- const payload = emitSignalCalls[0].contextPayload as Record<
615
- string,
616
- unknown
617
- >;
618
- expect(payload.guardianBindingChannel).toBe("vellum");
619
- });
620
-
621
- test("notifyGuardianOfAccessRequest does not create a decisionable request when both gateway and local reads are empty", async () => {
622
- // Genuinely unbound assistant: gateway empty AND no local binding. Prior
623
- // behavior rejects creation of a decisionable request without a principal.
624
- gatewayGuardians = [];
625
- const db = getDb();
626
- db.run("DELETE FROM contact_channels");
627
- db.run("DELETE FROM contacts");
628
-
629
- await expect(
630
- notifyGuardianOfAccessRequest({
631
- canonicalAssistantId: "self",
632
- sourceChannel: "telegram",
633
- conversationExternalId: "chat-123",
634
- actorExternalId: "unknown-user",
635
- }),
636
- ).rejects.toThrow();
637
-
638
- const pending = listCanonicalGuardianRequests({
639
- status: "pending",
640
- requesterExternalUserId: "unknown-user",
641
- kind: "access_request",
642
- });
643
- expect(pending.length).toBe(0);
644
- });
645
-
646
- test("notifyGuardianOfAccessRequest for voice channel includes actorDisplayName in contextPayload", async () => {
647
- const result = await notifyGuardianOfAccessRequest({
480
+ test("notifyGuardianOfAccessRequest for voice channel includes actorDisplayName in contextPayload", () => {
481
+ const result = notifyGuardianOfAccessRequest({
648
482
  canonicalAssistantId: "self",
649
483
  sourceChannel: "phone",
650
484
  conversationExternalId: "+15559998888",
@@ -674,8 +508,8 @@ describe("access-request-helper unit tests", () => {
674
508
  expect(pending.length).toBe(1);
675
509
  });
676
510
 
677
- test("notifyGuardianOfAccessRequest includes requestCode in contextPayload", async () => {
678
- const result = await notifyGuardianOfAccessRequest({
511
+ test("notifyGuardianOfAccessRequest includes requestCode in contextPayload", () => {
512
+ const result = notifyGuardianOfAccessRequest({
679
513
  canonicalAssistantId: "self",
680
514
  sourceChannel: "telegram",
681
515
  conversationExternalId: "chat-123",
@@ -695,8 +529,8 @@ describe("access-request-helper unit tests", () => {
695
529
  expect((payload.requestCode as string).length).toBe(6);
696
530
  });
697
531
 
698
- test("notifyGuardianOfAccessRequest includes previousMemberStatus in contextPayload", async () => {
699
- const result = await notifyGuardianOfAccessRequest({
532
+ test("notifyGuardianOfAccessRequest includes previousMemberStatus in contextPayload", () => {
533
+ const result = notifyGuardianOfAccessRequest({
700
534
  canonicalAssistantId: "self",
701
535
  sourceChannel: "telegram",
702
536
  conversationExternalId: "chat-123",
@@ -736,7 +570,7 @@ describe("access-request-helper unit tests", () => {
736
570
  ],
737
571
  };
738
572
 
739
- const result = await notifyGuardianOfAccessRequest({
573
+ const result = notifyGuardianOfAccessRequest({
740
574
  canonicalAssistantId: "self",
741
575
  sourceChannel: "phone",
742
576
  conversationExternalId: "+15556667777",
@@ -769,12 +603,6 @@ describe("access-request-helper unit tests", () => {
769
603
  // Set up a telegram guardian binding with the anchor principal so
770
604
  // guardianResolutionSource resolves to "source-channel-contact" and
771
605
  // sameChannelOnly is true.
772
- seedGatewayGuardian({
773
- channelType: "telegram",
774
- address: "guardian-user-456",
775
- externalChatId: "guardian-chat-456",
776
- principalId: anchorPrincipalId,
777
- });
778
606
  createGuardianBinding({
779
607
  channel: "telegram",
780
608
  guardianExternalUserId: "guardian-user-456",
@@ -797,7 +625,7 @@ describe("access-request-helper unit tests", () => {
797
625
  ],
798
626
  };
799
627
 
800
- const result = await notifyGuardianOfAccessRequest({
628
+ const result = notifyGuardianOfAccessRequest({
801
629
  canonicalAssistantId: "self",
802
630
  sourceChannel: "telegram",
803
631
  conversationExternalId: "chat-123",
@@ -24,10 +24,6 @@ mock.module("../util/logger.js", () => ({
24
24
  }),
25
25
  }));
26
26
 
27
- mock.module("../contacts/guardian-delivery-reader.js", () => ({
28
- getGuardianDelivery: async () => null,
29
- }));
30
-
31
27
  // Mock destination-resolver to return a destination for every requested channel.
32
28
  // External channels (telegram, slack) include bindingContext.
33
29
  mock.module("../notifications/destination-resolver.js", () => ({
@@ -36,36 +36,17 @@ mock.module("../prompts/system-prompt.js", () => ({
36
36
  buildCoreIdentityContext: () => null,
37
37
  }));
38
38
 
39
- // ── Guardian binding + contact notes mocks ───────────────────────────
39
+ // ── Guardian contact mock ────────────────────────────────────────────
40
40
 
41
- // Guardian binding (ACL) is resolved via the gateway pull; notes (INFO) are
42
- // joined locally by contactId. Tests drive both via mutable slots.
43
- let guardianDeliveryFixture: Array<{ contactId: string }> = [];
44
- let contactInfoFixture: Record<string, { notes: string | null } | null> = {};
45
-
46
- mock.module("../contacts/guardian-delivery-reader.js", () => ({
47
- getGuardianDelivery: async () => guardianDeliveryFixture,
48
- anyGuardian: (list: Array<{ contactId: string }>) => list[0],
49
- }));
41
+ let mockGuardianResult: {
42
+ contact: { notes: string | null };
43
+ channels: Record<string, unknown>[];
44
+ } | null = null;
50
45
 
51
46
  mock.module("../contacts/contact-store.js", () => ({
52
- findContactInfoById: (contactId: string) =>
53
- contactInfoFixture[contactId] ?? null,
47
+ listGuardianChannels: () => mockGuardianResult,
54
48
  }));
55
49
 
56
- const GUARDIAN_CONTACT_ID = "guardian-contact-1";
57
-
58
- /** Bind a guardian with the given notes (or no guardian when notes is null). */
59
- function setGuardian(notes: string | null | undefined): void {
60
- if (notes === undefined) {
61
- guardianDeliveryFixture = [];
62
- contactInfoFixture = {};
63
- return;
64
- }
65
- guardianDeliveryFixture = [{ contactId: GUARDIAN_CONTACT_ID }];
66
- contactInfoFixture = { [GUARDIAN_CONTACT_ID]: { notes } };
67
- }
68
-
69
50
  // ── Provider mock with system prompt capture ──────────────────────────
70
51
 
71
52
  let configuredProvider: {
@@ -153,12 +134,15 @@ describe("recipient context in notification decision engine", () => {
153
134
  beforeEach(() => {
154
135
  configuredProvider = null;
155
136
  extractedToolUse = null;
156
- setGuardian(undefined);
137
+ mockGuardianResult = null;
157
138
  capturedSystemPrompt = undefined;
158
139
  });
159
140
 
160
141
  test("guardian contact notes appear in system prompt as <recipient-context>", async () => {
161
- setGuardian("Prefers formal tone. Address as Dr. Smith.");
142
+ mockGuardianResult = {
143
+ contact: { notes: "Prefers formal tone. Address as Dr. Smith." },
144
+ channels: [{ type: "vellum" }],
145
+ };
162
146
  setupLLMProvider();
163
147
 
164
148
  const signal = makeSignal();
@@ -173,7 +157,7 @@ describe("recipient context in notification decision engine", () => {
173
157
  });
174
158
 
175
159
  test("recipient-context is omitted when no guardian exists", async () => {
176
- setGuardian(undefined);
160
+ mockGuardianResult = null;
177
161
  setupLLMProvider();
178
162
 
179
163
  const signal = makeSignal();
@@ -185,7 +169,10 @@ describe("recipient context in notification decision engine", () => {
185
169
  });
186
170
 
187
171
  test("recipient-context is omitted when guardian notes are null", async () => {
188
- setGuardian(null);
172
+ mockGuardianResult = {
173
+ contact: { notes: null },
174
+ channels: [{ type: "vellum" }],
175
+ };
189
176
  setupLLMProvider();
190
177
 
191
178
  const signal = makeSignal();
@@ -197,7 +184,10 @@ describe("recipient context in notification decision engine", () => {
197
184
  });
198
185
 
199
186
  test("recipient-context is omitted when guardian notes are empty string", async () => {
200
- setGuardian("");
187
+ mockGuardianResult = {
188
+ contact: { notes: "" },
189
+ channels: [{ type: "vellum" }],
190
+ };
201
191
  setupLLMProvider();
202
192
 
203
193
  const signal = makeSignal();
@@ -209,7 +199,10 @@ describe("recipient context in notification decision engine", () => {
209
199
  });
210
200
 
211
201
  test("large guardian notes are truncated to prevent oversized prompts", async () => {
212
- setGuardian("N".repeat(3000));
202
+ mockGuardianResult = {
203
+ contact: { notes: "N".repeat(3000) },
204
+ channels: [{ type: "vellum" }],
205
+ };
213
206
  setupLLMProvider();
214
207
 
215
208
  const signal = makeSignal();
@@ -233,7 +226,10 @@ describe("recipient context in notification decision engine", () => {
233
226
  });
234
227
 
235
228
  test("fallback path works correctly without recipient context", async () => {
236
- setGuardian("Prefers formal tone.");
229
+ mockGuardianResult = {
230
+ contact: { notes: "Prefers formal tone." },
231
+ channels: [{ type: "vellum" }],
232
+ };
237
233
  // null provider forces fallback path
238
234
  configuredProvider = null;
239
235
 
@@ -251,7 +247,10 @@ describe("recipient context in notification decision engine", () => {
251
247
  });
252
248
 
253
249
  test("recipient-context appears after user-preferences in prompt", async () => {
254
- setGuardian("Prefers brief updates.");
250
+ mockGuardianResult = {
251
+ contact: { notes: "Prefers brief updates." },
252
+ channels: [{ type: "vellum" }],
253
+ };
255
254
  setupLLMProvider();
256
255
 
257
256
  const signal = makeSignal();
@@ -20,10 +20,6 @@ mock.module("../util/logger.js", () => ({
20
20
  }),
21
21
  }));
22
22
 
23
- mock.module("../contacts/guardian-delivery-reader.js", () => ({
24
- getGuardianDelivery: async () => null,
25
- }));
26
-
27
23
  // Mock destination-resolver for broadcaster tests
28
24
  mock.module("../notifications/destination-resolver.js", () => ({
29
25
  resolveDestinations: (channels: string[]) => {
@@ -46,8 +42,6 @@ mock.module("../notifications/deliveries-store.js", () => ({
46
42
  // can be driven from tests without DB access.
47
43
  let mockExistingConversations: Record<string, { id: string }> = {};
48
44
  mock.module("../memory/conversation-crud.js", () => ({
49
- setConversationProcessingStartedAt: () => {},
50
- isConversationProcessing: () => false,
51
45
  getConversation: (id: string) => mockExistingConversations[id] ?? null,
52
46
  }));
53
47
 
@@ -68,25 +68,6 @@ mock.module("../notifications/emit-signal.js", () => ({
68
68
  },
69
69
  }));
70
70
 
71
- // Guardian principalId is resolved from the gateway binding reader. Mirror the
72
- // seeded vellum binding so dispatch can resolve the principal.
73
- mock.module("../contacts/guardian-delivery-reader.js", () => ({
74
- getGuardianDelivery: async () => [
75
- {
76
- channelType: "vellum",
77
- contactId: "guardian-vellum",
78
- principalId: "test-principal-id",
79
- address: "local",
80
- status: "active",
81
- },
82
- ],
83
- guardianForChannel: (
84
- list: Array<{ channelType: string; status: string }>,
85
- channelType: string,
86
- ) => list.find((g) => g.channelType === channelType && g.status === "active"),
87
- anyGuardian: (list: unknown[]) => list[0],
88
- }));
89
-
90
71
  import {
91
72
  createCallSession,
92
73
  createPendingQuestion,
@@ -58,16 +58,6 @@ let lastConstructorOptions: Record<string, unknown> | null = null;
58
58
  let shouldThrow: Error | null = null;
59
59
  const DEFAULT_SDK_TIMEOUT_MS = 1_860_000;
60
60
 
61
- // Each provider installs a `fetch` wrapper to capture raw error bodies, so the
62
- // constructor options carry a `fetch` function; assert the meaningful options
63
- // via objectContaining and confirm `fetch` is wired.
64
- function expectOpenAIConstructorOptions(
65
- expected: Record<string, unknown>,
66
- ): void {
67
- expect(lastConstructorOptions).toEqual(expect.objectContaining(expected));
68
- expect(typeof lastConstructorOptions?.fetch).toBe("function");
69
- }
70
-
71
61
  function userMsg(text: string): Message {
72
62
  return { role: "user", content: [{ type: "text", text }] };
73
63
  }
@@ -319,7 +309,7 @@ describe("OpenAIProvider", () => {
319
309
  });
320
310
 
321
311
  expect(compatible.name).toBe("ollama");
322
- expectOpenAIConstructorOptions({
312
+ expect(lastConstructorOptions).toEqual({
323
313
  apiKey: "sk-local",
324
314
  baseURL: "http://127.0.0.1:11434/v1",
325
315
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -332,7 +322,7 @@ describe("OpenAIProvider", () => {
332
322
  delete process.env.OLLAMA_BASE_URL;
333
323
  const ollama = new OllamaProvider("llama3.2");
334
324
  expect(ollama.name).toBe("ollama");
335
- expectOpenAIConstructorOptions({
325
+ expect(lastConstructorOptions).toEqual({
336
326
  apiKey: "ollama",
337
327
  baseURL: "http://127.0.0.1:11434/v1",
338
328
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -352,7 +342,7 @@ describe("OpenAIProvider", () => {
352
342
  process.env.OLLAMA_BASE_URL = " ";
353
343
  const ollama = new OllamaProvider("llama3.2");
354
344
  expect(ollama.name).toBe("ollama");
355
- expectOpenAIConstructorOptions({
345
+ expect(lastConstructorOptions).toEqual({
356
346
  apiKey: "ollama",
357
347
  baseURL: "http://127.0.0.1:11434/v1",
358
348
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1270,7 +1260,7 @@ describe("custom baseURL initialization", () => {
1270
1260
  });
1271
1261
 
1272
1262
  expect(managed.name).toBe("openai");
1273
- expectOpenAIConstructorOptions({
1263
+ expect(lastConstructorOptions).toEqual({
1274
1264
  apiKey: "ast-key-123",
1275
1265
  baseURL: "https://platform.example.com/v1/runtime-proxy/openai",
1276
1266
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1280,7 +1270,7 @@ describe("custom baseURL initialization", () => {
1280
1270
  test("OpenAIProvider without baseURL calls provider directly", () => {
1281
1271
  new OpenAIProvider("sk-user-key", "gpt-4o");
1282
1272
 
1283
- expectOpenAIConstructorOptions({
1273
+ expect(lastConstructorOptions).toEqual({
1284
1274
  apiKey: "sk-user-key",
1285
1275
  baseURL: undefined,
1286
1276
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1292,7 +1282,7 @@ describe("custom baseURL initialization", () => {
1292
1282
  streamTimeoutMs: 300_000,
1293
1283
  });
1294
1284
 
1295
- expectOpenAIConstructorOptions({
1285
+ expect(lastConstructorOptions).toEqual({
1296
1286
  apiKey: "sk-user-key",
1297
1287
  baseURL: undefined,
1298
1288
  timeout: 360_000,
@@ -1309,7 +1299,7 @@ describe("custom baseURL initialization", () => {
1309
1299
  );
1310
1300
 
1311
1301
  expect(managed.name).toBe("fireworks");
1312
- expectOpenAIConstructorOptions({
1302
+ expect(lastConstructorOptions).toEqual({
1313
1303
  apiKey: "ast-key-123",
1314
1304
  baseURL: "https://platform.example.com/v1/runtime-proxy/fireworks",
1315
1305
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1322,7 +1312,7 @@ describe("custom baseURL initialization", () => {
1322
1312
  "accounts/fireworks/models/llama-v3p1-70b-instruct",
1323
1313
  );
1324
1314
 
1325
- expectOpenAIConstructorOptions({
1315
+ expect(lastConstructorOptions).toEqual({
1326
1316
  apiKey: "fw-user-key",
1327
1317
  baseURL: "https://api.fireworks.ai/inference/v1",
1328
1318
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1335,7 +1325,7 @@ describe("custom baseURL initialization", () => {
1335
1325
  });
1336
1326
 
1337
1327
  expect(managed.name).toBe("openrouter");
1338
- expectOpenAIConstructorOptions({
1328
+ expect(lastConstructorOptions).toEqual({
1339
1329
  apiKey: "ast-key-123",
1340
1330
  baseURL: "https://platform.example.com/v1/runtime-proxy/openrouter",
1341
1331
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1345,7 +1335,7 @@ describe("custom baseURL initialization", () => {
1345
1335
  test("OpenRouterProvider without custom baseURL uses default OpenRouter URL", () => {
1346
1336
  new OpenRouterProvider("or-user-key", "openai/gpt-4o");
1347
1337
 
1348
- expectOpenAIConstructorOptions({
1338
+ expect(lastConstructorOptions).toEqual({
1349
1339
  apiKey: "or-user-key",
1350
1340
  baseURL: "https://openrouter.ai/api/v1",
1351
1341
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1358,7 +1348,7 @@ describe("custom baseURL initialization", () => {
1358
1348
  });
1359
1349
 
1360
1350
  expect(managed.name).toBe("minimax");
1361
- expectOpenAIConstructorOptions({
1351
+ expect(lastConstructorOptions).toEqual({
1362
1352
  apiKey: "ast-key-123",
1363
1353
  baseURL: "https://platform.example.com/v1/runtime-proxy/minimax",
1364
1354
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -1368,7 +1358,7 @@ describe("custom baseURL initialization", () => {
1368
1358
  test("MinimaxProvider without custom baseURL uses default MiniMax URL", () => {
1369
1359
  new MinimaxProvider("mm-user-key", "MiniMax-M2.7");
1370
1360
 
1371
- expectOpenAIConstructorOptions({
1361
+ expect(lastConstructorOptions).toEqual({
1372
1362
  apiKey: "mm-user-key",
1373
1363
  baseURL: "https://api.minimax.io/v1",
1374
1364
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -24,16 +24,6 @@ let lastConstructorOptions: Record<string, unknown> | null = null;
24
24
  let shouldThrow: Error | null = null;
25
25
  const DEFAULT_SDK_TIMEOUT_MS = 1_860_000;
26
26
 
27
- // Each provider installs a `fetch` wrapper to capture raw error bodies, so the
28
- // constructor options carry a `fetch` function; assert the meaningful options
29
- // via objectContaining and confirm `fetch` is wired.
30
- function expectOpenAIConstructorOptions(
31
- expected: Record<string, unknown>,
32
- ): void {
33
- expect(lastConstructorOptions).toEqual(expect.objectContaining(expected));
34
- expect(typeof lastConstructorOptions?.fetch).toBe("function");
35
- }
36
-
37
27
  // Simulate OpenAI.APIError
38
28
  class FakeAPIError extends Error {
39
29
  status: number;
@@ -228,7 +218,7 @@ describe("OpenAIResponsesProvider", () => {
228
218
  providerLabel: "Managed OpenAI",
229
219
  });
230
220
 
231
- expectOpenAIConstructorOptions({
221
+ expect(lastConstructorOptions).toEqual({
232
222
  apiKey: "sk-custom",
233
223
  baseURL: "https://proxy.example.com/v1",
234
224
  timeout: DEFAULT_SDK_TIMEOUT_MS,
@@ -240,7 +230,7 @@ describe("OpenAIResponsesProvider", () => {
240
230
  streamTimeoutMs: 300_000,
241
231
  });
242
232
 
243
- expectOpenAIConstructorOptions({
233
+ expect(lastConstructorOptions).toEqual({
244
234
  apiKey: "sk-custom",
245
235
  baseURL: undefined,
246
236
  timeout: 360_000,
@@ -72,8 +72,6 @@ const persistedRows: Array<{
72
72
  metadata: string | null;
73
73
  }> = [];
74
74
  mock.module("../memory/conversation-crud.js", () => ({
75
- setConversationProcessingStartedAt: () => {},
76
- isConversationProcessing: () => false,
77
75
  addMessage: (
78
76
  conversationId: string,
79
77
  role: string,