@vellumai/assistant 0.4.56 → 0.5.0

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 (457) 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 +204 -185
  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 +249 -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__/file-read-tool.test.ts +40 -0
  67. package/src/__tests__/gateway-only-enforcement.test.ts +2 -2
  68. package/src/__tests__/gateway-only-guard.test.ts +1 -0
  69. package/src/__tests__/gemini-image-service.test.ts +4 -4
  70. package/src/__tests__/gemini-provider.test.ts +6 -9
  71. package/src/__tests__/guardian-binding-drift-heal.test.ts +128 -0
  72. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  73. package/src/__tests__/host-file-read-tool.test.ts +87 -0
  74. package/src/__tests__/host-shell-tool.test.ts +6 -6
  75. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  76. package/src/__tests__/identity-intro-cache.test.ts +209 -0
  77. package/src/__tests__/intent-routing.test.ts +51 -99
  78. package/src/__tests__/invite-routes-http.test.ts +5 -0
  79. package/src/__tests__/list-messages-attachments.test.ts +1 -1
  80. package/src/__tests__/managed-proxy-context.test.ts +2 -5
  81. package/src/__tests__/managed-skill-lifecycle.test.ts +8 -8
  82. package/src/__tests__/media-generate-image.test.ts +32 -15
  83. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
  84. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +1 -1
  85. package/src/__tests__/memory-lifecycle-e2e.test.ts +24 -18
  86. package/src/__tests__/memory-recall-quality.test.ts +4 -3
  87. package/src/__tests__/memory-regressions.test.ts +86 -90
  88. package/src/__tests__/migration-cross-version-compatibility.test.ts +32 -32
  89. package/src/__tests__/migration-export-http.test.ts +26 -27
  90. package/src/__tests__/migration-import-commit-http.test.ts +165 -37
  91. package/src/__tests__/migration-import-preflight-http.test.ts +81 -20
  92. package/src/__tests__/migration-validate-http.test.ts +16 -16
  93. package/src/__tests__/model-intents.test.ts +2 -2
  94. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +1 -1
  95. package/src/__tests__/non-member-access-request.test.ts +3 -3
  96. package/src/__tests__/notification-broadcaster.test.ts +1 -1
  97. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  98. package/src/__tests__/notification-decision-identity.test.ts +8 -9
  99. package/src/__tests__/notification-decision-strategy.test.ts +1 -1
  100. package/src/__tests__/notification-deep-link.test.ts +1 -1
  101. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  102. package/src/__tests__/notification-schedule-dedup.test.ts +7 -7
  103. package/src/__tests__/oauth-store.test.ts +1 -3
  104. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -1
  105. package/src/__tests__/onboarding-template-contract.test.ts +23 -59
  106. package/src/__tests__/provider-error-scenarios.test.ts +154 -0
  107. package/src/__tests__/provider-fail-open-selection.test.ts +2 -2
  108. package/src/__tests__/provider-managed-proxy-integration.test.ts +8 -9
  109. package/src/__tests__/provider-registry-ollama.test.ts +5 -2
  110. package/src/__tests__/qdrant-manager.test.ts +7 -7
  111. package/src/__tests__/ratelimit.test.ts +0 -74
  112. package/src/__tests__/recording-handler.test.ts +0 -1
  113. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  114. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  115. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  116. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  117. package/src/__tests__/scheduler-recurrence.test.ts +46 -2
  118. package/src/__tests__/schema-transforms.test.ts +114 -54
  119. package/src/__tests__/secret-onetime-send.test.ts +20 -0
  120. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -2
  121. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  122. package/src/__tests__/send-endpoint-busy.test.ts +63 -4
  123. package/src/__tests__/send-notification-tool.test.ts +2 -2
  124. package/src/__tests__/shell-credential-ref.test.ts +0 -1
  125. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -2
  126. package/src/__tests__/skill-memory.test.ts +549 -0
  127. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -2
  128. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -0
  129. package/src/__tests__/slack-channel-config.test.ts +109 -94
  130. package/src/__tests__/swarm-conversation-integration.test.ts +2 -2
  131. package/src/__tests__/swarm-recursion.test.ts +2 -2
  132. package/src/__tests__/swarm-tool.test.ts +2 -2
  133. package/src/__tests__/system-prompt.test.ts +19 -66
  134. package/src/__tests__/telegram-config.test.ts +121 -0
  135. package/src/__tests__/terminal-tools.test.ts +1 -1
  136. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -2
  137. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  138. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  139. package/src/__tests__/tool-executor.test.ts +1 -1
  140. package/src/__tests__/trace-emitter.test.ts +8 -1
  141. package/src/__tests__/trust-store.test.ts +7 -8
  142. package/src/__tests__/twilio-routes.test.ts +1 -18
  143. package/src/__tests__/user-reference.test.ts +82 -2
  144. package/src/__tests__/vbundle-pax-and-symlink.test.ts +196 -0
  145. package/src/__tests__/verification-control-plane-policy.test.ts +1 -1
  146. package/src/approvals/guardian-request-resolvers.ts +3 -3
  147. package/src/avatar/ascii-renderer.ts +2 -2
  148. package/src/avatar/png-renderer.ts +2 -2
  149. package/src/avatar/resvg-lazy.ts +21 -0
  150. package/src/calls/guardian-dispatch.ts +1 -1
  151. package/src/calls/relay-access-wait.ts +2 -2
  152. package/src/calls/twilio-rest.ts +0 -248
  153. package/src/cli/AGENTS.md +5 -8
  154. package/src/cli/__tests__/notifications.test.ts +5 -5
  155. package/src/cli/commands/avatar.ts +64 -2
  156. package/src/cli/commands/conversations.ts +131 -1
  157. package/src/cli/commands/credentials.ts +2 -0
  158. package/src/cli/commands/notifications.ts +3 -3
  159. package/src/cli.ts +10 -0
  160. package/src/config/bundled-skills/acp/SKILL.md +5 -5
  161. package/src/config/bundled-skills/acp/TOOLS.json +6 -6
  162. package/src/config/bundled-skills/app-builder/SKILL.md +42 -42
  163. package/src/config/bundled-skills/app-builder/TOOLS.json +10 -10
  164. package/src/config/bundled-skills/browser/SKILL.md +15 -15
  165. package/src/config/bundled-skills/browser/TOOLS.json +14 -14
  166. package/src/config/bundled-skills/chatgpt-import/SKILL.md +2 -2
  167. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +1 -1
  168. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  169. package/src/config/bundled-skills/claude-code/SKILL.md +5 -5
  170. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  171. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -15
  172. package/src/config/bundled-skills/contacts/SKILL.md +3 -3
  173. package/src/config/bundled-skills/contacts/TOOLS.json +4 -4
  174. package/src/config/bundled-skills/document/SKILL.md +4 -4
  175. package/src/config/bundled-skills/document/TOOLS.json +2 -2
  176. package/src/config/bundled-skills/followups/TOOLS.json +3 -3
  177. package/src/config/bundled-skills/gmail/SKILL.md +32 -32
  178. package/src/config/bundled-skills/gmail/TOOLS.json +16 -16
  179. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +1 -1
  180. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
  181. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -1
  182. package/src/config/bundled-skills/google-calendar/TOOLS.json +5 -5
  183. package/src/config/bundled-skills/google-calendar/types.ts +1 -1
  184. package/src/config/bundled-skills/heartbeat/SKILL.md +43 -0
  185. package/src/config/bundled-skills/image-studio/SKILL.md +3 -3
  186. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -3
  187. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +16 -12
  188. package/src/config/bundled-skills/media-processing/SKILL.md +40 -40
  189. package/src/config/bundled-skills/media-processing/TOOLS.json +8 -8
  190. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +2 -2
  191. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +1 -1
  192. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +5 -5
  193. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +2 -2
  194. package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -2
  195. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -2
  196. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -3
  197. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  198. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +1 -1
  199. package/src/config/bundled-skills/messaging/SKILL.md +29 -25
  200. package/src/config/bundled-skills/messaging/TOOLS.json +11 -11
  201. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +1 -1
  202. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  203. package/src/config/bundled-skills/notifications/SKILL.md +3 -3
  204. package/src/config/bundled-skills/notifications/TOOLS.json +2 -2
  205. package/src/config/bundled-skills/notifications/tools/send-notification.ts +3 -3
  206. package/src/config/bundled-skills/orchestration/SKILL.md +1 -1
  207. package/src/config/bundled-skills/orchestration/TOOLS.json +1 -1
  208. package/src/config/bundled-skills/phone-calls/SKILL.md +18 -14
  209. package/src/config/bundled-skills/phone-calls/TOOLS.json +3 -3
  210. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +2 -2
  211. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +2 -2
  212. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +1 -1
  213. package/src/config/bundled-skills/playbooks/TOOLS.json +4 -4
  214. package/src/config/bundled-skills/schedule/SKILL.md +26 -26
  215. package/src/config/bundled-skills/schedule/TOOLS.json +5 -5
  216. package/src/config/bundled-skills/screen-watch/SKILL.md +3 -3
  217. package/src/config/bundled-skills/screen-watch/TOOLS.json +1 -1
  218. package/src/config/bundled-skills/sequences/SKILL.md +2 -2
  219. package/src/config/bundled-skills/sequences/TOOLS.json +10 -10
  220. package/src/config/bundled-skills/sequences/tools/sequence-analytics.ts +2 -2
  221. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +2 -2
  222. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +1 -1
  223. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +1 -1
  224. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +3 -3
  225. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +1 -1
  226. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +1 -1
  227. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  228. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  229. package/src/config/bundled-skills/skill-management/TOOLS.json +5 -5
  230. package/src/config/bundled-skills/skills-catalog/SKILL.md +84 -0
  231. package/src/config/bundled-skills/slack/SKILL.md +2 -2
  232. package/src/config/bundled-skills/slack/TOOLS.json +8 -8
  233. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +3 -3
  234. package/src/config/bundled-skills/subagent/TOOLS.json +5 -5
  235. package/src/config/bundled-skills/tasks/SKILL.md +1 -1
  236. package/src/config/bundled-skills/tasks/TOOLS.json +9 -9
  237. package/src/config/bundled-skills/transcribe/SKILL.md +5 -5
  238. package/src/config/bundled-skills/transcribe/TOOLS.json +1 -1
  239. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +10 -10
  240. package/src/config/bundled-skills/watcher/SKILL.md +4 -4
  241. package/src/config/bundled-skills/watcher/TOOLS.json +5 -5
  242. package/src/config/feature-flag-registry.json +33 -17
  243. package/src/config/schemas/sandbox.ts +1 -1
  244. package/src/config/schemas/services.ts +13 -3
  245. package/src/config/schemas/timeouts.ts +0 -10
  246. package/src/contacts/contact-store.ts +63 -0
  247. package/src/contacts/contacts-write.ts +1 -1
  248. package/src/daemon/assistant-attachments.ts +2 -2
  249. package/src/daemon/conversation-agent-loop-handlers.ts +2 -2
  250. package/src/daemon/conversation-agent-loop.ts +7 -30
  251. package/src/daemon/conversation-error.ts +24 -0
  252. package/src/daemon/conversation-memory.ts +8 -7
  253. package/src/daemon/conversation-runtime-assembly.ts +141 -275
  254. package/src/daemon/conversation-slash.ts +7 -26
  255. package/src/daemon/conversation-surfaces.ts +14 -0
  256. package/src/daemon/conversation-tool-setup.ts +9 -8
  257. package/src/daemon/conversation.ts +2 -0
  258. package/src/daemon/daemon-control.ts +1 -1
  259. package/src/daemon/date-context.ts +10 -83
  260. package/src/daemon/handlers/config-channels.ts +12 -2
  261. package/src/daemon/handlers/config-slack-channel.ts +7 -1
  262. package/src/daemon/handlers/config-telegram.ts +6 -1
  263. package/src/daemon/handlers/conversations.ts +2 -2
  264. package/src/daemon/handlers/skills.ts +4 -0
  265. package/src/daemon/lifecycle.ts +28 -4
  266. package/src/daemon/providers-setup.ts +1 -1
  267. package/src/daemon/server.ts +1 -5
  268. package/src/daemon/shutdown-handlers.ts +9 -3
  269. package/src/daemon/tool-side-effects.ts +40 -0
  270. package/src/daemon/trace-emitter.ts +26 -2
  271. package/src/events/domain-events.ts +1 -1
  272. package/src/events/tool-permission-telemetry-listener.ts +46 -0
  273. package/src/inbound/platform-callback-registration.ts +0 -18
  274. package/src/media/app-icon-generator.ts +15 -8
  275. package/src/media/avatar-router.ts +15 -8
  276. package/src/media/gemini-image-service.ts +125 -21
  277. package/src/memory/attachments-store.ts +3 -3
  278. package/src/memory/channel-verification-sessions.ts +6 -6
  279. package/src/memory/conversation-crud.ts +196 -1
  280. package/src/memory/{thread-starters-cadence.ts → conversation-starters-cadence.ts} +9 -42
  281. package/src/memory/conversation-title-service.ts +2 -3
  282. package/src/memory/db-init.ts +25 -1
  283. package/src/memory/invite-store.ts +4 -4
  284. package/src/memory/items-extractor.ts +4 -4
  285. package/src/memory/job-handlers/{thread-starters.ts → conversation-starters.ts} +123 -38
  286. package/src/memory/jobs-store.ts +3 -2
  287. package/src/memory/jobs-worker.ts +7 -5
  288. package/src/memory/lifecycle-events-store.ts +63 -0
  289. package/src/memory/migrations/172-rename-created-by-session-id.ts +27 -0
  290. package/src/memory/migrations/173-rename-source-session-id.ts +16 -0
  291. package/src/memory/migrations/174-rename-thread-starters-table.ts +52 -0
  292. package/src/memory/migrations/175-create-lifecycle-events.ts +15 -0
  293. package/src/memory/migrations/176-drop-capability-card-state.ts +36 -0
  294. package/src/memory/migrations/177-create-trace-events-table.ts +40 -0
  295. package/src/memory/migrations/index.ts +6 -0
  296. package/src/memory/migrations/registry.ts +13 -0
  297. package/src/memory/retriever.test.ts +223 -96
  298. package/src/memory/retriever.ts +115 -138
  299. package/src/memory/schema/calls.ts +1 -1
  300. package/src/memory/schema/contacts.ts +1 -1
  301. package/src/memory/schema/infrastructure.ts +29 -0
  302. package/src/memory/schema/memory-core.ts +7 -17
  303. package/src/memory/schema/notifications.ts +1 -1
  304. package/src/memory/search/formatting.ts +23 -6
  305. package/src/memory/search/lexical.ts +2 -0
  306. package/src/memory/search/semantic.ts +2 -0
  307. package/src/memory/search/staleness.ts +5 -1
  308. package/src/memory/search/types.ts +4 -0
  309. package/src/memory/task-memory-cleanup.ts +96 -6
  310. package/src/memory/trace-event-store.ts +148 -0
  311. package/src/notifications/README.md +1 -1
  312. package/src/notifications/decision-engine.ts +45 -4
  313. package/src/notifications/emit-signal.ts +5 -4
  314. package/src/notifications/events-store.ts +4 -4
  315. package/src/notifications/signal.ts +1 -1
  316. package/src/oauth/manual-token-connection.ts +49 -25
  317. package/src/permissions/checker.ts +6 -5
  318. package/src/permissions/defaults.ts +4 -4
  319. package/src/prompts/__tests__/build-cli-reference-section.test.ts +9 -90
  320. package/src/prompts/cache-boundary.ts +8 -0
  321. package/src/prompts/system-prompt.ts +105 -634
  322. package/src/prompts/templates/BOOTSTRAP.md +172 -33
  323. package/src/prompts/templates/IDENTITY.md +8 -24
  324. package/src/prompts/templates/SOUL.md +20 -41
  325. package/src/prompts/templates/USER.md +3 -19
  326. package/src/prompts/user-reference.ts +14 -16
  327. package/src/providers/anthropic/client.ts +51 -19
  328. package/src/providers/gemini/client.ts +6 -9
  329. package/src/providers/managed-proxy/constants.ts +1 -7
  330. package/src/providers/managed-proxy/context.ts +0 -1
  331. package/src/providers/model-intents.ts +5 -5
  332. package/src/providers/openai/client.ts +10 -1
  333. package/src/providers/openrouter/client.ts +1 -0
  334. package/src/providers/ratelimit.ts +0 -35
  335. package/src/providers/registry.ts +3 -5
  336. package/src/providers/retry.ts +18 -1
  337. package/src/runtime/access-request-helper.ts +16 -2
  338. package/src/runtime/auth/route-policy.ts +7 -0
  339. package/src/runtime/channel-verification-service.ts +1 -1
  340. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  341. package/src/runtime/guardian-vellum-migration.ts +61 -1
  342. package/src/runtime/http-server.ts +8 -4
  343. package/src/runtime/migrations/vbundle-builder.ts +212 -32
  344. package/src/runtime/migrations/vbundle-import-analyzer.ts +74 -8
  345. package/src/runtime/migrations/vbundle-importer.ts +66 -1
  346. package/src/runtime/migrations/vbundle-validator.ts +17 -3
  347. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +4 -4
  348. package/src/runtime/routes/attachment-routes.ts +2 -2
  349. package/src/runtime/routes/btw-routes.ts +93 -0
  350. package/src/runtime/routes/channel-verification-routes.ts +19 -2
  351. package/src/runtime/routes/conversation-management-routes.ts +55 -1
  352. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  353. package/src/runtime/routes/conversation-routes.ts +49 -5
  354. package/src/runtime/routes/conversation-starter-routes.ts +207 -0
  355. package/src/runtime/routes/guardian-bootstrap-routes.ts +13 -9
  356. package/src/runtime/routes/identity-intro-cache.ts +105 -0
  357. package/src/runtime/routes/identity-routes.ts +51 -0
  358. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -1
  359. package/src/runtime/routes/inbound-stages/verification-intercept.ts +1 -1
  360. package/src/runtime/routes/migration-routes.ts +25 -13
  361. package/src/runtime/routes/secret-routes.ts +18 -0
  362. package/src/runtime/routes/settings-routes.ts +9 -9
  363. package/src/runtime/routes/telemetry-routes.ts +53 -0
  364. package/src/runtime/routes/trace-event-routes.ts +62 -0
  365. package/src/runtime/tool-grant-request-helper.ts +1 -1
  366. package/src/runtime/verification-outbound-actions.ts +47 -31
  367. package/src/security/encrypted-store.ts +262 -78
  368. package/src/skills/catalog-install.ts +10 -0
  369. package/src/skills/managed-store.ts +2 -0
  370. package/src/skills/skill-memory.ts +222 -0
  371. package/src/subagent/manager.ts +1 -4
  372. package/src/telemetry/types.ts +10 -1
  373. package/src/telemetry/usage-telemetry-reporter.test.ts +7 -2
  374. package/src/telemetry/usage-telemetry-reporter.ts +53 -4
  375. package/src/tools/AGENTS.md +11 -11
  376. package/src/tools/acp/spawn.ts +1 -1
  377. package/src/tools/apps/executors.ts +8 -8
  378. package/src/tools/apps/registry.ts +1 -1
  379. package/src/tools/assets/materialize.ts +6 -6
  380. package/src/tools/assets/search.ts +10 -10
  381. package/src/tools/browser/__tests__/auth-cache.test.ts +2 -2
  382. package/src/tools/browser/__tests__/auth-detector.test.ts +4 -4
  383. package/src/tools/browser/auth-detector.ts +6 -6
  384. package/src/tools/browser/browser-execution.ts +13 -13
  385. package/src/tools/browser/browser-manager.ts +3 -3
  386. package/src/tools/browser/chrome-cdp.ts +5 -5
  387. package/src/tools/browser/jit-auth.ts +2 -2
  388. package/src/tools/browser/network-recorder.test.ts +2 -2
  389. package/src/tools/browser/network-recorder.ts +3 -3
  390. package/src/tools/browser/runtime-check.ts +3 -3
  391. package/src/tools/claude-code/claude-code.ts +2 -2
  392. package/src/tools/computer-use/definitions.ts +18 -18
  393. package/src/tools/credential-execution/make-authenticated-request.ts +4 -4
  394. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -3
  395. package/src/tools/credential-execution/run-authenticated-command.ts +4 -4
  396. package/src/tools/credentials/broker-types.ts +5 -5
  397. package/src/tools/credentials/broker.ts +15 -15
  398. package/src/tools/credentials/metadata-store.ts +2 -2
  399. package/src/tools/credentials/resolve.ts +1 -1
  400. package/src/tools/credentials/selection.ts +1 -1
  401. package/src/tools/credentials/tool-policy.ts +1 -1
  402. package/src/tools/credentials/vault.ts +115 -25
  403. package/src/tools/execution-target.ts +2 -2
  404. package/src/tools/executor.ts +7 -7
  405. package/src/tools/filesystem/edit.ts +2 -2
  406. package/src/tools/filesystem/read.ts +15 -4
  407. package/src/tools/filesystem/write.ts +1 -1
  408. package/src/tools/host-filesystem/edit.ts +2 -1
  409. package/src/tools/host-filesystem/read.ts +18 -1
  410. package/src/tools/host-filesystem/write.ts +1 -1
  411. package/src/tools/host-terminal/host-shell.ts +9 -8
  412. package/src/tools/mcp/mcp-tool-factory.ts +7 -6
  413. package/src/tools/memory/definitions.ts +6 -5
  414. package/src/tools/memory/handlers.test.ts +1 -1
  415. package/src/tools/network/__tests__/web-search.test.ts +3 -3
  416. package/src/tools/network/domain-normalize.ts +2 -2
  417. package/src/tools/network/script-proxy/session-manager.ts +10 -10
  418. package/src/tools/network/web-fetch.ts +1 -1
  419. package/src/tools/network/web-search.ts +3 -3
  420. package/src/tools/permission-checker.ts +8 -8
  421. package/src/tools/registry.ts +7 -7
  422. package/src/tools/schedule/list.ts +2 -2
  423. package/src/tools/schema-transforms.ts +31 -21
  424. package/src/tools/secret-detection-handler.ts +1 -1
  425. package/src/tools/sensitive-output-placeholders.ts +1 -1
  426. package/src/tools/shared/filesystem/edit-engine.ts +1 -1
  427. package/src/tools/shared/filesystem/file-ops-service.ts +3 -3
  428. package/src/tools/shared/filesystem/image-read.ts +25 -5
  429. package/src/tools/shared/filesystem/path-policy.ts +2 -2
  430. package/src/tools/shared/shell-output.ts +1 -1
  431. package/src/tools/side-effects.ts +1 -1
  432. package/src/tools/skills/execute.ts +1 -1
  433. package/src/tools/skills/load.ts +3 -3
  434. package/src/tools/skills/sandbox-runner.ts +3 -3
  435. package/src/tools/subagent/read.ts +1 -1
  436. package/src/tools/subagent/spawn.ts +2 -2
  437. package/src/tools/swarm/delegate.ts +3 -3
  438. package/src/tools/system/request-permission.ts +5 -4
  439. package/src/tools/terminal/backends/native.ts +4 -4
  440. package/src/tools/terminal/parser.ts +6 -6
  441. package/src/tools/terminal/sandbox-diagnostics.ts +1 -1
  442. package/src/tools/terminal/shell.ts +16 -16
  443. package/src/tools/tool-approval-handler.ts +21 -12
  444. package/src/tools/tool-manifest.ts +4 -4
  445. package/src/tools/types.ts +3 -3
  446. package/src/tools/ui-surface/definitions.ts +9 -37
  447. package/src/tools/watcher/list.ts +1 -1
  448. package/src/util/logger.ts +7 -2
  449. package/src/util/pricing.ts +4 -0
  450. package/src/util/retry.ts +29 -1
  451. package/src/workspace/migrations/007-web-search-provider-rename.ts +37 -0
  452. package/src/workspace/migrations/registry.ts +2 -0
  453. package/src/__tests__/cli-help-reference-sync.test.ts +0 -26
  454. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -190
  455. package/src/cli/reference.ts +0 -38
  456. package/src/memory/job-handlers/capability-cards.ts +0 -420
  457. package/src/runtime/routes/thread-starter-routes.ts +0 -294
