@vellumai/assistant 0.5.6 → 0.5.8

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 (442) hide show
  1. package/.env.example +16 -2
  2. package/ARCHITECTURE.md +6 -75
  3. package/Dockerfile +3 -2
  4. package/README.md +0 -2
  5. package/bun.lock +0 -414
  6. package/docker-entrypoint.sh +9 -0
  7. package/docs/architecture/keychain-broker.md +45 -240
  8. package/docs/architecture/memory.md +13 -11
  9. package/docs/architecture/security.md +0 -17
  10. package/docs/credential-execution-service.md +2 -2
  11. package/node_modules/@vellumai/ces-contracts/package.json +1 -0
  12. package/node_modules/@vellumai/ces-contracts/src/error.ts +1 -1
  13. package/node_modules/@vellumai/ces-contracts/src/grants.ts +1 -1
  14. package/node_modules/@vellumai/ces-contracts/src/handles.ts +1 -1
  15. package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -1
  16. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +120 -1
  17. package/node_modules/@vellumai/credential-storage/package.json +1 -0
  18. package/node_modules/@vellumai/egress-proxy/package.json +1 -0
  19. package/package.json +2 -3
  20. package/src/__tests__/actor-token-service.test.ts +0 -114
  21. package/src/__tests__/approval-cascade.test.ts +0 -1
  22. package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
  23. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  24. package/src/__tests__/browser-skill-endstate.test.ts +6 -5
  25. package/src/__tests__/btw-routes.test.ts +0 -39
  26. package/src/__tests__/call-controller.test.ts +0 -1
  27. package/src/__tests__/call-domain.test.ts +0 -128
  28. package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
  29. package/src/__tests__/ces-startup-timeout.test.ts +40 -0
  30. package/src/__tests__/channel-approval-routes.test.ts +0 -5
  31. package/src/__tests__/channel-readiness-service.test.ts +1 -60
  32. package/src/__tests__/checker.test.ts +4 -2
  33. package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
  34. package/src/__tests__/config-schema-cmd.test.ts +0 -2
  35. package/src/__tests__/config-schema.test.ts +3 -1
  36. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -1
  37. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
  38. package/src/__tests__/conversation-agent-loop.test.ts +2 -4
  39. package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
  40. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -1
  41. package/src/__tests__/conversation-error.test.ts +15 -1
  42. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  43. package/src/__tests__/conversation-messaging-secret-redirect.test.ts +1 -1
  44. package/src/__tests__/conversation-pre-run-repair.test.ts +0 -1
  45. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -1
  46. package/src/__tests__/conversation-queue.test.ts +0 -1
  47. package/src/__tests__/conversation-skill-tools.test.ts +0 -54
  48. package/src/__tests__/conversation-slash-queue.test.ts +0 -1
  49. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  50. package/src/__tests__/conversation-title-service.test.ts +87 -0
  51. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  52. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  53. package/src/__tests__/credential-execution-client.test.ts +5 -2
  54. package/src/__tests__/credential-execution-feature-gates.test.ts +59 -30
  55. package/src/__tests__/credential-execution-managed-contract.test.ts +35 -20
  56. package/src/__tests__/credential-security-e2e.test.ts +1 -67
  57. package/src/__tests__/credential-security-invariants.test.ts +6 -50
  58. package/src/__tests__/credentials-cli.test.ts +82 -3
  59. package/src/__tests__/daemon-credential-client.test.ts +123 -0
  60. package/src/__tests__/db-migration-rollback.test.ts +2015 -1
  61. package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -0
  62. package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
  63. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
  64. package/src/__tests__/gateway-client-managed-outbound.test.ts +79 -1
  65. package/src/__tests__/guardian-routing-state.test.ts +0 -5
  66. package/src/__tests__/host-shell-tool.test.ts +6 -7
  67. package/src/__tests__/http-user-message-parity.test.ts +3 -103
  68. package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
  69. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
  70. package/src/__tests__/intent-routing.test.ts +0 -13
  71. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
  72. package/src/__tests__/journal-context.test.ts +335 -0
  73. package/src/__tests__/keychain-broker-client.test.ts +161 -22
  74. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -3
  75. package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
  76. package/src/__tests__/memory-lifecycle-e2e.test.ts +70 -25
  77. package/src/__tests__/memory-recall-quality.test.ts +48 -17
  78. package/src/__tests__/memory-regressions.test.ts +408 -363
  79. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -3
  80. package/src/__tests__/migration-export-http.test.ts +2 -2
  81. package/src/__tests__/migration-import-commit-http.test.ts +2 -2
  82. package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
  83. package/src/__tests__/migration-validate-http.test.ts +2 -2
  84. package/src/__tests__/non-member-access-request.test.ts +2 -7
  85. package/src/__tests__/notification-decision-fallback.test.ts +4 -0
  86. package/src/__tests__/notification-decision-identity.test.ts +4 -0
  87. package/src/__tests__/notification-decision-strategy.test.ts +71 -0
  88. package/src/__tests__/oauth-cli.test.ts +5 -1
  89. package/src/__tests__/permission-types.test.ts +1 -0
  90. package/src/__tests__/provider-commit-message-generator.test.ts +0 -37
  91. package/src/__tests__/provider-error-scenarios.test.ts +0 -267
  92. package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
  93. package/src/__tests__/provider-streaming.benchmark.test.ts +2 -81
  94. package/src/__tests__/qdrant-manager.test.ts +28 -2
  95. package/src/__tests__/registry.test.ts +0 -6
  96. package/src/__tests__/relay-server.test.ts +1 -2
  97. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
  98. package/src/__tests__/script-proxy-injection-runtime.test.ts +1 -1
  99. package/src/__tests__/secret-onetime-send.test.ts +1 -1
  100. package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
  101. package/src/__tests__/secure-keys.test.ts +95 -272
  102. package/src/__tests__/shell-identity.test.ts +96 -6
  103. package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
  104. package/src/__tests__/skill-feature-flags.test.ts +46 -45
  105. package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
  106. package/src/__tests__/skill-load-inline-command.test.ts +8 -12
  107. package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
  108. package/src/__tests__/skill-load-tool.test.ts +0 -2
  109. package/src/__tests__/skill-memory.test.ts +17 -3
  110. package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
  111. package/src/__tests__/skills.test.ts +0 -2
  112. package/src/__tests__/slack-inbound-verification.test.ts +0 -4
  113. package/src/__tests__/stale-approval-dedup.test.ts +171 -0
  114. package/src/__tests__/stt-hints.test.ts +437 -0
  115. package/src/__tests__/suggestion-routes.test.ts +1 -32
  116. package/src/__tests__/system-prompt.test.ts +0 -1
  117. package/src/__tests__/task-memory-cleanup.test.ts +14 -0
  118. package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
  119. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
  120. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
  121. package/src/__tests__/twilio-routes-twiml.test.ts +139 -1
  122. package/src/__tests__/update-bulletin.test.ts +0 -2
  123. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
  124. package/src/__tests__/voice-quality.test.ts +58 -0
  125. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -7
  126. package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
  127. package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +220 -0
  128. package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
  129. package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
  130. package/src/acp/agent-process.ts +9 -1
  131. package/src/agent/loop.ts +1 -1
  132. package/src/approvals/guardian-request-resolvers.ts +164 -38
  133. package/src/calls/__tests__/tts-text-sanitizer.test.ts +254 -0
  134. package/src/calls/audio-store.test.ts +97 -0
  135. package/src/calls/audio-store.ts +205 -0
  136. package/src/calls/call-controller.ts +90 -8
  137. package/src/calls/call-domain.ts +3 -0
  138. package/src/calls/call-store.ts +10 -3
  139. package/src/calls/fish-audio-client.ts +129 -0
  140. package/src/calls/relay-server.ts +27 -0
  141. package/src/calls/stt-hints.ts +189 -0
  142. package/src/calls/tts-text-sanitizer.ts +61 -0
  143. package/src/calls/twilio-routes.ts +34 -5
  144. package/src/calls/types.ts +1 -0
  145. package/src/calls/voice-ingress-preflight.ts +0 -42
  146. package/src/calls/voice-quality.ts +38 -5
  147. package/src/calls/voice-session-bridge.ts +7 -12
  148. package/src/cli/commands/avatar.ts +2 -2
  149. package/src/cli/commands/config.ts +1 -4
  150. package/src/cli/commands/credentials.ts +128 -82
  151. package/src/cli/commands/doctor.ts +2 -2
  152. package/src/cli/commands/keys.ts +7 -7
  153. package/src/cli/commands/memory.ts +1 -1
  154. package/src/cli/commands/oauth/connections.ts +11 -29
  155. package/src/cli/commands/oauth/index.ts +7 -0
  156. package/src/cli/commands/oauth/platform.ts +525 -0
  157. package/src/cli/commands/platform.ts +3 -3
  158. package/src/cli/lib/daemon-credential-client.ts +284 -0
  159. package/src/cli.ts +1 -1
  160. package/src/config/assistant-feature-flags.ts +186 -5
  161. package/src/config/bundled-skills/AGENTS.md +34 -0
  162. package/src/config/bundled-skills/acp/SKILL.md +10 -0
  163. package/src/config/bundled-skills/app-builder/SKILL.md +0 -4
  164. package/src/config/bundled-skills/messaging/SKILL.md +5 -5
  165. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
  166. package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
  167. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -0
  168. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -0
  169. package/src/config/bundled-skills/settings/SKILL.md +15 -2
  170. package/src/config/bundled-skills/settings/TOOLS.json +47 -2
  171. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +59 -0
  172. package/src/config/bundled-skills/settings/tools/avatar-update.ts +80 -0
  173. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
  174. package/src/config/bundled-skills/slack/SKILL.md +1 -1
  175. package/src/config/bundled-tool-registry.ts +5 -11
  176. package/src/config/defaults.ts +0 -2
  177. package/src/config/env-registry.ts +5 -5
  178. package/src/config/env.ts +21 -14
  179. package/src/config/feature-flag-registry.json +49 -9
  180. package/src/config/loader.ts +106 -42
  181. package/src/config/schema.ts +9 -29
  182. package/src/config/schemas/calls.ts +30 -0
  183. package/src/config/schemas/fish-audio.ts +39 -0
  184. package/src/config/schemas/inference.ts +2 -2
  185. package/src/config/schemas/journal.ts +16 -0
  186. package/src/config/schemas/memory-processing.ts +2 -2
  187. package/src/config/schemas/security.ts +0 -4
  188. package/src/config/types.ts +1 -1
  189. package/src/contacts/contact-store.ts +39 -0
  190. package/src/contacts/types.ts +2 -0
  191. package/src/credential-execution/approval-bridge.ts +1 -0
  192. package/src/credential-execution/executable-discovery.ts +28 -4
  193. package/src/credential-execution/feature-gates.ts +16 -0
  194. package/src/credential-execution/process-manager.ts +38 -0
  195. package/src/credential-execution/startup-timeout.ts +36 -0
  196. package/src/daemon/approval-generators.ts +3 -9
  197. package/src/daemon/assistant-attachments.ts +9 -0
  198. package/src/daemon/config-watcher.ts +5 -0
  199. package/src/daemon/conversation-error.ts +13 -1
  200. package/src/daemon/conversation-memory.ts +1 -2
  201. package/src/daemon/conversation-process.ts +18 -1
  202. package/src/daemon/conversation-surfaces.ts +30 -1
  203. package/src/daemon/conversation-tool-setup.ts +0 -105
  204. package/src/daemon/conversation.ts +21 -1
  205. package/src/daemon/guardian-action-generators.ts +3 -9
  206. package/src/daemon/handlers/config-vercel.ts +92 -0
  207. package/src/daemon/handlers/skills.ts +2 -15
  208. package/src/daemon/install-symlink.ts +195 -0
  209. package/src/daemon/lifecycle.ts +234 -51
  210. package/src/daemon/message-types/conversations.ts +4 -4
  211. package/src/daemon/message-types/diagnostics.ts +3 -22
  212. package/src/daemon/message-types/messages.ts +0 -2
  213. package/src/daemon/message-types/upgrades.ts +8 -0
  214. package/src/daemon/server.ts +32 -95
  215. package/src/events/domain-events.ts +2 -1
  216. package/src/inbound/platform-callback-registration.ts +3 -3
  217. package/src/instrument.ts +8 -5
  218. package/src/memory/app-store.ts +31 -0
  219. package/src/memory/conversation-title-service.ts +50 -1
  220. package/src/memory/db-init.ts +16 -0
  221. package/src/memory/indexer.ts +19 -10
  222. package/src/memory/items-extractor.ts +328 -321
  223. package/src/memory/job-handlers/conversation-starters.ts +4 -1
  224. package/src/memory/job-handlers/summarization.ts +26 -16
  225. package/src/memory/jobs-store.ts +63 -6
  226. package/src/memory/jobs-worker.ts +31 -7
  227. package/src/memory/journal-memory.ts +214 -0
  228. package/src/memory/migrations/001-job-deferrals.ts +19 -0
  229. package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
  230. package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
  231. package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
  232. package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
  233. package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
  234. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
  235. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
  236. package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
  237. package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
  238. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
  239. package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
  240. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
  241. package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
  242. package/src/memory/migrations/116-messages-fts.ts +106 -1
  243. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
  244. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
  245. package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
  246. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
  247. package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
  248. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
  249. package/src/memory/migrations/141-rename-verification-table.ts +54 -0
  250. package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
  251. package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
  252. package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
  253. package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
  254. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
  255. package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
  256. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
  257. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
  258. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
  259. package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
  260. package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
  261. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
  262. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
  263. package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
  264. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
  265. package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
  266. package/src/memory/migrations/193-add-source-type-columns.ts +81 -0
  267. package/src/memory/migrations/index.ts +5 -0
  268. package/src/memory/migrations/registry.ts +98 -0
  269. package/src/memory/migrations/validate-migration-state.ts +137 -11
  270. package/src/memory/qdrant-circuit-breaker.ts +9 -0
  271. package/src/memory/qdrant-manager.ts +64 -7
  272. package/src/memory/retriever.test.ts +37 -25
  273. package/src/memory/retriever.ts +24 -49
  274. package/src/memory/schema/calls.ts +1 -0
  275. package/src/memory/schema/contacts.ts +1 -0
  276. package/src/memory/schema/memory-core.ts +2 -0
  277. package/src/memory/search/formatting.ts +7 -44
  278. package/src/memory/search/staleness.ts +4 -0
  279. package/src/memory/search/tier-classifier.ts +10 -2
  280. package/src/memory/search/types.ts +2 -5
  281. package/src/memory/task-memory-cleanup.ts +4 -3
  282. package/src/notifications/adapters/slack.ts +168 -6
  283. package/src/notifications/broadcaster.ts +1 -0
  284. package/src/notifications/copy-composer.ts +59 -2
  285. package/src/notifications/decision-engine.ts +4 -1
  286. package/src/notifications/signal.ts +2 -0
  287. package/src/notifications/types.ts +2 -0
  288. package/src/oauth/connection-resolver.ts +6 -4
  289. package/src/permissions/checker.ts +0 -38
  290. package/src/permissions/shell-identity.ts +76 -22
  291. package/src/permissions/types.ts +4 -2
  292. package/src/platform/client.ts +35 -7
  293. package/src/prompts/journal-context.ts +133 -0
  294. package/src/prompts/persona-resolver.ts +194 -0
  295. package/src/prompts/system-prompt.ts +44 -4
  296. package/src/prompts/templates/SOUL.md +10 -0
  297. package/src/prompts/templates/users/default.md +1 -0
  298. package/src/providers/provider-send-message.ts +3 -32
  299. package/src/providers/registry.ts +29 -179
  300. package/src/providers/types.ts +1 -1
  301. package/src/runtime/access-request-helper.ts +4 -0
  302. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  303. package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
  304. package/src/runtime/auth/__tests__/guard-tests.test.ts +9 -50
  305. package/src/runtime/auth/external-assistant-id.ts +13 -59
  306. package/src/runtime/auth/route-policy.ts +17 -1
  307. package/src/runtime/auth/token-service.ts +43 -138
  308. package/src/runtime/channel-readiness-service.ts +1 -16
  309. package/src/runtime/gateway-client.ts +47 -4
  310. package/src/runtime/guardian-decision-types.ts +45 -4
  311. package/src/runtime/http-server.ts +31 -3
  312. package/src/runtime/middleware/error-handler.ts +1 -9
  313. package/src/runtime/routes/access-request-decision.ts +2 -2
  314. package/src/runtime/routes/app-management-routes.ts +2 -1
  315. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +219 -30
  316. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +37 -14
  317. package/src/runtime/routes/audio-routes.ts +40 -0
  318. package/src/runtime/routes/btw-routes.ts +0 -17
  319. package/src/runtime/routes/channel-readiness-routes.ts +9 -4
  320. package/src/runtime/routes/conversation-query-routes.ts +63 -1
  321. package/src/runtime/routes/conversation-routes.ts +4 -44
  322. package/src/runtime/routes/debug-routes.ts +12 -9
  323. package/src/runtime/routes/diagnostics-routes.ts +1 -477
  324. package/src/runtime/routes/guardian-approval-interception.ts +168 -11
  325. package/src/runtime/routes/guardian-approval-prompt.ts +6 -1
  326. package/src/runtime/routes/guardian-approval-reply-helpers.ts +103 -21
  327. package/src/runtime/routes/identity-routes.ts +19 -30
  328. package/src/runtime/routes/inbound-message-handler.ts +31 -1
  329. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +64 -5
  330. package/src/runtime/routes/inbound-stages/background-dispatch.ts +52 -40
  331. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
  332. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  333. package/src/runtime/routes/integrations/twilio.ts +52 -10
  334. package/src/runtime/routes/integrations/vercel.ts +89 -0
  335. package/src/runtime/routes/log-export-routes.ts +5 -0
  336. package/src/runtime/routes/memory-item-routes.test.ts +3 -3
  337. package/src/runtime/routes/memory-item-routes.ts +46 -14
  338. package/src/runtime/routes/migration-rollback-routes.ts +209 -0
  339. package/src/runtime/routes/migration-routes.ts +17 -1
  340. package/src/runtime/routes/notification-routes.ts +58 -0
  341. package/src/runtime/routes/schedule-routes.ts +65 -0
  342. package/src/runtime/routes/secret-routes.ts +141 -10
  343. package/src/runtime/routes/settings-routes.ts +41 -1
  344. package/src/runtime/routes/tts-routes.ts +96 -0
  345. package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
  346. package/src/runtime/routes/workspace-commit-routes.ts +62 -0
  347. package/src/runtime/routes/workspace-routes.test.ts +22 -1
  348. package/src/runtime/routes/workspace-routes.ts +1 -1
  349. package/src/runtime/routes/workspace-utils.ts +86 -2
  350. package/src/security/ces-credential-client.ts +75 -29
  351. package/src/security/ces-rpc-credential-backend.ts +86 -0
  352. package/src/security/credential-backend.ts +22 -92
  353. package/src/security/keychain-broker-client.ts +10 -2
  354. package/src/security/secure-keys.ts +113 -115
  355. package/src/skills/catalog-install.ts +6 -32
  356. package/src/skills/skill-memory.ts +1 -0
  357. package/src/subagent/manager.ts +2 -5
  358. package/src/telemetry/usage-telemetry-reporter.ts +4 -2
  359. package/src/tools/acp/spawn.ts +78 -1
  360. package/src/tools/calls/call-start.ts +1 -0
  361. package/src/tools/credentials/vault.ts +5 -3
  362. package/src/tools/executor.ts +0 -4
  363. package/src/tools/memory/definitions.ts +3 -2
  364. package/src/tools/memory/handlers.ts +10 -7
  365. package/src/tools/network/script-proxy/session-manager.ts +19 -4
  366. package/src/tools/network/web-fetch.ts +3 -1
  367. package/src/tools/skills/execute.ts +1 -1
  368. package/src/tools/terminal/safe-env.ts +1 -0
  369. package/src/tools/types.ts +0 -8
  370. package/src/util/browser.ts +15 -0
  371. package/src/util/errors.ts +0 -12
  372. package/src/util/platform.ts +4 -51
  373. package/src/workspace/git-service.ts +5 -2
  374. package/src/workspace/migrations/001-avatar-rename.ts +15 -0
  375. package/src/workspace/migrations/003-seed-device-id.ts +17 -1
  376. package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
  377. package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
  378. package/src/workspace/migrations/006-services-config.ts +49 -0
  379. package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
  380. package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
  381. package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
  382. package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
  383. package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
  384. package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
  385. package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
  386. package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
  387. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
  388. package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
  389. package/src/workspace/migrations/017-seed-persona-dirs.ts +96 -0
  390. package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +184 -0
  391. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +103 -0
  392. package/src/workspace/migrations/migrate-to-workspace-volume.ts +27 -5
  393. package/src/workspace/migrations/registry.ts +12 -0
  394. package/src/workspace/migrations/runner.ts +106 -2
  395. package/src/workspace/migrations/types.ts +4 -0
  396. package/src/workspace/provider-commit-message-generator.ts +12 -21
  397. package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
  398. package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
  399. package/src/__tests__/diagnostics-export.test.ts +0 -288
  400. package/src/__tests__/local-gateway-health.test.ts +0 -209
  401. package/src/__tests__/provider-fail-open-selection.test.ts +0 -271
  402. package/src/__tests__/provider-failover-actual-provider.test.ts +0 -66
  403. package/src/__tests__/secret-ingress-handler.test.ts +0 -120
  404. package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
  405. package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
  406. package/src/__tests__/swarm-orchestrator.test.ts +0 -463
  407. package/src/__tests__/swarm-plan-validator.test.ts +0 -384
  408. package/src/__tests__/swarm-recursion.test.ts +0 -197
  409. package/src/__tests__/swarm-router-planner.test.ts +0 -234
  410. package/src/__tests__/swarm-tool.test.ts +0 -185
  411. package/src/__tests__/swarm-worker-backend.test.ts +0 -144
  412. package/src/__tests__/swarm-worker-runner.test.ts +0 -288
  413. package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
  414. package/src/commands/cc-command-registry.ts +0 -248
  415. package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
  416. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
  417. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
  418. package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
  419. package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
  420. package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
  421. package/src/config/schemas/swarm.ts +0 -82
  422. package/src/logfire.ts +0 -135
  423. package/src/memory/search/lexical.ts +0 -48
  424. package/src/providers/failover.ts +0 -186
  425. package/src/runtime/local-gateway-health.ts +0 -275
  426. package/src/security/secret-ingress.ts +0 -68
  427. package/src/swarm/backend-claude-code.ts +0 -225
  428. package/src/swarm/checkpoint.ts +0 -137
  429. package/src/swarm/graph-utils.ts +0 -53
  430. package/src/swarm/index.ts +0 -55
  431. package/src/swarm/limits.ts +0 -66
  432. package/src/swarm/orchestrator.ts +0 -424
  433. package/src/swarm/plan-validator.ts +0 -117
  434. package/src/swarm/router-planner.ts +0 -162
  435. package/src/swarm/router-prompts.ts +0 -39
  436. package/src/swarm/synthesizer.ts +0 -81
  437. package/src/swarm/types.ts +0 -72
  438. package/src/swarm/worker-backend.ts +0 -131
  439. package/src/swarm/worker-prompts.ts +0 -80
  440. package/src/swarm/worker-runner.ts +0 -170
  441. package/src/tools/claude-code/claude-code.ts +0 -610
  442. package/src/tools/swarm/delegate.ts +0 -205
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: settings
3
- description: Manage assistant voice and system settings
3
+ description: Manage assistant voice, avatar, and system settings
4
4
  compatibility: "Designed for Vellum personal assistants"
