@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
@@ -26,7 +26,7 @@
26
26
  * and skipped (no silent provider-safe rewrite — operator must rename).
27
27
  * - Multiple workspace tools register in a single batch.
28
28
  */
29
- import { mkdirSync, rmSync, utimesSync, writeFileSync } from "node:fs";
29
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
30
30
  import { tmpdir } from "node:os";
31
31
  import { join } from "node:path";
32
32
  import { afterAll, beforeEach, describe, expect, test } from "bun:test";
@@ -42,10 +42,7 @@ import {
42
42
  registerTool,
43
43
  } from "../tools/registry.js";
44
44
  import type { Tool, ToolContext, ToolExecutionResult } from "../tools/types.js";
45
- import {
46
- __resetWorkspaceToolCacheForTesting,
47
- loadWorkspaceTools,
48
- } from "../tools/workspace-tools/loader.js";
45
+ import { loadWorkspaceTools } from "../tools/workspace-tools/loader.js";
49
46
 
50
47
  // Per-test counter so each writeTool() call lands in a unique tempdir,
51
48
  // defeating bun's per-URL ESM cache between tests. Without this, a
@@ -90,23 +87,6 @@ function writeRemovedSentinel(name: string): void {
90
87
  writeFileSync(join(toolsDir, `${name}.removed`), "");
91
88
  }
92
89
 
