@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,225 +0,0 @@
1
- /**
2
- * Claude Code worker backend for swarm execution.
3
- *
4
- * Extracted from the swarm delegate tool so backend construction
5
- * is testable and swappable independently of the tool adapter.
6
- */
7
-
8
- import { resolveModelIntent } from "../providers/model-intents.js";
9
- import type { ModelIntent } from "../providers/types.js";
10
- import { getProviderKeyAsync } from "../security/secure-keys.js";
11
- import { getLogger } from "../util/logger.js";
12
- import type {
13
- SwarmWorkerBackend,
14
- SwarmWorkerBackendInput,
15
- } from "./worker-backend.js";
16
- import { getProfilePolicy } from "./worker-backend.js";
17
-
18
- const log = getLogger("swarm-backend-claude-code");
19
-
20
- const MAX_CLAUDE_CODE_DEPTH = 1;
21
- const DEPTH_ENV_VAR = "VELLUM_CLAUDE_CODE_DEPTH";
22
-
23
- /**
24
- * Create a Claude Code worker backend that enforces profile-based tool policies.
25
- * Uses the Claude Agent SDK to run autonomous worker tasks.
26
- */
27
- export function createClaudeCodeBackend(): SwarmWorkerBackend {
28
- return {
29
- name: "claude_code",
30
-
31
- async isAvailable(): Promise<boolean> {
32
- const apiKey = await getProviderKeyAsync("anthropic");
33
- return !!apiKey;
34
- },
35
-
36
- async runTask(input: SwarmWorkerBackendInput) {
37
- const start = Date.now();
38
- const stderrLines: string[] = [];
39
- try {
40
- const { query } = await import("@anthropic-ai/claude-agent-sdk");
41
- const apiKey = await getProviderKeyAsync("anthropic");
42
- if (!apiKey) {
43
- return {
44
- success: false,
45
- output: "No API key",
46
- failureReason: "backend_unavailable" as const,
47
- durationMs: 0,
48
- };
49
- }
50
-
51
- const profilePolicy = getProfilePolicy(input.profile);
52
-
53
- // Enforce profile restrictions — swarm workers run autonomously so
54
- // there is no user to prompt; denied tools are blocked, everything
55
- // else is allowed.
56
- const canUseTool: import("@anthropic-ai/claude-agent-sdk").CanUseTool =
57
- async (toolName) => {
58
- if (profilePolicy.deny.has(toolName)) {
59
- log.debug(
60
- { toolName, profile: input.profile },
61
- "Swarm worker tool denied by profile",
62
- );
63
- return {
64
- behavior: "deny" as const,
65
- message: `Tool "${toolName}" is denied by profile "${input.profile}"`,
66
- };
67
- }
68
- return { behavior: "allow" as const };
69
- };
70
-
71
- // Enforce nesting depth limit
72
- const currentDepth = parseInt(process.env[DEPTH_ENV_VAR] ?? "0", 10);
73
- if (currentDepth >= MAX_CLAUDE_CODE_DEPTH) {
74
- log.warn(
75
- { currentDepth, max: MAX_CLAUDE_CODE_DEPTH },
76
- "Swarm worker nesting depth exceeded",
77
- );
78
- return {
79
- success: false,
80
- output: `Nesting depth exceeded (depth ${currentDepth}, max ${MAX_CLAUDE_CODE_DEPTH})`,
81
- failureReason: "backend_unavailable" as const,
82
- durationMs: Date.now() - start,
83
- };
84
- }
85
-
86
- // Strip the SDK's nesting guard but set our own depth counter.
87
- const subprocessEnv: Record<string, string | undefined> = {
88
- ...process.env,
89
- ANTHROPIC_API_KEY: apiKey,
90
- [DEPTH_ENV_VAR]: String(currentDepth + 1),
91
- };
92
- delete subprocessEnv.CLAUDECODE;
93
- delete subprocessEnv.CLAUDE_CODE_ENTRYPOINT;
94
-
95
- const conversation = query({
96
- prompt: input.prompt,
97
- options: {
98
- cwd: input.workingDir,
99
- model: input.modelIntent
100
- ? resolveModelIntent(
101
- "anthropic",
102
- input.modelIntent as ModelIntent,
103
- )
104
- : "claude-sonnet-4-6",
105
- canUseTool,
106
- permissionMode: "default",
107
- maxTurns: 30,
108
- env: subprocessEnv,
109
- stderr: (data: string) => {
110
- const trimmed = data.trimEnd();
111
- if (trimmed) {
112
- stderrLines.push(trimmed);
113
- log.debug(
114
- { stderr: trimmed },
115
- "Swarm worker subprocess stderr",
116
- );
117
- }
118
- },
119
- },
120
- });
121
-
122
- let resultText = "";
123
- let hasError = false;
124
- for await (const message of conversation) {
125
- if (input.signal?.aborted) break;
126
- if (message.type === "assistant") {
127
- if (message.error) {
128
- log.error(
129
- { error: message.error, conversationId: message.session_id },
130
- "Swarm worker assistant message error",
131
- );
132
- hasError = true;
133
- resultText += `\n[Claude Code error: ${message.error}]`;
134
- }
135
- if (message.message?.content) {
136
- for (const block of message.message.content) {
137
- if (block.type === "text") resultText += block.text;
138
- }
139
- }
140
- } else if (message.type === "result") {
141
- if (message.subtype === "success") {
142
- log.info(
143
- {
144
- numTurns: message.num_turns,
145
- durationMs: message.duration_ms,
146
- costUsd: message.total_cost_usd,
147
- },
148
- "Swarm worker completed",
149
- );
150
- if (message.result && !resultText) {
151
- resultText = message.result;
152
- }
153
- } else {
154
- hasError = true;
155
- const errors = message.errors ?? [];
156
- const denials = message.permission_denials ?? [];
157
- log.error(
158
- {
159
- subtype: message.subtype,
160
- errors,
161
- permissionDenials: denials.length,
162
- numTurns: message.num_turns,
163
- durationMs: message.duration_ms,
164
- },
165
- "Swarm worker session failed",
166
- );
167
-
168
- const parts: string[] = [
169
- `[${message.subtype}] (${message.num_turns} turns, ${(
170
- message.duration_ms / 1000
171
- ).toFixed(1)}s)`,
172
- ];
173
- if (errors.length > 0) parts.push(`Errors: ${errors.join("; ")}`);
174
- if (denials.length > 0)
175
- parts.push(
176
- `Permission denied: ${denials
177
- .map((d: { tool_name: string }) => d.tool_name)
178
- .join(", ")}`,
179
- );
180
- resultText += `\n${parts.join("\n")}`;
181
- }
182
- }
183
- }
184
-
185
- // Treat abort as non-retryable cancellation, not a retryable timeout
186
- if (input.signal?.aborted) {
187
- return {
188
- success: false,
189
- output: "Cancelled (aborted)",
190
- failureReason: "cancelled" as const,
191
- durationMs: Date.now() - start,
192
- };
193
- }
194
-
195
- return {
196
- success: !hasError,
197
- output: resultText || "Completed",
198
- durationMs: Date.now() - start,
199
- };
200
- } catch (err) {
201
- const errMessage = err instanceof Error ? err.message : String(err);
202
- const recentStderr = stderrLines.slice(-20);
203
- log.error(
204
- { err, stderrTail: recentStderr },
205
- "Swarm worker execution failed",
206
- );
207
-
208
- const parts = [errMessage];
209
- if (recentStderr.length > 0) {
210
- parts.push(
211
- `\nSubprocess stderr (last ${
212
- recentStderr.length
213
- } lines):\n${recentStderr.join("\n")}`,
214
- );
215
- }
216
- return {
217
- success: false,
218
- output: parts.join(""),
219
- failureReason: "backend_unavailable" as const,
220
- durationMs: Date.now() - start,
221
- };
222
- }
223
- },
224
- };
225
- }
@@ -1,137 +0,0 @@
1
- import {
2
- existsSync,
3
- mkdirSync,
4
- readFileSync,
5
- renameSync,
6
- unlinkSync,
7
- writeFileSync,
8
- } from "node:fs";
9
- import { dirname, join } from "node:path";
10
-
11
- import { getLogger } from "../util/logger.js";
12
- import { getRootDir } from "../util/platform.js";
13
- import type { SwarmPlan, SwarmTaskResult } from "./types.js";
14
-
15
- const log = getLogger("swarm-checkpoint");
16
-
17
- /** Only allow safe token characters in runId (alphanumeric, hyphens, underscores, dots). */
18
- const SAFE_RUN_ID = /^[a-zA-Z0-9._-]+$/;
19
-
20
- function assertSafeRunId(runId: string): void {
21
- if (!SAFE_RUN_ID.test(runId)) {
22
- throw new Error(
23
- `Invalid runId: must match ${SAFE_RUN_ID} (got "${runId}")`,
24
- );
25
- }
26
- }
27
-
28
- export interface SwarmCheckpoint {
29
- runId: string;
30
- objective: string;
31
- /** Serialized plan for integrity verification on resume. */
32
- planTaskIds: string[];
33
- /** Stringified task dependency map for structural integrity on resume. */
34
- planHash: string;
35
- results: SwarmTaskResult[];
36
- /** Set of task IDs whose dependents were blocked due to failure. */
37
- blockedTaskIds: string[];
38
- updatedAt: string;
39
- }
40
-
41
- function getCheckpointDir(): string {
42
- return join(getRootDir(), "swarm-checkpoints");
43
- }
44
-
45
- function getCheckpointPath(runId: string): string {
46
- assertSafeRunId(runId);
47
- return join(getCheckpointDir(), `${runId}.json`);
48
- }
49
-
50
- /**
51
- * Deterministic fingerprint of a plan's structure: objective, task IDs,
52
- * roles, and dependency edges. Two plans with the same hash are structurally
53
- * identical and safe to resume from.
54
- */
55
- function computePlanHash(plan: SwarmPlan): string {
56
- const parts = plan.tasks.map(
57
- (t) => `${t.id}:${t.role}:${[...t.dependencies].sort().join(",")}`,
58
- );
59
- return `${plan.objective}|${parts.sort().join("|")}`;
60
- }
61
-
62
- /** Persist the current swarm progress to disk. */
63
- export function writeCheckpoint(
64
- runId: string,
65
- plan: SwarmPlan,
66
- results: Map<string, SwarmTaskResult>,
67
- blockedTaskIds: Set<string>,
68
- ): void {
69
- try {
70
- const path = getCheckpointPath(runId);
71
- const checkpoint: SwarmCheckpoint = {
72
- runId,
73
- objective: plan.objective,
74
- planTaskIds: plan.tasks.map((t) => t.id),
75
- planHash: computePlanHash(plan),
76
- results: Array.from(results.values()),
77
- blockedTaskIds: Array.from(blockedTaskIds),
78
- updatedAt: new Date().toISOString(),
79
- };
80
-
81
- mkdirSync(dirname(path), { recursive: true });
82
- // Atomic-ish write: write to temp then rename to avoid partial reads
83
- const tmpPath = path + ".tmp";
84
- writeFileSync(tmpPath, JSON.stringify(checkpoint, null, 2) + "\n");
85
- renameSync(tmpPath, path);
86
- } catch (err) {
87
- // Checkpoint failures should not crash the orchestrator
88
- log.warn(
89
- { runId, error: (err as Error).message },
90
- "Failed to write checkpoint",
91
- );
92
- }
93
- }
94
-
95
- /** Load a checkpoint from disk, or null if none exists. */
96
- export function loadCheckpoint(runId: string): SwarmCheckpoint | null {
97
- const path = getCheckpointPath(runId);
98
- if (!existsSync(path)) return null;
99
-
100
- try {
101
- const data = readFileSync(path, "utf-8");
102
- return JSON.parse(data) as SwarmCheckpoint;
103
- } catch (err) {
104
- log.warn(
105
- { runId, error: (err as Error).message },
106
- "Failed to read checkpoint, starting fresh",
107
- );
108
- return null;
109
- }
110
- }
111
-
112
- /** Remove a checkpoint file after successful completion. */
113
- export function removeCheckpoint(runId: string): void {
114
- const path = getCheckpointPath(runId);
115
- try {
116
- if (existsSync(path)) unlinkSync(path);
117
- } catch {
118
- // Best-effort cleanup
119
- }
120
- }
121
-
122
- /**
123
- * Validate that a checkpoint matches the current plan.
124
- * Compares objective, task IDs, roles, and dependency structure via planHash.
125
- * Falls back to subset check for checkpoints written before planHash existed.
126
- */
127
- export function isCheckpointCompatible(
128
- checkpoint: SwarmCheckpoint,
129
- plan: SwarmPlan,
130
- ): boolean {
131
- if (checkpoint.planHash) {
132
- return checkpoint.planHash === computePlanHash(plan);
133
- }
134
- // Legacy checkpoint without planHash — fall back to subset check
135
- const planTaskIds = new Set(plan.tasks.map((t) => t.id));
136
- return checkpoint.planTaskIds.every((id) => planTaskIds.has(id));
137
- }
@@ -1,53 +0,0 @@
1
- /**
2
- * Shared graph utilities for swarm DAG operations.
3
- */
4
-
5
- export interface GraphNode {
6
- id: string;
7
- dependencies: string[];
8
- }
9
-
10
- /**
11
- * Detect cycles in a directed graph using Kahn's algorithm.
12
- * Returns the IDs of nodes involved in cycles, or null if the graph is acyclic.
13
- */
14
- export function detectCycles(nodes: GraphNode[]): string[] | null {
15
- const inDegree = new Map<string, number>();
16
- const adj = new Map<string, string[]>();
17
-
18
- for (const node of nodes) {
19
- inDegree.set(node.id, 0);
20
- adj.set(node.id, []);
21
- }
22
-
23
- for (const node of nodes) {
24
- for (const dep of node.dependencies) {
25
- if (adj.has(dep)) {
26
- adj.get(dep)!.push(node.id);
27
- inDegree.set(node.id, (inDegree.get(node.id) ?? 0) + 1);
28
- }
29
- }
30
- }
31
-
32
- const queue: string[] = [];
33
- for (const [id, deg] of inDegree) {
34
- if (deg === 0) queue.push(id);
35
- }
36
-
37
- let processed = 0;
38
- while (queue.length > 0) {
39
- const current = queue.shift()!;
40
- processed++;
41
- for (const neighbor of adj.get(current)!) {
42
- const newDeg = (inDegree.get(neighbor) ?? 0) - 1;
43
- inDegree.set(neighbor, newDeg);
44
- if (newDeg === 0) queue.push(neighbor);
45
- }
46
- }
47
-
48
- if (processed < nodes.length) {
49
- return nodes.filter((n) => (inDegree.get(n.id) ?? 0) > 0).map((n) => n.id);
50
- }
51
-
52
- return null;
53
- }
@@ -1,55 +0,0 @@
1
- export type { SwarmCheckpoint } from "./checkpoint.js";
2
- export {
3
- isCheckpointCompatible,
4
- loadCheckpoint,
5
- removeCheckpoint,
6
- writeCheckpoint,
7
- } from "./checkpoint.js";
8
- export type { SwarmLimits } from "./limits.js";
9
- export {
10
- getTimeoutForRole,
11
- resolveSwarmLimits,
12
- SWARM_HARD_LIMITS,
13
- } from "./limits.js";
14
- export type {
15
- ExecuteSwarmOptions,
16
- OrchestratorEvent,
17
- OrchestratorEventKind,
18
- OrchestratorStatusCallback,
19
- } from "./orchestrator.js";
20
- export { executeSwarm } from "./orchestrator.js";
21
- export {
22
- SwarmPlanValidationError,
23
- validateAndNormalizePlan,
24
- } from "./plan-validator.js";
25
- export {
26
- generatePlan,
27
- makeFallbackPlan,
28
- parsePlanJSON,
29
- } from "./router-planner.js";
30
- export { synthesizeResults } from "./synthesizer.js";
31
- export type {
32
- SwarmExecutionSummary,
33
- SwarmPlan,
34
- SwarmRole,
35
- SwarmTaskNode,
36
- SwarmTaskResult,
37
- SwarmTaskStatus,
38
- } from "./types.js";
39
- export { VALID_SWARM_ROLES } from "./types.js";
40
- export type {
41
- ProfilePolicy,
42
- SwarmWorkerBackend,
43
- SwarmWorkerBackendInput,
44
- SwarmWorkerBackendResult,
45
- WorkerFailureReason,
46
- WorkerProfile,
47
- } from "./worker-backend.js";
48
- export { getProfilePolicy, roleToProfile } from "./worker-backend.js";
49
- export { buildWorkerPrompt, parseWorkerOutput } from "./worker-prompts.js";
50
- export type {
51
- RunWorkerTaskOptions,
52
- WorkerStatusCallback,
53
- WorkerStatusKind,
54
- } from "./worker-runner.js";
55
- export { runWorkerTask } from "./worker-runner.js";
@@ -1,66 +0,0 @@
1
- /**
2
- * Runtime limits for swarm execution, resolved from config.
3
- */
4
-
5
- import type { SwarmRole } from "./types.js";
6
-
7
- export interface SwarmLimits {
8
- maxWorkers: number;
9
- maxTasks: number;
10
- maxRetriesPerTask: number;
11
- workerTimeoutSec: number;
12
- /** Per-role timeout overrides. When set, takes precedence over workerTimeoutSec for that role. */
13
- roleTimeoutsSec: Partial<Record<SwarmRole, number>>;
14
- }
15
-
16
- /** Hard ceilings that config values are clamped to. */
17
- export const SWARM_HARD_LIMITS = {
18
- maxWorkers: 6,
19
- maxTasks: 20,
20
- maxRetriesPerTask: 3,
21
- } as const;
22
-
23
- /**
24
- * Resolve effective limits from config, clamping to hard ceilings.
25
- */
26
- export function resolveSwarmLimits(config: {
27
- maxWorkers: number;
28
- maxTasks: number;
29
- maxRetriesPerTask: number;
30
- workerTimeoutSec: number;
31
- roleTimeoutsSec?: Partial<Record<SwarmRole, number>>;
32
- }): SwarmLimits {
33
- const resolvedRoleTimeouts: Partial<Record<SwarmRole, number>> = {};
34
- if (config.roleTimeoutsSec) {
35
- for (const [role, timeout] of Object.entries(config.roleTimeoutsSec)) {
36
- if (timeout != null) {
37
- resolvedRoleTimeouts[role as SwarmRole] = Math.max(1, timeout);
38
- }
39
- }
40
- }
41
-
42
- return {
43
- maxWorkers: Math.min(
44
- Math.max(1, config.maxWorkers),
45
- SWARM_HARD_LIMITS.maxWorkers,
46
- ),
47
- maxTasks: Math.min(
48
- Math.max(1, config.maxTasks),
49
- SWARM_HARD_LIMITS.maxTasks,
50
- ),
51
- maxRetriesPerTask: Math.min(
52
- Math.max(0, config.maxRetriesPerTask),
53
- SWARM_HARD_LIMITS.maxRetriesPerTask,
54
- ),
55
- workerTimeoutSec: Math.max(1, config.workerTimeoutSec),
56
- roleTimeoutsSec: resolvedRoleTimeouts,
57
- };
58
- }
59
-
60
- /** Get the effective timeout for a given role, falling back to the global workerTimeoutSec. */
61
- export function getTimeoutForRole(
62
- limits: SwarmLimits,
63
- role: SwarmRole,
64
- ): number {
65
- return limits.roleTimeoutsSec[role] ?? limits.workerTimeoutSec;
66
- }