@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
@@ -1,10 +1,6 @@
1
1
  import { createHash, randomBytes } from "node:crypto";
2
2
 
3
- import type { GuardianDelivery } from "@vellumai/gateway-client";
4
- import {
5
- GetContactIpcResponseSchema,
6
- MarkChannelRevokedIpcResponseSchema,
7
- } from "@vellumai/gateway-client/gateway-ipc-contracts";
3
+ import { MarkChannelRevokedIpcResponseSchema } from "@vellumai/gateway-client/gateway-ipc-contracts";
8
4
 
9
5
  import { startVerificationCall } from "../../calls/call-domain.js";
10
6
  import type { ChannelId } from "../../channels/types.js";
@@ -15,8 +11,7 @@ import {
15
11
  getChannelById,
16
12
  getContact,
17
13
  } from "../../contacts/contact-store.js";
18
- import { getGuardianDelivery } from "../../contacts/guardian-delivery-reader.js";
19
- import type { ContactChannel } from "../../contacts/types.js";
14
+ import type { ChannelStatus } from "../../contacts/types.js";
20
15
  import { ipcCallPersistent } from "../../ipc/gateway-client.js";
21
16
  import { getBindingByChannelChat } from "../../memory/external-conversation-store.js";
22
17
  import { resolveGuardianName } from "../../prompts/user-reference.js";
