@vellumai/assistant 0.4.56 → 0.4.57

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 (450) hide show
  1. package/ARCHITECTURE.md +10 -10
  2. package/Dockerfile +3 -0
  3. package/README.md +11 -11
  4. package/docs/architecture/integrations.md +2 -2
  5. package/docs/architecture/memory.md +3 -4
  6. package/docs/credential-execution-service.md +13 -20
  7. package/node_modules/@vellumai/ces-contracts/src/error.ts +5 -4
  8. package/package.json +1 -1
  9. package/src/__tests__/actor-token-service.test.ts +7 -7
  10. package/src/__tests__/anthropic-provider.test.ts +172 -0
  11. package/src/__tests__/app-builder-tool-scripts.test.ts +15 -1
  12. package/src/__tests__/approval-cascade.test.ts +2 -2
  13. package/src/__tests__/approval-routes-http.test.ts +3 -4
  14. package/src/__tests__/asset-materialize-tool.test.ts +5 -5
  15. package/src/__tests__/asset-search-tool.test.ts +1 -1
  16. package/src/__tests__/assistant-attachments.test.ts +5 -5
  17. package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
  18. package/src/__tests__/assistant-feature-flags-integration.test.ts +50 -38
  19. package/src/__tests__/attachments-store.test.ts +2 -2
  20. package/src/__tests__/avatar-e2e.test.ts +5 -3
  21. package/src/__tests__/browser-skill-endstate.test.ts +0 -1
  22. package/src/__tests__/call-routes-http.test.ts +2 -2
  23. package/src/__tests__/callback-handoff-copy.test.ts +1 -1
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +158 -0
  25. package/src/__tests__/channel-readiness-routes.test.ts +0 -1
  26. package/src/__tests__/channel-readiness-service.test.ts +0 -1
  27. package/src/__tests__/checker.test.ts +31 -32
  28. package/src/__tests__/chrome-cdp.test.ts +47 -18
  29. package/src/__tests__/claude-code-skill-regression.test.ts +2 -2
  30. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  31. package/src/__tests__/config-schema.test.ts +9 -18
  32. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -4
  34. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -2
  35. package/src/__tests__/conversation-agent-loop.test.ts +11 -4
  36. package/src/__tests__/conversation-attachments.test.ts +1 -1
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +2 -2
  38. package/src/__tests__/conversation-error.test.ts +33 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +0 -1
  40. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  41. package/src/__tests__/conversation-pairing.test.ts +1 -1
  42. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -4
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +4 -4
  44. package/src/__tests__/conversation-queue.test.ts +23 -14
  45. package/src/__tests__/conversation-routes-slash-commands.test.ts +3 -3
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +185 -173
  47. package/src/__tests__/conversation-seed-composer.test.ts +1 -1
  48. package/src/__tests__/conversation-slash-queue.test.ts +4 -4
  49. package/src/__tests__/conversation-slash-unknown.test.ts +4 -4
  50. package/src/__tests__/conversation-starter-routes.test.ts +291 -0
  51. package/src/__tests__/conversation-wipe.test.ts +438 -0
  52. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -3
  53. package/src/__tests__/conversation-workspace-injection.test.ts +4 -5
  54. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -5
  55. package/src/__tests__/credential-security-e2e.test.ts +20 -0
  56. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  57. package/src/__tests__/credential-vault-unit.test.ts +227 -0
  58. package/src/__tests__/credentials-cli.test.ts +3 -0
  59. package/src/__tests__/date-context.test.ts +59 -377
  60. package/src/__tests__/drop-capability-card-state-migration.test.ts +169 -0
  61. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +11 -45
  62. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
  63. package/src/__tests__/encrypted-store.test.ts +237 -15
  64. package/src/__tests__/ephemeral-permissions.test.ts +4 -5
  65. package/src/__tests__/event-bus.test.ts +3 -3
  66. package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
  67. package/src/__tests__/gateway-only-guard.test.ts +1 -0
  68. package/src/__tests__/gemini-image-service.test.ts +4 -4
  69. package/src/__tests__/gemini-provider.test.ts +6 -9
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
  71. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  72. package/src/__tests__/host-shell-tool.test.ts +6 -6
  73. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  74. package/src/__tests__/intent-routing.test.ts +51 -99
  75. package/src/__tests__/invite-routes-http.test.ts +5 -0
  76. package/src/__tests__/list-messages-attachments.test.ts +1 -1
  77. package/src/__tests__/managed-proxy-context.test.ts +2 -5
  78. package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
  79. package/src/__tests__/media-generate-image.test.ts +32 -15
  80. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
  81. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
  82. package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
  83. package/src/__tests__/memory-recall-quality.test.ts +4 -3
  84. package/src/__tests__/memory-regressions.test.ts +86 -90
  85. package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
  86. package/src/__tests__/migration-export-http.test.ts +26 -27
  87. package/src/__tests__/migration-import-commit-http.test.ts +165 -37
  88. package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
  89. package/src/__tests__/migration-validate-http.test.ts +16 -16
  90. package/src/__tests__/model-intents.test.ts +1 -1
  91. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
  92. package/src/__tests__/notification-broadcaster.test.ts +1 -1
  93. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  94. package/src/__tests__/notification-decision-identity.test.ts +8 -9
  95. package/src/__tests__/notification-decision-strategy.test.ts +1 -1
  96. package/src/__tests__/notification-deep-link.test.ts +1 -1
  97. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  98. package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
  99. package/src/__tests__/oauth-store.test.ts +1 -3
  100. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
  101. package/src/__tests__/onboarding-template-contract.test.ts +23 -59
  102. package/src/__tests__/provider-error-scenarios.test.ts +154 -0
  103. package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
  104. package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
  105. package/src/__tests__/provider-registry-ollama.test.ts +5 -2
  106. package/src/__tests__/qdrant-manager.test.ts +7 -7
  107. package/src/__tests__/ratelimit.test.ts +0 -74
  108. package/src/__tests__/recording-handler.test.ts +0 -1
  109. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  110. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  111. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  112. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  113. package/src/__tests__/scheduler-recurrence.test.ts +46 -2
  114. package/src/__tests__/schema-transforms.test.ts +114 -54
  115. package/src/__tests__/secret-onetime-send.test.ts +20 -0
  116. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
  117. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  118. package/src/__tests__/send-endpoint-busy.test.ts +63 -4
  119. package/src/__tests__/send-notification-tool.test.ts +2 -2
  120. package/src/__tests__/shell-credential-ref.test.ts +0 -1
  121. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
  122. package/src/__tests__/skill-memory.test.ts +547 -0
  123. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
  124. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
  125. package/src/__tests__/slack-channel-config.test.ts +109 -94
  126. package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
  127. package/src/__tests__/swarm-recursion.test.ts +2 -2
  128. package/src/__tests__/swarm-tool.test.ts +2 -2
  129. package/src/__tests__/system-prompt.test.ts +19 -66
  130. package/src/__tests__/telegram-config.test.ts +121 -0
  131. package/src/__tests__/terminal-tools.test.ts +1 -1
  132. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
  133. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  134. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  135. package/src/__tests__/tool-executor.test.ts +1 -1
  136. package/src/__tests__/trace-emitter.test.ts +8 -1
  137. package/src/__tests__/trust-store.test.ts +7 -8
  138. package/src/__tests__/twilio-routes.test.ts +1 -18
  139. package/src/__tests__/user-reference.test.ts +82 -2
  140. package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
  141. package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
  142. package/src/approvals/guardian-request-resolvers.ts +3 -3
  143. package/src/avatar/ascii-renderer.ts +2 -2
  144. package/src/avatar/png-renderer.ts +2 -2
  145. package/src/avatar/resvg-lazy.ts +21 -0
  146. package/src/calls/guardian-dispatch.ts +1 -1
  147. package/src/calls/relay-access-wait.ts +2 -2
  148. package/src/calls/twilio-rest.ts +0 -248
  149. package/src/cli/AGENTS.md +5 -8
  150. package/src/cli/__tests__/notifications.test.ts +5 -5
  151. package/src/cli/commands/avatar.ts +64 -2
  152. package/src/cli/commands/conversations.ts +131 -1
  153. package/src/cli/commands/credentials.ts +2 -0
  154. package/src/cli/commands/notifications.ts +3 -3
  155. package/src/cli.ts +10 -0
  156. package/src/config/bundled-skills/acp/SKILL.md +5 -5
  157. package/src/config/bundled-skills/acp/TOOLS.json +6 -6
  158. package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
  159. package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
  160. package/src/config/bundled-skills/browser/SKILL.md +15 -15
  161. package/src/config/bundled-skills/browser/TOOLS.json +14 -14
  162. package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
  163. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
  164. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  165. package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
  166. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  167. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
  168. package/src/config/bundled-skills/contacts/SKILL.md +3 -3
  169. package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
  170. package/src/config/bundled-skills/document/SKILL.md +4 -4
  171. package/src/config/bundled-skills/document/TOOLS.json +2 -2
  172. package/src/config/bundled-skills/followups/TOOLS.json +3 -3
  173. package/src/config/bundled-skills/gmail/SKILL.md +32 -32
  174. package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
  175. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
  176. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  177. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
  178. package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
  179. package/src/config/bundled-skills/google-calendar/types.ts +1 -1
  180. package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
  181. package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
  182. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
  183. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
  184. package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
  185. package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
  186. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
  187. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
  188. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
  189. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
  190. package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
  191. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
  192. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
  193. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  194. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
  195. package/src/config/bundled-skills/messaging/SKILL.md +29 -25
  196. package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
  197. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
  198. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  199. package/src/config/bundled-skills/notifications/SKILL.md +3 -3
  200. package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
  201. package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
  202. package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
  203. package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
  204. package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
  205. package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
  206. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
  207. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
  208. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
  209. package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
  210. package/src/config/bundled-skills/schedule/SKILL.md +26 -26
  211. package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
  212. package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
  213. package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
  214. package/src/config/bundled-skills/sequences/SKILL.md +2 -2
  215. package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
  216. package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
  217. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
  218. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
  219. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
  220. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
  221. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
  222. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
  223. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  224. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  225. package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
  226. package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
  227. package/src/config/bundled-skills/slack/SKILL.md +2 -2
  228. package/src/config/bundled-skills/slack/TOOLS.json +8 -8
  229. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
  230. package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
  231. package/src/config/bundled-skills/tasks/SKILL.md +1 -1
  232. package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
  233. package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
  234. package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
  235. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
  236. package/src/config/bundled-skills/watcher/SKILL.md +4 -4
  237. package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
  238. package/src/config/feature-flag-registry.json +33 -17
  239. package/src/config/schemas/sandbox.ts +1 -1
  240. package/src/config/schemas/services.ts +13 -3
  241. package/src/config/schemas/timeouts.ts +0 -10
  242. package/src/contacts/contact-store.ts +63 -0
  243. package/src/contacts/contacts-write.ts +1 -1
  244. package/src/daemon/assistant-attachments.ts +2 -2
  245. package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
  246. package/src/daemon/conversation-agent-loop.ts +7 -30
  247. package/src/daemon/conversation-error.ts +24 -0
  248. package/src/daemon/conversation-memory.ts +8 -7
  249. package/src/daemon/conversation-runtime-assembly.ts +139 -274
  250. package/src/daemon/conversation-slash.ts +7 -26
  251. package/src/daemon/conversation-surfaces.ts +14 -0
  252. package/src/daemon/conversation-tool-setup.ts +9 -8
  253. package/src/daemon/conversation.ts +2 -0
  254. package/src/daemon/daemon-control.ts +1 -1
  255. package/src/daemon/date-context.ts +10 -83
  256. package/src/daemon/handlers/config-channels.ts +12 -2
  257. package/src/daemon/handlers/config-slack-channel.ts +7 -1
  258. package/src/daemon/handlers/config-telegram.ts +6 -1
  259. package/src/daemon/handlers/conversations.ts +2 -2
  260. package/src/daemon/handlers/skills.ts +4 -0
  261. package/src/daemon/lifecycle.ts +28 -4
  262. package/src/daemon/providers-setup.ts +1 -1
  263. package/src/daemon/server.ts +1 -5
  264. package/src/daemon/shutdown-handlers.ts +9 -3
  265. package/src/daemon/tool-side-effects.ts +40 -0
  266. package/src/daemon/trace-emitter.ts +25 -2
  267. package/src/events/domain-events.ts +1 -1
  268. package/src/events/tool-permission-telemetry-listener.ts +46 -0
  269. package/src/inbound/platform-callback-registration.ts +0 -18
  270. package/src/media/app-icon-generator.ts +15 -8
  271. package/src/media/avatar-router.ts +15 -8
  272. package/src/media/gemini-image-service.ts +125 -21
  273. package/src/memory/attachments-store.ts +3 -3
  274. package/src/memory/channel-verification-sessions.ts +6 -6
  275. package/src/memory/conversation-crud.ts +196 -1
  276. package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
  277. package/src/memory/conversation-title-service.ts +2 -3
  278. package/src/memory/db-init.ts +25 -1
  279. package/src/memory/invite-store.ts +4 -4
  280. package/src/memory/items-extractor.ts +4 -4
  281. package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
  282. package/src/memory/jobs-store.ts +3 -2
  283. package/src/memory/jobs-worker.ts +7 -5
  284. package/src/memory/lifecycle-events-store.ts +63 -0
  285. package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
  286. package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
  287. package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
  288. package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
  289. package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
  290. package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
  291. package/src/memory/migrations/index.ts +6 -0
  292. package/src/memory/migrations/registry.ts +13 -0
  293. package/src/memory/retriever.test.ts +223 -96
  294. package/src/memory/retriever.ts +115 -138
  295. package/src/memory/schema/calls.ts +1 -1
  296. package/src/memory/schema/contacts.ts +1 -1
  297. package/src/memory/schema/infrastructure.ts +29 -0
  298. package/src/memory/schema/memory-core.ts +7 -17
  299. package/src/memory/schema/notifications.ts +1 -1
  300. package/src/memory/search/formatting.ts +23 -6
  301. package/src/memory/search/lexical.ts +2 -0
  302. package/src/memory/search/semantic.ts +2 -0
  303. package/src/memory/search/staleness.ts +1 -0
  304. package/src/memory/search/types.ts +4 -0
  305. package/src/memory/task-memory-cleanup.ts +96 -6
  306. package/src/memory/trace-event-store.ts +148 -0
  307. package/src/notifications/README.md +1 -1
  308. package/src/notifications/decision-engine.ts +2 -2
  309. package/src/notifications/emit-signal.ts +4 -4
  310. package/src/notifications/events-store.ts +4 -4
  311. package/src/notifications/signal.ts +1 -1
  312. package/src/oauth/manual-token-connection.ts +49 -25
  313. package/src/permissions/checker.ts +6 -5
  314. package/src/permissions/defaults.ts +4 -4
  315. package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
  316. package/src/prompts/cache-boundary.ts +8 -0
  317. package/src/prompts/system-prompt.ts +105 -634
  318. package/src/prompts/templates/BOOTSTRAP.md +166 -33
  319. package/src/prompts/templates/IDENTITY.md +8 -23
  320. package/src/prompts/templates/SOUL.md +20 -41
  321. package/src/prompts/templates/USER.md +3 -19
  322. package/src/prompts/user-reference.ts +14 -16
  323. package/src/providers/anthropic/client.ts +46 -2
  324. package/src/providers/gemini/client.ts +6 -9
  325. package/src/providers/managed-proxy/constants.ts +1 -7
  326. package/src/providers/managed-proxy/context.ts +0 -1
  327. package/src/providers/model-intents.ts +5 -5
  328. package/src/providers/openai/client.ts +10 -1
  329. package/src/providers/openrouter/client.ts +1 -0
  330. package/src/providers/ratelimit.ts +0 -35
  331. package/src/providers/registry.ts +3 -5
  332. package/src/providers/retry.ts +18 -1
  333. package/src/runtime/access-request-helper.ts +1 -1
  334. package/src/runtime/auth/route-policy.ts +7 -0
  335. package/src/runtime/channel-verification-service.ts +1 -1
  336. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  337. package/src/runtime/guardian-vellum-migration.ts +63 -1
  338. package/src/runtime/http-server.ts +8 -4
  339. package/src/runtime/migrations/vbundle-builder.ts +212 -32
  340. package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
  341. package/src/runtime/migrations/vbundle-importer.ts +66 -1
  342. package/src/runtime/migrations/vbundle-validator.ts +17 -3
  343. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
  344. package/src/runtime/routes/attachment-routes.ts +2 -2
  345. package/src/runtime/routes/btw-routes.ts +9 -0
  346. package/src/runtime/routes/channel-verification-routes.ts +19 -2
  347. package/src/runtime/routes/conversation-management-routes.ts +55 -1
  348. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  349. package/src/runtime/routes/conversation-routes.ts +49 -5
  350. package/src/runtime/routes/conversation-starter-routes.ts +207 -0
  351. package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
  352. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
  353. package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
  354. package/src/runtime/routes/migration-routes.ts +25 -13
  355. package/src/runtime/routes/secret-routes.ts +18 -0
  356. package/src/runtime/routes/settings-routes.ts +8 -8
  357. package/src/runtime/routes/telemetry-routes.ts +53 -0
  358. package/src/runtime/routes/trace-event-routes.ts +62 -0
  359. package/src/runtime/tool-grant-request-helper.ts +1 -1
  360. package/src/runtime/verification-outbound-actions.ts +47 -31
  361. package/src/security/encrypted-store.ts +263 -78
  362. package/src/skills/catalog-install.ts +10 -0
  363. package/src/skills/managed-store.ts +2 -0
  364. package/src/skills/skill-memory.ts +220 -0
  365. package/src/subagent/manager.ts +1 -4
  366. package/src/telemetry/types.ts +10 -1
  367. package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
  368. package/src/telemetry/usage-telemetry-reporter.ts +51 -4
  369. package/src/tools/AGENTS.md +11 -11
  370. package/src/tools/acp/spawn.ts +1 -1
  371. package/src/tools/apps/executors.ts +8 -8
  372. package/src/tools/apps/registry.ts +1 -1
  373. package/src/tools/assets/materialize.ts +6 -6
  374. package/src/tools/assets/search.ts +10 -10
  375. package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
  376. package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
  377. package/src/tools/browser/auth-detector.ts +6 -6
  378. package/src/tools/browser/browser-execution.ts +13 -13
  379. package/src/tools/browser/browser-manager.ts +3 -3
  380. package/src/tools/browser/chrome-cdp.ts +5 -5
  381. package/src/tools/browser/jit-auth.ts +2 -2
  382. package/src/tools/browser/network-recorder.test.ts +2 -2
  383. package/src/tools/browser/network-recorder.ts +3 -3
  384. package/src/tools/browser/runtime-check.ts +3 -3
  385. package/src/tools/claude-code/claude-code.ts +2 -2
  386. package/src/tools/computer-use/definitions.ts +18 -18
  387. package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
  388. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
  389. package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
  390. package/src/tools/credentials/broker-types.ts +5 -5
  391. package/src/tools/credentials/broker.ts +15 -15
  392. package/src/tools/credentials/metadata-store.ts +2 -2
  393. package/src/tools/credentials/resolve.ts +1 -1
  394. package/src/tools/credentials/selection.ts +1 -1
  395. package/src/tools/credentials/tool-policy.ts +1 -1
  396. package/src/tools/credentials/vault.ts +115 -25
  397. package/src/tools/execution-target.ts +2 -2
  398. package/src/tools/executor.ts +7 -7
  399. package/src/tools/filesystem/edit.ts +2 -2
  400. package/src/tools/filesystem/read.ts +1 -1
  401. package/src/tools/filesystem/write.ts +1 -1
  402. package/src/tools/host-filesystem/edit.ts +2 -1
  403. package/src/tools/host-filesystem/read.ts +2 -1
  404. package/src/tools/host-filesystem/write.ts +1 -1
  405. package/src/tools/host-terminal/host-shell.ts +9 -8
  406. package/src/tools/mcp/mcp-tool-factory.ts +7 -6
  407. package/src/tools/memory/definitions.ts +6 -5
  408. package/src/tools/memory/handlers.test.ts +1 -1
  409. package/src/tools/network/__tests__/web-search.test.ts +3 -3
  410. package/src/tools/network/domain-normalize.ts +2 -2
  411. package/src/tools/network/script-proxy/session-manager.ts +10 -10
  412. package/src/tools/network/web-fetch.ts +1 -1
  413. package/src/tools/network/web-search.ts +3 -3
  414. package/src/tools/permission-checker.ts +8 -8
  415. package/src/tools/registry.ts +7 -7
  416. package/src/tools/schedule/list.ts +2 -2
  417. package/src/tools/schema-transforms.ts +31 -21
  418. package/src/tools/secret-detection-handler.ts +1 -1
  419. package/src/tools/sensitive-output-placeholders.ts +1 -1
  420. package/src/tools/shared/filesystem/edit-engine.ts +1 -1
  421. package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
  422. package/src/tools/shared/filesystem/image-read.ts +25 -5
  423. package/src/tools/shared/filesystem/path-policy.ts +2 -2
  424. package/src/tools/shared/shell-output.ts +1 -1
  425. package/src/tools/side-effects.ts +1 -1
  426. package/src/tools/skills/execute.ts +1 -1
  427. package/src/tools/skills/load.ts +3 -3
  428. package/src/tools/skills/sandbox-runner.ts +3 -3
  429. package/src/tools/subagent/read.ts +1 -1
  430. package/src/tools/subagent/spawn.ts +2 -2
  431. package/src/tools/swarm/delegate.ts +3 -3
  432. package/src/tools/system/request-permission.ts +5 -4
  433. package/src/tools/terminal/backends/native.ts +4 -4
  434. package/src/tools/terminal/parser.ts +6 -6
  435. package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
  436. package/src/tools/terminal/shell.ts +16 -16
  437. package/src/tools/tool-approval-handler.ts +21 -12
  438. package/src/tools/tool-manifest.ts +4 -4
  439. package/src/tools/types.ts +3 -3
  440. package/src/tools/ui-surface/definitions.ts +9 -37
  441. package/src/tools/watcher/list.ts +1 -1
  442. package/src/util/logger.ts +7 -2
  443. package/src/util/retry.ts +29 -1
  444. package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
  445. package/src/workspace/migrations/registry.ts +2 -0
  446. package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
  447. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
  448. package/src/cli/reference.ts +0 -38
  449. package/src/memory/job-handlers/capability-cards.ts +0 -420
  450. package/src/runtime/routes/thread-starter-routes.ts +0 -294