5
5
  metadata:
6
6
  emoji: "\u2699\uFE0F"
@@ -8,4 +8,17 @@ metadata:
8
8
  display-name: "Settings"
9
9
  ---
10
10
 
11
- Tools for managing assistant settings: voice configuration (TTS voice, PTT activation key, conversation timeout), system settings navigation, and in-app settings tab navigation.
11
+ Tools for managing assistant settings: voice configuration (TTS voice, PTT activation key, conversation timeout), avatar management, system settings navigation, and in-app settings tab navigation.
12
+
13
+ ## Avatar
14
+
15
+ When the user asks to set, change, or update your avatar to an image they provide:
16
+
17
+ 1. Find the uploaded image in the conversation attachments directory
18
+ 2. Use the `set_avatar` tool with the `image_path` parameter set to the workspace-relative path (e.g. `conversations/<id>/attachments/Dropped Image.png`)
19
+
20
+ The tool copies the image to the canonical location (`data/avatar/avatar-image.png`) and notifies the app to refresh automatically.
21
+
22
+ When the user asks to remove, clear, or reset their avatar, use the `remove_avatar` tool. It deletes only the custom image and preserves the native character traits so the character avatar is restored automatically.
23
+
24
+ **Do NOT use `bash`, `cp`, or `rm` for avatar operations** — always use `set_avatar` / `remove_avatar` so the app is properly notified and character traits are preserved.
@@ -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,13 @@
11
11
  "properties": {
12
12
  "setting": {
13
13
  "type": "string",
14
- "enum": ["activation_key", "conversation_timeout", "tts_voice_id"],
14
+ "enum": [
15
+ "activation_key",
16
+ "conversation_timeout",
17
+ "fish_audio_reference_id",
18
+ "tts_provider",
19
+ "tts_voice_id"
20
+ ],
15
21
  "description": "The voice setting to change"
16
22
  },
17
23
  "value": {
@@ -79,6 +85,45 @@
79
85
  },
80
86
  "executor": "tools/navigate-settings-tab.ts",
81
87
  "execution_target": "host"
88
+ },
89
+ {
90
+ "name": "set_avatar",
91
+ "description": "Set the assistant's avatar to an image file. Copies the source image to the canonical avatar location (data/avatar/avatar-image.png), removes any native character avatar files, and notifies the app to refresh. Use this when the user asks to set, change, or update the avatar to a specific image (e.g. from a conversation attachment).",
92
+ "category": "system",
93
+ "risk": "low",
94
+ "input_schema": {
95
+ "type": "object",
96
+ "properties": {
97
+ "image_path": {
98
+ "type": "string",
99
+ "description": "Path to the image file. Can be absolute or relative to the workspace directory (e.g. 'conversations/<id>/attachments/Dropped Image.png')."
100
+ },
101
+ "activity": {
102
+ "type": "string",
103
+ "description": "Brief non-technical explanation of what you are doing, shown to the user as a status update."
104
+ }
105
+ },
106
+ "required": ["image_path"]
107
+ },
108
+ "executor": "tools/avatar-update.ts",
109
+ "execution_target": "sandbox"
110
+ },
111
+ {
112
+ "name": "remove_avatar",
113
+ "description": "Remove the custom avatar image and restore the native character avatar. Only deletes the custom image — preserves character traits so the character avatar is automatically restored. Use this when the user asks to remove, clear, or reset their avatar.",
114
+ "category": "system",
115
+ "risk": "low",
116
+ "input_schema": {
117
+ "type": "object",
118
+ "properties": {
119
+ "activity": {
120
+ "type": "string",
121
+ "description": "Brief non-technical explanation of what you are doing, shown to the user as a status update."
122
+ }
123
+ }
124
+ },
125
+ "executor": "tools/avatar-remove.ts",
126
+ "execution_target": "sandbox"
82
127
  }
