@vellumai/assistant 0.5.5 → 0.5.7

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 (382) hide show
  1. package/.env.example +16 -2
  2. package/ARCHITECTURE.md +6 -75
  3. package/Dockerfile +4 -5
  4. package/README.md +0 -2
  5. package/bun.lock +0 -414
  6. package/docs/architecture/keychain-broker.md +45 -240
  7. package/docs/architecture/security.md +0 -17
  8. package/docs/credential-execution-service.md +2 -2
  9. package/node_modules/@vellumai/ces-contracts/package.json +1 -0
  10. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +119 -0
  11. package/node_modules/@vellumai/credential-storage/package.json +1 -0
  12. package/node_modules/@vellumai/egress-proxy/package.json +1 -0
  13. package/package.json +2 -3
  14. package/src/__tests__/actor-token-service.test.ts +1 -2
  15. package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
  16. package/src/__tests__/browser-skill-endstate.test.ts +6 -5
  17. package/src/__tests__/btw-routes.test.ts +0 -39
  18. package/src/__tests__/call-domain.test.ts +0 -128
  19. package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
  20. package/src/__tests__/channel-approval-routes.test.ts +0 -5
  21. package/src/__tests__/channel-readiness-service.test.ts +1 -60
  22. package/src/__tests__/checker.test.ts +4 -2
  23. package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
  24. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  25. package/src/__tests__/config-schema.test.ts +3 -3
  26. package/src/__tests__/context-window-manager.test.ts +78 -0
  27. package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
  28. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  29. package/src/__tests__/conversation-skill-tools.test.ts +0 -54
  30. package/src/__tests__/conversation-title-service.test.ts +117 -1
  31. package/src/__tests__/credential-execution-feature-gates.test.ts +28 -14
  32. package/src/__tests__/credential-execution-managed-contract.test.ts +33 -18
  33. package/src/__tests__/credential-security-e2e.test.ts +0 -66
  34. package/src/__tests__/credential-security-invariants.test.ts +4 -45
  35. package/src/__tests__/credentials-cli.test.ts +78 -0
  36. package/src/__tests__/db-migration-rollback.test.ts +2015 -1
  37. package/src/__tests__/docker-signing-key-bootstrap.test.ts +98 -0
  38. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
  39. package/src/__tests__/guardian-routing-state.test.ts +0 -5
  40. package/src/__tests__/host-shell-tool.test.ts +6 -7
  41. package/src/__tests__/http-user-message-parity.test.ts +3 -103
  42. package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
  43. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
  44. package/src/__tests__/intent-routing.test.ts +0 -13
  45. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
  46. package/src/__tests__/keychain-broker-client.test.ts +161 -22
  47. package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
  48. package/src/__tests__/memory-regressions.test.ts +8 -30
  49. package/src/__tests__/migration-export-http.test.ts +2 -2
  50. package/src/__tests__/migration-import-commit-http.test.ts +2 -2
  51. package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
  52. package/src/__tests__/migration-validate-http.test.ts +2 -2
  53. package/src/__tests__/non-member-access-request.test.ts +0 -5
  54. package/src/__tests__/notification-decision-fallback.test.ts +4 -0
  55. package/src/__tests__/notification-decision-identity.test.ts +4 -0
  56. package/src/__tests__/permission-types.test.ts +1 -0
  57. package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
  58. package/src/__tests__/qdrant-manager.test.ts +28 -2
  59. package/src/__tests__/registry.test.ts +0 -6
  60. package/src/__tests__/require-fresh-approval.test.ts +4 -0
  61. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
  62. package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
  63. package/src/__tests__/secure-keys.test.ts +83 -263
  64. package/src/__tests__/shell-identity.test.ts +96 -6
  65. package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
  66. package/src/__tests__/skill-feature-flags.test.ts +46 -45
  67. package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
  68. package/src/__tests__/skill-load-inline-command.test.ts +8 -12
  69. package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
  70. package/src/__tests__/skill-load-tool.test.ts +0 -2
  71. package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
  72. package/src/__tests__/skills.test.ts +0 -2
  73. package/src/__tests__/slack-inbound-verification.test.ts +0 -4
  74. package/src/__tests__/suggestion-routes.test.ts +1 -32
  75. package/src/__tests__/system-prompt.test.ts +0 -1
  76. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -0
  77. package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
  78. package/src/__tests__/tool-executor.test.ts +4 -0
  79. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
  80. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
  81. package/src/__tests__/update-bulletin.test.ts +0 -2
  82. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
  83. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -6
  84. package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
  85. package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +218 -0
  86. package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
  87. package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
  88. package/src/calls/audio-store.test.ts +97 -0
  89. package/src/calls/audio-store.ts +205 -0
  90. package/src/calls/call-controller.ts +85 -7
  91. package/src/calls/call-domain.ts +3 -0
  92. package/src/calls/call-store.ts +10 -3
  93. package/src/calls/fish-audio-client.ts +117 -0
  94. package/src/calls/relay-server.ts +27 -0
  95. package/src/calls/twilio-routes.ts +2 -1
  96. package/src/calls/types.ts +1 -0
  97. package/src/calls/voice-ingress-preflight.ts +0 -42
  98. package/src/calls/voice-quality.ts +26 -5
  99. package/src/calls/voice-session-bridge.ts +6 -12
  100. package/src/cli/commands/config.ts +1 -4
  101. package/src/cli/commands/conversations.ts +0 -18
  102. package/src/cli/commands/credentials.ts +34 -4
  103. package/src/cli/commands/oauth/index.ts +7 -0
  104. package/src/cli/commands/oauth/platform.ts +179 -0
  105. package/src/cli/commands/platform.ts +3 -3
  106. package/src/config/assistant-feature-flags.ts +186 -5
  107. package/src/config/bundled-skills/messaging/SKILL.md +5 -5
  108. package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
  109. package/src/config/bundled-skills/settings/TOOLS.json +2 -2
  110. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
  111. package/src/config/bundled-tool-registry.ts +1 -11
  112. package/src/config/env-registry.ts +1 -1
  113. package/src/config/env.ts +16 -16
  114. package/src/config/feature-flag-registry.json +48 -16
  115. package/src/config/loader.ts +98 -31
  116. package/src/config/schema.ts +4 -25
  117. package/src/config/schemas/calls.ts +13 -0
  118. package/src/config/schemas/fish-audio.ts +39 -0
  119. package/src/config/schemas/memory.ts +0 -4
  120. package/src/config/schemas/platform.ts +1 -1
  121. package/src/config/schemas/security.ts +4 -4
  122. package/src/config/types.ts +0 -1
  123. package/src/contacts/contact-store.ts +39 -0
  124. package/src/contacts/types.ts +2 -0
  125. package/src/context/window-manager.ts +53 -2
  126. package/src/credential-execution/approval-bridge.ts +1 -0
  127. package/src/credential-execution/executable-discovery.ts +28 -4
  128. package/src/credential-execution/feature-gates.ts +16 -0
  129. package/src/credential-execution/process-manager.ts +38 -0
  130. package/src/daemon/assistant-attachments.ts +9 -0
  131. package/src/daemon/config-watcher.ts +6 -4
  132. package/src/daemon/conversation-agent-loop.ts +0 -60
  133. package/src/daemon/conversation-memory.ts +0 -117
  134. package/src/daemon/conversation-runtime-assembly.ts +0 -2
  135. package/src/daemon/conversation-tool-setup.ts +0 -105
  136. package/src/daemon/conversation.ts +10 -1
  137. package/src/daemon/handlers/config-vercel.ts +92 -0
  138. package/src/daemon/handlers/conversations.ts +0 -11
  139. package/src/daemon/handlers/skills.ts +2 -15
  140. package/src/daemon/install-symlink.ts +195 -0
  141. package/src/daemon/lifecycle.ts +229 -96
  142. package/src/daemon/message-types/conversations.ts +3 -4
  143. package/src/daemon/message-types/diagnostics.ts +3 -22
  144. package/src/daemon/message-types/messages.ts +0 -2
  145. package/src/daemon/message-types/upgrades.ts +8 -0
  146. package/src/daemon/server.ts +30 -92
  147. package/src/events/domain-events.ts +2 -1
  148. package/src/followups/followup-store.ts +5 -2
  149. package/src/inbound/platform-callback-registration.ts +3 -3
  150. package/src/instrument.ts +8 -5
  151. package/src/memory/conversation-crud.ts +0 -236
  152. package/src/memory/conversation-title-service.ts +76 -11
  153. package/src/memory/db-init.ts +15 -11
  154. package/src/memory/indexer.ts +15 -106
  155. package/src/memory/items-extractor.ts +15 -1
  156. package/src/memory/job-handlers/conversation-starters.ts +4 -1
  157. package/src/memory/job-handlers/embedding.ts +0 -79
  158. package/src/memory/job-utils.ts +1 -1
  159. package/src/memory/jobs-store.ts +30 -13
  160. package/src/memory/jobs-worker.ts +31 -27
  161. package/src/memory/migrations/001-job-deferrals.ts +19 -0
  162. package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
  163. package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
  164. package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
  165. package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
  166. package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
  167. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
  168. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
  169. package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
  170. package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
  171. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
  172. package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
  173. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
  174. package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
  175. package/src/memory/migrations/116-messages-fts.ts +106 -1
  176. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
  177. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
  178. package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
  179. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
  180. package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
  181. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
  182. package/src/memory/migrations/141-rename-verification-table.ts +54 -0
  183. package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
  184. package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
  185. package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
  186. package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
  187. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
  188. package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
  189. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
  190. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
  191. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
  192. package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
  193. package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
  194. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
  195. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
  196. package/src/memory/migrations/189-drop-simplified-memory.ts +42 -0
  197. package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
  198. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
  199. package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
  200. package/src/memory/migrations/index.ts +5 -3
  201. package/src/memory/migrations/registry.ts +90 -0
  202. package/src/memory/migrations/validate-migration-state.ts +137 -11
  203. package/src/memory/qdrant-circuit-breaker.ts +9 -0
  204. package/src/memory/qdrant-client.ts +4 -6
  205. package/src/memory/qdrant-manager.ts +64 -7
  206. package/src/memory/schema/calls.ts +1 -0
  207. package/src/memory/schema/contacts.ts +1 -0
  208. package/src/memory/schema/conversations.ts +0 -3
  209. package/src/memory/schema/index.ts +0 -2
  210. package/src/messaging/draft-store.ts +2 -2
  211. package/src/notifications/decision-engine.ts +4 -1
  212. package/src/oauth/connection-resolver.ts +6 -4
  213. package/src/permissions/checker.ts +0 -38
  214. package/src/permissions/defaults.ts +3 -3
  215. package/src/permissions/shell-identity.ts +76 -22
  216. package/src/permissions/trust-client.ts +2 -13
  217. package/src/permissions/trust-store.ts +8 -3
  218. package/src/permissions/types.ts +4 -2
  219. package/src/platform/client.ts +35 -7
  220. package/src/prompts/persona-resolver.ts +138 -0
  221. package/src/prompts/system-prompt.ts +36 -4
  222. package/src/prompts/templates/users/default.md +1 -0
  223. package/src/providers/registry.ts +27 -40
  224. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  225. package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
  226. package/src/runtime/auth/external-assistant-id.ts +13 -59
  227. package/src/runtime/auth/route-policy.ts +29 -1
  228. package/src/runtime/auth/token-service.ts +53 -15
  229. package/src/runtime/channel-readiness-service.ts +1 -16
  230. package/src/runtime/http-server.ts +29 -2
  231. package/src/runtime/middleware/error-handler.ts +1 -9
  232. package/src/runtime/routes/audio-routes.ts +40 -0
  233. package/src/runtime/routes/btw-routes.ts +0 -17
  234. package/src/runtime/routes/conversation-management-routes.ts +0 -36
  235. package/src/runtime/routes/conversation-query-routes.ts +106 -2
  236. package/src/runtime/routes/conversation-routes.ts +4 -43
  237. package/src/runtime/routes/diagnostics-routes.ts +1 -477
  238. package/src/runtime/routes/identity-routes.ts +18 -29
  239. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
  240. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  241. package/src/runtime/routes/integrations/vercel.ts +89 -0
  242. package/src/runtime/routes/log-export-routes.ts +5 -0
  243. package/src/runtime/routes/memory-item-routes.test.ts +221 -3
  244. package/src/runtime/routes/memory-item-routes.ts +144 -4
  245. package/src/runtime/routes/migration-rollback-routes.ts +209 -0
  246. package/src/runtime/routes/migration-routes.ts +17 -1
  247. package/src/runtime/routes/notification-routes.ts +58 -0
  248. package/src/runtime/routes/schedule-routes.ts +65 -0
  249. package/src/runtime/routes/settings-routes.ts +41 -1
  250. package/src/runtime/routes/tts-routes.ts +86 -0
  251. package/src/runtime/routes/upgrade-broadcast-routes.ts +175 -0
  252. package/src/runtime/routes/workspace-commit-routes.ts +62 -0
  253. package/src/runtime/routes/workspace-routes.test.ts +22 -1
  254. package/src/runtime/routes/workspace-routes.ts +1 -1
  255. package/src/runtime/routes/workspace-utils.ts +86 -2
  256. package/src/schedule/schedule-store.ts +0 -21
  257. package/src/security/ces-credential-client.ts +59 -22
  258. package/src/security/ces-rpc-credential-backend.ts +85 -0
  259. package/src/security/credential-backend.ts +12 -88
  260. package/src/security/keychain-broker-client.ts +10 -2
  261. package/src/security/secure-keys.ts +94 -113
  262. package/src/skills/catalog-install.ts +13 -7
  263. package/src/skills/inline-command-render.ts +5 -1
  264. package/src/skills/inline-command-runner.ts +30 -2
  265. package/src/telemetry/usage-telemetry-reporter.ts +4 -2
  266. package/src/tools/calls/call-start.ts +1 -0
  267. package/src/tools/executor.ts +0 -4
  268. package/src/tools/memory/handlers.ts +1 -129
  269. package/src/tools/network/script-proxy/session-manager.ts +19 -4
  270. package/src/tools/network/web-fetch.ts +3 -1
  271. package/src/tools/permission-checker.ts +18 -0
  272. package/src/tools/skills/execute.ts +1 -1
  273. package/src/tools/skills/load.ts +9 -2
  274. package/src/tools/types.ts +0 -8
  275. package/src/util/errors.ts +0 -12
  276. package/src/util/platform.ts +8 -55
  277. package/src/util/xml.ts +8 -0
  278. package/src/workspace/git-service.ts +5 -2
  279. package/src/workspace/heartbeat-service.ts +5 -24
  280. package/src/workspace/migrations/001-avatar-rename.ts +15 -0
  281. package/src/workspace/migrations/003-seed-device-id.ts +17 -1
  282. package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
  283. package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
  284. package/src/workspace/migrations/006-services-config.ts +49 -0
  285. package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
  286. package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
  287. package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
  288. package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
  289. package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
  290. package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
  291. package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
  292. package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
  293. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
  294. package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
  295. package/src/workspace/migrations/017-seed-persona-dirs.ts +95 -0
  296. package/src/workspace/migrations/migrate-to-workspace-volume.ts +23 -1
  297. package/src/workspace/migrations/registry.ts +8 -0
  298. package/src/workspace/migrations/runner.ts +106 -2
  299. package/src/workspace/migrations/types.ts +4 -0
  300. package/src/__tests__/archive-recall.test.ts +0 -560
  301. package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
  302. package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
  303. package/src/__tests__/conversation-memory-dirty-tail.test.ts +0 -150
  304. package/src/__tests__/conversation-switch-memory-reduction.test.ts +0 -474
  305. package/src/__tests__/db-memory-archive-migration.test.ts +0 -372
  306. package/src/__tests__/db-memory-brief-state-migration.test.ts +0 -213
  307. package/src/__tests__/db-memory-reducer-checkpoints.test.ts +0 -273
  308. package/src/__tests__/diagnostics-export.test.ts +0 -288
  309. package/src/__tests__/local-gateway-health.test.ts +0 -209
  310. package/src/__tests__/memory-brief-open-loops.test.ts +0 -530
  311. package/src/__tests__/memory-brief-time.test.ts +0 -285
  312. package/src/__tests__/memory-brief-wrapper.test.ts +0 -311
  313. package/src/__tests__/memory-chunk-archive.test.ts +0 -400
  314. package/src/__tests__/memory-chunk-dual-write.test.ts +0 -453
  315. package/src/__tests__/memory-episode-archive.test.ts +0 -370
  316. package/src/__tests__/memory-episode-dual-write.test.ts +0 -626
  317. package/src/__tests__/memory-observation-archive.test.ts +0 -375
  318. package/src/__tests__/memory-observation-dual-write.test.ts +0 -318
  319. package/src/__tests__/memory-reducer-job.test.ts +0 -538
  320. package/src/__tests__/memory-reducer-scheduling.test.ts +0 -473
  321. package/src/__tests__/memory-reducer-store.test.ts +0 -728
  322. package/src/__tests__/memory-reducer-types.test.ts +0 -707
  323. package/src/__tests__/memory-reducer.test.ts +0 -704
  324. package/src/__tests__/memory-simplified-config.test.ts +0 -281
  325. package/src/__tests__/secret-ingress-handler.test.ts +0 -120
  326. package/src/__tests__/simplified-memory-e2e.test.ts +0 -666
  327. package/src/__tests__/simplified-memory-runtime.test.ts +0 -616
  328. package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
  329. package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
  330. package/src/__tests__/swarm-orchestrator.test.ts +0 -463
  331. package/src/__tests__/swarm-plan-validator.test.ts +0 -384
  332. package/src/__tests__/swarm-recursion.test.ts +0 -197
  333. package/src/__tests__/swarm-router-planner.test.ts +0 -234
  334. package/src/__tests__/swarm-tool.test.ts +0 -185
  335. package/src/__tests__/swarm-worker-backend.test.ts +0 -144
  336. package/src/__tests__/swarm-worker-runner.test.ts +0 -288
  337. package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
  338. package/src/commands/cc-command-registry.ts +0 -248
  339. package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
  340. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
  341. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
  342. package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
  343. package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
  344. package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
  345. package/src/config/schemas/memory-simplified.ts +0 -101
  346. package/src/config/schemas/swarm.ts +0 -82
  347. package/src/logfire.ts +0 -135
  348. package/src/memory/archive-recall.ts +0 -516
  349. package/src/memory/archive-store.ts +0 -400
  350. package/src/memory/brief-formatting.ts +0 -33
  351. package/src/memory/brief-open-loops.ts +0 -266
  352. package/src/memory/brief-time.ts +0 -162
  353. package/src/memory/brief.ts +0 -75
  354. package/src/memory/job-handlers/backfill-simplified-memory.ts +0 -462
  355. package/src/memory/job-handlers/reduce-conversation-memory.ts +0 -229
  356. package/src/memory/migrations/185-memory-brief-state.ts +0 -52
  357. package/src/memory/migrations/186-memory-archive.ts +0 -109
  358. package/src/memory/migrations/187-memory-reducer-checkpoints.ts +0 -19
  359. package/src/memory/reducer-scheduler.ts +0 -242
  360. package/src/memory/reducer-store.ts +0 -271
  361. package/src/memory/reducer-types.ts +0 -106
  362. package/src/memory/reducer.ts +0 -467
  363. package/src/memory/schema/memory-archive.ts +0 -121
  364. package/src/memory/schema/memory-brief.ts +0 -55
  365. package/src/runtime/local-gateway-health.ts +0 -275
  366. package/src/security/secret-ingress.ts +0 -68
  367. package/src/swarm/backend-claude-code.ts +0 -225
  368. package/src/swarm/checkpoint.ts +0 -137
  369. package/src/swarm/graph-utils.ts +0 -53
  370. package/src/swarm/index.ts +0 -55
  371. package/src/swarm/limits.ts +0 -66
  372. package/src/swarm/orchestrator.ts +0 -424
  373. package/src/swarm/plan-validator.ts +0 -117
  374. package/src/swarm/router-planner.ts +0 -162
  375. package/src/swarm/router-prompts.ts +0 -39
  376. package/src/swarm/synthesizer.ts +0 -81
  377. package/src/swarm/types.ts +0 -72
  378. package/src/swarm/worker-backend.ts +0 -131
  379. package/src/swarm/worker-prompts.ts +0 -80
  380. package/src/swarm/worker-runner.ts +0 -170
  381. package/src/tools/claude-code/claude-code.ts +0 -610
  382. package/src/tools/swarm/delegate.ts +0 -205