@@ -2,8 +2,8 @@ import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import type { ToolDefinition } from "../providers/types.js";
4
4
  import {
5
- injectReasonField,
6
- REASON_SKIP_SET,
5
+ ACTIVITY_SKIP_SET,
6
+ injectActivityField,
7
7
  schemaDefinesProperty,
8
8
  } from "../tools/schema-transforms.js";
9
9
 
@@ -14,26 +14,26 @@ function makeDef(
14
14
  return { name, description: `Tool ${name}`, input_schema: schema };
15
15
  }
16
16
 
17
- describe("REASON_SKIP_SET", () => {
18
- test("contains expected tool names", () => {
19
- expect(REASON_SKIP_SET.has("skill_execute")).toBe(true);
20
- expect(REASON_SKIP_SET.has("bash")).toBe(true);
21
- expect(REASON_SKIP_SET.has("host_bash")).toBe(true);
22
- expect(REASON_SKIP_SET.has("request_system_permission")).toBe(true);
23
- expect(REASON_SKIP_SET.size).toBe(4);
17
+ describe("ACTIVITY_SKIP_SET", () => {
18
+ test("is empty (all tools now define their own activity property)", () => {
19
+ expect(ACTIVITY_SKIP_SET.size).toBe(0);
24
20
  });
25
21
  });
26
22
 
27
- describe("injectReasonField", () => {
28
- test("injects reason on a tool without it", () => {
23
+ describe("injectActivityField", () => {
24
+ test("injects activity on a tool without it", () => {
29
25
  const defs = [makeDef("my_tool")];
30
- const result = injectReasonField(defs);
26
+ const result = injectActivityField(defs);
31
27
  const schema = result[0].input_schema as Record<string, unknown>;
32
28
  const props = schema.properties as Record<string, unknown>;
33
- expect(props.reason).toEqual({ type: "string" });
29
+ expect(props.activity).toEqual({
30
+ type: "string",
31
+ description:
32
+ "Brief, natural description of what you're doing, shown as a live status update (e.g. 'Checking your project settings')",
33
+ });
34
34
  });
35
35
 
36
- test("adds reason to required array", () => {
36
+ test("adds activity to required array", () => {
37
37
  const defs = [
38
38
  makeDef("my_tool", {
39
39
  type: "object",
@@ -41,9 +41,9 @@ describe("injectReasonField", () => {
41
41
  required: ["foo"],
42
42
  }),
43
43
  ];
44
- const result = injectReasonField(defs);
44
+ const result = injectActivityField(defs);
45
45
  const schema = result[0].input_schema as Record<string, unknown>;
46
- expect(schema.required).toEqual(["foo", "reason"]);
46
+ expect(schema.required).toEqual(["foo", "activity"]);
47
47
  });
48
48
 
49
49
  test("creates required array if missing", () => {
@@ -53,38 +53,38 @@ describe("injectReasonField", () => {
53
53
  properties: { foo: { type: "string" } },
54
54
  }),
55
55
  ];
56
- const result = injectReasonField(defs);
56
+ const result = injectActivityField(defs);
57
57
  const schema = result[0].input_schema as Record<string, unknown>;
58
- expect(schema.required).toEqual(["reason"]);
58
+ expect(schema.required).toEqual(["activity"]);
59
59
  });
60
60
 
61
61
  test("skips tools in skip set (returns unchanged)", () => {
62
62
  const defs = [makeDef("bash"), makeDef("host_bash")];
63
- const result = injectReasonField(defs);
63
+ const result = injectActivityField(defs, new Set(["bash", "host_bash"]));
64
64
  // Should be the exact same object references
65
65
  expect(Object.is(result[0], defs[0])).toBe(true);
66
66
  expect(Object.is(result[1], defs[1])).toBe(true);
67
- // No reason injected
67
+ // No activity injected
68
68
  const schema0 = result[0].input_schema as Record<string, unknown>;
69
69
  const props0 = schema0.properties as Record<string, unknown>;
70
- expect("reason" in props0).toBe(false);
70
+ expect("activity" in props0).toBe(false);
71
71
  });
72
72
 
73
- test("skips tools that already have reason in properties", () => {
73
+ test("skips tools that already have activity in properties", () => {
74
74
  const defs = [
75
75
  makeDef("my_tool", {
76
76
  type: "object",
77
- properties: { reason: { type: "number" } },
77
+ properties: { activity: { type: "number" } },
78
78
  required: [],
79
79
  }),
80
80
  ];
81
- const result = injectReasonField(defs);
81
+ const result = injectActivityField(defs);
82
82
  // Should be the exact same object reference (no clone needed)
83
83
  expect(Object.is(result[0], defs[0])).toBe(true);
84
84
  const schema = result[0].input_schema as Record<string, unknown>;
85
85
  const props = schema.properties as Record<string, unknown>;
86
- // Original reason type preserved
87
- expect(props.reason).toEqual({ type: "number" });
86
+ // Original activity type preserved
87
+ expect(props.activity).toEqual({ type: "number" });
88
88
  });
89
89
 
90
90
  test("does NOT mutate original definition objects", () => {
@@ -97,10 +97,10 @@ describe("injectReasonField", () => {
97
97
  };
98
98
  const defs = [makeDef("my_tool", originalSchema)];
99
99
 
100
- const result = injectReasonField(defs);
100
+ const result = injectActivityField(defs);
101
101
 
102
102
  // Original properties object is untouched
103
- expect("reason" in originalProps).toBe(false);
103
+ expect("activity" in originalProps).toBe(false);
104
104
  // Original required array is untouched
105
105
  expect(originalRequired).toEqual(["foo"]);
106
106
  // Original schema properties ref is the same object
@@ -115,40 +115,40 @@ describe("injectReasonField", () => {
115
115
 
116
116
  test("passes through non-object schemas unchanged", () => {
117
117
  const defs = [makeDef("my_tool", { type: "string" })];
118
- const result = injectReasonField(defs);
118
+ const result = injectActivityField(defs);
119
119
  expect(Object.is(result[0], defs[0])).toBe(true);
120
120
  });
121
121
 
122
122
  test("passes through schemas without properties unchanged", () => {
123
123
  const defs = [makeDef("my_tool", { type: "object" })];
124
- const result = injectReasonField(defs);
124
+ const result = injectActivityField(defs);
125
125
  expect(Object.is(result[0], defs[0])).toBe(true);
126
126
  });
127
127
 
128
- test("skips tools with reason defined inside allOf member (composite schema)", () => {
128
+ test("skips tools with activity defined inside allOf member (composite schema)", () => {
129
129
  const defs = [
130
130
  makeDef("my_tool", {
131
131
  type: "object",
132
132
  properties: { foo: { type: "string" } },
133
133
  allOf: [
134
134
  {
135
- properties: { reason: { type: "string" } },
135
+ properties: { activity: { type: "string" } },
136
136
  },
137
137
  ],
138
138
  required: [],
139
139
  }),
140
140
  ];
141
- const result = injectReasonField(defs);
141
+ const result = injectActivityField(defs);
142
142
  // Should be the exact same object reference (no injection)
143
143
  expect(Object.is(result[0], defs[0])).toBe(true);
144
144
  const schema = result[0].input_schema as Record<string, unknown>;
145
145
  const props = schema.properties as Record<string, unknown>;
146
- // Top-level properties should NOT have reason injected
147
- expect("reason" in props).toBe(false);
146
+ // Top-level properties should NOT have activity injected
147
+ expect("activity" in props).toBe(false);
148
148
  });
149
149
 
150
150
  test("handles empty definitions array", () => {
151
- const result = injectReasonField([]);
151
+ const result = injectActivityField([]);
152
152
  expect(result).toEqual([]);
153
153
  });
154
154
  });
@@ -157,44 +157,44 @@ describe("schemaDefinesProperty", () => {
157
157
  test("returns true for direct properties match", () => {
158
158
  const schema = {
159
159
  type: "object",
160
- properties: { reason: { type: "string" } },
160
+ properties: { activity: { type: "string" } },
161
161
  };
162
- expect(schemaDefinesProperty(schema, "reason")).toBe(true);
162
+ expect(schemaDefinesProperty(schema, "activity")).toBe(true);
163
163
  });
164
164
 
165
165
  test("returns true for property in allOf member", () => {
166
166
  const schema = {
167
- allOf: [{ properties: { reason: { type: "string" } } }],
167
+ allOf: [{ properties: { activity: { type: "string" } } }],
168
168
  };
169
- expect(schemaDefinesProperty(schema, "reason")).toBe(true);
169
+ expect(schemaDefinesProperty(schema, "activity")).toBe(true);
170
170
  });
171
171
 
172
172
  test("returns true for property in oneOf member", () => {
173
173
  const schema = {
174
174
  oneOf: [
175
175
  { properties: { foo: { type: "string" } } },
176
- { properties: { reason: { type: "string" } } },
176
+ { properties: { activity: { type: "string" } } },
177
177
  ],
178
178
  };
179
- expect(schemaDefinesProperty(schema, "reason")).toBe(true);
179
+ expect(schemaDefinesProperty(schema, "activity")).toBe(true);
180
180
  });
181
181
 
182
182
  test("returns true for property in anyOf member", () => {
183
183
  const schema = {
184
- anyOf: [{ properties: { reason: { type: "string" } } }],
184
+ anyOf: [{ properties: { activity: { type: "string" } } }],
185
185
  };
186
- expect(schemaDefinesProperty(schema, "reason")).toBe(true);
186
+ expect(schemaDefinesProperty(schema, "activity")).toBe(true);
187
187
  });
188
188
 
189
189
  test("returns true for nested allOf within oneOf", () => {
190
190
  const schema = {
191
191
  oneOf: [
192
192
  {
193
- allOf: [{ properties: { reason: { type: "string" } } }],
193
+ allOf: [{ properties: { activity: { type: "string" } } }],
194
194
  },
195
195
  ],
196
196
  };
197
- expect(schemaDefinesProperty(schema, "reason")).toBe(true);
197
+ expect(schemaDefinesProperty(schema, "activity")).toBe(true);
198
198
  });
199
199
 
200
200
  test("returns false when property not defined", () => {
@@ -202,25 +202,85 @@ describe("schemaDefinesProperty", () => {
202
202
  type: "object",
203
203
  properties: { foo: { type: "string" } },
204
204
  };
205
- expect(schemaDefinesProperty(schema, "reason")).toBe(false);
205
+ expect(schemaDefinesProperty(schema, "activity")).toBe(false);
206
206
  });
207
207
 
208
- test("returns false for $ref (fail-closed)", () => {
208
+ test("returns false for $ref with default behavior (fail-closed)", () => {
209
209
  const schema = { $ref: "#/definitions/Foo" };
210
- expect(schemaDefinesProperty(schema, "reason")).toBe(false);
210
+ expect(schemaDefinesProperty(schema, "activity")).toBe(false);
211
+ });
212
+
213
+ test("returns true for $ref with assume-defined behavior (fail-open)", () => {
214
+ const schema = { $ref: "#/definitions/Foo" };
215
+ expect(
216
+ schemaDefinesProperty(schema, "activity", {
217
+ refBehavior: "assume-defined",
218
+ }),
219
+ ).toBe(true);
220
+ });
221
+
222
+ test("returns true for $ref nested in allOf with assume-defined refBehavior", () => {
223
+ const schema = {
224
+ allOf: [{ $ref: "#/definitions/Foo" }],
225
+ };
226
+ expect(
227
+ schemaDefinesProperty(schema, "activity", {
228
+ refBehavior: "assume-defined",
229
+ }),
230
+ ).toBe(true);
231
+ });
232
+
233
+ test("returns false for $ref nested in allOf with assume-undefined refBehavior", () => {
234
+ const schema = {
235
+ allOf: [{ $ref: "#/definitions/Foo" }],
236
+ };
237
+ expect(
238
+ schemaDefinesProperty(schema, "activity", {
239
+ refBehavior: "assume-undefined",
240
+ }),
241
+ ).toBe(false);
242
+ });
243
+
244
+ test("returns true for $ref nested in oneOf with assume-defined refBehavior", () => {
245
+ const schema = {
246
+ oneOf: [{ $ref: "#/definitions/Foo" }],
247
+ };
248
+ expect(
249
+ schemaDefinesProperty(schema, "activity", {
250
+ refBehavior: "assume-defined",
251
+ }),
252
+ ).toBe(true);
253
+ });
254
+
255
+ test("returns true for $ref nested in anyOf with assume-defined refBehavior", () => {
256
+ const schema = {
257
+ anyOf: [{ $ref: "#/definitions/Foo" }],
258
+ };
259
+ expect(
260
+ schemaDefinesProperty(schema, "activity", {
261
+ refBehavior: "assume-defined",
262
+ }),
263
+ ).toBe(true);
264
+ });
265
+
266
+ test("returns false for $ref nested in allOf with default refBehavior (fail-closed)", () => {
267
+ const schema = {
268
+ allOf: [{ $ref: "#/definitions/Foo" }],
269
+ };
270
+ expect(schemaDefinesProperty(schema, "activity")).toBe(false);
211
271
  });
212
272
 
213
273
  test("returns false for null schema", () => {
214
- expect(schemaDefinesProperty(null, "reason")).toBe(false);
274
+ expect(schemaDefinesProperty(null, "activity")).toBe(false);
215
275
  });
216
276
 
217
277
  test("returns false for undefined schema", () => {
218
- expect(schemaDefinesProperty(undefined, "reason")).toBe(false);
278
+ expect(schemaDefinesProperty(undefined, "activity")).toBe(false);
219
279
  });
220
280
 
221
281
  test("returns false for non-object schema", () => {
222
- expect(schemaDefinesProperty("not-an-object", "reason")).toBe(false);
223
- expect(schemaDefinesProperty(42, "reason")).toBe(false);
224
- expect(schemaDefinesProperty(true, "reason")).toBe(false);
282
+ expect(schemaDefinesProperty("not-an-object", "activity")).toBe(false);
283
+ expect(schemaDefinesProperty(42, "activity")).toBe(false);
284
+ expect(schemaDefinesProperty(true, "activity")).toBe(false);
225
285
  });
226
286
  });
@@ -14,9 +14,29 @@ const mockConfig = {
14
14
  timeouts: { permissionTimeoutSec: 300 },
15
15
  };
16
16
 
17
+ function setMockNestedValue(
18
+ obj: Record<string, unknown>,
19
+ path: string,
20
+ value: unknown,
21
+ ): void {
22
+ const keys = path.split(".");
23
+ let current = obj;
24
+ for (let i = 0; i < keys.length - 1; i++) {
25
+ const key = keys[i];
26
+ if (current[key] == null || typeof current[key] !== "object") {
27
+ current[key] = {};
28
+ }
29
+ current = current[key] as Record<string, unknown>;
30
+ }
31
+ current[keys[keys.length - 1]] = value;
32
+ }
33
+
17
34
  mock.module("../config/loader.js", () => ({
18
35
  getConfig: () => mockConfig,
19
36
  loadConfig: () => mockConfig,
37
+ loadRawConfig: () => ({}),
38
+ saveRawConfig: () => {},
39
+ setNestedValue: setMockNestedValue,
20
40
  invalidateConfigCache: () => {},
21
41
  }));
22
42
 
@@ -24,9 +24,12 @@ const mockConfig = {
24
24
  "image-generation": {
25
25
  mode: "your-own" as const,
26
26
  provider: "gemini",
27
- model: "gemini-2.5-flash-image",
27
+ model: "gemini-3.1-flash-image-preview",
28
+ },
29
+ "web-search": {
30
+ mode: "your-own" as const,
31
+ provider: "inference-provider-native",
28
32
  },
29
- "web-search": { mode: "your-own" as const, provider: "anthropic-native" },
30
33
  },
31
34
  };
32
35
 
@@ -20,8 +20,7 @@ const mockConfig = {
20
20
  shellMaxTimeoutSec: 600,
21
21
  permissionTimeoutSec: 300,
22
22
  },
23
- sandbox: { enabled: false },
24
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
23
+ rateLimit: { maxRequestsPerMinute: 0 },
25
24
  secretDetection: {
26
25
  enabled: true,
27
26
  action: "warn" as "redact" | "warn" | "block",
@@ -16,7 +16,10 @@ mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
16
16
  import { createGuardianBinding } from "../contacts/contacts-write.js";
17
17
  import type { Conversation } from "../daemon/conversation.js";
18
18
  import type { ServerMessage } from "../daemon/message-protocol.js";
19
- import { createCanonicalGuardianRequest } from "../memory/canonical-guardian-store.js";
19
+ import {
20
+ createCanonicalGuardianRequest,
21
+ getCanonicalGuardianRequest,
22
+ } from "../memory/canonical-guardian-store.js";
20
23
  import { getOrCreateConversation } from "../memory/conversation-key-store.js";
21
24
 
22
25
  const testDir = realpathSync(
@@ -49,7 +52,7 @@ mock.module("../config/loader.js", () => ({
49
52
  model: "test",
50
53
  provider: "test",
51
54
  memory: { enabled: false },
52
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
55
+ rateLimit: { maxRequestsPerMinute: 0 },
53
56
  secretDetection: { enabled: false },
54
57
  contextWindow: { maxInputTokens: 200000 },
55
58
  services: {
@@ -61,9 +64,9 @@ mock.module("../config/loader.js", () => ({
61
64
  "image-generation": {
62
65
  mode: "your-own",
63
66
  provider: "gemini",
64
- model: "gemini-2.5-flash-image",
67
+ model: "gemini-3.1-flash-image-preview",
65
68
  },
66
- "web-search": { mode: "your-own", provider: "anthropic-native" },
69
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
67
70
  },
68
71
  }),
69
72
  }));
@@ -896,4 +899,60 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
896
899
 
897
900
  await stopServer();
898
901
  });
902
+
903
+ test("auto-deny resolves canonical guardian request so stale records do not cause pending_interaction_not_found", async () => {
904
+ const conversationKey = "conv-auto-deny-canonical";
905
+ const { conversationId } = getOrCreateConversation(conversationKey);
906
+ const requestId = "req-auto-deny-canonical";
907
+
908
+ // Step 1: Create a pending approval conversation with a canonical request.
909
+ const { conversation, denyAllPendingConfirmationsMock } =
910
+ makePendingApprovalConversation(requestId, false);
911
+
912
+ pendingInteractions.register(requestId, {
913
+ conversation,
914
+ conversationId,
915
+ kind: "confirmation",
916
+ });
917
+ createCanonicalGuardianRequest({
918
+ id: requestId,
919
+ kind: "tool_approval",
920
+ sourceType: "desktop",
921
+ sourceChannel: "vellum",
922
+ conversationId,
923
+ toolName: "bash",
924
+ guardianPrincipalId: "test-principal-id",
925
+ status: "pending",
926
+ requestCode: "STALE1",
927
+ expiresAt: Date.now() + 5 * 60 * 1000,
928
+ });
929
+
930
+ await startServer(() => conversation);
931
+
932
+ // Step 2: Send a non-approval message to trigger auto-deny of the
933
+ // pending confirmation. "do something else" is not an approval phrase,
934
+ // so tryConsumeCanonicalGuardianReply won't consume it, and the
935
+ // auto-deny path will fire.
936
+ const res = await fetch(messagesUrl(), {
937
+ method: "POST",
938
+ headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
939
+ body: JSON.stringify({
940
+ conversationKey,
941
+ content: "do something else instead",
942
+ sourceChannel: "vellum",
943
+ interface: "macos",
944
+ }),
945
+ });
946
+ expect(res.status).toBe(202);
947
+ expect(denyAllPendingConfirmationsMock).toHaveBeenCalledTimes(1);
948
+
949
+ // Step 3: Verify the canonical guardian request was resolved to "denied".
950
+ // Without the fix, this would remain "pending", causing
951
+ // pending_interaction_not_found errors on subsequent "yes" messages.
952
+ const canonicalRequest = getCanonicalGuardianRequest(requestId);
953
+ expect(canonicalRequest).toBeDefined();
954
+ expect(canonicalRequest!.status).toBe("denied");
955
+
956
+ await stopServer();
957
+ });
899
958
  });
@@ -39,7 +39,7 @@ describe("send-notification tool", () => {
39
39
  expect(emitNotificationSignalMock).toHaveBeenCalledWith({
40
40
  sourceEventName: "user.send_notification",
41
41
  sourceChannel: "assistant_tool",
42
- sourceSessionId: "conv-override",
42
+ sourceContextId: "conv-override",
43
43
  attentionHints: {
44
44
  requiresAction: true,
45
45
  urgency: "high",
@@ -50,7 +50,7 @@ describe("send-notification tool", () => {
50
50
  contextPayload: {
51
51
  requestedMessage: "Your verification code is 123456",
52
52
  requestedByTool: "send_notification",
53
- requestedBySessionId: "conv-1",
53
+ requestedByContextId: "conv-1",
54
54
  requestedTitle: "Verification code",
55
55
  requestedByConversationId: "conv-override",
56
56
  preferredChannels: ["vellum"],
@@ -23,7 +23,6 @@ mock.module("../config/loader.js", () => ({
23
23
  ui: {},
24
24
 
25
25
  timeouts: { shellDefaultTimeoutSec: 120, shellMaxTimeoutSec: 600 },
26
- sandbox: { enabled: false, backend: "none" },
27
26
  secretDetection: { allowOneTimeSend: false },
28
27
  }),
29
28
  }));
@@ -34,8 +34,7 @@ const mockConfig = {
34
34
  shellMaxTimeoutSec: 600,
35
35
  permissionTimeoutSec: 300,
36
36
  },
37
- sandbox: { enabled: false },
38
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
37
+ rateLimit: { maxRequestsPerMinute: 0 },
39
38
  secretDetection: {
40
39
  enabled: true,
41
40
  action: "warn" as const,