83
128
  ]
84
129
  }
@@ -0,0 +1,59 @@
1
+ import { existsSync, unlinkSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import { buildAssistantEvent } from "../../../../runtime/assistant-event.js";
5
+ import { assistantEventHub } from "../../../../runtime/assistant-event-hub.js";
6
+ import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../../../runtime/assistant-scope.js";
7
+ import type {
8
+ ToolContext,
9
+ ToolExecutionResult,
10
+ } from "../../../../tools/types.js";
11
+ import { getLogger } from "../../../../util/logger.js";
12
+ import { getWorkspaceDir } from "../../../../util/platform.js";
13
+
14
+ const log = getLogger("avatar-remove");
15
+
16
+ export async function run(
17
+ _input: Record<string, unknown>,
18
+ _context: ToolContext,
19
+ ): Promise<ToolExecutionResult> {
20
+ const avatarDir = join(getWorkspaceDir(), "data", "avatar");
21
+ const avatarPath = join(avatarDir, "avatar-image.png");
22
+
23
+ if (!existsSync(avatarPath)) {
24
+ return {
25
+ content: "No custom avatar to remove — already using the default.",
26
+ isError: false,
27
+ };
28
+ }
29
+
30
+ try {
31
+ unlinkSync(avatarPath);
32
+ } catch (err) {
33
+ const message = err instanceof Error ? err.message : String(err);
34
+ log.error({ error: message }, "Failed to remove avatar image");
35
+ return { content: `Error removing avatar: ${message}`, isError: true };
36
+ }
37
+
38
+ // character-traits.json is intentionally preserved so the native
39
+ // character avatar is restored automatically.
40
+
41
+ // Notify connected clients so the avatar refreshes immediately.
42
+ assistantEventHub
43
+ .publish(
44
+ buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
45
+ type: "avatar_updated",
46
+ avatarPath,
47
+ }),
48
+ )
49
+ .catch((err) => {
50
+ log.warn({ err }, "Failed to publish avatar_updated event");
51
+ });
52
+
53
+ log.info("Custom avatar removed, reverting to character avatar");
54
+
55
+ return {
56
+ content: "Custom avatar removed. The character avatar has been restored.",
57
+ isError: false,
58
+ };
59
+ }
@@ -0,0 +1,80 @@
1
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+
4
+ import { buildAssistantEvent } from "../../../../runtime/assistant-event.js";
5
+ import { assistantEventHub } from "../../../../runtime/assistant-event-hub.js";
6
+ import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../../../runtime/assistant-scope.js";
7
+ import type {
8
+ ToolContext,
9
+ ToolExecutionResult,
10
+ } from "../../../../tools/types.js";
11
+ import { getLogger } from "../../../../util/logger.js";
12
+ import { getWorkspaceDir } from "../../../../util/platform.js";
13
+
14
+ const log = getLogger("avatar-update");
15
+
16
+ /** Canonical path where the custom avatar PNG is stored. */
17
+ function getAvatarPath(): string {
18
+ return join(getWorkspaceDir(), "data", "avatar", "avatar-image.png");
19
+ }
20
+
21
+ export async function run(
22
+ input: Record<string, unknown>,
23
+ _context: ToolContext,
24
+ ): Promise<ToolExecutionResult> {
25
+ const sourcePath = input.image_path as string | undefined;
26
+
27
+ if (!sourcePath || typeof sourcePath !== "string") {
28
+ return {
29
+ content:
30
+ 'Error: "image_path" is required. Provide the path to the image file (absolute or relative to workspace).',
31
+ isError: true,
32
+ };
33
+ }
34
+
35
+ const workspaceDir = getWorkspaceDir();
36
+ const resolvedSource = sourcePath.startsWith("/")
37
+ ? sourcePath
38
+ : join(workspaceDir, sourcePath);
39
+
40
+ if (!existsSync(resolvedSource)) {
41
+ return {
42
+ content: `Error: source file not found: ${resolvedSource}`,
43
+ isError: true,
44
+ };
45
+ }
46
+
47
+ const avatarPath = getAvatarPath();
48
+ const avatarDir = dirname(avatarPath);
49
+
50
+ try {
51
+ mkdirSync(avatarDir, { recursive: true });
52
+ copyFileSync(resolvedSource, avatarPath);
53
+ } catch (err) {
54
+ const message = err instanceof Error ? err.message : String(err);
55
+ log.error({ error: message }, "Failed to copy avatar image");
56
+ return { content: `Error copying avatar: ${message}`, isError: true };
57
+ }
58
+
59
+ // Keep character-traits.json and character-ascii.txt so the character
60
+ // avatar can be restored if the custom image is later removed.
61
+
62
+ // Notify connected clients so the avatar refreshes immediately.
63
+ assistantEventHub
64
+ .publish(
65
+ buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
66
+ type: "avatar_updated",
67
+ avatarPath,
68
+ }),
69
+ )
70
+ .catch((err) => {
71
+ log.warn({ err }, "Failed to publish avatar_updated event");
72
+ });
73
+
74
+ log.info({ avatarPath, source: resolvedSource }, "Avatar updated");
75
+
76
+ return {
77
+ content: `Avatar updated from ${sourcePath}. The app will refresh automatically.`,
78
+ isError: false,
79
+ };
80
+ }
@@ -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,
@@ -76,4 +76,4 @@ For setting up recurring digests, load the `slack-digest-setup` skill which cove
76
76
 
