@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
@@ -193,11 +193,11 @@ describe("validateDrafts", () => {
193
193
  expect(result.warnings).toHaveLength(0);
194
194
  });
195
195
 
196
- test("accepts a 25 MB attachment (under 50 MB limit)", () => {
196
+ test("accepts a 75 MB attachment (under 100 MB limit)", () => {
197
197
  const drafts = [
198
198
  makeDraft({
199
199
  filename: "video.mov",
200
- sizeBytes: 25 * 1024 * 1024,
200
+ sizeBytes: 75 * 1024 * 1024,
201
201
  }),
202
202
  ];
203
203
  const result = validateDrafts(drafts);
@@ -205,18 +205,18 @@ describe("validateDrafts", () => {
205
205
  expect(result.warnings).toHaveLength(0);
206
206
  });
207
207
 
208
- test("rejects a 51 MB attachment with warning mentioning 50.0 MB limit", () => {
208
+ test("rejects a 101 MB attachment with warning mentioning 100.0 MB limit", () => {
209
209
  const drafts = [
210
210
  makeDraft({
211
211
  filename: "huge.mov",
212
- sizeBytes: 51 * 1024 * 1024,
212
+ sizeBytes: 101 * 1024 * 1024,
213
213
  }),
214
214
  ];
215
215
  const result = validateDrafts(drafts);
216
216
  expect(result.accepted).toHaveLength(0);
217
217
  expect(result.warnings).toHaveLength(1);
218
218
  expect(result.warnings[0]).toContain("huge.mov");
219
- expect(result.warnings[0]).toContain("50.0 MB");
219
+ expect(result.warnings[0]).toContain("100.0 MB");
220
220
  expect(result.warnings[0]).toContain("limit");
221
221
  });
222
222
  });
@@ -41,7 +41,7 @@ mock.module("../config/loader.js", () => ({
41
41
  model: "test",
42
42
  provider: "test",
43
43
  memory: { enabled: false },
44
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
44
+ rateLimit: { maxRequestsPerMinute: 0 },
45
45
  secretDetection: { enabled: false },
46
46
  }),
47
47
  }));
@@ -29,7 +29,6 @@ const TEST_DIR = join(
29
29
  );
30
30
 
31
31
  let currentConfig: Record<string, unknown> = {
32
- sandbox: { enabled: false, backend: "native" },
33
32
  services: {
34
33
  inference: {
35
34
  mode: "your-own",
@@ -39,9 +38,9 @@ let currentConfig: Record<string, unknown> = {
39
38
  "image-generation": {
40
39
  mode: "your-own",
41
40
  provider: "gemini",
42
- model: "gemini-2.5-flash-image",
41
+ model: "gemini-3.1-flash-image-preview",
43
42
  },
44
- "web-search": { mode: "your-own", provider: "anthropic-native" },
43
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
45
44
  },
46
45
  };
47
46
 
@@ -132,7 +131,6 @@ const { skillFlagKey } = await import("../config/skill-state.js");
132
131
  beforeEach(() => {
133
132
  mkdirSync(TEST_DIR, { recursive: true });
134
133
  currentConfig = {
135
- sandbox: { enabled: false, backend: "native" },
136
134
  services: {
137
135
  inference: {
138
136
  mode: "your-own",
@@ -142,9 +140,9 @@ beforeEach(() => {
142
140
  "image-generation": {
143
141
  mode: "your-own",
144
142
  provider: "gemini",
145
- model: "gemini-2.5-flash-image",
143
+ model: "gemini-3.1-flash-image-preview",
146
144
  },
147
- "web-search": { mode: "your-own", provider: "anthropic-native" },
145
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
148
146
  },
149
147
  };
150
148
  });
@@ -186,7 +184,7 @@ function createSkillOnDisk(
186
184
  // ---------------------------------------------------------------------------
187
185
 
188
186
  describe("buildSystemPrompt assistant feature flag filtering", () => {
189
- test("flag OFF skill does not appear in <available_skills> section", () => {
187
+ test("flag OFF skill does not appear in skills catalog", () => {
190
188
  createSkillOnDisk(
191
189
  DECLARED_SKILL_ID,
192
190
  "Contacts",
@@ -201,7 +199,6 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
201
199
  );
202
200
 
203
201
  currentConfig = {
204
- sandbox: { enabled: false, backend: "native" },
205
202
  assistantFeatureFlagValues: {
206
203
  [DECLARED_FLAG_KEY]: false,
207
204
  "feature_flags.browser.enabled": true,
@@ -215,17 +212,20 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
215
212
  "image-generation": {
216
213
  mode: "your-own",
217
214
  provider: "gemini",
218
- model: "gemini-2.5-flash-image",
215
+ model: "gemini-3.1-flash-image-preview",
216
+ },
217
+ "web-search": {
218
+ mode: "your-own",
219
+ provider: "inference-provider-native",
219
220
  },
220
- "web-search": { mode: "your-own", provider: "anthropic-native" },
221
221
  },
222
222
  };
223
223
 
224
224
  const result = buildSystemPrompt();
225
225
 
226
226
  // browser is explicitly enabled, declared flagged skill is explicitly off
227
- expect(result).toContain('id="browser"');
228
- expect(result).not.toContain(`id="${DECLARED_SKILL_ID}"`);
227
+ expect(result).toContain("**browser**");
228
+ expect(result).not.toContain(`**${DECLARED_SKILL_ID}**`);
229
229
  });
230
230
 
231
231
  test("declared skills hidden when no flag overrides set (registry defaults to false)", () => {
@@ -243,7 +243,6 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
243
243
  );
244
244
 
245
245
  currentConfig = {
246
- sandbox: { enabled: false, backend: "native" },
247
246
  services: {
248
247
  inference: {
249
248
  mode: "your-own",
@@ -253,17 +252,20 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
253
252
  "image-generation": {
254
253
  mode: "your-own",
255
254
  provider: "gemini",
256
- model: "gemini-2.5-flash-image",
255
+ model: "gemini-3.1-flash-image-preview",
256
+ },
257
+ "web-search": {
258
+ mode: "your-own",
259
+ provider: "inference-provider-native",
257
260
  },
258
- "web-search": { mode: "your-own", provider: "anthropic-native" },
259
261
  },
260
262
  };
261
263
 
262
264
  const result = buildSystemPrompt();
263
265
 
264
266
  // Both skills declare feature flags with registry defaultEnabled: false
265
- expect(result).not.toContain(`id="${DECLARED_SKILL_ID}"`);
266
- expect(result).not.toContain('id="email-channel"');
267
+ expect(result).not.toContain(`**${DECLARED_SKILL_ID}**`);
268
+ expect(result).not.toContain("**email-channel**");
267
269
  });
268
270
 
269
271
  test("flagged-off skills hidden when all flags are OFF", () => {
@@ -281,7 +283,6 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
281
283
  );
282
284
 
283
285
  currentConfig = {
284
- sandbox: { enabled: false, backend: "native" },
285
286
  assistantFeatureFlagValues: {
286
287
  [DECLARED_FLAG_KEY]: false,
287
288
  "feature_flags.email-channel.enabled": false,
@@ -295,16 +296,19 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
295
296
  "image-generation": {
296
297
  mode: "your-own",
297
298
  provider: "gemini",
298
- model: "gemini-2.5-flash-image",
299
+ model: "gemini-3.1-flash-image-preview",
300
+ },
301
+ "web-search": {
302
+ mode: "your-own",
303
+ provider: "inference-provider-native",
299
304
  },
300
- "web-search": { mode: "your-own", provider: "anthropic-native" },
301
305
  },
302
306
  };
303
307
 
304
308
  const result = buildSystemPrompt();
305
309
 
306
- expect(result).not.toContain(`id="${DECLARED_SKILL_ID}"`);
307
- expect(result).not.toContain('id="email-channel"');
310
+ expect(result).not.toContain(`**${DECLARED_SKILL_ID}**`);
311
+ expect(result).not.toContain("**email-channel**");
308
312
  });
309
313
 
310
314
  test("assistantFeatureFlagValues overrides control visibility", () => {
@@ -316,7 +320,6 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
316
320
  );
317
321
 
318
322
  currentConfig = {
319
- sandbox: { enabled: false, backend: "native" },
320
323
  assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: true },
321
324
  services: {
322
325
  inference: {
@@ -327,15 +330,18 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
327
330
  "image-generation": {
328
331
  mode: "your-own",
329
332
  provider: "gemini",
330
- model: "gemini-2.5-flash-image",
333
+ model: "gemini-3.1-flash-image-preview",
334
+ },
335
+ "web-search": {
336
+ mode: "your-own",
337
+ provider: "inference-provider-native",
331
338
  },
332
- "web-search": { mode: "your-own", provider: "anthropic-native" },
333
339
  },
334
340
  };
335
341
 
336
342
  const result = buildSystemPrompt();
337
343
 
338
- expect(result).toContain(`id="${DECLARED_SKILL_ID}"`);
344
+ expect(result).toContain(`**${DECLARED_SKILL_ID}**`);
339
345
  });
340
346
 
341
347
  test("persisted overrides for undeclared flags are respected", () => {
@@ -347,7 +353,6 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
347
353
  );
348
354
 
349
355
  currentConfig = {
350
- sandbox: { enabled: false, backend: "native" },
351
356
  assistantFeatureFlagValues: { "feature_flags.browser.enabled": false },
352
357
  services: {
353
358
  inference: {
@@ -358,9 +363,12 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
358
363
  "image-generation": {
359
364
  mode: "your-own",
360
365
  provider: "gemini",
361
- model: "gemini-2.5-flash-image",
366
+ model: "gemini-3.1-flash-image-preview",
367
+ },
368
+ "web-search": {
369
+ mode: "your-own",
370
+ provider: "inference-provider-native",
362
371
  },
363
- "web-search": { mode: "your-own", provider: "anthropic-native" },
364
372
  },
365
373
  };
366
374
 
@@ -368,7 +376,7 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
368
376
 
369
377
  // browser declares featureFlag: "browser" and the user
370
378
  // explicitly disabled it — that override must be honored.
371
- expect(result).not.toContain('id="browser"');
379
+ expect(result).not.toContain("**browser**");
372
380
  });
373
381
 
374
382
  test("declared flags with no persisted override use registry default", () => {
@@ -380,7 +388,6 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
380
388
  );
381
389
 
382
390
  currentConfig = {
383
- sandbox: { enabled: false, backend: "native" },
384
391
  services: {
385
392
  inference: {
386
393
  mode: "your-own",
@@ -390,23 +397,25 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
390
397
  "image-generation": {
391
398
  mode: "your-own",
392
399
  provider: "gemini",
393
- model: "gemini-2.5-flash-image",
400
+ model: "gemini-3.1-flash-image-preview",
401
+ },
402
+ "web-search": {
403
+ mode: "your-own",
404
+ provider: "inference-provider-native",
394
405
  },
395
- "web-search": { mode: "your-own", provider: "anthropic-native" },
396
406
  },
397
407
  };
398
408
 
399
409
  const result = buildSystemPrompt();
400
410
 
401
411
  // browser is declared in the registry with defaultEnabled: true
402
- expect(result).toContain('id="browser"');
412
+ expect(result).toContain("**browser**");
403
413
  });
404
414
 
405
415
  test("skill without featureFlag is never flag-gated", () => {
406
416
  createSkillOnDisk("my-skill", "My Skill", "A skill without feature flag");
407
417
 
408
418
  currentConfig = {
409
- sandbox: { enabled: false, backend: "native" },
410
419
  services: {
411
420
  inference: {
412
421
  mode: "your-own",
@@ -416,16 +425,19 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
416
425
  "image-generation": {
417
426
  mode: "your-own",
418
427
  provider: "gemini",
419
- model: "gemini-2.5-flash-image",
428
+ model: "gemini-3.1-flash-image-preview",
429
+ },
430
+ "web-search": {
431
+ mode: "your-own",
432
+ provider: "inference-provider-native",
420
433
  },
421
- "web-search": { mode: "your-own", provider: "anthropic-native" },
422
434
  },
423
435
  };
424
436
 
425
437
  const result = buildSystemPrompt();
426
438
 
427
439
  // Skills without featureFlag declared are never gated — always pass through
428
- expect(result).toContain('id="my-skill"');
440
+ expect(result).toContain("**my-skill**");
429
441
  });
430
442
  });
431
443
 
@@ -31,7 +31,7 @@ mock.module("../config/loader.js", () => ({
31
31
  model: "test",
32
32
  provider: "test",
33
33
  memory: { enabled: false },
34
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
34
+ rateLimit: { maxRequestsPerMinute: 0 },
35
35
  }),
36
36
  }));
37
37
 
@@ -167,7 +167,7 @@ describe("uploadAttachment", () => {
167
167
  });
168
168
 
169
169
  test("accepts payload exactly at MAX_UPLOAD_BYTES", () => {
170
- // MAX_UPLOAD_BYTES (50 MB) is divisible by 3, so (MAX/3)*4 base64 chars
170
+ // MAX_UPLOAD_BYTES (100 MB) is divisible by 3, so (MAX/3)*4 base64 chars
171
171
  // decodes to exactly MAX bytes with no padding.
172
172
  const exactLength = (MAX_UPLOAD_BYTES / 3) * 4;
173
173
  const exactData = "A".repeat(exactLength);
@@ -27,7 +27,7 @@ const geminiGenerateContentFn = mock(async () => geminiGenerateContentResult);
27
27
 
28
28
  mock.module("../config/loader.js", () => ({
29
29
  getConfig: () => ({
30
- imageGenModel: "gemini-2.5-flash-image",
30
+ imageGenModel: "gemini-3.1-flash-image-preview",
31
31
  services: {
32
32
  inference: {
33
33
  mode: "your-own",
@@ -37,9 +37,9 @@ mock.module("../config/loader.js", () => ({
37
37
  "image-generation": {
38
38
  mode: "your-own",
39
39
  provider: "gemini",
40
- model: "gemini-2.5-flash-image",
40
+ model: "gemini-3.1-flash-image-preview",
41
41
  },
42
- "web-search": { mode: "your-own", provider: "anthropic-native" },
42
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
43
43
  },
44
44
  }),
45
45
  }));
@@ -47,6 +47,8 @@ mock.module("../config/loader.js", () => ({
47
47
  mock.module("../security/secure-keys.js", () => ({
48
48
  getSecureKeyAsync: async (name: string) =>
49
49
  name === "gemini" ? mockGeminiKey : null,
50
+ getProviderKeyAsync: async (provider: string) =>
51
+ provider === "gemini" ? mockGeminiKey : undefined,
50
52
  }));
51
53
 
52
54
  mock.module("../util/platform.js", () => ({
@@ -8,7 +8,6 @@ import { afterAll, beforeAll, describe, expect, mock, test } from "bun:test";
8
8
 
9
9
  mock.module("../config/loader.js", () => ({
10
10
  getConfig: () => ({
11
- sandbox: { enabled: false, backend: "native" },
12
11
  assistantFeatureFlagValues: {
13
12
  "feature_flags.browser.enabled": true,
14
13
  },
@@ -54,7 +54,7 @@ mock.module("../config/loader.js", () => ({
54
54
  model: "test",
55
55
  provider: "test",
56
56
  memory: { enabled: false },
57
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
57
+ rateLimit: { maxRequestsPerMinute: 0 },
58
58
  secretDetection: { enabled: false },
59
59
  calls: mockCallsConfig,
60
60
  }),
@@ -62,7 +62,7 @@ mock.module("../config/loader.js", () => ({
62
62
  model: "test",
63
63
  provider: "test",
64
64
  memory: { enabled: false },
65
- rateLimit: { maxRequestsPerMinute: 0, maxTokensPerSession: 0 },
65
+ rateLimit: { maxRequestsPerMinute: 0 },
66
66
  secretDetection: { enabled: false },
67
67
  calls: mockCallsConfig,
68
68
  ingress: {
@@ -17,7 +17,7 @@ function buildSignal(
17
17
  signalId: "test-signal-1",
18
18
  createdAt: Date.now(),
19
19
  sourceChannel: "phone",
20
- sourceSessionId: "test-session-1",
20
+ sourceContextId: "test-session-1",
21
21
  sourceEventName: "ingress.access_request.callback_handoff",
22
22
  contextPayload: {
23
23
  requestId: "req-123",
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Regression test: POST /v1/conversations/:id/cancel must resolve the
3
+ * conversation key to the internal conversation ID before calling
4
+ * cancelGeneration(). Without resolveConversationId(), the cancel
5
+ * endpoint receives the client's local conversation key (which differs
6
+ * from the daemon's internal ID), fails to find the conversation, and
7
+ * silently ignores the cancel — leaving the stream running.
8
+ */
9
+ import { mkdtempSync, realpathSync, rmSync } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { afterAll, describe, expect, mock, test } from "bun:test";
13
+
14
+ mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
15
+
16
+ const testDir = realpathSync(
17
+ mkdtempSync(join(tmpdir(), "cancel-resolve-key-test-")),
18
+ );
19
+
20
+ mock.module("../util/platform.js", () => ({
21
+ getRootDir: () => testDir,
22
+ getDataDir: () => testDir,
23
+ isMacOS: () => process.platform === "darwin",
24
+ isLinux: () => process.platform === "linux",
25
+ isWindows: () => process.platform === "win32",
26
+ getPidPath: () => join(testDir, "test.pid"),
27
+ getDbPath: () => join(testDir, "test.db"),
28
+ getLogPath: () => join(testDir, "test.log"),
29
+ ensureDataDir: () => {},
30
+ }));
31
+
32
+ mock.module("../util/logger.js", () => ({
33
+ getLogger: () =>
34
+ new Proxy({} as Record<string, unknown>, {
35
+ get: () => () => {},
36
+ }),
37
+ }));
38
+
39
+ mock.module("../config/loader.js", () => ({
40
+ getConfig: () => ({
41
+ ui: {},
42
+ model: "test",
43
+ provider: "test",
44
+ memory: { enabled: false },
45
+ rateLimit: { maxRequestsPerMinute: 0 },
46
+ secretDetection: { enabled: false },
47
+ contextWindow: { maxInputTokens: 200000 },
48
+ services: {
49
+ inference: {
50
+ mode: "your-own",
51
+ provider: "anthropic",
52
+ model: "claude-opus-4-6",
53
+ },
54
+ "image-generation": {
55
+ mode: "your-own",
56
+ provider: "gemini",
57
+ model: "gemini-3.1-flash-image-preview",
58
+ },
59
+ "web-search": { mode: "your-own", provider: "inference-provider-native" },
60
+ },
61
+ }),
62
+ }));
63
+
64
+ import { getOrCreateConversation } from "../memory/conversation-key-store.js";
65
+ import { initializeDb, resetDb } from "../memory/db.js";
66
+ import { conversationManagementRouteDefinitions } from "../runtime/routes/conversation-management-routes.js";
67
+
68
+ initializeDb();
69
+
70
+ afterAll(() => {
71
+ resetDb();
72
+ try {
73
+ rmSync(testDir, { recursive: true, force: true });
74
+ } catch {
75
+ /* best effort */
76
+ }
77
+ });
78
+
79
+ describe("POST /v1/conversations/:id/cancel", () => {
80
+ test("resolves conversation key to internal ID before cancelling", () => {
81
+ // Create a conversation via key — this assigns an internal ID that
82
+ // differs from the key.
83
+ const conversationKey = "client-local-uuid-abc123";
84
+ const mapping = getOrCreateConversation(conversationKey);
85
+ const internalId = mapping.conversationId;
86
+
87
+ // Sanity: key and internal ID should differ.
88
+ expect(internalId).not.toBe(conversationKey);
89
+
90
+ // Track which ID cancelGeneration receives.
91
+ let cancelledId: string | undefined;
92
+ const routes = conversationManagementRouteDefinitions({
93
+ switchConversation: async () => null,
94
+ renameConversation: () => false,
95
+ clearAllConversations: () => 0,
96
+ cancelGeneration: (id) => {
97
+ cancelledId = id;
98
+ return true;
99
+ },
100
+ destroyConversation: () => {},
101
+ undoLastMessage: async () => null,
102
+ regenerateResponse: async () => null,
103
+ });
104
+
105
+ const cancelRoute = routes.find(
106
+ (r) => r.endpoint === "conversations/:id/cancel",
107
+ )!;
108
+
109
+ // Simulate the HTTP handler with the conversation KEY (what the
110
+ // macOS client sends — it uses the key, not the internal ID).
111
+ cancelRoute.handler({
112
+ params: { id: conversationKey },
113
+ req: new Request("http://localhost/v1/conversations/x/cancel", {
114
+ method: "POST",
115
+ }),
116
+ url: new URL("http://localhost/v1/conversations/x/cancel"),
117
+ server: undefined as never,
118
+ authContext: undefined as never,
119
+ });
120
+
121
+ // cancelGeneration must receive the INTERNAL ID, not the raw key.
122
+ expect(cancelledId).toBe(internalId);
123
+ });
124
+
125
+ test("falls back to raw ID when key is not in the mapping", () => {
126
+ let cancelledId: string | undefined;
127
+ const routes = conversationManagementRouteDefinitions({
128
+ switchConversation: async () => null,
129
+ renameConversation: () => false,
130
+ clearAllConversations: () => 0,
131
+ cancelGeneration: (id) => {
132
+ cancelledId = id;
133
+ return true;
134
+ },
135
+ destroyConversation: () => {},
136
+ undoLastMessage: async () => null,
137
+ regenerateResponse: async () => null,
138
+ });
139
+
140
+ const cancelRoute = routes.find(
141
+ (r) => r.endpoint === "conversations/:id/cancel",
142
+ )!;
143
+
144
+ // Use an ID that isn't a known key — should pass through as-is.
145
+ const directId = "direct-conversation-id";
146
+ cancelRoute.handler({
147
+ params: { id: directId },
148
+ req: new Request("http://localhost/v1/conversations/x/cancel", {
149
+ method: "POST",
150
+ }),
151
+ url: new URL("http://localhost/v1/conversations/x/cancel"),
152
+ server: undefined as never,
153
+ authContext: undefined as never,
154
+ });
155
+
156
+ expect(cancelledId).toBe(directId);
157
+ });
158
+ });
@@ -19,7 +19,6 @@ let mockPrimaryInboxAddress: string | undefined;
19
19
  mock.module("../calls/twilio-rest.js", () => ({
20
20
  hasTwilioCredentials: () => mockHasTwilioCredentials,
21
21
  getPhoneNumberSid: async () => null,
22
- getTollFreeVerificationStatus: async () => null,
23
22
  }));
24
23
 
25
24
  mock.module("../config/env.js", () => ({}));
@@ -13,7 +13,6 @@ let mockGatewayHealth = {
13
13
 
14
14
  mock.module("../calls/twilio-rest.js", () => ({
15
15
  getPhoneNumberSid: async () => null,
16
- getTollFreeVerificationStatus: async () => null,
17
16
  getTwilioCredentials: () => ({
18
17
  accountSid: "AC_test",
19
18
  authToken: "test-auth-token",