@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
@@ -175,6 +175,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
175
175
  importance: 0.7,
176
176
  fingerprint: "fp-assistant-inferred",
177
177
  verificationState: "assistant_inferred",
178
+ sourceType: "extraction",
179
+ sourceMessageRole: "assistant",
178
180
  scopeId: "default",
179
181
  firstSeenAt: now + 10,
180
182
  lastSeenAt: now + 10,
@@ -189,6 +191,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
189
191
  importance: 0.8,
190
192
  fingerprint: "fp-user-reported",
191
193
  verificationState: "user_reported",
194
+ sourceType: "extraction",
195
+ sourceMessageRole: "user",
192
196
  scopeId: "default",
193
197
  firstSeenAt: now + 20,
194
198
  lastSeenAt: now + 20,
@@ -203,6 +207,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
203
207
  importance: 0.5,
204
208
  fingerprint: "fp-other-conv",
205
209
  verificationState: "assistant_inferred",
210
+ sourceType: "extraction",
211
+ sourceMessageRole: "assistant",
206
212
  scopeId: "default",
207
213
  firstSeenAt: now + 30,
208
214
  lastSeenAt: now + 30,
@@ -217,6 +223,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
217
223
  importance: 0.4,
218
224
  fingerprint: "fp-already-superseded",
219
225
  verificationState: "assistant_inferred",
226
+ sourceType: "extraction",
227
+ sourceMessageRole: "assistant",
220
228
  scopeId: "default",
221
229
  firstSeenAt: now + 5,
222
230
  lastSeenAt: now + 5,
@@ -449,6 +457,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
449
457
  importance: 0.7,
450
458
  fingerprint: "fp-cross-sourced",
451
459
  verificationState: "assistant_inferred",
460
+ sourceType: "extraction",
461
+ sourceMessageRole: "assistant",
452
462
  scopeId: "default",
453
463
  firstSeenAt: now + 10,
454
464
  lastSeenAt: now + 20,
@@ -572,6 +582,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
572
582
  importance: 0.7,
573
583
  fingerprint: "fp-cross-sched",
574
584
  verificationState: "assistant_inferred",
585
+ sourceType: "extraction",
586
+ sourceMessageRole: "assistant",
575
587
  scopeId: "default",
576
588
  firstSeenAt: now + 10,
577
589
  lastSeenAt: now + 20,
@@ -688,6 +700,8 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
688
700
  importance: 0.7,
689
701
  fingerprint: "fp-good-corroboration",
690
702
  verificationState: "assistant_inferred",
703
+ sourceType: "extraction",
704
+ sourceMessageRole: "assistant",
691
705
  scopeId: "default",
692
706
  firstSeenAt: now + 10,
693
707
  lastSeenAt: now + 20,
@@ -330,7 +330,7 @@ describe("ToolExecutor → real shell allowlist integration", () => {
330
330
  expect(patterns).toContain("action:git");
331
331
  });
332
332
 
333
- test("pipeline command produces only exact option", async () => {
333
+ test("pipeline command produces exact + action-key options", async () => {
334
334
  const { prompter, getAllowlist } = makeCapturingPrompter();
335
335
  const executor = new ToolExecutor(prompter);
336
336
 
@@ -343,9 +343,11 @@ describe("ToolExecutor → real shell allowlist integration", () => {
343
343
  const allowlist = getAllowlist();
344
344
  expect(allowlist).toBeDefined();
345
345
 
346
- // Pipelines are complex commands — only exact option, no action keys
347
- expect(allowlist!.length).toBe(1);
346
+ // Pipelines now produce exact option + action key options
347
+ expect(allowlist!.length).toBeGreaterThanOrEqual(2);
348
348
  expect(allowlist![0].pattern).toBe("cat file.txt | grep error");
349
349
  expect(allowlist![0].description).toContain("compound");
350
+ // Action keys from the first segment before the pipe
351
+ expect(allowlist!.some((o) => o.pattern.startsWith("action:"))).toBe(true);
350
352
  });
351
353
  });
@@ -41,11 +41,6 @@ mock.module("../util/logger.js", () => ({
41
41
  }),
42
42
  }));