77
77
  ## Connection
78
78
 
79
- Before using any Slack tool, verify that Slack is connected. If not connected, guide the user through the Slack setup flow described in the messaging skill.
79
+ Before using any Slack tool, verify that Slack is connected. If not connected, load the **slack-app-setup** skill (`skill_load` with `skill: "slack-app-setup"`) and follow its step-by-step guided flow. Do NOT improvise setup instructions — the `slack-app-setup` skill is the single source of truth for Slack connection setup. Slack uses Socket Mode (not OAuth) and does not require redirect URLs or any OAuth flow.
@@ -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";
@@ -136,6 +132,8 @@ import * as sequenceImport from "./bundled-skills/sequences/tools/sequence-impor
136
132
  import * as sequenceList from "./bundled-skills/sequences/tools/sequence-list.js";
137
133
  import * as sequenceUpdate from "./bundled-skills/sequences/tools/sequence-update.js";
138
134
  // ── settings ───────────────────────────────────────────────────────────────────
135
+ import * as avatarRemove from "./bundled-skills/settings/tools/avatar-remove.js";
136
+ import * as avatarUpdate from "./bundled-skills/settings/tools/avatar-update.js";
139
137
  import * as navigateSettingsTab from "./bundled-skills/settings/tools/navigate-settings-tab.js";