@@ -0,0 +1,179 @@
1
+ import type { Command } from "commander";
2
+
3
+ import { getConfig } from "../../../config/loader.js";
4
+ import {
5
+ type Services,
6
+ ServicesSchema,
7
+ } from "../../../config/schemas/services.js";
8
+ import { getProvider } from "../../../oauth/oauth-store.js";
9
+ import { VellumPlatformClient } from "../../../platform/client.js";
10
+ import { getCliLogger } from "../../logger.js";
11
+ import { shouldOutputJson, writeOutput } from "../../output.js";
12
+
13
+ const log = getCliLogger("cli");
14
+
15
+ /**
16
+ * Normalize a bare provider name (e.g. "google") into the canonical provider
17
+ * key used internally (e.g. "integration:google").
18
+ */
19
+ function toProviderKey(provider: string): string {
20
+ return provider.startsWith("integration:")
21
+ ? provider
22
+ : `integration:${provider}`;
23
+ }
24
+
25
+ export function registerPlatformCommands(oauth: Command): void {
26
+ const platform = oauth
27
+ .command("platform")
28
+ .description(
29
+ "Query platform-managed OAuth provider status and connections",
30
+ );
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // platform status <provider>
34
+ // ---------------------------------------------------------------------------
35
+
36
+ platform
37
+ .command("status <provider>")
38
+ .description(
39
+ "Check whether a provider supports managed OAuth and list the user's active connections",
40
+ )
41
+ .addHelpText(
42
+ "after",
43
+ `
44
+ Arguments:
45
+ provider Provider name (e.g. google, slack, twitter)
46
+
47
+ Checks whether the platform offers managed OAuth for the given provider,
48
+ whether managed mode is currently enabled, and lists any active connections
49
+ the user has set up on the platform.
50
+
51
+ Examples:
52
+ $ assistant oauth platform status google
53
+ $ assistant oauth platform status slack --json`,
54
+ )
55
+ .action(
56
+ async (
57
+ provider: string,
58
+ _opts: Record<string, unknown>,
59
+ cmd: Command,
60
+ ) => {
61
+ try {
62
+ const providerKey = toProviderKey(provider);
63
+ const providerRow = getProvider(providerKey);
64
+
65
+ // 1. Check if the provider even supports managed mode
66
+ const managedKey = providerRow?.managedServiceConfigKey;
67
+ if (!managedKey || !(managedKey in ServicesSchema.shape)) {
68
+ writeOutput(cmd, {
69
+ ok: true,
70
+ provider,
71
+ managedAvailable: false,
72
+ managedEnabled: false,
73
+ connections: [],
74
+ });
75
+ if (!shouldOutputJson(cmd)) {
76
+ log.info(
77
+ `Provider "${provider}" does not support platform-managed OAuth`,
78
+ );
79
+ }
80
+ return;
81
+ }
82
+
83
+ // 2. Check if managed mode is enabled in the services config
84
+ const services: Services = getConfig().services;
85
+ const managedEnabled =
86
+ services[managedKey as keyof Services].mode === "managed";
87
+
88
+ if (!managedEnabled) {
89
+ writeOutput(cmd, {
90
+ ok: true,
91
+ provider,
92
+ managedAvailable: true,
93
+ managedEnabled: false,
94
+ connections: [],
95
+ });
96
+ if (!shouldOutputJson(cmd)) {
97
+ log.info(
98
+ `Provider "${provider}" supports managed OAuth but is set to "your-own" mode`,
99
+ );
100
+ }
101
+ return;
102
+ }
103
+
104
+ // 3. Fetch active connections from the platform
105
+ const client = await VellumPlatformClient.create();
106
+ if (!client || !client.platformAssistantId) {
107
+ writeOutput(cmd, {
108
+ ok: false,
109
+ error:
110
+ "Platform prerequisites not met (not logged in or missing assistant ID)",
111
+ });
112
+ process.exitCode = 1;
113
+ return;
114
+ }
115
+
116
+ const params = new URLSearchParams();
117
+ params.set("provider", provider);
118
+ params.set("status", "ACTIVE");
119
+
120
+ const path = `/v1/assistants/${encodeURIComponent(client.platformAssistantId)}/oauth/connections/?${params.toString()}`;
121
+ const response = await client.fetch(path);
122
+
123
+ if (!response.ok) {
124
+ writeOutput(cmd, {
125
+ ok: false,
126
+ error: `Platform returned HTTP ${response.status}`,
127
+ });
128
+ process.exitCode = 1;
129
+ return;
130
+ }
131
+
132
+ const body = (await response.json()) as unknown;
133
+
134
+ // The platform returns either a flat array or a {results: [...]} wrapper.
135
+ const rawEntries = (
136
+ Array.isArray(body)
137
+ ? body
138
+ : ((body as Record<string, unknown>).results ?? [])
139
+ ) as Array<{
140
+ id: string;
141
+ account_label?: string;
142
+ scopes_granted?: string[];
143
+ status?: string;
144
+ }>;
145
+
146
+ const connections = rawEntries.map((c) => ({
147
+ id: c.id,
148
+ accountLabel: c.account_label ?? null,
149
+ scopesGranted: c.scopes_granted ?? [],
150
+ status: c.status ?? "ACTIVE",
151
+ }));
152
+
153
+ writeOutput(cmd, {
154
+ ok: true,
155
+ provider,
156
+ managedAvailable: true,
157
+ managedEnabled: true,
158
+ connections,
159
+ });
160
+
161
+ if (!shouldOutputJson(cmd)) {
162
+ if (connections.length === 0) {
163
+ log.info(
164
+ `Provider "${provider}" is managed but has no active connections`,
165
+ );
166
+ } else {
167
+ log.info(
168
+ `Provider "${provider}": ${connections.length} active connection(s)`,
169
+ );
170
+ }
171
+ }
172
+ } catch (err) {
173
+ const message = err instanceof Error ? err.message : String(err);
174
+ writeOutput(cmd, { ok: false, error: message });
175
+ process.exitCode = 1;
176
+ }
177
+ },
178
+ );
179
+ }
@@ -24,7 +24,7 @@ export function registerPlatformCommand(program: Command): void {
24
24
  `
25
25
  The platform subsystem manages callback routing, containerized deployment
26
26
  context, and webhook forwarding for assistants running inside platform
27
- containers. When IS_CONTAINERIZED=true with a configured PLATFORM_BASE_URL
27
+ containers. When IS_CONTAINERIZED=true with a configured VELLUM_PLATFORM_URL
28
28
  and PLATFORM_ASSISTANT_ID, external service callbacks (Telegram webhooks,
29
29
  Twilio webhooks, OAuth redirects) route through the platform's gateway proxy
30
30
  instead of hitting the assistant directly.
@@ -51,7 +51,7 @@ running.
51
51
 
52
52
  Fields:
53
53
  containerized Whether IS_CONTAINERIZED is set (boolean)
54
- baseUrl PLATFORM_BASE_URL — the platform gateway base URL
54
+ baseUrl VELLUM_PLATFORM_URL — the platform gateway base URL
55
55
  assistantId PLATFORM_ASSISTANT_ID — this assistant's platform UUID
56
56
  hasInternalApiKey Whether PLATFORM_INTERNAL_API_KEY is set (boolean,
57
57
  value not disclosed)
@@ -136,7 +136,7 @@ Known callback path/type combinations:
136
136
  --path oauth/callback --type oauth
137
137
 
138
138
  Requires a containerized environment (IS_CONTAINERIZED=true) with
139
- PLATFORM_BASE_URL and PLATFORM_ASSISTANT_ID configured. Returns the
139
+ VELLUM_PLATFORM_URL and PLATFORM_ASSISTANT_ID configured. Returns the
140
140
  platform-provided stable callback URL that external services should use.
141
141
 
142
142
  Examples:
@@ -5,7 +5,8 @@
5
5
  * `meta/feature-flags/feature-flag-registry.json` and resolves the effective
6
6
  * enabled/disabled state for each declared assistant-scope flag by consulting
7
7
  * (in priority order):
8
- * 1. `config.assistantFeatureFlagValues[key]` (explicit override)
8
+ * 1. Override values from `~/.vellum/protected/feature-flags.json` (local)
9
+ * or via the gateway HTTP API (Docker/containerized)
9
10
  * 2. defaults registry `defaultEnabled` (for declared keys)
10
11
  * 3. `true` (for undeclared keys)
11
12
  *
@@ -14,8 +15,10 @@
14
15
  */
15
16
 
16
17
  import { existsSync, readFileSync } from "node:fs";
18
+ import { homedir } from "node:os";
17
19
  import { dirname, join } from "node:path";
18
20
 
21
+ import { getBaseDataDir, getIsContainerized } from "./env-registry.js";
19
22
  import type { AssistantConfig } from "./schema.js";
20
23
 
21
24
  // ---------------------------------------------------------------------------
@@ -105,6 +108,182 @@ function parseRegistryToDefaults(parsed: unknown): FeatureFlagDefaultsRegistry {
105
108
  return result;
106
109
  }
107
110
 
111
+ // ---------------------------------------------------------------------------
112
+ // Override loading — reads from protected directory or gateway HTTP
113
+ // ---------------------------------------------------------------------------
114
+
115
+ /**
116
+ * Module-level cache of feature flag override values. Populated lazily on
117
+ * first access, invalidated by `clearFeatureFlagOverridesCache()`.
118
+ */
119
+ let cachedOverrides: Record<string, boolean> | null = null;
120
+
121
+ /**
122
+ * File format for `~/.vellum/protected/feature-flags.json`, matching the
123
+ * gateway's feature-flag-store.ts schema.
124
+ */
125
+ interface FeatureFlagFileData {
126
+ version: 1;
127
+ values: Record<string, boolean>;
128
+ }
129
+
130
+ /**
131
+ * Resolve the path to the feature flag overrides file.
132
+ *
133
+ * Docker: `GATEWAY_SECURITY_DIR/feature-flags.json`
134
+ * Local: `~/.vellum/protected/feature-flags.json`
135
+ *
136
+ * Uses `BASE_DATA_DIR` when set (multi-instance mode) so per-instance
137
+ * feature flag files are correctly scoped.
138
+ */
139
+ function getFeatureFlagOverridesPath(): string {
140
+ const securityDir = process.env.GATEWAY_SECURITY_DIR;
141
+ if (securityDir) {
142
+ return join(securityDir, "feature-flags.json");
143
+ }
144
+ const root = join(getBaseDataDir() || homedir(), ".vellum");
145
+ return join(root, "protected", "feature-flags.json");
146
+ }
147
+
148
+ /**
149
+ * Load override values from the protected feature-flags.json file.
150
+ * Returns an empty record if the file doesn't exist or is malformed.
151
+ */
152
+ function loadOverridesFromFile(): Record<string, boolean> {
153
+ const path = getFeatureFlagOverridesPath();
154
+ if (!existsSync(path)) return {};
155
+
156
+ try {
157
+ const raw = readFileSync(path, "utf-8");
158
+ const data = JSON.parse(raw) as FeatureFlagFileData;
159
+ if (data.version !== 1) return {};
160
+ if (
161
+ data.values &&
162
+ typeof data.values === "object" &&
163
+ !Array.isArray(data.values)
164
+ ) {
165
+ const filtered: Record<string, boolean> = {};
166
+ for (const [k, v] of Object.entries(data.values)) {
167
+ if (typeof v === "boolean") filtered[k] = v;
168
+ }
169
+ return filtered;
170
+ }
171
+ return {};
172
+ } catch {
173
+ return {};
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Load override values from the gateway via synchronous HTTP call.
179
+ *
180
+ * Follows the trust-client pattern: uses `Bun.spawnSync` + `curl` to make
181
+ * a blocking GET request to the gateway's feature-flags endpoint. The
182
+ * gateway returns `{ flags: Array<{ key, enabled, ... }> }` and we extract
183
+ * just the key → enabled map.
184
+ */
185
+ function loadOverridesFromGateway(): Record<string, boolean> {
186
+ try {
187
+ // Lazy-import to avoid circular dependency and keep this module
188
+ // importable from bootstrap code when not in containerized mode.
189
+ const { getGatewayInternalBaseUrl } =
190
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
191
+ require("./env.js") as typeof import("./env.js");
192
+ const { mintEdgeRelayToken } =
193
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
194
+ require("../runtime/auth/token-service.js") as typeof import("../runtime/auth/token-service.js");
195
+
196
+ const url = `${getGatewayInternalBaseUrl()}/v1/feature-flags`;
197
+ const token = mintEdgeRelayToken();
198
+
199
+ const proc = Bun.spawnSync(
200
+ [
201
+ "curl",
202
+ "-s",
203
+ "-S",
204
+ "-X",
205
+ "GET",
206
+ "--max-time",
207
+ "10",
208
+ "-H",
209
+ `Authorization: Bearer ${token}`,
210
+ "-H",
211
+ "Accept: application/json",
212
+ "-w",
213
+ "\n%{http_code}",
214
+ url,
215
+ ],
216
+ { stdout: "pipe", stderr: "pipe" },
217
+ );
218
+
219
+ if (proc.exitCode !== 0) return {};
220
+
221
+ const output = proc.stdout.toString().trim();
222
+ const lastNewline = output.lastIndexOf("\n");
223
+ const responseBody = lastNewline >= 0 ? output.slice(0, lastNewline) : "";
224
+ const statusCode = parseInt(
225
+ lastNewline >= 0 ? output.slice(lastNewline + 1) : output,
226
+ 10,
227
+ );
228
+
229
+ if (statusCode < 200 || statusCode >= 300) return {};
230
+ if (!responseBody) return {};
231
+
232
+ const parsed = JSON.parse(responseBody) as {
233
+ flags?: Array<{ key: string; enabled: boolean }>;
234
+ };
235
+ if (!Array.isArray(parsed.flags)) return {};
236
+
237
+ const result: Record<string, boolean> = {};
238
+ for (const entry of parsed.flags) {
239
+ if (typeof entry.key === "string" && typeof entry.enabled === "boolean") {
240
+ result[entry.key] = entry.enabled;
241
+ }
242
+ }
243
+ return result;
244
+ } catch {
245
+ return {};
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Load overrides from the appropriate source based on runtime mode.
251
+ * Results are cached at module level.
252
+ */
253
+ function loadOverrides(): Record<string, boolean> {
254
+ if (cachedOverrides != null) return cachedOverrides;
255
+
256
+ cachedOverrides = getIsContainerized()
257
+ ? loadOverridesFromGateway()
258
+ : loadOverridesFromFile();
259
+
260
+ return cachedOverrides;
261
+ }
262
+
263
+ /**
264
+ * Invalidate the cached override values so the next call to
265
+ * `isAssistantFeatureFlagEnabled` re-reads from the source.
266
+ *
267
+ * Called by the config watcher when the feature-flags file changes.
268
+ */
269
+ export function clearFeatureFlagOverridesCache(): void {
270
+ cachedOverrides = null;
271
+ }
272
+
273
+ /**
274
+ * Directly inject override values into the module-level cache.
275
+ *
276
+ * **Test-only** — bypasses file/gateway loading so unit tests can control
277
+ * flag state without writing to disk. Production code should never call this;
278
+ * use `clearFeatureFlagOverridesCache()` instead and let the resolver
279
+ * re-read from the appropriate source.
280
+ */
281
+ export function _setOverridesForTesting(
282
+ overrides: Record<string, boolean>,
283
+ ): void {
284
+ cachedOverrides = { ...overrides };
285
+ }
286
+
108
287
  // ---------------------------------------------------------------------------
109
288
  // Public API
110
289
  // ---------------------------------------------------------------------------
@@ -113,19 +292,21 @@ function parseRegistryToDefaults(parsed: unknown): FeatureFlagDefaultsRegistry {
113
292
  * Resolve whether an assistant feature flag is enabled.
114
293
  *
115
294
  * Resolution order:
116
- * 1. `config.assistantFeatureFlagValues[key]` (explicit override)
295
+ * 1. Override from `~/.vellum/protected/feature-flags.json` (local) or
296
+ * gateway HTTP (Docker/containerized)
117
297
  * 2. defaults registry `defaultEnabled` (for declared assistant-scope keys)
118
298
  * 3. `true` (for undeclared keys with no override)
119
299
  */
120
300
  export function isAssistantFeatureFlagEnabled(
121
301
  key: string,
122
- config: AssistantConfig,
302
+ _config: AssistantConfig,
123
303
  ): boolean {
124
304
  const defaults = loadDefaultsRegistry();
125
305
  const declared = defaults[key];
306
+ const overrides = loadOverrides();
126
307
 
127
- // 1. Check config overrides
128
- const explicit = config.assistantFeatureFlagValues?.[key];
308
+ // 1. Check overrides from protected feature-flags file / gateway
309
+ const explicit = overrides[key];
129
310
  if (typeof explicit === "boolean") return explicit;
130
311
 
131
312
  // 2. For declared keys, use the registry default
@@ -70,7 +70,7 @@ Slack connects via Socket Mode using a bot token and app-level token (not OAuth)
70
70
  - Call `skill_load` with `skill: "slack-app-setup"` to load the dependency skill.
71
71
  - Tell the user Slack isn't connected yet and briefly explain what the setup involves, then follow the skill's guided flow.
72
72
 
73
- The slack-app-setup skill handles: manifest-driven app creation, app token and bot token collection via secure prompt (never accept tokens pasted in plaintext chat), and Slack connection setup through the same settings handler used by the Settings UI. That handler validates the bot token, stores workspace metadata, and activates Socket Mode. The skill also covers optional guardian verification.
73
+ The slack-app-setup skill handles: manifest-driven app creation, app token and bot token collection via secure prompt (never accept tokens pasted in plaintext chat), and Slack connection setup through the same settings handler used by the Settings UI. That handler validates the bot token, stores workspace metadata, and activates Socket Mode. The skill also covers optional identity verification.
74
74
 
75
75
  ### Telegram
76
76
 
@@ -81,15 +81,15 @@ Telegram uses a bot token (not OAuth). Load the **telegram-setup** skill (which
81
81
 
82
82
  The telegram-setup skill handles: verifying the bot token from @BotFather, generating a webhook secret, registering bot commands, and storing credentials securely via the secure credential prompt flow. **Never accept a Telegram bot token pasted in plaintext chat - always use the secure prompt.** Webhook registration with Telegram is handled automatically by the gateway on startup and whenever credentials change.
83
83
 
84
- The telegram-setup skill also includes **guardian verification**, which links your Telegram account as the trusted guardian for the bot.
84
+ The telegram-setup skill also includes **channel verification**, which links your Telegram account for verified message delivery.
85
85
 
86
- ### Guardian Verification (Voice or Telegram)
86
+ ### Channel Verification (Voice or Telegram)
87
87
 
88
- If the user asks to verify their guardian identity for voice or Telegram, load the **guardian-verify-setup** skill:
88
+ If the user asks to verify their identity for voice or Telegram, load the **guardian-verify-setup** skill:
89
89
 
90
90
  - Call `skill_load` with `skill: "guardian-verify-setup"` to load the dependency skill.
91
91
 
92
- The guardian-verify-setup skill handles the full outbound verification flow for voice and Telegram channels. It collects the user's destination (phone number or Telegram chat ID/handle), initiates an outbound verification session, and guides the user through entering or replying with the verification code. This is the single source of truth for guardian verification setup -- do not duplicate the verification flow inline.
92
+ The guardian-verify-setup skill handles the full outbound verification flow for voice and Telegram channels. It collects the user's destination (phone number or Telegram chat ID/handle), initiates an outbound verification session, and guides the user through entering or replying with the verification code. This is the single source of truth for channel verification setup -- do not duplicate the verification flow inline.
93
93
 
94
94
  ## Error Recovery
95
95
 
@@ -26,6 +26,10 @@
26
26
  "enum": ["assistant_number", "user_number"],
27
27
  "description": "Which phone number to use as the caller ID. assistant_number uses the AI assistant's Twilio number; user_number uses the user's verified personal number."
28
28
  },
29
+ "skip_disclosure": {
30
+ "type": "boolean",
31
+ "description": "Skip the disclosure announcement at the start of the call. Set to true when calling someone who already knows who you are (e.g. your guardian, a family member, or a close contact)."
32
+ },
29
33
  "activity": {
30
34
  "type": "string",
31
35
  "description": "Brief non-technical explanation of why this tool is being called"
@@ -3,7 +3,7 @@
3
3
  "tools": [
4
4
  {
5
5
  "name": "voice_config_update",
6
- "description": "Update a voice configuration setting (TTS voice ID, PTT activation key, conversation timeout). Changes take effect immediately.",
6
+ "description": "Update a voice configuration setting (TTS provider, TTS voice ID, Fish Audio reference ID, PTT activation key, conversation timeout). Changes take effect immediately.",
7
7
  "category": "system",
8
8
  "risk": "low",
9
9
  "input_schema": {
@@ -11,7 +11,7 @@
11
11
  "properties": {
12
12
  "setting": {
13
13
  "type": "string",
14
- "enum": ["activation_key", "conversation_timeout", "tts_voice_id"],
14
+ "enum": ["activation_key", "conversation_timeout", "fish_audio_reference_id", "tts_provider", "tts_voice_id"],
15
15
  "description": "The voice setting to change"
16
16
  },
17
17
  "value": {
@@ -24,6 +24,11 @@ const VOICE_SETTINGS = {
24
24
  type: "number" as const,
25
25
  },
26
26
  tts_voice_id: { userDefaultsKey: "ttsVoiceId", type: "string" as const },
27
+ tts_provider: { userDefaultsKey: "ttsProvider", type: "string" as const },
28
+ fish_audio_reference_id: {
29
+ userDefaultsKey: "fishAudioReferenceId",
30
+ type: "string" as const,
31
+ },
27
32
  } as const;
28
33
 
29
34
  type VoiceSettingName = keyof typeof VOICE_SETTINGS;
@@ -36,6 +41,8 @@ const FRIENDLY_NAMES: Record<VoiceSettingName, string> = {
36
41
  activation_key: "PTT activation key",
37
42
  conversation_timeout: "Conversation timeout",
38
43
  tts_voice_id: "ElevenLabs voice",
44
+ tts_provider: "TTS provider",
45
+ fish_audio_reference_id: "Fish Audio voice",
39
46
  };
40
47
 
41
48
  function validateSetting(
@@ -97,6 +104,25 @@ function validateSetting(
97
104
  }
98
105
  return { ok: true, coerced: trimmed };
99
106
  }
107
+ case "tts_provider": {
108
+ const valid = ["elevenlabs", "fish-audio"];
109
+ if (typeof value !== "string" || !valid.includes(value.trim())) {
110
+ return {
111
+ ok: false,
112
+ error: `tts_provider must be one of: ${valid.join(", ")}`,
113
+ };
114
+ }
115
+ return { ok: true, coerced: value.trim() };
116
+ }
117
+ case "fish_audio_reference_id": {
118
+ if (typeof value !== "string" || value.trim().length === 0) {
119
+ return {
120
+ ok: false,
121
+ error: "fish_audio_reference_id must be a non-empty string",
122
+ };
123
+ }
124
+ return { ok: true, coerced: value.trim() };
125
+ }
100
126
  default:
101
127
  return { ok: false, error: `Unknown setting "${setting}"` };
102
128
  }
@@ -166,6 +192,22 @@ export async function run(
166
192
  invalidateConfigCache();
167
193
  }
168
194
 
195
+ // For tts_provider, persist to config file (calls.voice.ttsProvider).
196
+ if (setting === "tts_provider") {
197
+ const raw = loadRawConfig();
198
+ setNestedValue(raw, "calls.voice.ttsProvider", validation.coerced);
199
+ saveRawConfig(raw);
200
+ invalidateConfigCache();
201
+ }
202
+
203
+ // For fish_audio_reference_id, persist to config file (fishAudio.referenceId).
204
+ if (setting === "fish_audio_reference_id") {
205
+ const raw = loadRawConfig();
206
+ setNestedValue(raw, "fishAudio.referenceId", validation.coerced);
207
+ saveRawConfig(raw);
208
+ invalidateConfigCache();
209
+ }
210
+
169
211
  return {
170
212
  content: `${friendlyName} updated to ${JSON.stringify(
171
213
  validation.coerced,
@@ -13,7 +13,7 @@
13
13
  * bun run scripts/generate-bundled-tool-registry.ts
14
14
  */
15
15
  import type { SkillToolScript } from "../tools/skills/script-contract.js";
16
- // ── acp ─────────────────────────────────────────────────────────────────────────
16
+ // ── acp ────────────────────────────────────────────────────────────────────────
17
17
  import * as acpAbort from "./bundled-skills/acp/tools/acp-abort.js";
18
18
  import * as acpSpawn from "./bundled-skills/acp/tools/acp-spawn.js";
19
19
  import * as acpStatus from "./bundled-skills/acp/tools/acp-status.js";
@@ -39,8 +39,6 @@ import * as browserWaitFor from "./bundled-skills/browser/tools/browser-wait-for
39
39
  import * as browserWaitForDownload from "./bundled-skills/browser/tools/browser-wait-for-download.js";
40
40
  // ── chatgpt-import ─────────────────────────────────────────────────────────────
41
41
  import * as chatgptImport from "./bundled-skills/chatgpt-import/tools/chatgpt-import.js";
42
- // ── claude-code ────────────────────────────────────────────────────────────────
43
- import * as claudeCode from "./bundled-skills/claude-code/tools/claude-code.js";
44
42
  // ── computer-use ───────────────────────────────────────────────────────────────
45
43
  import * as computerUseClick from "./bundled-skills/computer-use/tools/computer-use-click.js";
46
44
  import * as computerUseDone from "./bundled-skills/computer-use/tools/computer-use-done.js";
@@ -107,8 +105,6 @@ import * as messagingSend from "./bundled-skills/messaging/tools/messaging-send.
107
105
  import * as messagingSenderDigest from "./bundled-skills/messaging/tools/messaging-sender-digest.js";
108
106
  // ── notifications ──────────────────────────────────────────────────────────────
109
107
  import * as sendNotification from "./bundled-skills/notifications/tools/send-notification.js";
110
- // ── orchestration ──────────────────────────────────────────────────────────────
111
- import * as swarmDelegate from "./bundled-skills/orchestration/tools/swarm-delegate.js";
112
108
  // ── phone-calls ────────────────────────────────────────────────────────────────
113
109
  import * as callEnd from "./bundled-skills/phone-calls/tools/call-end.js";
114
110
  import * as callStart from "./bundled-skills/phone-calls/tools/call-start.js";
@@ -210,9 +206,6 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
210
206
  // chatgpt-import
211
207
  ["chatgpt-import:tools/chatgpt-import.ts", chatgptImport],
212
208
 
213
- // claude-code
214
- ["claude-code:tools/claude-code.ts", claudeCode],
215
-
216
209
  // computer-use
217
210
  ["computer-use:tools/computer-use-observe.ts", computerUseObserve],
218
211
  ["computer-use:tools/computer-use-click.ts", computerUseClick],
@@ -298,9 +291,6 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
298
291
  // notifications
299
292
  ["notifications:tools/send-notification.ts", sendNotification],
300
293
 
301
- // orchestration
302
- ["orchestration:tools/swarm-delegate.ts", swarmDelegate],
303
-
304
294
  // phone-calls
305
295
  ["phone-calls:tools/call-start.ts", callStart],
306
296
  ["phone-calls:tools/call-status.ts", callStatus],
@@ -72,7 +72,7 @@ export function getWorkspaceDirOverride(): string | undefined {
72
72
  const KNOWN_VELLUM_VARS = new Set([
73
73
  "VELLUM_ASSISTANT_NAME",
74
74
  "VELLUM_AWS_ROLE_ARN",
75
- "VELLUM_CLAUDE_CODE_DEPTH",
75
+ "VELLUM_CLOUD",
76
76
  "VELLUM_CUSTOM_QR_CODE_PATH",
77
77
  "VELLUM_DAEMON_AUTOSTART",
78
78
  "VELLUM_DAEMON_NOAUTH",