@@ -331,254 +331,6 @@ export async function updatePhoneNumberWebhooks(
331
331
  }
332
332
  }
333
333
 
334
- // ── Toll-Free Verification ──────────────────────────────────────────────
335
-
336
- /** Twilio Messaging API base URL for toll-free verification endpoints. */
337
- const TOLLFREE_VERIFICATION_BASE =
338
- "https://messaging.twilio.com/v1/Tollfree/Verifications";
339
-
340
- export interface TollFreeVerification {
341
- sid: string;
342
- status: string;
343
- rejectionReason?: string;
344
- rejectionReasons?: string[];
345
- errorCode?: string;
346
- editAllowed?: boolean;
347
- editExpiration?: string;
348
- regulationType?: string;
349
- }
350
-
351
- function parseTollFreeVerification(
352
- raw: Record<string, unknown>,
353
- ): TollFreeVerification {
354
- return {
355
- sid: raw.sid as string,
356
- status: raw.status as string,
357
- rejectionReason: (raw.rejection_reason as string) ?? undefined,
358
- rejectionReasons: (raw.rejection_reasons as string[]) ?? undefined,
359
- errorCode: raw.error_code != null ? String(raw.error_code) : undefined,
360
- editAllowed: (raw.edit_allowed as boolean) ?? undefined,
361
- editExpiration: (raw.edit_expiration as string) ?? undefined,
362
- regulationType: (raw.regulation_type as string) ?? undefined,
363
- };
364
- }
365
-
366
- /**
367
- * Get toll-free verification status for a phone number.
368
- * If `phoneNumberSid` is provided, filters by that SID; otherwise returns the
369
- * first verification found.
370
- */
371
- export async function getTollFreeVerificationStatus(
372
- accountSid: string,
373
- authToken: string,
374
- phoneNumberSid?: string,
375
- ): Promise<TollFreeVerification | null> {
376
- const params = new URLSearchParams();
377
- if (phoneNumberSid) params.set("TollfreePhoneNumberSid", phoneNumberSid);
378
-
379
- const url = params.toString()
380
- ? `${TOLLFREE_VERIFICATION_BASE}?${params.toString()}`
381
- : TOLLFREE_VERIFICATION_BASE;
382
-
383
- const res = await fetch(url, {
384
- method: "GET",
385
- headers: { Authorization: twilioAuthHeader(accountSid, authToken) },
386
- });
387
-
388
- if (!res.ok) {
389
- const text = await res.text();
390
- throw new ProviderError(
391
- `Twilio Toll-Free Verification API error ${res.status}: ${text}`,
392
- "twilio",
393
- res.status,
394
- );
395
- }
396
-
397
- const data = (await res.json()) as {
398
- verifications?: Array<Record<string, unknown>>;
399
- };
400
- const verifications = data.verifications ?? [];
401
- if (verifications.length === 0) return null;
402
-
403
- return parseTollFreeVerification(verifications[0]);
404
- }
405
-
406
- /** Fetch a specific toll-free verification by SID. */
407
- export async function getTollFreeVerificationBySid(
408
- accountSid: string,
409
- authToken: string,
410
- verificationSid: string,
411
- ): Promise<TollFreeVerification | null> {
412
- const res = await fetch(
413
- `${TOLLFREE_VERIFICATION_BASE}/${encodeURIComponent(verificationSid)}`,
414
- {
415
- method: "GET",
416
- headers: { Authorization: twilioAuthHeader(accountSid, authToken) },
417
- },
418
- );
419
-
420
- if (res.status === 404) {
421
- return null;
422
- }
423
-
424
- if (!res.ok) {
425
- const text = await res.text();
426
- throw new ProviderError(
427
- `Twilio Toll-Free Verification fetch error ${res.status}: ${text}`,
428
- "twilio",
429
- res.status,
430
- );
431
- }
432
-
433
- const data = (await res.json()) as Record<string, unknown>;
434
- return parseTollFreeVerification(data);
435
- }
436
-
437
- export interface TollFreeVerificationSubmitParams {
438
- tollfreePhoneNumberSid: string;
439
- businessName: string;
440
- businessWebsite: string;
441
- notificationEmail: string;
442
- useCaseCategories: string[];
443
- useCaseSummary: string;
444
- productionMessageSample: string;
445
- optInImageUrls: string[];
446
- optInType: string;
447
- messageVolume: string;
448
- businessType?: string;
449
- customerProfileSid?: string;
450
- }
451
-
452
- /** Submit a new toll-free verification request. */
453
- export async function submitTollFreeVerification(
454
- accountSid: string,
455
- authToken: string,
456
- params: TollFreeVerificationSubmitParams,
457
- ): Promise<TollFreeVerification> {
458
- const body = new URLSearchParams();
459
- body.set("TollfreePhoneNumberSid", params.tollfreePhoneNumberSid);
460
- body.set("BusinessName", params.businessName);
461
- body.set("BusinessWebsite", params.businessWebsite);
462
- body.set("NotificationEmail", params.notificationEmail);
463
- body.set("UseCaseSummary", params.useCaseSummary);
464
- body.set("ProductionMessageSample", params.productionMessageSample);
465
- body.set("OptInType", params.optInType);
466
- body.set("MessageVolume", params.messageVolume);
467
- body.set("BusinessType", params.businessType ?? "SOLE_PROPRIETOR");
468
-
469
- for (const cat of params.useCaseCategories) {
470
- body.append("UseCaseCategories", cat);
471
- }
472
- for (const url of params.optInImageUrls) {
473
- body.append("OptInImageUrls", url);
474
- }
475
- if (params.customerProfileSid) {
476
- body.set("CustomerProfileSid", params.customerProfileSid);
477
- }
478
-
479
- const res = await fetch(TOLLFREE_VERIFICATION_BASE, {
480
- method: "POST",
481
- headers: {
482
- Authorization: twilioAuthHeader(accountSid, authToken),
483
- "Content-Type": "application/x-www-form-urlencoded",
484
- },
485
- body: body.toString(),
486
- });
487
-
488
- if (!res.ok) {
489
- const text = await res.text();
490
- throw new ProviderError(
491
- `Twilio Toll-Free Verification submit error ${res.status}: ${text}`,
492
- "twilio",
493
- res.status,
494
- );
495
- }
496
-
497
- const data = (await res.json()) as Record<string, unknown>;
498
- return parseTollFreeVerification(data);
499
- }
500
-
501
- /** Update an existing toll-free verification. */
502
- export async function updateTollFreeVerification(
503
- accountSid: string,
504
- authToken: string,
505
- verificationSid: string,
506
- params: Partial<TollFreeVerificationSubmitParams>,
507
- ): Promise<TollFreeVerification> {
508
- const body = new URLSearchParams();
509
- if (params.businessName) body.set("BusinessName", params.businessName);
510
- if (params.businessWebsite)
511
- body.set("BusinessWebsite", params.businessWebsite);
512
- if (params.notificationEmail)
513
- body.set("NotificationEmail", params.notificationEmail);
514
- if (params.useCaseSummary) body.set("UseCaseSummary", params.useCaseSummary);
515
- if (params.productionMessageSample)
516
- body.set("ProductionMessageSample", params.productionMessageSample);
517
- if (params.optInType) body.set("OptInType", params.optInType);
518
- if (params.messageVolume) body.set("MessageVolume", params.messageVolume);
519
- if (params.businessType) body.set("BusinessType", params.businessType);
520
- if (params.useCaseCategories) {
521
- for (const cat of params.useCaseCategories) {
522
- body.append("UseCaseCategories", cat);
523
- }
524
- }
525
- if (params.optInImageUrls) {
526
- for (const url of params.optInImageUrls) {
527
- body.append("OptInImageUrls", url);
528
- }
529
- }
530
- if (params.customerProfileSid)
531
- body.set("CustomerProfileSid", params.customerProfileSid);
532
-
533
- const res = await fetch(
534
- `${TOLLFREE_VERIFICATION_BASE}/${encodeURIComponent(verificationSid)}`,
535
- {
536
- method: "POST",
537
- headers: {
538
- Authorization: twilioAuthHeader(accountSid, authToken),
539
- "Content-Type": "application/x-www-form-urlencoded",
540
- },
541
- body: body.toString(),
542
- },
543
- );
544
-
545
- if (!res.ok) {
546
- const text = await res.text();
547
- throw new ProviderError(
548
- `Twilio Toll-Free Verification update error ${res.status}: ${text}`,
549
- "twilio",
550
- res.status,
551
- );
552
- }
553
-
554
- const data = (await res.json()) as Record<string, unknown>;
555
- return parseTollFreeVerification(data);
556
- }
557
-
558
- /** Delete a toll-free verification. */
559
- export async function deleteTollFreeVerification(
560
- accountSid: string,
561
- authToken: string,
562
- verificationSid: string,
563
- ): Promise<void> {
564
- const res = await fetch(
565
- `${TOLLFREE_VERIFICATION_BASE}/${encodeURIComponent(verificationSid)}`,
566
- {
567
- method: "DELETE",
568
- headers: { Authorization: twilioAuthHeader(accountSid, authToken) },
569
- },
570
- );
571
-
572
- if (!res.ok) {
573
- const text = await res.text();
574
- throw new ProviderError(
575
- `Twilio Toll-Free Verification delete error ${res.status}: ${text}`,
576
- "twilio",
577
- res.status,
578
- );
579
- }
580
- }
581
-
582
334
  /**
583
335
  * Get the SID for an incoming phone number.
584
336
  * Looks up the number via `IncomingPhoneNumbers.json?PhoneNumber=...`.
package/src/cli/AGENTS.md CHANGED
@@ -6,14 +6,11 @@ Commands in `assistant/src/cli/` are scoped to a **single running assistant inst
6
6
 
7
7
  This contrasts with `cli/`, which manages the **lifecycle of assistant instances** (create, start, stop, delete) and operates across instances. See `cli/AGENTS.md`.
8
8
 
9
- ## When a command belongs here vs `cli/`
10
-
11
- | `assistant/src/cli/` (this directory) | `cli/` |
12
- | --------------------------------------------------- | ----------------------------------------------- |
13
- | Operates within a single assistant's workspace | Operates on or across assistant instances |
14
- | Manages instance-local state (config, memory, etc.) | Manages lifecycle (create, start, stop, delete) |
15
- | Implicitly scoped to the running assistant | Requires specifying which assistant to target |
16
- | May require or start the daemon | Works without an assistant process running |
9
+ ## Scope
10
+
11
+ Commands here operate on a **single running assistant's** local state — config, memory, contacts, trust rules, conversations, autonomy, etc. They are implicitly scoped to the running assistant and may require or start the daemon.
12
+
13
+ For commands that manage the **lifecycle of assistant instances** (create, start, stop, delete), see `cli/AGENTS.md`.
17
14
 
18
15
  Examples: `config`, `contacts`, `memory`, `autonomy`, `conversations`, `doctor` belong here. `hatch`, `wake`, `sleep`, `retire`, `ps`, `ssh` belong in `cli/`.
19
16
 
@@ -337,7 +337,7 @@ describe("notifications list", () => {
337
337
  id: `evt-${Date.now()}-1`,
338
338
  sourceEventName: "user.send_notification",
339
339
  sourceChannel: "assistant_tool",
340
- sourceSessionId: "session-1",
340
+ sourceContextId: "session-1",
341
341
  attentionHints: {
342
342
  requiresAction: true,
343
343
  urgency: "medium",
@@ -362,7 +362,7 @@ describe("notifications list", () => {
362
362
  id: `evt-limit-${Date.now()}-${i}`,
363
363
  sourceEventName: "user.send_notification",
364
364
  sourceChannel: "assistant_tool",
365
- sourceSessionId: `session-limit-${i}`,
365
+ sourceContextId: `session-limit-${i}`,
366
366
  attentionHints: {
367
367
  requiresAction: true,
368
368
  urgency: "medium",
@@ -386,7 +386,7 @@ describe("notifications list", () => {
386
386
  id: `evt-filter-notif-${Date.now()}`,
387
387
  sourceEventName: "user.send_notification",
388
388
  sourceChannel: "assistant_tool",
389
- sourceSessionId: "session-filter-1",
389
+ sourceContextId: "session-filter-1",
390
390
  attentionHints: {
391
391
  requiresAction: true,
392
392
  urgency: "medium",
@@ -400,7 +400,7 @@ describe("notifications list", () => {
400
400
  id: `evt-filter-reminder-${Date.now()}`,
401
401
  sourceEventName: "schedule.notify",
402
402
  sourceChannel: "scheduler",
403
- sourceSessionId: "session-filter-2",
403
+ sourceContextId: "session-filter-2",
404
404
  attentionHints: {
405
405
  requiresAction: true,
406
406
  urgency: "high",
@@ -430,7 +430,7 @@ describe("notifications list", () => {
430
430
  id: `evt-custom-${Date.now()}`,
431
431
  sourceEventName: "custom.my_event",
432
432
  sourceChannel: "assistant_tool",
433
- sourceSessionId: "session-custom",
433
+ sourceContextId: "session-custom",
434
434
  attentionHints: {
435
435
  requiresAction: true,
436
436
  urgency: "medium",
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from "node:fs";
1
+ import { existsSync, readFileSync, unlinkSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
4
  import type { Command } from "commander";
@@ -9,6 +9,10 @@ import {
9
9
  type CharacterTraits,
10
10
  writeTraitsAndRenderAvatar,
11
11
  } from "../../avatar/traits-png-sync.js";
12
+ import { setPlatformBaseUrl } from "../../config/env.js";
13
+ import { credentialKey } from "../../security/credential-key.js";
14
+ import { getSecureKeyAsync } from "../../security/secure-keys.js";
15
+ import { generateAndSaveAvatar } from "../../tools/system/avatar-generator.js";
12
16
  import { getWorkspaceDir } from "../../util/platform.js";
13
17
  import { log } from "../logger.js";
14
18
  import { writeOutput } from "../output.js";
@@ -39,9 +43,67 @@ Files are stored in ~/.vellum/workspace/data/avatar/:
39
43
  Examples:
40
44
  $ assistant avatar character update --body-shape blob --eye-style curious --color green
41
45
  $ assistant avatar character components
42
- $ assistant avatar character ascii`,
46
+ $ assistant avatar character ascii
47
+ $ assistant avatar generate --description "a cute blue cat"`,
43
48
  );
44
49
 
50
+ avatar
51
+ .command("generate")
52
+ .description("Generate an AI avatar from a text description")
53
+ .requiredOption(
54
+ "--description <text>",
55
+ "Description of the avatar to generate",
56
+ )
57
+ .addHelpText(
58
+ "after",
59
+ `
60
+ Generates an avatar image using AI based on the provided text description
61
+ and saves it as the assistant's avatar PNG. This replaces any existing
62
+ native character avatar — the character traits and ASCII files are removed.
63
+
64
+ On success, writes avatar-image.png to ~/.vellum/workspace/data/avatar/
65
+ and removes character-traits.json and character-ascii.txt if they exist.
66
+
67
+ Examples:
68
+ $ assistant avatar generate --description "a cute blue cat"
69
+ $ assistant avatar generate --description "a friendly robot with green eyes"`,
70
+ )
71
+ .action(async (opts: { description: string }) => {
72
+ // Rehydrate the platform base URL from the credential store so the
73
+ // managed proxy fallback works. The CLI runs as a separate process
74
+ // without the daemon's in-memory state.
75
+ try {
76
+ const key = credentialKey("vellum", "platform_base_url");
77
+ const persisted = await getSecureKeyAsync(key);
78
+ if (persisted) {
79
+ setPlatformBaseUrl(persisted);
80
+ }
81
+ } catch {
82
+ // Non-fatal — direct Gemini key may still work
83
+ }
84
+
85
+ const result = await generateAndSaveAvatar(opts.description);
86
+
87
+ if (result.isError) {
88
+ log.error(result.content);
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+
93
+ // Remove native character files since AI-generated image takes precedence
94
+ const avatarDir = join(getWorkspaceDir(), "data", "avatar");
95
+ const traitsPath = join(avatarDir, "character-traits.json");
96
+ const asciiPath = join(avatarDir, "character-ascii.txt");
97
+ try {
98
+ if (existsSync(traitsPath)) unlinkSync(traitsPath);
99
+ if (existsSync(asciiPath)) unlinkSync(asciiPath);
100
+ } catch {
101
+ // Best-effort cleanup
102
+ }
103
+
104
+ log.info(result.content);
105
+ });
106
+
45
107
  const character = avatar
46
108
  .command("character")
47
109
  .description("Manage the native character avatar");
@@ -1,8 +1,13 @@
1
1
  import type { Command } from "commander";
2
2
 
3
- import { getQdrantUrlEnv } from "../../config/env.js";
3
+ import {
4
+ getQdrantUrlEnv,
5
+ getRuntimeHttpHost,
6
+ getRuntimeHttpPort,
7
+ } from "../../config/env.js";
4
8
  import { getConfig } from "../../config/loader.js";
5
9
  import { shouldAutoStartDaemon } from "../../daemon/connection-policy.js";
10
+ import { healthCheckHost, isHttpHealthy } from "../../daemon/daemon-control.js";
6
11
  import { ensureDaemonRunning } from "../../daemon/lifecycle.js";
7
12
  import { formatJson, formatMarkdown } from "../../export/formatter.js";
8
13
  import {
@@ -10,13 +15,20 @@ import {
10
15
  createConversation,
11
16
  getConversation,
12
17
  getMessages,
18
+ wipeConversation,
13
19
  } from "../../memory/conversation-crud.js";
14
20
  import { listConversations } from "../../memory/conversation-queries.js";
15
21
  import {
16
22
  selectEmbeddingBackend,
17
23
  SPARSE_EMBEDDING_VERSION,
18
24
  } from "../../memory/embedding-backend.js";
25
+ import { enqueueMemoryJob } from "../../memory/jobs-store.js";
19
26
  import { initQdrantClient } from "../../memory/qdrant-client.js";
27
+ import {
28
+ initAuthSigningKey,
29
+ loadOrCreateSigningKey,
30
+ mintDaemonDeliveryToken,
31
+ } from "../../runtime/auth/token-service.js";
20
32
  import { timeAgo } from "../../util/time.js";
21
33
  import { initializeDb } from "../db.js";
22
34
  import { log } from "../logger.js";
@@ -253,4 +265,122 @@ Examples:
253
265
 
254
266
  log.info("Done.");
255
267
  });
268
+
269
+ conversations
270
+ .command("wipe <conversationId>")
271
+ .description("Wipe a conversation and revert all memory changes it made")
272
+ .option("-y, --yes", "Skip confirmation prompt")
273
+ .addHelpText(
274
+ "after",
275
+ `
276
+ Arguments:
277
+ conversationId Conversation ID (or unique prefix). Supports prefix matching.
278
+
279
+ Permanently wipes the conversation and reverts all memory changes it caused:
280
+ restores superseded memory items, deletes conversation summaries, and cancels
281
+ pending memory jobs. This action cannot be undone.
282
+
283
+ Examples:
284
+ $ assistant conversations wipe abc123
285
+ $ assistant conversations wipe abc123 --yes`,
286
+ )
287
+ .action(async (conversationId: string, opts?: { yes?: boolean }) => {
288
+ initializeDb();
289
+
290
+ // Resolve conversation with prefix matching (same pattern as `export`)
291
+ let conversation = getConversation(conversationId);
292
+ if (!conversation) {
293
+ const all = listConversations(Number.MAX_SAFE_INTEGER);
294
+ const match = all.find((c) => c.id.startsWith(conversationId));
295
+ if (match) {
296
+ conversation = match;
297
+ } else {
298
+ log.error(`Conversation not found: ${conversationId}`);
299
+ process.exit(1);
300
+ }
301
+ }
302
+
303
+ if (!opts?.yes) {
304
+ const readline = await import("node:readline");
305
+ const rl = readline.createInterface({
306
+ input: process.stdin,
307
+ output: process.stdout,
308
+ });
309
+ const answer = await new Promise<string>((resolve) => {
310
+ rl.question(
311
+ `Wipe conversation "${conversation!.title ?? "Untitled"}" and revert all memory changes? (y/N) `,
312
+ resolve,
313
+ );
314
+ });
315
+ rl.close();
316
+ if (answer.toLowerCase() !== "y") {
317
+ log.info("Cancelled");
318
+ return;
319
+ }
320
+ }
321
+
322
+ // When the assistant is running, delegate to its HTTP wipe endpoint
323
+ // so it tears down in-memory conversation state before deleting DB
324
+ // rows — preventing FK constraint failures from follow-up writes.
325
+ if (await isHttpHealthy()) {
326
+ const port = getRuntimeHttpPort();
327
+ const host = healthCheckHost(getRuntimeHttpHost());
328
+ initAuthSigningKey(loadOrCreateSigningKey());
329
+ const token = mintDaemonDeliveryToken();
330
+ const res = await fetch(
331
+ `http://${host}:${port}/v1/conversations/${conversation.id}/wipe`,
332
+ {
333
+ method: "POST",
334
+ headers: { Authorization: `Bearer ${token}` },
335
+ },
336
+ );
337
+ if (!res.ok) {
338
+ const body = await res.text();
339
+ log.error(`Assistant wipe failed (${res.status}): ${body}`);
340
+ process.exit(1);
341
+ }
342
+ const json = (await res.json()) as {
343
+ unsupersededItems: number;
344
+ deletedSummaries: number;
345
+ cancelledJobs: number;
346
+ };
347
+ log.info(
348
+ `Wiped conversation "${conversation.title ?? "Untitled"}". ` +
349
+ `Restored ${json.unsupersededItems} memory items, ` +
350
+ `deleted ${json.deletedSummaries} summaries, ` +
351
+ `cancelled ${json.cancelledJobs} jobs.`,
352
+ );
353
+ return;
354
+ }
355
+
356
+ // Daemon not running — safe to wipe directly (no in-memory state).
357
+ const result = wipeConversation(conversation.id);
358
+
359
+ // Enqueue Qdrant cleanup
360
+ for (const segId of result.segmentIds) {
361
+ enqueueMemoryJob("delete_qdrant_vectors", {
362
+ targetType: "segment",
363
+ targetId: segId,
364
+ });
365
+ }
366
+ for (const itemId of result.orphanedItemIds) {
367
+ enqueueMemoryJob("delete_qdrant_vectors", {
368
+ targetType: "item",
369
+ targetId: itemId,
370
+ });
371
+ }
372
+ for (const summaryId of result.deletedSummaryIds) {
373
+ enqueueMemoryJob("delete_qdrant_vectors", {
374
+ targetType: "summary",
375
+ targetId: summaryId,
376
+ });
377
+ }
378
+
379
+ log.info(
380
+ `Wiped conversation "${conversation.title ?? "Untitled"}". ` +
381
+ `Restored ${result.unsupersededItemIds.length} memory items, ` +
382
+ `deleted ${result.deletedSummaryIds.length} summaries, ` +
383
+ `cancelled ${result.cancelledJobCount} jobs.`,
384
+ );
385
+ });
256
386
  }
@@ -4,6 +4,7 @@ import {
4
4
  fetchManagedCatalog,
5
5
  type ManagedCredentialDescriptor,
6
6
  } from "../../credential-execution/managed-catalog.js";
7
+ import { syncManualTokenConnection } from "../../oauth/manual-token-connection.js";
7
8
  import {
8
9
  disconnectOAuthProvider,
9
10
  getConnectionByProvider,
@@ -439,6 +440,7 @@ Examples:
439
440
  usageDescription: opts.description,
440
441
  allowedTools,
441
442
  });
443
+ await syncManualTokenConnection(service);
442
444
 
443
445
  writeOutput(cmd, {
444
446
  ok: true,
@@ -252,12 +252,12 @@ Examples:
252
252
 
253
253
  initializeDb();
254
254
 
255
- const sourceSessionId = opts.conversationId ?? `cli-${Date.now()}`;
255
+ const sourceContextId = opts.conversationId ?? `cli-${Date.now()}`;
256
256
 
257
257
  const result = await emitNotificationSignal({
258
258
  sourceEventName: opts.sourceEventName,
259
259
  sourceChannel: opts.sourceChannel,
260
- sourceSessionId,
260
+ sourceContextId,
261
261
  attentionHints: {
262
262
  requiresAction: opts.requiresAction ?? true,
263
263
  urgency,
@@ -374,7 +374,7 @@ Examples:
374
374
  id: row.id,
375
375
  sourceEventName: row.sourceEventName,
376
376
  sourceChannel: row.sourceChannel,
377
- sourceSessionId: row.sourceSessionId,
377
+ sourceContextId: row.sourceContextId,
378
378
  urgency: (JSON.parse(row.attentionHintsJson) as { urgency: string })
379
379
  .urgency,
380
380
  dedupeKey: row.dedupeKey,
package/src/cli.ts CHANGED
@@ -160,6 +160,7 @@ export async function startCli(): Promise<void> {
160
160
  let pendingConfirmation = false;
161
161
  let pendingCopySession = false;
162
162
  let toolStreaming = false;
163
+ let lastDisplayedError: string | null = null;
163
164
  let eventSubscription: EventStreamWatcher | null = null;
164
165
  const spinner = new Spinner();
165
166
 
@@ -842,6 +843,14 @@ export async function startCli(): Promise<void> {
842
843
  renderConfirmationPrompt(msg);
843
844
  break;
844
845
 
846
+ case "conversation_error":
847
+ spinner.stop();
848
+ if (lastDisplayedError !== msg.userMessage) {
849
+ process.stdout.write(`\n[Error: ${msg.userMessage}]\n`);
850
+ }
851
+ lastDisplayedError = null;
852
+ break;
853
+
845
854
  case "error":
846
855
  spinner.stop();
847
856
  generating = false;
@@ -852,6 +861,7 @@ export async function startCli(): Promise<void> {
852
861
  rl.removeAllListeners("line");
853
862
  rl.on("line", handleLine);
854
863
  }
864
+ lastDisplayedError = msg.message;
855
865
  process.stdout.write(`\n[Error: ${msg.message}]\n`);
856
866
  prompt();
857
867
  break;
@@ -8,7 +8,7 @@ metadata:
8
8
  display-name: "ACP"
9
9
  ---
10
10
 
11
- ACP agent orchestration spawn external coding agents (Claude Code, Codex, Gemini CLI, etc.) to work on tasks via the Agent Client Protocol.
11
+ ACP agent orchestration - spawn external coding agents (Claude Code, Codex, Gemini CLI, etc.) to work on tasks via the Agent Client Protocol.
12
12
 
13
13
  ## Usage
14
14
 
@@ -40,13 +40,13 @@ When the user first tries to use ACP and it's not configured, set it up automati
40
40
  }
41
41
  ```
42
42
 
43
- 3. **Wait a few seconds** for the config watcher to pick up the change (it hot-reloads automatically no restart needed).
43
+ 3. **Wait a few seconds** for the config watcher to pick up the change (it hot-reloads automatically - no restart needed).
44
44
 
45
- 4. Then retry the `acp_spawn` call. Do NOT run `vellum sleep && vellum wake` that kills the conversation.
45
+ 4. Then retry the `acp_spawn` call. Do NOT run `vellum sleep && vellum wake` - that kills the conversation.
46
46
 
47
47
  ## Critical: correct agent command
48
48
 
49
- - The command MUST be `claude-agent-acp` this is the ACP adapter from `@zed-industries/claude-agent-acp`.
49
+ - The command MUST be `claude-agent-acp` - this is the ACP adapter from `@zed-industries/claude-agent-acp`.
50
50
  - NEVER use `claude`, `claude -p`, `claude --acp`, or any other command. Only `claude-agent-acp` speaks the ACP JSON-RPC protocol.
51
51
  - NEVER change an existing ACP config to use a different command. If the config already has `claude-agent-acp`, leave it alone.
52
52
 
@@ -55,4 +55,4 @@ When the user first tries to use ACP and it's not configured, set it up automati
55
55
  - The spawned agent runs autonomously with its own tools, file editing, and terminal access.
56
56
  - Results are streamed back and injected into the conversation when the agent completes.
57
57
  - Use `acp_status` to check on running agents and `acp_abort` to stop them.
58
- - The `cwd` parameter controls where the agent works set it to the project root the user wants the agent to operate in.
58
+ - The `cwd` parameter controls where the agent works - set it to the project root the user wants the agent to operate in.