140
138
  import * as openSystemSettings from "./bundled-skills/settings/tools/open-system-settings.js";
141
139
  import * as voiceConfigUpdate from "./bundled-skills/settings/tools/voice-config-update.js";
@@ -210,9 +208,6 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
210
208
  // chatgpt-import
211
209
  ["chatgpt-import:tools/chatgpt-import.ts", chatgptImport],
212
210
 
213
- // claude-code
214
- ["claude-code:tools/claude-code.ts", claudeCode],
215
-
216
211
  // computer-use
217
212
  ["computer-use:tools/computer-use-observe.ts", computerUseObserve],
218
213
  ["computer-use:tools/computer-use-click.ts", computerUseClick],
@@ -298,9 +293,6 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
298
293
  // notifications
299
294
  ["notifications:tools/send-notification.ts", sendNotification],
300
295
 
301
- // orchestration
302
- ["orchestration:tools/swarm-delegate.ts", swarmDelegate],
303
-
304
296
  // phone-calls
305
297
  ["phone-calls:tools/call-start.ts", callStart],
306
298
  ["phone-calls:tools/call-status.ts", callStatus],
@@ -333,6 +325,8 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
333
325
  ["sequences:tools/sequence-analytics.ts", sequenceAnalytics],
334
326
 
335
327
  // settings