43
43
 
44
- // Mock security check to always pass
45
- mock.module("../security/secret-ingress.js", () => ({
46
- checkIngressForSecrets: () => ({ blocked: false }),
47
- }));
48
-
49
44
  mock.module("../config/env.js", () => ({
50
45
  isHttpAuthDisabled: () => true,
51
46
  getGatewayInternalBaseUrl: () => "http://127.0.0.1:7830",
@@ -36,10 +36,6 @@ mock.module("../util/logger.js", () => ({
36
36
  }),
37
37
  }));
38
38
 
39
- mock.module("../security/secret-ingress.js", () => ({
40
- checkIngressForSecrets: () => ({ blocked: false }),
41
- }));
42
-
43
39
  mock.module("../config/env.js", () => ({
44
40
  isHttpAuthDisabled: () => true,
45
41
  getGatewayInternalBaseUrl: () => "http://127.0.0.1:7830",
@@ -2,7 +2,8 @@
2
2
  * Unit tests for TwiML generation with voice quality profiles.
3
3
  *
4
4
  * Tests that generateTwiML correctly uses profile values for
5
- * ttsProvider, voice, language, and transcriptionProvider.
5
+ * ttsProvider, voice, language, transcriptionProvider,
6
+ * and interruptSensitivity.
6
7
  */
7
8
  import { describe, expect, mock, test } from "bun:test";
8
9
 
@@ -26,6 +27,7 @@ describe("generateTwiML with voice quality profile", () => {
26
27
  transcriptionProvider: "Deepgram",
27
28
  ttsProvider: "Google",
28
29
  voice: "Google.en-US-Journey-O",
30
+ interruptSensitivity: "low",
29
31
  });
30
32
 
31
33
  expect(twiml).toContain('ttsProvider="Google"');
@@ -40,6 +42,7 @@ describe("generateTwiML with voice quality profile", () => {
40
42
  transcriptionProvider: "Deepgram",
41
43
  ttsProvider: "ElevenLabs",
42
44
  voice: "voice123-turbo_v2_5-1_0.5_0.75",
45
+ interruptSensitivity: "low",
43
46
  });
44
47
 
45
48
  expect(twiml).toContain('ttsProvider="ElevenLabs"');
@@ -52,6 +55,7 @@ describe("generateTwiML with voice quality profile", () => {
52
55
  transcriptionProvider: "Deepgram",
53
56
  ttsProvider: "Google",
54
57
  voice: "Google.en-US-Journey-O",
58
+ interruptSensitivity: "low",
55
59
  });
56
60
 
57
61
  expect(twiml).toContain('voice="Google.en-US-Journey-O"');
@@ -63,6 +67,7 @@ describe("generateTwiML with voice quality profile", () => {
63
67
  transcriptionProvider: "Deepgram",
64
68
  ttsProvider: "ElevenLabs",
65
69
  voice: "abc123-turbo_v2_5-1_0.5_0.75",
70
+ interruptSensitivity: "low",
66
71
  });
67
72
 
68
73
  expect(twiml).toContain('voice="abc123-turbo_v2_5-1_0.5_0.75"');
@@ -74,6 +79,7 @@ describe("generateTwiML with voice quality profile", () => {
74
79
  transcriptionProvider: "Google",
75
80
  ttsProvider: "Google",
76
81
  voice: "Google.es-MX-Standard-A",
82
+ interruptSensitivity: "low",
77
83
  });
78
84
 
79
85
  expect(twiml).toContain('language="es-MX"');
@@ -85,6 +91,7 @@ describe("generateTwiML with voice quality profile", () => {
85
91
  transcriptionProvider: "Google",
86
92
  ttsProvider: "Google",
87
93
  voice: "Google.en-US-Journey-O",
94
+ interruptSensitivity: "low",
88
95
  });
89
96
 
90
97
  expect(twiml).toContain('transcriptionProvider="Google"');
@@ -96,6 +103,7 @@ describe("generateTwiML with voice quality profile", () => {
96
103
  transcriptionProvider: "Deepgram",
97
104
  ttsProvider: "Google",
98
105
  voice: 'voice<>&"test',
106
+ interruptSensitivity: "low",
99
107
  });
100
108
 
101
109
  expect(twiml).toContain('voice="voice&lt;&gt;&amp;&quot;test"');
@@ -108,6 +116,7 @@ describe("generateTwiML with voice quality profile", () => {
108
116
  transcriptionProvider: "Deepgram",
109
117
  ttsProvider: "Google",
110
118
  voice: "Google.en-US-Journey-O",
119
+ interruptSensitivity: "low",
111
120
  });
112
121
 
113
122
  expect(twiml).toContain(`callSessionId=${callSessionId}`);
@@ -119,6 +128,7 @@ describe("generateTwiML with voice quality profile", () => {
119
128
  transcriptionProvider: "Deepgram",
120
129
  ttsProvider: "Google",
121
130
  voice: "Google.en-US-Journey-O",
131
+ interruptSensitivity: "low",
122
132
  });
123
133
 
124
134
  expect(twiml).toContain('interruptible="true"');
@@ -131,8 +141,136 @@ describe("generateTwiML with voice quality profile", () => {
131
141
  transcriptionProvider: "Deepgram",
132
142
  ttsProvider: "Google",
133
143
  voice: "Google.en-US-Journey-O",
144
+ interruptSensitivity: "low",
134
145
  });
135
146
 
136
147
  expect(twiml).not.toContain("welcomeGreeting=");
137
148
  });
149
+
150
+ test('TwiML includes interruptSensitivity="low" when profile has low', () => {
151
+ const twiml = generateTwiML(callSessionId, relayUrl, welcomeGreeting, {
152
+ language: "en-US",
153
+ transcriptionProvider: "Deepgram",
154
+ ttsProvider: "Google",
155
+ voice: "Google.en-US-Journey-O",
156
+ interruptSensitivity: "low",
157
+ });
158
+
159
+ expect(twiml).toContain('interruptSensitivity="low"');
160
+ });
161
+
162
+ test("custom interruptSensitivity values are reflected correctly", () => {
163
+ const twimlMedium = generateTwiML(
164
+ callSessionId,
165
+ relayUrl,
166
+ welcomeGreeting,
167
+ {
168
+ language: "en-US",
169
+ transcriptionProvider: "Deepgram",
170
+ ttsProvider: "Google",
171
+ voice: "Google.en-US-Journey-O",
172
+ interruptSensitivity: "medium",
173
+ },
174
+ );
175
+
176
+ expect(twimlMedium).toContain('interruptSensitivity="medium"');
177
+
178
+ const twimlHigh = generateTwiML(
179
+ callSessionId,
180
+ relayUrl,
181
+ welcomeGreeting,
182
+ {
183
+ language: "en-US",
184
+ transcriptionProvider: "Deepgram",
185
+ ttsProvider: "Google",
186
+ voice: "Google.en-US-Journey-O",
187
+ interruptSensitivity: "high",
188
+ },
189
+ );
190
+
191
+ expect(twimlHigh).toContain('interruptSensitivity="high"');
192
+ });
193
+
194
+ test("hints attribute present when hints string is non-empty", () => {
195
+ const twiml = generateTwiML(
196
+ callSessionId,
197
+ relayUrl,
198
+ welcomeGreeting,
199
+ {
200
+ language: "en-US",
201
+ transcriptionProvider: "Deepgram",
202
+ ttsProvider: "ElevenLabs",
203
+ voice: "voice123",
204
+ interruptSensitivity: "low",
205
+ },
206
+ undefined,
207
+ undefined,
208
+ "Alice,Bob,Vellum",
209
+ );
210
+
211
+ expect(twiml).toContain('hints="Alice,Bob,Vellum"');
212
+ });
213
+
214
+ test("hints attribute omitted when hints string is empty", () => {
215
+ const twiml = generateTwiML(
216
+ callSessionId,
217
+ relayUrl,
218
+ welcomeGreeting,
219
+ {
220
+ language: "en-US",
221
+ transcriptionProvider: "Deepgram",
222
+ ttsProvider: "ElevenLabs",
223
+ voice: "voice123",
224
+ interruptSensitivity: "low",
225
+ },
226
+ undefined,
227
+ undefined,
228
+ "",
229
+ );
230
+
231
+ expect(twiml).not.toContain("hints=");
232
+ });
233
+
234
+ test("hints attribute omitted when hints parameter is undefined", () => {
235
+ const twiml = generateTwiML(
236
+ callSessionId,
237
+ relayUrl,
238
+ welcomeGreeting,
239
+ {
240
+ language: "en-US",
241
+ transcriptionProvider: "Deepgram",
242
+ ttsProvider: "ElevenLabs",
243
+ voice: "voice123",
244
+ interruptSensitivity: "low",
245
+ },
246
+ undefined,
247
+ undefined,
248
+ undefined,
249
+ );
250
+
251
+ expect(twiml).not.toContain("hints=");
252
+ });
253
+
254
+ test("XML special characters in hints are escaped properly", () => {
255
+ const twiml = generateTwiML(
256
+ callSessionId,
257
+ relayUrl,
258
+ welcomeGreeting,
259
+ {
260
+ language: "en-US",
261
+ transcriptionProvider: "Deepgram",
262
+ ttsProvider: "ElevenLabs",
263
+ voice: "voice123",
264
+ interruptSensitivity: "low",
265
+ },
266
+ undefined,
267
+ undefined,
268
+ 'O\'Brien,Smith & Jones,"Dr. Lee"',
269
+ );
270
+
271
+ expect(twiml).toContain(
272
+ 'hints="O&apos;Brien,Smith &amp; Jones,&quot;Dr. Lee&quot;"',
273
+ );
274
+ expect(twiml).not.toContain("hints=\"O'Brien");
275
+ });
138
276
  });