93
- /** Delete `<workspaceDir>/tools/<name><ext>` (defaults to `.ts`). */
94
- function removeToolFile(name: string, ext = ".ts"): void {
95
- rmSync(join(currentWorkspaceDir, "tools", `${name}${ext}`), { force: true });
96
- }
97
-
98
- /**
99
- * Overwrite an existing tool file and bump its mtime into the future so the
100
- * reconcile's mtime gate re-imports it even when the rewrite lands within
101
- * the same millisecond as the original write.
102
- */
103
- function rewriteTool(name: string, body: string, ext = ".ts"): void {
104
- const path = join(currentWorkspaceDir, "tools", `${name}${ext}`);
105
- writeFileSync(path, body);
106
- const future = new Date(Date.now() + 5000);
107
- utimesSync(path, future, future);
108
- }
109
-
110
90
  function makeFakeCoreTool(name: string): Tool {
111
91
  return {
112
92
  name,
@@ -114,9 +94,6 @@ function makeFakeCoreTool(name: string): Tool {
114
94
  category: "test",
115
95
  defaultRiskLevel: RiskLevel.Low,
116
96
  executionTarget: "sandbox",
117
- // Match the finalized shape the registry stores (defaults filled), so
118
- // `getCoreToolOverride(name)` toEqual comparisons hold after registration.
119
- exclusive: false,
120
97
  input_schema: { type: "object", properties: {}, required: [] },
121
98
  async execute(
122
99
  _input: Record<string, unknown>,
@@ -156,7 +133,6 @@ export default {
156
133
  describe("workspace tool loader", () => {
157
134
  beforeEach(() => {
158
135
  __clearRegistryForTesting();
159
- __resetWorkspaceToolCacheForTesting();
160
136
  freshWorkspace();
161
137
  });
162
138
 
@@ -340,173 +316,4 @@ export default 42;
340
316
  const names = getWorkspaceToolNames().sort();
341
317
  expect(names).toEqual(["alpha", "beta", "gamma"]);
342
318
  });
343
-
344
- // ── Reconcile-on-read behavior ─────────────────────────────────────────
345
- //
346
- // loadWorkspaceTools() is idempotent and re-derives registry state from
347
- // disk on every call. These cases cover the deltas a repeat call applies,
348
- // which is what replaces the old filesystem watcher.
349
-
350
- test("repeat call with no disk changes is a no-op (does not throw or duplicate)", async () => {
351
- writeTool("stable_tool", WELL_FORMED_BODY);
352
-
353
- await loadWorkspaceTools();
354
- // A second reconcile must not throw on the already-registered name —
355
- // the mtime cache recognizes the unchanged file and skips re-import.
356
- await loadWorkspaceTools();
357
-
358
- expect(getTool("stable_tool")).toBeDefined();
359
- expect(getWorkspaceToolNames()).toEqual(["stable_tool"]);
360
- });
361
-
362
- test("a file added after the first reconcile registers on the next", async () => {
363
- writeTool("first", WELL_FORMED_BODY);
364
- await loadWorkspaceTools();
365
- expect(getWorkspaceToolNames()).toEqual(["first"]);
366
-
367
- writeTool("second", WELL_FORMED_BODY);
368
- await loadWorkspaceTools();
369
-
370
- expect(getWorkspaceToolNames().sort()).toEqual(["first", "second"]);
371
- });
372
-
373
- test("a changed file is re-imported on the next reconcile", async () => {
374
- writeTool("mutable", WELL_FORMED_BODY);
375
- await loadWorkspaceTools();
376
- expect(getTool("mutable")?.description).toBe("from workspace");
377
-
378
- rewriteTool(
379
- "mutable",
380
- `
381
- export default {
382
- description: "edited in place",
383
- defaultRiskLevel: "low",
384
- input_schema: { type: "object", properties: {}, required: [] },
385
- async execute() {
386
- return { content: "edited", isError: false };
387
- },
388
- };
389
- `,
390
- );
391
- await loadWorkspaceTools();
392
-
393
- expect(getTool("mutable")?.description).toBe("edited in place");
394
- });
395
-
396
- test("a deleted net-new tool file is unregistered on the next reconcile", async () => {
397
- writeTool("ephemeral", WELL_FORMED_BODY);
398
- await loadWorkspaceTools();
399
- expect(getTool("ephemeral")).toBeDefined();
400
-
401
- removeToolFile("ephemeral");
402
- await loadWorkspaceTools();
403
-
404
- expect(getTool("ephemeral")).toBeUndefined();
405
- expect(getWorkspaceToolNames()).toEqual([]);
406
- });
407
-
408
- test("deleting an override file restores the stashed core tool", async () => {
409
- const core = makeFakeCoreTool("restore_me");
410
- registerTool(core);
411
- writeTool("restore_me", WELL_FORMED_BODY);
412
-
413
- await loadWorkspaceTools();
414
- expect(getToolOwner("restore_me")?.kind).toBe("workspace");
415
-
416
- removeToolFile("restore_me");
417
- await loadWorkspaceTools();
418
-
419
- expect(getToolOwner("restore_me")).toBeUndefined();
420
- expect(getTool("restore_me")).toEqual(core);
421
- expect(getCoreToolOverride("restore_me")).toBeUndefined();
422
- });
423
-
424
- test("deleting a .removed sentinel restores the stripped core tool", async () => {
425
- const core = makeFakeCoreTool("strip_then_restore");
426
- registerTool(core);
427
- writeRemovedSentinel("strip_then_restore");
428
-
429
- await loadWorkspaceTools();
430
- expect(getTool("strip_then_restore")).toBeUndefined();
431
- expect(getStrippedCoreToolNames()).toContain("strip_then_restore");
432
-
433
- removeToolFile("strip_then_restore", ".removed");
434
- await loadWorkspaceTools();
435
-
436
- expect(getTool("strip_then_restore")).toEqual(core);
437
- expect(getStrippedCoreToolNames()).not.toContain("strip_then_restore");
438
- });
439
-
440
- test("the registered name is the filename stem, ignoring the file's own name field", async () => {
441
- // The default export sets a different `name` — the loader must pin the
442
- // registered name to the stem ("stem_wins") so the mtime cache and the
443
- // unregister-on-delete path stay keyed by the same name.
444
- writeTool(
445
- "stem_wins",
446
- `
447
- export default {
448
- name: "different_name",
449
- description: "name field should be ignored",
450
- defaultRiskLevel: "low",
451
- input_schema: { type: "object", properties: {}, required: [] },
452
- async execute() {
453
- return { content: "ok", isError: false };
454
- },
455
- };
456
- `,
457
- );
458
-
459
- await loadWorkspaceTools();
460
-
461
- expect(getTool("stem_wins")).toBeDefined();
462
- expect(getTool("different_name")).toBeUndefined();
463
- expect(getWorkspaceToolNames()).toEqual(["stem_wins"]);
464
-
465
- // Deleting the file unregisters by stem — no leaked "different_name".
466
- removeToolFile("stem_wins");
467
- await loadWorkspaceTools();
468
- expect(getTool("stem_wins")).toBeUndefined();
469
- expect(getTool("different_name")).toBeUndefined();
470
- });
471
-
472
- test("per-tool isolation on reconcile: a bad file does not drop a valid edited tool", async () => {
473
- writeTool("good_edit", WELL_FORMED_BODY);
474
- await loadWorkspaceTools();
475
- expect(getTool("good_edit")?.description).toBe("from workspace");
476
-
477
- // Add a file that throws at import, and edit the good tool, in the same
478
- // reconcile. The broken file must not prevent the edited tool from
479
- // re-registering.
480
- writeTool("broken_now", `throw new Error("boom at import");`);
481
- rewriteTool(
482
- "good_edit",
483
- `
484
- export default {
485
- description: "edited and still here",
486
- defaultRiskLevel: "low",
487
- input_schema: { type: "object", properties: {}, required: [] },
488
- async execute() {
489
- return { content: "ok", isError: false };
490
- },
491
- };
492
- `,
493
- );
494
- await loadWorkspaceTools();
495
-
496
- expect(getTool("broken_now")).toBeUndefined();
497
- expect(getTool("good_edit")?.description).toBe("edited and still here");
498
- });
499
-
500
- test("an edit that breaks an existing tool keeps the prior registration", async () => {
501
- writeTool("was_good", WELL_FORMED_BODY);
502
- await loadWorkspaceTools();
503
- expect(getTool("was_good")?.description).toBe("from workspace");
504
-
505
- // Rewrite the file into something that throws at import. The prior,
506
- // working registration must stay in place rather than being torn down.
507
- rewriteTool("was_good", `throw new Error("now broken");`);
508
- await loadWorkspaceTools();
509
-
510
- expect(getTool("was_good")?.description).toBe("from workspace");
511
- });
512
319
  });
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Tests that the `workspace-tools-watcher` feature flag gates the dynamic
3
+ * hot-reload watcher in `WorkspaceToolsWatcher.start()`.
4
+ *
5
+ * The initial disk scan (`loadWorkspaceTools()`) is unconditional and lives
6
+ * elsewhere; this suite only covers whether the live `fs.watch` loop mounts.
7
+ */
8
+ import { mkdirSync, rmSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
+
13
+ import { clearFeatureFlagOverridesCache } from "../config/assistant-feature-flags.js";
14
+ import { WorkspaceToolsWatcher } from "../daemon/workspace-tools-watcher.js";
15
+ import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
16
+
17
+ const FLAG = "workspace-tools-watcher";
18
+ const TEST_BASE_DIR = join(
19
+ tmpdir(),
20
+ `vellum-workspace-tools-watcher-flag-test-${process.pid}-${Date.now()}`,
21
+ );
22
+ let caseCounter = 0;
23
+
24
+ function freshWorkspaceWithToolsDir(): void {
25
+ caseCounter += 1;
26
+ const dir = join(TEST_BASE_DIR, `case-${caseCounter}`);
27
+ mkdirSync(join(dir, "tools"), { recursive: true });
28
+ process.env.VELLUM_WORKSPACE_DIR = dir;
29
+ }
30
+
31
+ beforeEach(() => {
32
+ WorkspaceToolsWatcher.resetForTests();
33
+ clearFeatureFlagOverridesCache();
34
+ freshWorkspaceWithToolsDir();
35
+ });
36
+
37
+ afterEach(() => {
38
+ WorkspaceToolsWatcher.resetForTests();
39
+ clearFeatureFlagOverridesCache();
40
+ delete process.env.VELLUM_WORKSPACE_DIR;
41
+ rmSync(TEST_BASE_DIR, { recursive: true, force: true });
42
+ });
43
+
44
+ describe("WorkspaceToolsWatcher feature-flag gate", () => {
45
+ test("does not mount the watch loop when the flag is off", () => {
46
+ // GIVEN the workspace tools directory exists
47
+ // AND the watcher flag is disabled
48
+ setOverridesForTesting({ [FLAG]: false });
49
+
50
+ // WHEN the watcher starts
51
+ const watcher = WorkspaceToolsWatcher.getInstance();
52
+ watcher.start();
53
+
54
+ // THEN no fs.watch loop is mounted
55
+ expect(watcher.isWatchingForTests()).toBe(false);
56
+ });
57
+
58
+ test("mounts the watch loop when the flag is on", () => {
59
+ // GIVEN the workspace tools directory exists
60
+ // AND the watcher flag is enabled
61
+ setOverridesForTesting({ [FLAG]: true });
62
+
63
+ // WHEN the watcher starts
64
+ const watcher = WorkspaceToolsWatcher.getInstance();
65
+ watcher.start();
66
+
67
+ // THEN a live fs.watch loop is mounted
68
+ expect(watcher.isWatchingForTests()).toBe(true);
69
+ });
70
+ });
package/src/agent/loop.ts CHANGED
@@ -625,20 +625,6 @@ export type LoopToolExecutor = (
625
625
  activityMetadata?: ToolActivityMetadata;
626
626
  }>;
627
627
 
628
- /**
629
- * The benign result returned for a sibling tool call that was deferred because
630
- * an exclusive tool ran in the same turn. Phrased so the model treats it as a
631
- * "not run yet" signal — read the exclusive tool's output, then re-issue this
632
- * call if it is still the right next step.
633
- */
634
- function deferredForExclusiveMessage(exclusiveToolName: string): string {
635
- return (
636
- `(not run: \`${exclusiveToolName}\` was called this turn and runs first, on its own, ` +
637
- `so the rest of your tool calls were held back. Read its output, then call this tool ` +
638
- `again if it is still the right next step.)`
639
- );
640
- }
641
-
642
628
  export interface AgentLoopConstructorOptions {
643
629
  /** LLM provider the loop issues every call through. */
644
630
  provider: Provider;
@@ -648,14 +634,6 @@ export interface AgentLoopConstructorOptions {
648
634
  tools?: ToolDefinition[];
649
635
  toolExecutor?: LoopToolExecutor;
650
636
  resolveTools?: (history: Message[]) => ToolDefinition[];
651
- /**
652
- * Decide whether a tool runs exclusively in its turn (see
653
- * {@link ToolDefinition.exclusive}). When it returns true for a tool present
654
- * in a multi-call turn, the loop runs only that tool and defers the siblings
655
- * un-run. Injected by the conversation wiring, which can read the tool
656
- * registry; lightweight loops that omit it never defer.
657
- */
658
- isExclusiveTool?: (toolName: string) => boolean;
659
637
  /**
660
638
  * Conversation this loop drives. Scopes the loop-held compaction circuit
661
639
  * breaker and is the source of truth the loop's pipeline contexts and
@@ -681,7 +659,6 @@ export class AgentLoop {
681
659
  private tools: ToolDefinition[];
682
660
  private resolveTools: ((history: Message[]) => ToolDefinition[]) | null;
683
661
  private toolExecutor: LoopToolExecutor | null;
684
- private isExclusiveTool: ((toolName: string) => boolean) | null;
685
662
 
686
663
  /**
687
664
  * Conversation this loop drives. Source of truth for the `conversationId`
@@ -711,7 +688,6 @@ export class AgentLoop {
711
688
  tools,
712
689
  toolExecutor,
713
690
  resolveTools,
714
- isExclusiveTool,
715
691
  conversationId,
716
692
  resolveConversationDir,
717
693
  } = options;
@@ -721,7 +697,6 @@ export class AgentLoop {
721
697
  this.tools = tools ?? [];
722
698
  this.resolveTools = resolveTools ?? null;
723
699
  this.toolExecutor = toolExecutor ?? null;
724
- this.isExclusiveTool = isExclusiveTool ?? null;
725
700
  this.conversationId = conversationId;
726
701
  this.resolveConversationDir = resolveConversationDir ?? null;
727
702
  this.compactionCircuit = new CompactionCircuit(this.conversationId);
@@ -1908,39 +1883,8 @@ export class AgentLoop {
1908
1883
  "Tool execution start",
1909
1884
  );
1910
1885
 
1911
- // When an exclusive tool (e.g. the advisor) is among this turn's calls,
1912
- // it must run alone: the model should incorporate its output before
1913
- // acting on anything else. Run only the first exclusive call and defer
1914
- // the siblings with a benign, un-run result so the model re-issues them
1915
- // next turn if still needed. Every tool_use still gets a matching
1916
- // tool_result, so history stays well-formed.
1917
- const exclusiveBlock = this.isExclusiveTool
1918
- ? toolUseBlocks.find((block) => this.isExclusiveTool!(block.name))
1919
- : undefined;
1920
- const deferSiblings =
1921
- exclusiveBlock !== undefined && toolUseBlocks.length > 1;
1922
- if (deferSiblings) {
1923
- rlog.info(
1924
- {
1925
- turn: toolUseTurns,
1926
- exclusiveTool: exclusiveBlock!.name,
1927
- deferred: toolUseBlocks
1928
- .filter((block) => block !== exclusiveBlock)
1929
- .map((block) => block.name),
1930
- },
1931
- "Exclusive tool present — running it alone and deferring sibling tool calls this turn",
1932
- );
1933
- }
1934
-
1935
1886
  const toolExecutionPromise = Promise.all(
1936
1887
  toolUseBlocks.map(async (toolUse) => {
1937
- if (deferSiblings && toolUse !== exclusiveBlock) {
1938
- const result: Awaited<ReturnType<LoopToolExecutor>> = {
1939
- content: deferredForExclusiveMessage(exclusiveBlock!.name),
1940
- isError: false,
1941
- };
1942
- return { toolUse, result };
1943
- }
1944
1888
  const result = await this.toolExecutor!(
1945
1889
  toolUse.name,
1946
1890
  toolUse.input,
package/src/api/index.ts CHANGED
@@ -11,7 +11,6 @@ import { ConfirmationRequestEventSchema } from "./events/confirmation-request.js
11
11
  import { ContactRequestEventSchema } from "./events/contact-request.js";
12
12
  import { ConversationErrorEventSchema } from "./events/conversation-error.js";
13
13
  import { ConversationListInvalidatedEventSchema } from "./events/conversation-list-invalidated.js";
14
- import { ConversationNoticeEventSchema } from "./events/conversation-notice.js";
15
14
  import { ConversationTitleUpdatedEventSchema } from "./events/conversation-title-updated.js";
16
15
  import { DiskPressureStatusChangedEventSchema } from "./events/disk-pressure-status-changed.js";
17
16
  import { DocumentCommentCreatedEventSchema } from "./events/document-comment-created.js";
@@ -62,10 +61,6 @@ export {
62
61
  CALL_SITE_COMPACTION_AGENT,
63
62
  CALL_SITE_SYNTHETIC_AGENT_ERROR_MESSAGE,
64
63
  } from "./constants/call-sites.js";
65
- export {
66
- SSE_REPLAY_RING_AGE_LIMIT_MS,
67
- SSE_REPLAY_RING_COUNT_LIMIT,
68
- } from "./constants/sse-replay.js";
69
64
  export { DEFAULT_TOOL_EXECUTION_TIMEOUT_SEC } from "./constants/tool-execution.js";
70
65
  export {
71
66
  type AssistantActivityAnchor,
@@ -139,11 +134,6 @@ export {
139
134
  type ConversationListInvalidatedReason,
140
135
  ConversationListInvalidatedReasonSchema,
141
136
  } from "./events/conversation-list-invalidated.js";
142
- export {
143
- type ConversationNoticeEvent,
144
- ConversationNoticeEventSchema,
145
- ConversationNoticeSourceSchema,
146
- } from "./events/conversation-notice.js";
147
137
  export {
148
138
  type ConversationTitleUpdatedEvent,
149
139
  ConversationTitleUpdatedEventSchema,
@@ -440,8 +430,6 @@ export {
440
430
  LlmContextResponseSchema,
441
431
  } from "./responses/llm-context-response.js";
442
432
  export {
443
- type LLMCallError,
444
- LLMCallErrorSchema,
445
433
  type LLMCallSummary,
446
434
  LLMCallSummarySchema,
447
435
  type LLMContextSection,
@@ -483,12 +471,7 @@ export {
483
471
  type WorkflowLeaf,
484
472
  WorkflowLeafSchema,
485
473
  } from "./responses/workflow-journal.js";
486
- export {
487
- type CardSurfaceData,
488
- CardSurfaceDataSchema,
489
- type FileUploadSurfaceData,
490
- FileUploadSurfaceDataSchema,
491
- } from "./surfaces.js";
474
+ export { type CardSurfaceData, CardSurfaceDataSchema } from "./surfaces.js";
492
475
 
493
476
  /**
494
477
  * Canonical SSE event schema for the assistant runtime.
@@ -515,7 +498,6 @@ export const AssistantEventSchema = z.discriminatedUnion("type", [
515
498
  ContactRequestEventSchema,
516
499
  ConversationErrorEventSchema,
517
500
  ConversationListInvalidatedEventSchema,
518
- ConversationNoticeEventSchema,
519
501
  ConversationTitleUpdatedEventSchema,
520
502
  DiskPressureStatusChangedEventSchema,
521
503
  DocumentCommentCreatedEventSchema,
@@ -67,34 +67,6 @@ export const LLMContextSectionSchema = z.object({
67
67
 
68
68
  export type LLMContextSection = z.infer<typeof LLMContextSectionSchema>;
69
69
 
70
- /**
71
- * Structured provider/transport error recorded when an LLM call was
72
- * rejected before producing a response. Mirrors the on-disk
73
- * `responsePayload.error` shape written by
74
- * `buildProviderErrorResponsePayload` — the inspector branches on the
75
- * presence of this field to render a failed call distinctly (failure
76
- * banner in the Response tab, $0.00 cost in the rail, etc.) instead of
77
- * the generic "section rendering unavailable" fallback.
78
- *
79
- * Every field is optional because the serializer degrades a plain
80
- * `Error` down to just `{ name, message }`; only the wrapper object is
81
- * guaranteed.
82
- */
83
- export const LLMCallErrorSchema = z.object({
84
- name: z.string().nullish(),
85
- message: z.string().nullish(),
86
- code: z.string().nullish(),
87
- provider: z.string().nullish(),
88
- statusCode: z.number().nullish(),
89
- retryAfterMs: z.number().nullish(),
90
- apiErrorCode: z.string().nullish(),
91
- apiErrorType: z.string().nullish(),
92
- apiErrorParam: z.string().nullish(),
93
- requestId: z.string().nullish(),
94
- });
95
-
96
- export type LLMCallError = z.infer<typeof LLMCallErrorSchema>;
97
-
98
70
  /**
99
71
  * One LLM request log row.
100
72
  *
@@ -116,7 +88,6 @@ export const LLMRequestLogEntrySchema = z.object({
116
88
  responseSections: z.array(LLMContextSectionSchema).nullish(),
117
89
  agentLoopExitReason: z.string().nullish(),
118
90
  callSite: z.string().nullish(),
119
- error: LLMCallErrorSchema.nullish(),
120
91
  });
121
92
 
122
93
  export type LLMRequestLogEntry = z.infer<typeof LLMRequestLogEntrySchema>;
@@ -31,23 +31,6 @@ export const SubagentDetailEventSchema = z.object({
31
31
  toolName: z.string().optional(),
32
32
  isError: z.boolean().optional(),
33
33
  messageId: z.string().optional(),
34
- /**
35
- * Tool-call id — the `tool_use.id` on a tool-call event and the referencing
36
- * `tool_use_id` on its tool-result event, in the daemon's canonical
37
- * content-block format. That format is provider-agnostic: every provider
38
- * (Anthropic, OpenAI, Gemini, …) normalizes its native tool calls into these
39
- * `tool_use`/`tool_result` blocks (see `providers/types.ts`), so this id is
40
- * present regardless of which model produced the call. Lets the web client
41
- * pair a result with its call and key the nested tool-detail view, so tool
42
- * pills on reloaded/history subagents are clickable (not just live ones).
43
- */
44
- toolUseId: z.string().optional(),
45
- /**
46
- * Raw tool input object on tool-call events. (`content` also carries a
47
- * JSON-stringified copy for back-compat / label derivation.) Surfaced in the
48
- * tool-detail view's input section.
49
- */
50
- input: z.record(z.string(), z.unknown()).optional(),
51
34
  });
52
35
 
53
36
  export type SubagentDetailEvent = z.infer<typeof SubagentDetailEventSchema>;
@@ -11,9 +11,9 @@
11
11
  * normalizer *supports* — anything the model sends outside these fields is
12
12
  * dropped (and logged) there, which is how we learn the shapes to recover.
13
13
  *
14
- * Card and file_upload use canonical schemas; the remaining types are
15
- * hand-written interfaces in `daemon/message-types/surfaces.ts` pending
16
- * migration.
14
+ * Card is the first surface type migrated to a canonical schema; the remaining
15
+ * types still live as hand-written interfaces in
16
+ * `daemon/message-types/surfaces.ts` pending migration.
17
17
  */
18
18
 
19
19
  import { z } from "zod";
@@ -31,39 +31,3 @@ export const CardSurfaceDataSchema = z.object({
31
31
  templateData: z.record(z.string(), z.unknown()).optional(),
32
32
  });
33
33
  export type CardSurfaceData = z.infer<typeof CardSurfaceDataSchema>;
34
-
35
- /**
36
- * Accepted MIME-type / extension patterns for a `file_upload` surface.
37
- *
38
- * The renderer consumes this as a `string[]` — it calls `.join`/`.some`/
39
- * `.length` on the value — but the model may emit a single comma-joined string
40
- * ("image/*, application/pdf") or a bare string. Coercing every shape to a
41
- * clean `string[]` keeps that array invariant intact: a string is split on
42
- * commas; array entries are stringified and trimmed; blanks and any non-array
43
- * value collapse to `undefined` (no restriction).
44
- */
45
- const FileUploadAcceptedTypesSchema = z.preprocess((value) => {
46
- const items =
47
- typeof value === "string"
48
- ? value.split(",")
49
- : Array.isArray(value)
50
- ? value
51
- : [];
52
- const cleaned = items
53
- .map((item) =>
54
- typeof item === "string" || typeof item === "number"
55
- ? String(item).trim()
56
- : "",
57
- )
58
- .filter((item) => item.length > 0);
59
- return cleaned.length > 0 ? cleaned : undefined;
60
- }, z.array(z.string()).optional());
61
-
62
- export const FileUploadSurfaceDataSchema = z.object({
63
- prompt: z.coerce.string().optional(),
64
- acceptedTypes: FileUploadAcceptedTypesSchema,
65
- /** A non-positive or non-numeric value is dropped rather than rejecting the surface. */
66
- maxFiles: z.coerce.number().int().positive().optional().catch(undefined),
67
- maxSizeBytes: z.coerce.number().positive().optional().catch(undefined),
68
- });
69
- export type FileUploadSurfaceData = z.infer<typeof FileUploadSurfaceDataSchema>;
@@ -36,7 +36,6 @@ import { deliverChannelReply } from "../runtime/gateway-client.js";
36
36
  import * as pendingInteractions from "../runtime/pending-interactions.js";
37
37
  import { TC_GRANT_WAIT_MAX_MS } from "../tools/tool-approval-handler.js";
38
38
  import { getLogger } from "../util/logger.js";
39
- import { resolveDeliverCallbackUrlForChannel } from "./guardian-channel-delivery.js";
40
39
 
41
40
  const log = getLogger("guardian-request-resolvers");
42
41
 
@@ -243,6 +242,17 @@ export type ResolverResult =
243
242
  }
244
243
  | { ok: false; reason: string };
245
244
 
245
+ function resolveDeliverCallbackUrlForChannel(channel: string): string | null {
246
+ switch (channel) {
247
+ case "telegram":
248
+ case "whatsapp":
249
+ case "slack":
250
+ return `/deliver/${channel}`;
251
+ default:
252
+ return null;
253
+ }
254
+ }
255
+
246
256
  /** Interface that kind-specific resolvers implement. */
247
257
  export interface GuardianRequestResolver {
248
258
  /** The request kind this resolver handles (matches canonical_guardian_requests.kind). */