@@ -33,7 +28,6 @@ import {
33
28
  findActiveSession,
34
29
  getGuardianBinding,
35
30
  getPendingSession,
36
- isGuardianBoundForChannel,
37
31
  revokeBinding,
38
32
  revokePendingSessions,
39
33
  updateSessionDelivery,
@@ -82,64 +76,23 @@ export function getReadinessService(): ChannelReadinessService {
82
76
  return _readinessService;
83
77
  }
84
78
 
85
- // ---------------------------------------------------------------------------
86
- // Gateway delivery lookup
87
- // ---------------------------------------------------------------------------
88
-
89
- /**
90
- * Resolve the gateway-owned delivery (ACL source of truth) for a contact
91
- * channel, matching on type and either address or externalChatId. Returns
92
- * `undefined` when the gateway is unreachable or has no binding for it.
93
- */
94
- async function deliveryForChannel(
95
- channel: Pick<ContactChannel, "type" | "address" | "externalChatId">,
96
- ): Promise<GuardianDelivery | undefined> {
97
- const guardians = await getGuardianDelivery({ channelTypes: [channel.type] });
98
- if (!guardians) return undefined;
99
- return guardians.find(
100
- (g) =>
101
- g.channelType === channel.type &&
102
- ((channel.address && g.address === channel.address) ||
103
- (channel.externalChatId != null &&
104
- g.externalChatId === channel.externalChatId)),
105
- );
106
- }
107
-
108
- /**
109
- * Read a contact channel's verified state from the gateway contact-channel read
110
- * (ACL source of truth). Covers all contacts, not just guardian deliveries.
111
- * Returns `undefined` when the gateway is unreachable or has no such channel.
112
- */
113
- async function gatewayContactChannelState(
114
- channel: Pick<ContactChannel, "id" | "contactId">,
115
- ): Promise<{ status: string; verifiedAt: number | null } | undefined> {
116
- const result = await ipcCallPersistent("contacts_get_rich", {
117
- contactId: channel.contactId,
118
- });
119
- if (!result || (result as { contact?: unknown }).contact == null) {
120
- return undefined;
121
- }
122
- const { contact } = GetContactIpcResponseSchema.parse(result);
123
- const ch = contact.channels.find((c) => c.id === channel.id);
124
- return ch ? { status: ch.status, verifiedAt: ch.verifiedAt } : undefined;
125
- }
126
-
127
79
  // ---------------------------------------------------------------------------
128
80
  // Extracted business logic functions
129
81
  // ---------------------------------------------------------------------------
130
82
 
131
- export async function createInboundChallenge(
83
+ export function createInboundChallenge(
132
84
  channel?: ChannelId,
133
85
  rebind?: boolean,
134
86
  conversationId?: string,
135
- ): Promise<ChannelVerificationSessionResult> {
87
+ ): ChannelVerificationSessionResult {
88
+ const resolvedAssistantId = DAEMON_INTERNAL_ASSISTANT_ID;
136
89
  const resolvedChannel = channel ?? "telegram";
137
90
 
138
- // Gateway-backed presence guard: block re-binding when a guardian is already
139
- // bound. Null-list (gateway unreachable) is treated as bound, so a transient
140
- // miss blocks rather than letting a second binding through.
141
- const alreadyBound = await isGuardianBoundForChannel(resolvedChannel);
142
- if (alreadyBound && !rebind) {
91
+ const existingBinding = getGuardianBinding(
92
+ resolvedAssistantId,
93
+ resolvedChannel,
94
+ );
95
+ if (existingBinding && !rebind) {
143
96
  return {
144
97
  success: false,
145
98
  error: "already_bound",
@@ -162,13 +115,13 @@ export async function createInboundChallenge(
162
115
  };
163
116
  }
164
117
 
165
- export async function getVerificationStatus(
118
+ export function getVerificationStatus(
166
119
  channel?: ChannelId,
167
- ): Promise<ChannelVerificationSessionResult> {
120
+ ): ChannelVerificationSessionResult {
168
121
  const resolvedAssistantId = DAEMON_INTERNAL_ASSISTANT_ID;
169
122
  const resolvedChannel = channel ?? "telegram";
170
123
 
171
- const binding = await getGuardianBinding(resolvedAssistantId, resolvedChannel);
124
+ const binding = getGuardianBinding(resolvedAssistantId, resolvedChannel);
172
125
 
173
126
  // Read the contact directly to get displayName — getGuardianBinding is a
174
127
  // compatibility shim that doesn't carry metadataJson.
@@ -236,10 +189,7 @@ export async function revokeVerificationForChannel(
236
189
 
237
190
  // Capture binding before revoking so we can downgrade the guardian's
238
191
  // channel — without this, the guardian would still pass the ACL check.
239
- const bindingBeforeRevoke = await getGuardianBinding(
240
- assistantId,
241
- resolvedChannel,
242
- );
192
+ const bindingBeforeRevoke = getGuardianBinding(assistantId, resolvedChannel);
243
193
  if (!bindingBeforeRevoke) {
244
194
  return {
245
195
  success: true,
@@ -256,16 +206,13 @@ export async function revokeVerificationForChannel(
256
206
 
257
207
  // Relay the ACL downgrade to the gateway (source of truth). The gateway's
258
208
  // mark_channel_revoked enforces the guardian guard and dual-writes the
259
- // contact-channel status back to the assistant DB. Gate on the gateway
260
- // delivery's live status, not the assistant DB column, so a redundant revoke
261
- // is still skipped for an already-revoked binding.
209
+ // contact-channel status back to the assistant DB.
262
210
  if (contactResult) {
263
- const delivery = await deliveryForChannel(contactResult.channel);
264
- const deliveryStatus = delivery?.status;
211
+ const channelStatus: ChannelStatus = contactResult.channel.status;
265
212
  if (
266
- deliveryStatus === "active" ||
267
- deliveryStatus === "pending" ||
268
- deliveryStatus === "unverified"
213
+ channelStatus === "active" ||
214
+ channelStatus === "pending" ||
215
+ channelStatus === "unverified"
269
216
  ) {
270
217
  const result = await ipcCallPersistent("mark_channel_revoked", {
271
218
  contactChannelId: contactResult.channel.id,
@@ -347,10 +294,7 @@ export async function verifyTrustedContact(
347
294
  };
348
295
  }
349
296
 
350
- // Already-verified short-circuit derived from the gateway contact-channel read
351
- // (ACL SoT), which covers all contacts — not just guardian deliveries.
352
- const gwState = await gatewayContactChannelState(channel);
353
- if (gwState?.status === "active" && gwState.verifiedAt != null) {
297
+ if (channel.status === "active" && channel.verifiedAt != null) {
354
298
  return {
355
299
  success: false,
356
300
  error: "already_verified",
@@ -635,7 +579,7 @@ export async function handleChannelVerificationSession(
635
579
  ...publicResult,
636
580
  });
637
581
  } else {
638
- const result = await createInboundChallenge(
582
+ const result = createInboundChallenge(
639
583
  channel,
640
584
  msg.rebind,
641
585
  msg.conversationId,
@@ -646,7 +590,7 @@ export async function handleChannelVerificationSession(
646
590
  });
647
591
  }
648
592
  } else if (msg.action === "status") {
649
- const result = await getVerificationStatus(channel);
593
+ const result = getVerificationStatus(channel);
650
594
  broadcastMessage({
651
595
  type: "channel_verification_session_response",
652
596
  ...result,
@@ -1,12 +1,10 @@
1
1
  import { v4 as uuid } from "uuid";
2
2
 
3
3
  import { peekAcpSessionManager } from "../../acp/index.js";
4
- import { resolveCanonicalGuardianRequest } from "../../memory/canonical-guardian-store.js";
5
4
  import { clearAll, getConversation } from "../../memory/conversation-crud.js";
6
5
  import { resolveConversationId } from "../../memory/conversation-key-store.js";
7
6
  import { broadcastMessage } from "../../runtime/assistant-event-hub.js";
8
7
  import { resolveCapabilities } from "../../runtime/capabilities.js";
9
- import * as pendingInteractions from "../../runtime/pending-interactions.js";
10
8
  import { getSubagentManager } from "../../subagent/index.js";
11
9
  import { createAbortReason } from "../../util/abort-reasons.js";
12
10
  import { UserError } from "../../util/errors.js";
@@ -391,81 +389,6 @@ export function steerToMessage(
391
389
  return { steered: true };
392
390
  }
393
391
 
394
- /**
395
- * Supersede an open `ask_question` prompt when a new chat message is enqueued
396
- * for the same conversation.
397
- *
398
- * A queued message while a clarification question is open means the user chose
399
- * to move on rather than answer it. Steering to that message aborts the parked
400
- * turn — which settles the open question via its turn-abort signal — repairs
401
- * the dangling `tool_use`, and drains the message, instead of stranding it
402
- * behind a prompt no one is going to answer. Only `ask_question` prompts
403
- * (`kind: "question"`) trigger this; pending confirmations are handled
404
- * separately by the enqueue path's auto-deny.
405
- *
406
- * Returns `true` when a parked question was found and a steer was issued.
407
- */
408
- export function steerOnEnqueuedMessageIfQuestionParked(
409
- conversationId: string,
410
- enqueuedRequestId: string,
411
- ): boolean {
412
- const hasParkedQuestion = pendingInteractions
413
- .getByConversation(conversationId)
414
- .some((interaction) => interaction.kind === "question");
415
- if (!hasParkedQuestion) return false;
416
- steerToMessage(conversationId, enqueuedRequestId);
417
- return true;
418
- }
419
-
420
- /**
421
- * Supersede interactions left pending by an in-flight turn when a new message
422
- * is enqueued for a busy conversation. Centralized so every ingress path (the
423
- * HTTP send handler and the CLI signal path) gets identical handling:
424
- *
425
- * 1. Auto-deny pending confirmations — notify the client and sync the
426
- * canonical guardian record *before* clearing the prompter-owned
427
- * confirmations, so a later guardian reply can't match a stale "pending"
428
- * record and fail with `pending_interaction_not_found`.
429
- * 2. Supersede a parked ask_question by steering to the enqueued message.
430
- *
431
- * Order matters: the steer aborts the turn, which denies the prompter's
432
- * confirmations as a side effect, so the canonical/notification sync must run
433
- * first. `removeByConversation` preserves `question` entries, so the parked
434
- * question is still registered for the steer even after the confirmation sweep.
435
- */
436
- export function supersedePendingInteractionsOnEnqueue(
437
- conversationId: string,
438
- enqueuedRequestId: string,
439
- ): void {
440
- const conversation = findConversation(conversationId);
441
- if (!conversation) return;
442
-
443
- if (conversation.hasAnyPendingConfirmation()) {
444
- for (const interaction of pendingInteractions.getByConversation(
445
- conversationId,
446
- )) {
447
- if (interaction.kind === "confirmation") {
448
- // sendToClient (wired to the SSE hub) delivers the denial to clients.
449
- conversation.emitConfirmationStateChanged({
450
- conversationId,
451
- requestId: interaction.requestId,
452
- state: "denied" as const,
453
- source: "auto_deny" as const,
454
- });
455
- // Sync the canonical guardian record so stale "pending" rows aren't
456
- // matched by later guardian reply routing.
457
- resolveCanonicalGuardianRequest(interaction.requestId, "pending", {
458
- status: "denied",
459
- });
460
- }
461
- }
462
- conversation.denyAllPendingConfirmations();
463
- pendingInteractions.removeByConversation(conversationId);
464
- }
465
-
466
- steerOnEnqueuedMessageIfQuestionParked(conversationId, enqueuedRequestId);
467
- }
468
-
469
392
  // ---------------------------------------------------------------------------
470
393
  // HTTP handler (delegates to shared logic)
471
394
  // ---------------------------------------------------------------------------
@@ -966,10 +966,6 @@ export async function runDaemon(): Promise<void> {
966
966
  }
967
967
  }
968
968
 
969
- // `startMemoryJobsWorker` selects the worker implementation based on
970
- // `memory.worker.enabled` (in-process vs. a separate OS process).
971
- // Shutdown stops whichever worker is actually running — see
972
- // shutdown-handlers.ts.
973
969
  log.info("Daemon startup: starting memory worker");
974
970
  bgRefs.memoryWorker = startMemoryJobsWorker();
975
971
 
@@ -7,7 +7,6 @@
7
7
 
8
8
  import { getConfig, invalidateConfigCache } from "../config/loader.js";
9
9
  import { getMcpServerManager } from "../mcp/manager.js";
10
- import { migrateLegacyMcpHeaders } from "../mcp/mcp-header-store.js";
11
10
  import { createMcpToolsFromServer } from "../tools/mcp/mcp-tool-factory.js";
12
11
  import { registerMcpTools, unregisterAllMcpTools } from "../tools/registry.js";
13
12
  import { getLogger } from "../util/logger.js";
@@ -56,15 +55,6 @@ async function doReload(): Promise<McpReloadResult> {
56
55
  try {
57
56
  const manager = getMcpServerManager();
58
57
 
59
- // 0. Migrate any legacy plaintext headers from config.json into
60
- // the credential store before loading config for server startup.
61
- // No-ops when no legacy headers remain; errors are logged, not thrown.
62
- try {
63
- await migrateLegacyMcpHeaders();
64
- } catch (err) {
65
- log.warn({ err }, "Legacy MCP header migration failed — continuing");
66
- }
67
-
68
58
  // 1. Validate new config before tearing down existing servers.
69
59
  // If the config is broken we abort early, preserving the current
70
60
  // working MCP setup instead of leaving zero servers.
@@ -59,18 +59,6 @@ function configWithV2(enabled: boolean): AssistantConfig {
59
59
  return { memory: { v2: { enabled } } } as unknown as AssistantConfig;
60
60
  }
61
61
 
62
- /** Poll until `m` has been called at least `n` times, or `timeoutMs` elapses. */
63
- async function waitForCalls(
64
- m: { mock: { calls: unknown[] } },
65
- n: number,
66
- timeoutMs = 1000,
67
- ): Promise<void> {
68
- const start = Date.now();
69
- while (m.mock.calls.length < n && Date.now() - start < timeoutMs) {
70
- await new Promise((resolve) => setTimeout(resolve, 5));
71
- }
72
- }
73
-
74
62
  afterEach(() => {
75
63
  seedSkill.mockClear();
76
64
  seedCli.mockClear();
@@ -140,64 +128,4 @@ describe("maybeReseedCapabilitiesAfterManagedCredential", () => {
140
128
 
141
129
  expect(seedCli).toHaveBeenCalledTimes(1);
142
130
  });
143
-
144
- test("enqueues the v3 maintain pass even when one catalog reseed rejects", async () => {
145
- proxyState.prereqs = true;
146
- v3State.live = true;
147
- seedSkill.mockImplementationOnce(async () => {
148
- throw new Error('Embedding backend "gemini" is not configured');
149
- });
150
-
151
- await maybeReseedCapabilitiesAfterManagedCredential(configWithV2(true));
152
-
153
- // The CLI catalog seeded, so v3 must still rebuild its lanes — a single
154
- // catalog failure cannot suppress the maintain pass.
155
- expect(seedCli).toHaveBeenCalledTimes(1);
156
- expect(enqueueJob).toHaveBeenCalledTimes(1);
157
- expect(enqueueJob).toHaveBeenCalledWith("memory_v3_maintain", {});
158
- });
159
-
160
- test("enqueues the v3 maintain pass without blocking when a catalog reseed exceeds the timeout", async () => {
161
- proxyState.prereqs = true;
162
- v3State.live = true;
163
- // Skill reseed never settles — mirrors the wedged getCatalog()/embed seen in
164
- // the field. The CLI reseed completes normally.
165
- seedSkill.mockImplementationOnce(() => new Promise<void>(() => {}));
166
-
167
- await maybeReseedCapabilitiesAfterManagedCredential(configWithV2(true), {
168
- reseedTimeoutMs: 20,
169
- });
170
-
171
- // An unbounded `Promise.all` barrier would hang here forever; the bounded
172
- // barrier lets the CLI catalog's maintain pass enqueue regardless.
173
- expect(seedCli).toHaveBeenCalledTimes(1);
174
- expect(enqueueJob).toHaveBeenCalledTimes(1);
175
- expect(enqueueJob).toHaveBeenCalledWith("memory_v3_maintain", {});
176
- });
177
-
178
- test("re-enqueues the v3 maintain pass when a straggler catalog finishes after the timeout", async () => {
179
- proxyState.prereqs = true;
180
- v3State.live = true;
181
- let resolveSkill!: () => void;
182
- seedSkill.mockImplementationOnce(
183
- () =>
184
- new Promise<void>((resolve) => {
185
- resolveSkill = resolve;
186
- }),
187
- );
188
-
189
- await maybeReseedCapabilitiesAfterManagedCredential(configWithV2(true), {
190
- reseedTimeoutMs: 10,
191
- });
192
-
193
- // Post-barrier enqueue fires once even though the skill catalog is still
194
- // embedding.
195
- expect(enqueueJob).toHaveBeenCalledTimes(1);
196
-
197
- // The straggler lands; maintain re-enqueues so its late capability rows are
198
- // reconciled without waiting out the 6h backstop.
199
- resolveSkill();
200
- await waitForCalls(enqueueJob, 2);
201
- expect(enqueueJob).toHaveBeenCalledTimes(2);
202
- });
203
131
  });
@@ -49,36 +49,6 @@ export function maybeSeedMemoryV2CliCommands(config: AssistantConfig): void {
49
49
  .catch((err) => log.warn({ err }, "Failed to seed v2 CLI-command entries"));
50
50
  }
51
51
 
52
- /**
53
- * Default upper bound on how long
54
- * {@link maybeReseedCapabilitiesAfterManagedCredential} waits for the capability
55
- * reseeds before enqueuing the v3 maintain pass. The reseeds keep running
56
- * detached past this bound — it only stops the barrier from waiting on a wedged
57
- * catalog (a stalled `getCatalog()` or a managed-proxy embed that never
58
- * returns). A straggler that finishes later re-enqueues maintain.
59
- */
60
- const RESEED_BARRIER_TIMEOUT_MS = 120_000;
61
-
62
- /**
63
- * Resolve to `true` if `p` settles within `ms`, or `false` if the timeout wins.
64
- * Always clears the timer, so a `p` that settles first leaves no pending timer
65
- * keeping the event loop (or a test) alive.
66
- */
67
- async function settledWithin(
68
- p: Promise<unknown>,
69
- ms: number,
70
- ): Promise<boolean> {
71
- let timer: ReturnType<typeof setTimeout> | undefined;
72
- const timedOut = new Promise<false>((resolve) => {
73
- timer = setTimeout(() => resolve(false), ms);
74
- });
75
- try {
76
- return await Promise.race([p.then(() => true), timedOut]);
77
- } finally {
78
- if (timer) clearTimeout(timer);
79
- }
80
- }
81
-
82
52
  /**
83
53
  * Re-seed the v2 skill and CLI-command capability entries once a managed-proxy
84
54
  * credential lands, closing the first-boot race where the daemon's startup seed
@@ -113,23 +83,9 @@ async function settledWithin(
113
83
  * dense store and its lane-invalidation stage forces a rebuild against the now-
114
84
  * populated index, so v3 surfaces the skill/CLI pages within seconds instead of
115
85
  * waiting out the backstop.
116
- *
117
- * The maintain enqueue must NOT be gated on both catalogs settling. The two
118
- * embeds are independent, and a single wedged catalog (a stalled `getCatalog()`
119
- * or a managed-proxy embed that never returns) would otherwise block the v3 lane
120
- * rebuild indefinitely, so the catalog that DID seed never reaches the selector.
121
- * The barrier is therefore bounded by `reseedTimeoutMs`: maintain is enqueued
122
- * once the barrier resolves (the pass is idempotent and reconciles whatever the
123
- * page index currently holds), and a straggler catalog that finishes after the
124
- * timeout re-enqueues maintain so its late rows are picked up without waiting out
125
- * the backstop.
126
- *
127
- * `reseedTimeoutMs` is injectable for tests; production uses
128
- * {@link RESEED_BARRIER_TIMEOUT_MS}.
129
86
  */
130
87
  export async function maybeReseedCapabilitiesAfterManagedCredential(
131
88
  config: AssistantConfig,
132
- opts: { reseedTimeoutMs?: number } = {},
133
89
  ): Promise<void> {
134
90
  if (!config.memory.v2.enabled) return;
135
91
 
@@ -159,59 +115,35 @@ export async function maybeReseedCapabilitiesAfterManagedCredential(
159
115
  ],
160
116
  ];
161
117
 
162
- // Each reseed is contained so one catalog's embed failure (or hang) never
163
- // rejects the caller or aborts the other. Started here but not awaited as a
164
- // single barrier — the bounded wait below decides when to stop waiting.
165
- const reseeds = catalogs.map(([label, seed]) =>
166
- seed().then(
167
- () =>
118
+ await Promise.all(
119
+ catalogs.map(async ([label, seed]) => {
120
+ try {
121
+ await seed();
168
122
  log.info(
169
123
  `Memory v2 ${label} entries seeded after managed proxy credential update`,
170
- ),
171
- (err: unknown) =>
124
+ );
125
+ } catch (err) {
172
126
  log.warn(
173
127
  { err },
174
128
  `Failed to seed v2 ${label} entries after managed proxy credential update`,
175
- ),
176
- ),
129
+ );
130
+ }
131
+ }),
177
132
  );
178
133
 
179
- // When v3 is live, a maintain pass embeds the freshly-seeded capability rows
180
- // into `memory_v3_sections` and invalidates the lanes so v3 surfaces the
181
- // skill/CLI pages within seconds instead of waiting out the 6h backstop.
182
- // Resolve the gate + enqueuer once and reuse for the post-barrier enqueue and
183
- // the straggler re-enqueue below.
134
+ // The stores (and the page index) are now populated; when v3 is live, kick a
135
+ // maintain pass so it embeds the capability rows into `memory_v3_sections` and
136
+ // invalidates its lanes immediately rather than waiting out the 6h backstop.
184
137
  const { isMemoryV3Live } = await import("../config/memory-v3-gate.js");
185
- const v3Live = isMemoryV3Live(config);
186
- const enqueueMaintain = async (): Promise<void> => {
187
- if (!v3Live) return;
188
- try {
189
- const { enqueueMemoryJob } = await import("../memory/jobs-store.js");
190
- enqueueMemoryJob("memory_v3_maintain", {});
191
- } catch (err) {
192
- log.warn(
193
- { err },
194
- "Failed to enqueue memory_v3_maintain after managed proxy credential update",
195
- );
196
- }
197
- };
198
-
199
- // Bound the barrier so a wedged catalog can't block the maintain enqueue
200
- // indefinitely; the reseeds keep running detached past the timeout.
201
- const timeoutMs = opts.reseedTimeoutMs ?? RESEED_BARRIER_TIMEOUT_MS;
202
- const allReseeds = Promise.allSettled(reseeds);
203
- const settledInTime = await settledWithin(allReseeds, timeoutMs);
204
-
205
- await enqueueMaintain();
206
-
207
- if (!settledInTime) {
138
+ if (!isMemoryV3Live(config)) return;
139
+ try {
140
+ const { enqueueMemoryJob } = await import("../memory/jobs-store.js");
141
+ enqueueMemoryJob("memory_v3_maintain", {});
142
+ } catch (err) {
208
143
  log.warn(
209
- { timeoutMs },
210
- "Capability reseed still running after the barrier timeout — enqueued v3 maintain now; will re-enqueue when the straggler catalog finishes",
144
+ { err },
145
+ "Failed to enqueue memory_v3_maintain after managed proxy credential update",
211
146
  );
212
- // The straggler is still embedding; re-enqueue maintain once it lands so its
213
- // late capability rows are reconciled without waiting out the 6h backstop.
214
- void allReseeds.then(() => enqueueMaintain());
215
147
  }
216
148
  }
217
149
 
@@ -4,7 +4,6 @@ import type { CompactionCircuitClosedEvent } from "../../api/events/compaction-c
4
4
  import type { CompactionCircuitOpenEvent } from "../../api/events/compaction-circuit-open.js";
5
5
  import type { ConversationErrorEvent } from "../../api/events/conversation-error.js";
6
6
  import type { ConversationListInvalidatedEvent } from "../../api/events/conversation-list-invalidated.js";
7
- import type { ConversationNoticeEvent } from "../../api/events/conversation-notice.js";
8
7
  import type { ConversationTitleUpdatedEvent } from "../../api/events/conversation-title-updated.js";
9
8
  import type { GenerationCancelledEvent } from "../../api/events/generation-cancelled.js";
10
9
  import type { GenerationHandoffEvent } from "../../api/events/generation-handoff.js";
@@ -544,7 +543,6 @@ export type _ConversationsServerMessages =
544
543
  | CompactionCircuitOpenEvent
545
544
  | CompactionCircuitClosedEvent
546
545
  | ConversationErrorEvent
547
- | ConversationNoticeEvent
548
546
  | ConversationInfo
549
547
  | ConversationTitleUpdatedEvent
550
548
  | ConversationListResponse
@@ -3,21 +3,14 @@
3
3
  import {
4
4
  type CardSurfaceData,
5
5
  CardSurfaceDataSchema,
6
- type FileUploadSurfaceData,
7
- FileUploadSurfaceDataSchema,
8
6
  } from "../../api/surfaces.js";
9
7
 
10
8
  // Surface `data` shapes are wire payloads owned by `@vellumai/assistant-api`.
11
- // Card and file_upload are migrated (canonical Zod schemas); the remaining
12
- // types below are still hand-written interfaces pending migration. Re-exported
13
- // so the daemon's surface protocol barrel (`message-protocol.ts`) keeps
14
- // surfacing them to daemon consumers under their canonical names.
15
- export {
16
- type CardSurfaceData,
17
- CardSurfaceDataSchema,
18
- type FileUploadSurfaceData,
19
- FileUploadSurfaceDataSchema,
20
- };
9
+ // Card is migrated (canonical Zod schema); the remaining types below are still
10
+ // hand-written interfaces pending migration. Re-exported so the daemon's
11
+ // surface protocol barrel (`message-protocol.ts`) keeps surfacing them to
12
+ // daemon consumers under their canonical names.
13
+ export { type CardSurfaceData, CardSurfaceDataSchema };
21
14
 
22
15
  // === Surface type definitions ===
23
16
 
@@ -162,6 +155,13 @@ export interface DynamicPageSurfaceData {
162
155
  preview?: DynamicPagePreview;
163
156
  }
164
157
 
158
+ export interface FileUploadSurfaceData {
159
+ prompt: string;
160
+ acceptedTypes?: string[];
161
+ maxFiles?: number;
162
+ maxSizeBytes?: number;
163
+ }
164
+
165
165
  export interface TableColumn {
166
166
  id: string;
167
167
  label: string;
@@ -48,6 +48,7 @@ import { parseIdentityFields } from "./handlers/identity.js";
48
48
  import type { ConversationCreateOptions } from "./handlers/shared.js";
49
49
  import { setGlobalSkillIpcSender } from "./meet-host-supervisor.js";
50
50
  import { refreshSkillCapabilityMemories } from "./skill-memory-refresh.js";
51
+ import { WorkspaceToolsWatcher } from "./workspace-tools-watcher.js";
51
52
 
52
53
  const log = getLogger("server");
53
54
 
@@ -307,6 +308,8 @@ export class DaemonServer {
307
308
 
308
309
  this.appSourceWatcher.start((appId) => this.handleAppSourceChange(appId));
309
310
 
311
+ WorkspaceToolsWatcher.getInstance().start();
312
+
310
313
  // Broadcast contacts_changed to all clients when any contact mutation occurs.
311
314
  this.unsubscribeContactChange = onContactChange(() => {
312
315
  broadcastMessage({ type: "contacts_changed" });
@@ -321,6 +324,7 @@ export class DaemonServer {
321
324
  this.evictor.stop();
322
325
  this.configWatcher.stop();
323
326
  this.appSourceWatcher.stop();
327
+ WorkspaceToolsWatcher.getInstance().stop();
324
328
  this.cliIpc.stop();
325
329
  this.skillIpc.stop();
326
330
  if (this.unsubscribeContactChange) {
@@ -5,7 +5,6 @@ import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
5
5
  import type { McpServerManager } from "../mcp/manager.js";
6
6
  import { getSqlite, resetDb } from "../memory/db-connection.js";
7
7
  import type { QdrantManager } from "../memory/qdrant-manager.js";
8
- import { stopMemoryWorkerProcess } from "../memory/worker-control.js";
9
8
  import type { RuntimeHttpServer } from "../runtime/http-server.js";
10
9
  import { browserManager } from "../tools/browser/browser-manager.js";
11
10
  import { cleanupShellOutputTempFiles } from "../tools/shared/shell-output.js";
@@ -118,27 +117,8 @@ export function installShutdownHandlers(deps: ShutdownDeps): void {
118
117
  await browserManager.closeAllPages();
119
118
  cleanupShellOutputTempFiles();
120
119
  deps.scheduler.stop();
121
-
122
- // Stop the in-process memory worker if one was started on the daemon's
123
- // event loop (memory.worker.enabled = false).
124
120
  deps.getMemoryWorker()?.stop();
125
121
 
126
- // Stop the out-of-process memory worker if it's actually running. This is
127
- // keyed off live state rather than config: the worker may have been
128
- // spawned at startup (memory.worker.enabled = true) or out of band via
129
- // `assistant memory worker start`, so we stop whatever is actually there.
130
- try {
131
- const workerStatus = stopMemoryWorkerProcess();
132
- if (workerStatus.status === "running") {
133
- log.info(
134
- { pid: workerStatus.pid },
135
- "Sent SIGTERM to memory worker process",
136
- );
137
- }
138
- } catch (err) {
139
- log.warn({ err }, "Failed to stop memory worker process (non-fatal)");
140
- }
141
-
142
122
  if (deps.mcpManager) {
143
123
  try {
144
124
  await deps.mcpManager.stop();
@@ -124,13 +124,4 @@ export interface ToolSetupContext extends SurfaceConversationContext {
124
124
  * return `undefined` for the in-flight (background) subagent.
125
125
  */
126
126
  currentTurnOverrideProfile?: string;
127
- /**
128
- * Whether the current turn has no human present to answer clarification
129
- * prompts. Resolved once per turn by the agent loop — honoring an explicit
130
- * per-run `isInteractive` option (e.g. scheduled/background turns) over the
131
- * live client state — so tool execution sees turn-level interactivity rather
132
- * than re-deriving it from `hasNoClient`/`headlessLock`, which would read a
133
- * scheduled turn running on a client-attached conversation as interactive.
134
- */
135
- currentTurnIsNonInteractive?: boolean;
136
127
  }