328
+ ["settings:tools/avatar-update.ts", avatarUpdate],
329
+ ["settings:tools/avatar-remove.ts", avatarRemove],
336
330
  ["settings:tools/voice-config-update.ts", voiceConfigUpdate],
337
331
  ["settings:tools/open-system-settings.ts", openSystemSettings],
338
332
  ["settings:tools/navigate-settings-tab.ts", navigateSettingsTab],
@@ -2,6 +2,4 @@ import { applyNestedDefaults } from "./loader.js";
2
2
  import type { AssistantConfig } from "./types.js";
3
3
 
4
4
  // Single source of truth: Zod schema field-level .default() values.
5
- // Uses applyNestedDefaults to cascade through nested .default({}) calls,
6
- // which Zod 4 doesn't resolve in a single parse pass.
7
5
  export const DEFAULT_CONFIG: AssistantConfig = applyNestedDefaults({});
@@ -55,12 +55,12 @@ export function getIsContainerized(): boolean {
55
55
  }
56
56
 
57
57
  /**
58
- * WORKSPACE_DIR — string, default: undefined
59
- * When set, overrides the default workspace directory. Used in containerized
60
- * deployments where the workspace is a separate volume.
58
+ * VELLUM_WORKSPACE_DIR — string, default: undefined
59
+ * Overrides the default workspace directory.
60
+ * Used in containerized deployments where the workspace is a separate volume.
61
61
  */
