@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,248 +0,0 @@
1
- import {
2
- closeSync,
3
- existsSync,
4
- openSync,
5
- readdirSync,
6
- readFileSync,
7
- readSync,
8
- } from "node:fs";
9
- import { basename, dirname, join, resolve } from "node:path";
10
-
11
- import { FRONTMATTER_REGEX } from "../skills/frontmatter.js";
12
- import { getLogger } from "../util/logger.js";
13
-
14
- const log = getLogger("cc-commands");
15
-
16
- // ─── Types ───────────────────────────────────────────────────────────────────
17
-
18
- export interface CCCommandEntry {
19
- /** Command name: basename without .md extension. */
20
- name: string;
21
- /** First non-empty line after frontmatter, stripped of heading markers. */
22
- summary: string;
23
- /** Absolute path to the .md file. */
24
- filePath: string;
25
- /** Directory containing the `.claude/commands/` folder. */
26
- source: string;
27
- }
28
-
29
- export interface CCCommandRegistry {
30
- /** Commands keyed by lowercase name. */
31
- entries: Map<string, CCCommandEntry>;
32
- /** Timestamp (ms) when discovery was performed. */
33
- discoveredAt: number;
34
- }
35
-
36
- // ─── Constants ───────────────────────────────────────────────────────────────
37
-
38
- const COMMAND_NAME_REGEX = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
39
- const DEFAULT_CACHE_TTL_MS = 30_000;
40
- const MAX_SUMMARY_LENGTH = 100;
41
-
42
- /**
43
- * Maximum bytes to read from each command file during discovery.
44
- * 1 KiB is enough for frontmatter (typically < 200 B) plus several content
45
- * lines, which is all we need to extract a one-line summary.
46
- */
47
- const SUMMARY_READ_BYTES = 1024;
48
-
49
- // ─── Cache ───────────────────────────────────────────────────────────────────
50
-
51
- const cache = new Map<string, CCCommandRegistry>();
52
-
53
- /** Clear all cached registries. */
54
- export function invalidateCCCommandCache(): void {
55
- cache.clear();
56
- log.debug("CC command cache invalidated");
57
- }
58
-
59
- // ─── Partial I/O ─────────────────────────────────────────────────────────────
60
-
61
- /**
62
- * Read at most `maxBytes` from the beginning of a file.
63
- * Uses low-level `openSync`/`readSync` so we never pull the entire file into
64
- * memory — important when command templates are large but we only need the
65
- * first few lines for summary extraction.
66
- */
67
- function readFileHead(filePath: string, maxBytes: number): string {
68
- const fd = openSync(filePath, "r");
69
- try {
70
- const buf = Buffer.alloc(maxBytes);
71
- const bytesRead = readSync(fd, buf, 0, maxBytes, 0);
72
- return buf.toString("utf-8", 0, bytesRead);
73
- } finally {
74
- closeSync(fd);
75
- }
76
- }
77
-
78
- // ─── Summary extraction ──────────────────────────────────────────────────────
79
-
80
- /**
81
- * Extract a one-line summary from the beginning of a markdown file.
82
- * Skips YAML frontmatter if present, then returns the first non-empty line
83
- * with leading `#` heading markers stripped. Truncates to 100 chars.
84
- */
85
- function extractSummary(content: string): string {
86
- // Strip frontmatter if present
87
- let body = content;
88
- const fmMatch = content.match(FRONTMATTER_REGEX);
89
- if (fmMatch) {
90
- body = content.slice(fmMatch[0].length);
91
- } else if (/^---\r?\n/.test(content)) {
92
- if (Buffer.byteLength(content, "utf-8") >= SUMMARY_READ_BYTES) {
93
- // Content starts with a frontmatter opening delimiter but the closing
94
- // delimiter was not found. The content length reached SUMMARY_READ_BYTES,
95
- // so the read was likely truncated — the missing closing `---` is
96
- // probably just beyond the read boundary. Return empty rather than
97
- // surfacing partial frontmatter fields as a summary.
98
- return "";
99
- }
100
- // Small file that starts with `---` (thematic break or unclosed
101
- // frontmatter opener). Skip the leading `---` line and extract the
102
- // first real content line from the remainder.
103
- body = content.replace(/^---\r?\n/, "");
104
- }
105
-
106
- // Find first non-empty line
107
- const lines = body.split(/\r?\n/);
108
- for (const line of lines) {
109
- const trimmed = line.trim();
110
- if (!trimmed) continue;
111
-
112
- // Strip leading # heading markers
113
- const stripped = trimmed.replace(/^#+\s*/, "");
114
- if (!stripped) continue;
115
-
116
- // Truncate if needed
117
- if (stripped.length > MAX_SUMMARY_LENGTH) {
118
- return stripped.slice(0, MAX_SUMMARY_LENGTH);
119
- }
120
- return stripped;
121
- }
122
-
123
- return "";
124
- }
125
-
126
- // ─── Discovery ───────────────────────────────────────────────────────────────
127
-
128
- /**
129
- * Discover `.claude/commands/*.md` files by walking up from `cwd`.
130
- * Nearest directory wins on name collisions (child overrides parent).
131
- * Results are cached per cwd with a 30-second TTL.
132
- */
133
- export function discoverCCCommands(
134
- cwd: string,
135
- ttlMs: number = DEFAULT_CACHE_TTL_MS,
136
- ): CCCommandRegistry {
137
- const resolvedCwd = resolve(cwd);
138
-
139
- // Check cache
140
- const cached = cache.get(resolvedCwd);
141
- if (cached && Date.now() - cached.discoveredAt < ttlMs) {
142
- log.debug({ cwd: resolvedCwd }, "CC command cache hit");
143
- return cached;
144
- }
145
-
146
- log.debug(
147
- { cwd: resolvedCwd },
148
- "CC command cache miss, discovering commands",
149
- );
150
-
151
- const entries = new Map<string, CCCommandEntry>();
152
- let current = resolvedCwd;
153
-
154
- // Walk up the directory tree; collect commands from each level.
155
- // Since child directories should win on name collisions, we only add entries
156
- // that haven't been seen yet (first occurrence = nearest ancestor).
157
- while (true) {
158
- const commandsDir = join(current, ".claude", "commands");
159
-
160
- if (existsSync(commandsDir)) {
161
- try {
162
- const files = readdirSync(commandsDir, { withFileTypes: true });
163
- for (const file of files) {
164
- if (!file.isFile()) continue;
165
- if (!file.name.endsWith(".md")) continue;
166
-
167
- const nameWithoutExt = basename(file.name, ".md");
168
-
169
- // Validate command name
170
- if (!COMMAND_NAME_REGEX.test(nameWithoutExt)) {
171
- log.warn(
172
- { fileName: file.name, dir: commandsDir },
173
- "Skipping invalid CC command filename",
174
- );
175
- continue;
176
- }
177
-
178
- const key = nameWithoutExt.toLowerCase();
179
-
180
- // Child directories win — skip if already discovered from a closer ancestor
181
- if (entries.has(key)) continue;
182
-
183
- const filePath = join(commandsDir, file.name);
184
-
185
- let summary = "";
186
- try {
187
- const head = readFileHead(filePath, SUMMARY_READ_BYTES);
188
- summary = extractSummary(head);
189
- } catch (err) {
190
- log.warn(
191
- { err, filePath },
192
- "Failed to read CC command file for summary extraction",
193
- );
194
- }
195
-
196
- entries.set(key, {
197
- name: nameWithoutExt,
198
- summary,
199
- filePath,
200
- source: current,
201
- });
202
- }
203
- } catch (err) {
204
- log.warn({ err, commandsDir }, "Failed to read CC commands directory");
205
- }
206
- }
207
-
208
- const parent = dirname(current);
209
- if (parent === current) break; // reached filesystem root
210
- current = parent;
211
- }
212
-
213
- log.debug(
214
- { cwd: resolvedCwd, count: entries.size },
215
- "CC command discovery complete",
216
- );
217
-
218
- const registry: CCCommandRegistry = {
219
- entries,
220
- discoveredAt: Date.now(),
221
- };
222
-
223
- cache.set(resolvedCwd, registry);
224
- return registry;
225
- }
226
-
227
- // ─── Lookup ──────────────────────────────────────────────────────────────────
228
-
229
- /**
230
- * Look up a single CC command by name (case-insensitive).
231
- */
232
- export function getCCCommand(
233
- cwd: string,
234
- name: string,
235
- ): CCCommandEntry | undefined {
236
- const registry = discoverCCCommands(cwd);
237
- return registry.entries.get(name.toLowerCase());
238
- }
239
-
240
- // ─── Template loading ────────────────────────────────────────────────────────
241
-
242
- /**
243
- * Load the full markdown content of a CC command file.
244
- * This is deferred to execution time to avoid reading full files during discovery.
245
- */
246
- export function loadCCCommandTemplate(entry: CCCommandEntry): string {
247
- return readFileSync(entry.filePath, "utf-8");
248
- }
@@ -1,53 +0,0 @@
1
- ---
2
- name: claude-code
3
- description: Delegate coding tasks to Claude Code
4
- compatibility: "Designed for Vellum personal assistants"
5
- metadata:
6
- emoji: "💻"
7
- vellum:
8
- display-name: "Claude Code"
9
- ---
10
-
11
- You are delegating a coding task to Claude Code, an autonomous AI coding agent. Use this skill when the user needs hands-on software engineering work done.
12
-
13
- ## Capabilities
14
-
15
- Claude Code can:
16
- - Read, write, and edit files across a codebase
17
- - Run shell commands (build, test, lint, deploy scripts)
18
- - Perform multi-step engineering tasks autonomously (refactoring, implementing features, debugging)
19
- - Search codebases for patterns, definitions, and usage
20
- - Work with git repositories (commits, branches, diffs)
21
-
22
- ## When to Delegate
23
-
24
- Delegate to Claude Code when the task involves:
25
- - Writing or modifying source code
26
- - Running build/test/lint commands and iterating on failures
27
- - Exploring a codebase to answer architectural questions
28
- - Multi-file refactors or migrations
29
- - Debugging issues that require reading code and running tests
30
- - Any task that benefits from direct filesystem and shell access
31
-
32
- Do NOT delegate when:
33
- - The user just wants a conversational answer or explanation
34
- - The task is pure information retrieval with no code changes needed
35
- - The user explicitly wants to discuss an approach before implementation
36
-
37
- ## Guardrails
38
-
39
- - Claude Code runs in a sandboxed environment with approval flows for destructive actions
40
- - File writes, edits, and shell commands that modify state require user confirmation (unless auto-approved by trust rules)
41
- - Read-only operations (file reads, searches, web fetches) are auto-approved
42
- - The working directory defaults to the current conversation's working directory but can be overridden
43
-
44
- ## Worker Profiles
45
-
46
- Claude Code supports scoped worker profiles that restrict tool access:
47
-
48
- - **general** (default) - Full access to all tools.
49
- - **researcher** - Read-only access. Can search, read files, and browse the web but cannot write or execute commands.
50
- - **coder** - Full read/write/execute access optimized for implementation tasks.
51
- - **reviewer** - Read-only access tailored for code review, with emphasis on analysis and feedback.
52
-
53
- Select the profile that best matches the task to enforce least-privilege access.
@@ -1,47 +0,0 @@
1
- {
2
- "version": 1,
3
- "tools": [
4
- {
5
- "name": "claude_code",
6
- "description": "Delegate a coding task to Claude Code, an AI-powered coding agent that can read, write, and edit files, run shell commands, and perform complex multi-step software engineering tasks autonomously.",
7
- "category": "coding",
8
- "risk": "medium",
9
- "input_schema": {
10
- "type": "object",
11
- "properties": {
12
- "prompt": {
13
- "type": "string",
14
- "description": "The coding task or question for Claude Code to work on. Use this for free-form tasks. Mutually exclusive with command."
15
- },
16
- "command": {
17
- "type": "string",
18
- "description": "Name of a .claude/commands/*.md command template to execute. The template will be loaded and $ARGUMENTS substituted before execution. Use this instead of prompt when invoking a named CC command."
19
- },
20
- "arguments": {
21
- "type": "string",
22
- "description": "Arguments to substitute into the command template ($ARGUMENTS placeholder). Only used with the command input."
23
- },
24
- "working_dir": {
25
- "type": "string",
26
- "description": "Working directory for Claude Code (defaults to conversation working directory)"
27
- },
28
- "resume": {
29
- "type": "string",
30
- "description": "Claude Code session ID to resume a previous session"
31
- },
32
- "model": {
33
- "type": "string",
34
- "description": "Model to use (defaults to claude-sonnet-4-6)"
35
- },
36
- "profile": {
37
- "type": "string",
38
- "enum": ["general", "researcher", "coder", "reviewer"],
39
- "description": "Worker profile that scopes tool access. Defaults to general."
40
- }
41
- }
42
- },
43
- "executor": "tools/claude-code.ts",
44
- "execution_target": "host"
45
- }
46
- ]
47
- }
@@ -1,12 +0,0 @@
1
- import { claudeCodeTool } from "../../../../tools/claude-code/claude-code.js";
2
- import type {
3
- ToolContext,
4
- ToolExecutionResult,
5
- } from "../../../../tools/types.js";
6
-
7
- export async function run(
8
- input: Record<string, unknown>,
9
- context: ToolContext,
10
- ): Promise<ToolExecutionResult> {
11
- return claudeCodeTool.execute(input, context);
12
- }
@@ -1,33 +0,0 @@
1
- ---
2
- name: orchestration
3
- description: Decompose complex tasks into parallel specialist subtasks
4
- compatibility: "Designed for Vellum personal assistants"
5
- metadata:
6
- emoji: "\U0001F500"
7
- vellum:
8
- display-name: "Orchestration"
9
- activation-hints:
10
- - "Multiple independent work streams that benefit from parallel execution"
11
- avoid-when:
12
- - "Single-focus tasks -- work directly"
13
- ---
14
-
15
- Use `swarm_delegate` when facing complex multi-part tasks that benefit from parallel execution. The tool decomposes an objective into independent specialist subtasks, runs them concurrently, and synthesises the results.
16
-
17
- ## When to use
18
-
19
- - The request involves **multiple independent work streams** (e.g. research + coding + review).
20
- - Tasks can run in parallel without sequential dependencies.
21
- - The combined work would take significantly longer if done serially.
22
-
23
- ## When NOT to use
24
-
25
- - Simple single-step requests - just do them directly.
26
- - Tasks that are inherently sequential (each step depends on the previous result).
27
- - Requests where the user is asking for a quick answer, not a deep workflow.
28
-
29
- ## Tips
30
-
31
- - Provide a clear, specific `objective`. The planner uses it to decompose the work.
32
- - Pass relevant `context` about the codebase or project when available.
33
- - The `max_workers` parameter caps concurrency (1-6); the default comes from config.
@@ -1,35 +0,0 @@
1
- {
2
- "version": 1,
3
- "tools": [
4
- {
5
- "name": "swarm_delegate",
6
- "description": "Decompose a complex task into parallel specialist subtasks and execute them concurrently. Use this for multi-part tasks that benefit from parallel research, coding, and review.",
7
- "category": "orchestration",
8
- "risk": "medium",
9
- "input_schema": {
10
- "type": "object",
11
- "properties": {
12
- "objective": {
13
- "type": "string",
14
- "description": "The complex task to decompose and execute in parallel"
15
- },
16
- "context": {
17
- "type": "string",
18
- "description": "Optional additional context about the task or codebase"
19
- },
20
- "max_workers": {
21
- "type": "number",
22
- "description": "Maximum concurrent workers (1-6, default from config)"
23
- },
24
- "activity": {
25
- "type": "string",
26
- "description": "Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand."
27
- }
28
- },
29
- "required": ["objective"]
30
- },
31
- "executor": "tools/swarm-delegate.ts",
32
- "execution_target": "host"
33
- }
34
- ]
35
- }
@@ -1,12 +0,0 @@
1
- import { swarmDelegateTool } from "../../../../tools/swarm/delegate.js";
2
- import type {
3
- ToolContext,
4
- ToolExecutionResult,
5
- } from "../../../../tools/types.js";
6
-
7
- export async function run(
8
- input: Record<string, unknown>,
9
- context: ToolContext,
10
- ): Promise<ToolExecutionResult> {
11
- return swarmDelegateTool.execute(input, context);
12
- }
@@ -1,82 +0,0 @@
1
- import { z } from "zod";
2
-
3
- export const SwarmConfigSchema = z
4
- .object({
5
- enabled: z
6
- .boolean({ error: "swarm.enabled must be a boolean" })
7
- .default(true)
8
- .describe("Whether swarm (parallel multi-agent) execution is enabled"),
9
- maxWorkers: z
10
- .number({ error: "swarm.maxWorkers must be a number" })
11
- .int("swarm.maxWorkers must be an integer")
12
- .positive("swarm.maxWorkers must be a positive integer")
13
- .max(6, "swarm.maxWorkers must be at most 6")
14
- .default(3)
15
- .describe("Maximum number of concurrent swarm workers"),
16
- maxTasks: z
17
- .number({ error: "swarm.maxTasks must be a number" })
18
- .int("swarm.maxTasks must be an integer")
19
- .positive("swarm.maxTasks must be a positive integer")
20
- .max(20, "swarm.maxTasks must be at most 20")
21
- .default(8)
22
- .describe("Maximum number of tasks a single swarm can execute"),
23
- maxRetriesPerTask: z
24
- .number({ error: "swarm.maxRetriesPerTask must be a number" })
25
- .int("swarm.maxRetriesPerTask must be an integer")
26
- .nonnegative("swarm.maxRetriesPerTask must be a non-negative integer")
27
- .max(3, "swarm.maxRetriesPerTask must be at most 3")
28
- .default(1)
29
- .describe("Maximum number of retries for a failed swarm task"),
30
- workerTimeoutSec: z
31
- .number({ error: "swarm.workerTimeoutSec must be a number" })
32
- .int("swarm.workerTimeoutSec must be an integer")
33
- .positive("swarm.workerTimeoutSec must be a positive integer")
34
- .default(900)
35
- .describe("Timeout for a single swarm worker in seconds"),
36
- roleTimeoutsSec: z
37
- .object({
38
- router: z
39
- .number()
40
- .int()
41
- .positive()
42
- .optional()
43
- .describe("Timeout override for router workers (seconds)"),
44
- researcher: z
45
- .number()
46
- .int()
47
- .positive()
48
- .optional()
49
- .describe("Timeout override for researcher workers (seconds)"),
50
- coder: z
51
- .number()
52
- .int()
53
- .positive()
54
- .optional()
55
- .describe("Timeout override for coder workers (seconds)"),
56
- reviewer: z
57
- .number()
58
- .int()
59
- .positive()
60
- .optional()
61
- .describe("Timeout override for reviewer workers (seconds)"),
62
- })
63
- .default({})
64
- .describe("Per-role timeout overrides for swarm workers"),
65
- plannerModelIntent: z
66
- .enum(["latency-optimized", "quality-optimized", "vision-optimized"], {
67
- error: "swarm.plannerModelIntent must be a valid model intent",
68
- })
69
- .default("latency-optimized")
70
- .describe("Model selection strategy for the swarm planning phase"),
71
- synthesizerModelIntent: z
72
- .enum(["latency-optimized", "quality-optimized", "vision-optimized"], {
73
- error: "swarm.synthesizerModelIntent must be a valid model intent",
74
- })
75
- .default("quality-optimized")
76
- .describe(
77
- "Model selection strategy for the swarm synthesis (result-combining) phase",
78
- ),
79
- })
80
- .describe("Swarm configuration — parallel multi-agent task execution");
81
-
82
- export type SwarmConfig = z.infer<typeof SwarmConfigSchema>;
package/src/logfire.ts DELETED
@@ -1,135 +0,0 @@
1
- import { getLogfireToken } from "./config/env.js";
2
- import type {
3
- Message,
4
- Provider,
5
- ProviderResponse,
6
- SendMessageOptions,
7
- ToolDefinition,
8
- } from "./providers/types.js";
9
- import { getLogger } from "./util/logger.js";
10
- import { APP_VERSION } from "./version.js";
11
-
12
- const log = getLogger("logfire");
13
-
14
- type LogfireModule = typeof import("@pydantic/logfire-node");
15
-
16
- let logfireEnabled: boolean = !!getLogfireToken();
17
-
18
- let logfireInstance: LogfireModule | null = null;
19
-
20
- /**
21
- * Initialize Logfire for LLM observability.
22
- * Dynamically imports @pydantic/logfire-node only when enabled.
23
- * Non-fatal on failure (logs warning and continues).
24
- */
25
- export async function initLogfire(): Promise<void> {
26
- if (!logfireEnabled) return;
27
-
28
- try {
29
- const logfire = await import("@pydantic/logfire-node");
30
- logfire.configure({
31
- token: getLogfireToken(),
32
- serviceName: "vellum-assistant",
33
- serviceVersion: APP_VERSION,
34
- });
35
- logfireInstance = logfire;
36
- log.info("Logfire initialized");
37
- } catch (err) {
38
- log.warn(
39
- { err },
40
- "Failed to initialize Logfire — LLM observability disabled",
41
- );
42
- }
43
- }
44
-
45
- /**
46
- * Disable Logfire after early initialization. Called when the user has opted
47
- * out via the feature flag. Nulls out the instance so future wrapWithLogfire
48
- * calls become no-ops.
49
- */
50
- export function disableLogfire(): void {
51
- logfireEnabled = false;
52
- logfireInstance = null;
53
- log.info("Logfire disabled by feature flag");
54
- }
55
-
56
- /**
57
- * Wraps a provider with Logfire tracing spans.
58
- * When logfireEnabled is false, returns the provider as-is (no wrapper allocated).
59
- */
60
- export function wrapWithLogfire(provider: Provider): Provider {
61
- if (!logfireEnabled) return provider;
62
- return new LogfireProvider(provider);
63
- }
64
-
65
- /**
66
- * Wrapper provider that instruments each sendMessage call with a Logfire span.
67
- * When Logfire is not initialized, acts as a pure pass-through with zero overhead.
68
- */
69
- class LogfireProvider implements Provider {
70
- public readonly name: string;
71
-
72
- constructor(private readonly inner: Provider) {
73
- this.name = inner.name;
74
- }
75
-
76
- async sendMessage(
77
- messages: Message[],
78
- tools?: ToolDefinition[],
79
- systemPrompt?: string,
80
- options?: SendMessageOptions,
81
- ): Promise<ProviderResponse> {
82
- if (!logfireInstance) {
83
- return this.inner.sendMessage(messages, tools, systemPrompt, options);
84
- }
85
-
86
- const start = Date.now();
87
-
88
- return logfireInstance.span(
89
- `llm.${this.name}`,
90
- {
91
- "llm.provider": this.name,
92
- "llm.message_count": messages.length,
93
- "llm.tool_count": tools?.length ?? 0,
94
- },
95
- {},
96
- async (span) => {
97
- try {
98
- const response = await this.inner.sendMessage(
99
- messages,
100
- tools,
101
- systemPrompt,
102
- options,
103
- );
104
- const durationMs = Date.now() - start;
105
-
106
- span.setAttributes({
107
- "llm.model": response.model,
108
- "llm.stop_reason": response.stopReason,
109
- "llm.usage.input_tokens": response.usage.inputTokens,
110
- "llm.usage.output_tokens": response.usage.outputTokens,
111
- "llm.usage.cache_creation_input_tokens":
112
- response.usage.cacheCreationInputTokens ?? 0,
113
- "llm.usage.cache_read_input_tokens":
114
- response.usage.cacheReadInputTokens ?? 0,
115
- "llm.duration_ms": durationMs,
116
- "llm.success": true,
117
- });
118
-
119
- return response;
120
- } catch (error) {
121
- const durationMs = Date.now() - start;
122
- span.setAttributes({
123
- "llm.duration_ms": durationMs,
124
- "llm.success": false,
125
- "llm.error.type":
126
- error instanceof Error ? error.constructor.name : "Unknown",
127
- "llm.error.message":
128
- error instanceof Error ? error.message : String(error),
129
- });
130
- throw error;
131
- }
132
- },
133
- );
134
- }
135
- }