@@ -66,8 +66,6 @@ mock.module("../util/platform.js", () => ({
66
66
  getSandboxWorkingDir: () => "",
67
67
  getInterfacesDir: () => "",
68
68
  getClipboardCommand: () => null,
69
- readLockfile: () => null,
70
- writeLockfile: () => {},
71
69
  readPlatformToken: () => null,
72
70
  readSessionToken: () => null,
73
71
  getTCPPort: () => 8765,
@@ -61,9 +61,7 @@ const platformOverrides: Record<string, (...args: unknown[]) => unknown> = {
61
61
  getSessionTokenPath: () => join(TEST_DIR, "session-token"),
62
62
  readSessionToken: () => null,
63
63
  getClipboardCommand: () => null,
64
- readLockfile: () => null,
65
64
  normalizeAssistantId: (id: unknown) => String(id),
66
- writeLockfile: () => {},
67
65
  getEmbeddingModelsDir: () => join(TEST_DIR, "embedding-models"),
68
66
  getTCPPort: () => 8765,
69
67
  isTCPEnabled: () => false,
@@ -141,7 +139,6 @@ interface TestConfig {
141
139
  permissions: { mode: "strict" | "workspace" };
142
140
  skills: { load: { extraDirs: string[] } };
143
141
  sandbox: { enabled: boolean };
144
- assistantFeatureFlagValues?: Record<string, boolean>;
145
142
  [key: string]: unknown;
146
143
  }
147
144
 
@@ -149,9 +146,6 @@ const testConfig: TestConfig = {
149
146
  permissions: { mode: "workspace" },
150
147
  skills: { load: { extraDirs: [] } },
151
148
  sandbox: { enabled: true },
152
- assistantFeatureFlagValues: {
153
- "feature_flags.inline-skill-commands.enabled": true,
154
- },
155
149
  };
156
150
 
157
151
  mock.module("../config/loader.js", () => ({
@@ -169,6 +163,8 @@ mock.module("../config/loader.js", () => ({
169
163
 
170
164
  await import("../tools/skills/load.js");
171
165
  const { getTool } = await import("../tools/registry.js");
166
+ const { _setOverridesForTesting } =
167
+ await import("../config/assistant-feature-flags.js");
172
168
 
173
169
  // ── Helpers ──────────────────────────────────────────────────────────────
174
170
 
@@ -228,16 +224,17 @@ describe("vellum-self-knowledge inline command expansion", () => {
228
224
  ) => mockRunInlineCommand(command, workingDir),
229
225
  }));
230
226
 
231
- // Enable the feature flag
232
- testConfig.assistantFeatureFlagValues = {
227
+ // Enable the feature flag via protected directory override
228
+ _setOverridesForTesting({
233
229
  "feature_flags.inline-skill-commands.enabled": true,
234
- };
230
+ });
235
231
  testConfig.skills = { load: { extraDirs: [] } };
236
232
 
237
233
  installSelfKnowledgeSkill();
238
234
  });
239
235
 
240
236
  afterEach(() => {
237
+ _setOverridesForTesting({});
241
238
  if (existsSync(TEST_DIR)) {
242
239
  rmSync(TEST_DIR, { recursive: true, force: true });
243
240
  }
@@ -124,4 +124,62 @@ describe("resolveVoiceQualityProfile", () => {
124
124
  const profile = resolveVoiceQualityProfile();
125
125
  expect(profile.voice).toBe("voice1-turbo_v2_5-0.9_0.8_0.9");
126
126
  });
127
+
128
+ test("interruptSensitivity defaults to 'low' when not configured", () => {
129
+ mockConfig = {
130
+ elevenlabs: { voiceId: "abc" },
131
+ calls: {
132
+ voice: {
133
+ language: "en-US",
134
+ transcriptionProvider: "Deepgram",
135
+ },
136
+ },
137
+ };
138
+ const profile = resolveVoiceQualityProfile();
139
+ expect(profile.interruptSensitivity).toBe("low");
140
+ });
141
+
142
+ test("interruptSensitivity reflects configured value", () => {
143
+ mockConfig = {
144
+ elevenlabs: { voiceId: "abc" },
145
+ calls: {
146
+ voice: {
147
+ language: "en-US",
148
+ transcriptionProvider: "Deepgram",
149
+ interruptSensitivity: "high",
150
+ },
151
+ },
152
+ };
153
+ const profile = resolveVoiceQualityProfile();
154
+ expect(profile.interruptSensitivity).toBe("high");
155
+ });
156
+
157
+ test("hints defaults to empty array when not configured", () => {
158
+ mockConfig = {
159
+ elevenlabs: { voiceId: "abc" },
160
+ calls: {
161
+ voice: {
162
+ language: "en-US",
163
+ transcriptionProvider: "Deepgram",
164
+ },
165
+ },
166
+ };
167
+ const profile = resolveVoiceQualityProfile();
168
+ expect(profile.hints).toEqual([]);
169
+ });
170
+
171
+ test("hints reflects configured values", () => {
172
+ mockConfig = {
173
+ elevenlabs: { voiceId: "abc" },
174
+ calls: {
175
+ voice: {
176
+ language: "en-US",
177
+ transcriptionProvider: "Deepgram",
178
+ hints: ["Vellum", "Velissa", "AI assistant"],
179
+ },
180
+ },
181
+ };
182
+ const profile = resolveVoiceQualityProfile();
183
+ expect(profile.hints).toEqual(["Vellum", "Velissa", "AI assistant"]);
184
+ });
127
185
  });
@@ -54,7 +54,6 @@ mock.module("../config/loader.js", () => ({
54
54
  ui: {},
55
55
 
56
56
  provider: "anthropic",
57
- providerOrder: ["anthropic"],
58
57
  calls: {
59
58
  enabled: true,
60
59
  provider: "twilio",
@@ -70,12 +69,6 @@ mock.module("../config/loader.js", () => ({
70
69
  }),
71
70
  }));
72
71
 
73
- // ── Secret ingress mock ────────────────────────────────────────────
74
-
75
- mock.module("../security/secret-ingress.js", () => ({
76
- checkIngressForSecrets: () => ({ blocked: false }),
77
- }));
78
-
79
72
  // ── Assistant event hub mock ───────────────────────────────────────
80
73
 
81
74
  mock.module("../runtime/assistant-event-hub.js", () => ({