62
62
  export function getWorkspaceDirOverride(): string | undefined {
63
- return str("WORKSPACE_DIR");
63
+ return str("VELLUM_WORKSPACE_DIR");
64
64
  }
65
65
 
66
66
  // ── Known env var names ──────────────────────────────────────────────────────
@@ -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",
package/src/config/env.ts CHANGED
@@ -15,6 +15,7 @@
15
15
 
16
16
  import { getLogger } from "../util/logger.js";
17
17
  import { checkUnrecognizedEnvVars } from "./env-registry.js";
18
+ import { getConfig } from "./loader.js";
18
19
 
19
20
  const log = getLogger("env");
20
21
 
@@ -111,15 +112,8 @@ export function hasUngatedHttpAuthDisabled(): boolean {
111
112
 
112
113
  // ── Monitoring ───────────────────────────────────────────────────────────────
113
114
 
114
- export function getLogfireToken(): string | undefined {
115
- return str("LOGFIRE_TOKEN");
116
- }
117
-
118
- const DEFAULT_SENTRY_DSN =
119
- "https://db2d38a082e4ee35eeaea08c44b376ec@o4504590528675840.ingest.us.sentry.io/4510874712276992";
120
-
121
115
  export function getSentryDsn(): string {
122
- return str("SENTRY_DSN") ?? DEFAULT_SENTRY_DSN;
116
+ return str("SENTRY_DSN_ASSISTANT") ?? "";
123
117
  }
124
118
 
125
119
  // ── Qdrant ───────────────────────────────────────────────────────────────────
@@ -132,6 +126,10 @@ export function getQdrantHttpPortEnv(): number | undefined {
132
126
  return int("QDRANT_HTTP_PORT");
133
127
  }
134
128
 
129
+ export function getQdrantReadyzTimeoutMs(): number | undefined {
130
+ return int("QDRANT_READYZ_TIMEOUT_MS");
131
+ }
132
+
135
133
  // ── Ollama ───────────────────────────────────────────────────────────────────
136
134
 
137
135
  export function getOllamaBaseUrlEnv(): string | undefined {
@@ -147,7 +145,19 @@ export function setPlatformBaseUrl(value: string | undefined): void {
147
145
  }
148
146
 
149
147
  export function getPlatformBaseUrl(): string {
150
- return str("PLATFORM_BASE_URL") ?? _platformBaseUrlOverride ?? "";
148
+ let configUrl: string | undefined;
149
+ try {
150
+ const val = getConfig().platform.baseUrl;
151
+ if (val) configUrl = val;
152
+ } catch {
153
+ // Config not yet available (early bootstrap) — fall through
154
+ }
155
+ return (
156
+ configUrl ||
157
+ str("VELLUM_PLATFORM_URL") ||
158
+ _platformBaseUrlOverride ||
159
+ "https://platform.vellum.ai"
160
+ );
151
161
  }
152
162
 
153
163
  let _platformAssistantIdOverride: string | undefined;
@@ -205,14 +215,11 @@ export function getPlatformInternalApiKey(): string {
205
215
  // ── Telemetry ──────────────────────────────────────────────────────────────────
206
216
 
207
217
  export function getTelemetryPlatformUrl(): string {
208
- return str("TELEMETRY_PLATFORM_URL") ?? "https://platform.vellum.ai";
218
+ return str("TELEMETRY_PLATFORM_URL") ?? "";
209
219
  }
210
220
 
211
221
  export function getTelemetryAppToken(): string {
212
- return (
213
- str("TELEMETRY_APP_TOKEN") ??
214
- "e01cf85768cc3617e986f0a7f1966b72e25316526c5db54c8b94a9c3c5c9eaed"
215
- );
222
+ return str("TELEMETRY_APP_TOKEN") ?? "";
216
223
  }
217
224
 
218
225
  // ── Startup validation ──────────────────────────────────────────────────────
@@ -17,6 +17,14 @@
17
17
  "description": "Enable user-hosted onboarding flow",
18
18
  "defaultEnabled": false
19
19
  },
20
+ {
21
+ "id": "platform-hosted-enabled",
22
+ "scope": "macos",
23
+ "key": "platform_hosted_enabled",
24
+ "label": "Platform Hosted Assistants",
25
+ "description": "Enable the Vellum Cloud hosting option on the Hosting screen",
26
+ "defaultEnabled": false
27
+ },
20
28
  {
21
29
  "id": "contacts",
22
30
  "scope": "assistant",
@@ -65,14 +73,6 @@
65
73
  "description": "Show Component Gallery and Replay Onboarding in the menu bar",
66
74
  "defaultEnabled": false
67
75
  },
68
- {
69
- "id": "logfire",
70
- "scope": "assistant",
71
- "key": "feature_flags.logfire.enabled",
72
- "label": "Logfire LLM Observability",
73
- "description": "Enable Logfire tracing for LLM request/response telemetry when LOGFIRE_TOKEN is set",
74
- "defaultEnabled": false
75
- },
76
76
  {
77
77
  "id": "ces-tools",
78
78
  "scope": "assistant",
@@ -111,7 +111,15 @@
111
111
  "key": "feature_flags.ces-managed-sidecar.enabled",
112
112
  "label": "CES Managed Sidecar Transport",
113
113
  "description": "Use managed sidecar transport for CES communication when running in a containerized environment",
114
- "defaultEnabled": false
114
+ "defaultEnabled": true
115
+ },
116
+ {
117
+ "id": "ces-credential-backend",
118
+ "scope": "assistant",
119
+ "key": "feature_flags.ces-credential-backend.enabled",
120
+ "label": "CES Credential Backend",
121
+ "description": "Route credential reads and writes through the CES process instead of accessing the encrypted store directly",
122
+ "defaultEnabled": true
115
123
  },
116
124
  {
117
125
  "id": "settings-billing",
@@ -257,6 +265,14 @@
257
265
  "description": "Show the Embedding service card in Models & Services settings",
258
266
  "defaultEnabled": false
259
267
  },
268
+ {
269
+ "id": "settings-schedules",
270
+ "scope": "assistant",
271
+ "key": "feature_flags.settings-schedules.enabled",
272
+ "label": "Schedules Settings Tab",
273
+ "description": "Show the Schedules tab in Settings for viewing and managing schedules",
274
+ "defaultEnabled": false
275
+ },
260
276
  {
261
277
  "id": "quick-input",
262
278
  "scope": "macos",
@@ -288,6 +304,30 @@
288
304
  "label": "Channel Voice Transcription",
289
305
  "description": "Auto-transcribe voice/audio messages received from channels (Telegram, WhatsApp) before processing",
290
306
  "defaultEnabled": true
307
+ },
308
+ {
309
+ "id": "sounds",
310
+ "scope": "assistant",
311
+ "key": "feature_flags.sounds.enabled",
312
+ "label": "Sounds",
313
+ "description": "Enable the Sounds tab in Settings and all app sound playback (event sounds, random ambient sounds)",
314
+ "defaultEnabled": true
315
+ },
316
+ {
317
+ "id": "message-tts",
318
+ "scope": "assistant",
319
+ "key": "feature_flags.message-tts.enabled",
320
+ "label": "Message Text-to-Speech",
321
+ "description": "Show a speaker button on assistant messages to generate and play the message as audio via Fish Audio TTS",
322
+ "defaultEnabled": false
323
+ },
324
+ {
325
+ "id": "backward-releases",
326
+ "scope": "assistant",
327
+ "key": "feature_flags.backward-releases.enabled",
328
+ "label": "Backward Releases",
329
+ "description": "Show older versions in the version picker, allowing rollback to previous releases",
330
+ "defaultEnabled": true
291
331
  }
292
332
  ]
293
333
  }