@vellumai/assistant 0.5.5 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/.env.example +16 -2
  2. package/ARCHITECTURE.md +6 -75
  3. package/Dockerfile +4 -5
  4. package/README.md +0 -2
  5. package/bun.lock +0 -414
  6. package/docs/architecture/keychain-broker.md +45 -240
  7. package/docs/architecture/security.md +0 -17
  8. package/docs/credential-execution-service.md +2 -2
  9. package/node_modules/@vellumai/ces-contracts/package.json +1 -0
  10. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +119 -0
  11. package/node_modules/@vellumai/credential-storage/package.json +1 -0
  12. package/node_modules/@vellumai/egress-proxy/package.json +1 -0
  13. package/package.json +2 -3
  14. package/src/__tests__/actor-token-service.test.ts +1 -2
  15. package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
  16. package/src/__tests__/browser-skill-endstate.test.ts +6 -5
  17. package/src/__tests__/btw-routes.test.ts +0 -39
  18. package/src/__tests__/call-domain.test.ts +0 -128
  19. package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
  20. package/src/__tests__/channel-approval-routes.test.ts +0 -5
  21. package/src/__tests__/channel-readiness-service.test.ts +1 -60
  22. package/src/__tests__/checker.test.ts +4 -2
  23. package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
  24. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  25. package/src/__tests__/config-schema.test.ts +3 -3
  26. package/src/__tests__/context-window-manager.test.ts +78 -0
  27. package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
  28. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  29. package/src/__tests__/conversation-skill-tools.test.ts +0 -54
  30. package/src/__tests__/conversation-title-service.test.ts +117 -1
  31. package/src/__tests__/credential-execution-feature-gates.test.ts +28 -14
  32. package/src/__tests__/credential-execution-managed-contract.test.ts +33 -18
  33. package/src/__tests__/credential-security-e2e.test.ts +0 -66
  34. package/src/__tests__/credential-security-invariants.test.ts +4 -45
  35. package/src/__tests__/credentials-cli.test.ts +78 -0
  36. package/src/__tests__/db-migration-rollback.test.ts +2015 -1
  37. package/src/__tests__/docker-signing-key-bootstrap.test.ts +98 -0
  38. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
  39. package/src/__tests__/guardian-routing-state.test.ts +0 -5
  40. package/src/__tests__/host-shell-tool.test.ts +6 -7
  41. package/src/__tests__/http-user-message-parity.test.ts +3 -103
  42. package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
  43. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
  44. package/src/__tests__/intent-routing.test.ts +0 -13
  45. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
  46. package/src/__tests__/keychain-broker-client.test.ts +161 -22
  47. package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
  48. package/src/__tests__/memory-regressions.test.ts +8 -30
  49. package/src/__tests__/migration-export-http.test.ts +2 -2
  50. package/src/__tests__/migration-import-commit-http.test.ts +2 -2
  51. package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
  52. package/src/__tests__/migration-validate-http.test.ts +2 -2
  53. package/src/__tests__/non-member-access-request.test.ts +0 -5
  54. package/src/__tests__/notification-decision-fallback.test.ts +4 -0
  55. package/src/__tests__/notification-decision-identity.test.ts +4 -0
  56. package/src/__tests__/permission-types.test.ts +1 -0
  57. package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
  58. package/src/__tests__/qdrant-manager.test.ts +28 -2
  59. package/src/__tests__/registry.test.ts +0 -6
  60. package/src/__tests__/require-fresh-approval.test.ts +4 -0
  61. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
  62. package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
  63. package/src/__tests__/secure-keys.test.ts +83 -263
  64. package/src/__tests__/shell-identity.test.ts +96 -6
  65. package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
  66. package/src/__tests__/skill-feature-flags.test.ts +46 -45
  67. package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
  68. package/src/__tests__/skill-load-inline-command.test.ts +8 -12
  69. package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
  70. package/src/__tests__/skill-load-tool.test.ts +0 -2
  71. package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
  72. package/src/__tests__/skills.test.ts +0 -2
  73. package/src/__tests__/slack-inbound-verification.test.ts +0 -4
  74. package/src/__tests__/suggestion-routes.test.ts +1 -32
  75. package/src/__tests__/system-prompt.test.ts +0 -1
  76. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -0
  77. package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
  78. package/src/__tests__/tool-executor.test.ts +4 -0
  79. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
  80. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
  81. package/src/__tests__/update-bulletin.test.ts +0 -2
  82. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
  83. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -6
  84. package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
  85. package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +218 -0
  86. package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
  87. package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
  88. package/src/calls/audio-store.test.ts +97 -0
  89. package/src/calls/audio-store.ts +205 -0
  90. package/src/calls/call-controller.ts +85 -7
  91. package/src/calls/call-domain.ts +3 -0
  92. package/src/calls/call-store.ts +10 -3
  93. package/src/calls/fish-audio-client.ts +117 -0
  94. package/src/calls/relay-server.ts +27 -0
  95. package/src/calls/twilio-routes.ts +2 -1
  96. package/src/calls/types.ts +1 -0
  97. package/src/calls/voice-ingress-preflight.ts +0 -42
  98. package/src/calls/voice-quality.ts +26 -5
  99. package/src/calls/voice-session-bridge.ts +6 -12
  100. package/src/cli/commands/config.ts +1 -4
  101. package/src/cli/commands/conversations.ts +0 -18
  102. package/src/cli/commands/credentials.ts +34 -4
  103. package/src/cli/commands/oauth/index.ts +7 -0
  104. package/src/cli/commands/oauth/platform.ts +179 -0
  105. package/src/cli/commands/platform.ts +3 -3
  106. package/src/config/assistant-feature-flags.ts +186 -5
  107. package/src/config/bundled-skills/messaging/SKILL.md +5 -5
  108. package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
  109. package/src/config/bundled-skills/settings/TOOLS.json +2 -2
  110. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
  111. package/src/config/bundled-tool-registry.ts +1 -11
  112. package/src/config/env-registry.ts +1 -1
  113. package/src/config/env.ts +16 -16
  114. package/src/config/feature-flag-registry.json +48 -16
  115. package/src/config/loader.ts +98 -31
  116. package/src/config/schema.ts +4 -25
  117. package/src/config/schemas/calls.ts +13 -0
  118. package/src/config/schemas/fish-audio.ts +39 -0
  119. package/src/config/schemas/memory.ts +0 -4
  120. package/src/config/schemas/platform.ts +1 -1
  121. package/src/config/schemas/security.ts +4 -4
  122. package/src/config/types.ts +0 -1
  123. package/src/contacts/contact-store.ts +39 -0
  124. package/src/contacts/types.ts +2 -0
  125. package/src/context/window-manager.ts +53 -2
  126. package/src/credential-execution/approval-bridge.ts +1 -0
  127. package/src/credential-execution/executable-discovery.ts +28 -4
  128. package/src/credential-execution/feature-gates.ts +16 -0
  129. package/src/credential-execution/process-manager.ts +38 -0
  130. package/src/daemon/assistant-attachments.ts +9 -0
  131. package/src/daemon/config-watcher.ts +6 -4
  132. package/src/daemon/conversation-agent-loop.ts +0 -60
  133. package/src/daemon/conversation-memory.ts +0 -117
  134. package/src/daemon/conversation-runtime-assembly.ts +0 -2
  135. package/src/daemon/conversation-tool-setup.ts +0 -105
  136. package/src/daemon/conversation.ts +10 -1
  137. package/src/daemon/handlers/config-vercel.ts +92 -0
  138. package/src/daemon/handlers/conversations.ts +0 -11
  139. package/src/daemon/handlers/skills.ts +2 -15
  140. package/src/daemon/install-symlink.ts +195 -0
  141. package/src/daemon/lifecycle.ts +229 -96
  142. package/src/daemon/message-types/conversations.ts +3 -4
  143. package/src/daemon/message-types/diagnostics.ts +3 -22
  144. package/src/daemon/message-types/messages.ts +0 -2
  145. package/src/daemon/message-types/upgrades.ts +8 -0
  146. package/src/daemon/server.ts +30 -92
  147. package/src/events/domain-events.ts +2 -1
  148. package/src/followups/followup-store.ts +5 -2
  149. package/src/inbound/platform-callback-registration.ts +3 -3
  150. package/src/instrument.ts +8 -5
  151. package/src/memory/conversation-crud.ts +0 -236
  152. package/src/memory/conversation-title-service.ts +76 -11
  153. package/src/memory/db-init.ts +15 -11
  154. package/src/memory/indexer.ts +15 -106
  155. package/src/memory/items-extractor.ts +15 -1
  156. package/src/memory/job-handlers/conversation-starters.ts +4 -1
  157. package/src/memory/job-handlers/embedding.ts +0 -79
  158. package/src/memory/job-utils.ts +1 -1
  159. package/src/memory/jobs-store.ts +30 -13
  160. package/src/memory/jobs-worker.ts +31 -27
  161. package/src/memory/migrations/001-job-deferrals.ts +19 -0
  162. package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
  163. package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
  164. package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
  165. package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
  166. package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
  167. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
  168. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
  169. package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
  170. package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
  171. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
  172. package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
  173. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
  174. package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
  175. package/src/memory/migrations/116-messages-fts.ts +106 -1
  176. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
  177. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
  178. package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
  179. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
  180. package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
  181. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
  182. package/src/memory/migrations/141-rename-verification-table.ts +54 -0
  183. package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
  184. package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
  185. package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
  186. package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
  187. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
  188. package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
  189. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
  190. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
  191. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
  192. package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
  193. package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
  194. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
  195. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
  196. package/src/memory/migrations/189-drop-simplified-memory.ts +42 -0
  197. package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
  198. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
  199. package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
  200. package/src/memory/migrations/index.ts +5 -3
  201. package/src/memory/migrations/registry.ts +90 -0
  202. package/src/memory/migrations/validate-migration-state.ts +137 -11
  203. package/src/memory/qdrant-circuit-breaker.ts +9 -0
  204. package/src/memory/qdrant-client.ts +4 -6
  205. package/src/memory/qdrant-manager.ts +64 -7
  206. package/src/memory/schema/calls.ts +1 -0
  207. package/src/memory/schema/contacts.ts +1 -0
  208. package/src/memory/schema/conversations.ts +0 -3
  209. package/src/memory/schema/index.ts +0 -2
  210. package/src/messaging/draft-store.ts +2 -2
  211. package/src/notifications/decision-engine.ts +4 -1
  212. package/src/oauth/connection-resolver.ts +6 -4
  213. package/src/permissions/checker.ts +0 -38
  214. package/src/permissions/defaults.ts +3 -3
  215. package/src/permissions/shell-identity.ts +76 -22
  216. package/src/permissions/trust-client.ts +2 -13
  217. package/src/permissions/trust-store.ts +8 -3
  218. package/src/permissions/types.ts +4 -2
  219. package/src/platform/client.ts +35 -7
  220. package/src/prompts/persona-resolver.ts +138 -0
  221. package/src/prompts/system-prompt.ts +36 -4
  222. package/src/prompts/templates/users/default.md +1 -0
  223. package/src/providers/registry.ts +27 -40
  224. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  225. package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
  226. package/src/runtime/auth/external-assistant-id.ts +13 -59
  227. package/src/runtime/auth/route-policy.ts +29 -1
  228. package/src/runtime/auth/token-service.ts +53 -15
  229. package/src/runtime/channel-readiness-service.ts +1 -16
  230. package/src/runtime/http-server.ts +29 -2
  231. package/src/runtime/middleware/error-handler.ts +1 -9
  232. package/src/runtime/routes/audio-routes.ts +40 -0
  233. package/src/runtime/routes/btw-routes.ts +0 -17
  234. package/src/runtime/routes/conversation-management-routes.ts +0 -36
  235. package/src/runtime/routes/conversation-query-routes.ts +106 -2
  236. package/src/runtime/routes/conversation-routes.ts +4 -43
  237. package/src/runtime/routes/diagnostics-routes.ts +1 -477
  238. package/src/runtime/routes/identity-routes.ts +18 -29
  239. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
  240. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  241. package/src/runtime/routes/integrations/vercel.ts +89 -0
  242. package/src/runtime/routes/log-export-routes.ts +5 -0
  243. package/src/runtime/routes/memory-item-routes.test.ts +221 -3
  244. package/src/runtime/routes/memory-item-routes.ts +144 -4
  245. package/src/runtime/routes/migration-rollback-routes.ts +209 -0
  246. package/src/runtime/routes/migration-routes.ts +17 -1
  247. package/src/runtime/routes/notification-routes.ts +58 -0
  248. package/src/runtime/routes/schedule-routes.ts +65 -0
  249. package/src/runtime/routes/settings-routes.ts +41 -1
  250. package/src/runtime/routes/tts-routes.ts +86 -0
  251. package/src/runtime/routes/upgrade-broadcast-routes.ts +175 -0
  252. package/src/runtime/routes/workspace-commit-routes.ts +62 -0
  253. package/src/runtime/routes/workspace-routes.test.ts +22 -1
  254. package/src/runtime/routes/workspace-routes.ts +1 -1
  255. package/src/runtime/routes/workspace-utils.ts +86 -2
  256. package/src/schedule/schedule-store.ts +0 -21
  257. package/src/security/ces-credential-client.ts +59 -22
  258. package/src/security/ces-rpc-credential-backend.ts +85 -0
  259. package/src/security/credential-backend.ts +12 -88
  260. package/src/security/keychain-broker-client.ts +10 -2
  261. package/src/security/secure-keys.ts +94 -113
  262. package/src/skills/catalog-install.ts +13 -7
  263. package/src/skills/inline-command-render.ts +5 -1
  264. package/src/skills/inline-command-runner.ts +30 -2
  265. package/src/telemetry/usage-telemetry-reporter.ts +4 -2
  266. package/src/tools/calls/call-start.ts +1 -0
  267. package/src/tools/executor.ts +0 -4
  268. package/src/tools/memory/handlers.ts +1 -129
  269. package/src/tools/network/script-proxy/session-manager.ts +19 -4
  270. package/src/tools/network/web-fetch.ts +3 -1
  271. package/src/tools/permission-checker.ts +18 -0
  272. package/src/tools/skills/execute.ts +1 -1
  273. package/src/tools/skills/load.ts +9 -2
  274. package/src/tools/types.ts +0 -8
  275. package/src/util/errors.ts +0 -12
  276. package/src/util/platform.ts +8 -55
  277. package/src/util/xml.ts +8 -0
  278. package/src/workspace/git-service.ts +5 -2
  279. package/src/workspace/heartbeat-service.ts +5 -24
  280. package/src/workspace/migrations/001-avatar-rename.ts +15 -0
  281. package/src/workspace/migrations/003-seed-device-id.ts +17 -1
  282. package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
  283. package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
  284. package/src/workspace/migrations/006-services-config.ts +49 -0
  285. package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
  286. package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
  287. package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
  288. package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
  289. package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
  290. package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
  291. package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
  292. package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
  293. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
  294. package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
  295. package/src/workspace/migrations/017-seed-persona-dirs.ts +95 -0
  296. package/src/workspace/migrations/migrate-to-workspace-volume.ts +23 -1
  297. package/src/workspace/migrations/registry.ts +8 -0
  298. package/src/workspace/migrations/runner.ts +106 -2
  299. package/src/workspace/migrations/types.ts +4 -0
  300. package/src/__tests__/archive-recall.test.ts +0 -560
  301. package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
  302. package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
  303. package/src/__tests__/conversation-memory-dirty-tail.test.ts +0 -150
  304. package/src/__tests__/conversation-switch-memory-reduction.test.ts +0 -474
  305. package/src/__tests__/db-memory-archive-migration.test.ts +0 -372
  306. package/src/__tests__/db-memory-brief-state-migration.test.ts +0 -213
  307. package/src/__tests__/db-memory-reducer-checkpoints.test.ts +0 -273
  308. package/src/__tests__/diagnostics-export.test.ts +0 -288
  309. package/src/__tests__/local-gateway-health.test.ts +0 -209
  310. package/src/__tests__/memory-brief-open-loops.test.ts +0 -530
  311. package/src/__tests__/memory-brief-time.test.ts +0 -285
  312. package/src/__tests__/memory-brief-wrapper.test.ts +0 -311
  313. package/src/__tests__/memory-chunk-archive.test.ts +0 -400
  314. package/src/__tests__/memory-chunk-dual-write.test.ts +0 -453
  315. package/src/__tests__/memory-episode-archive.test.ts +0 -370
  316. package/src/__tests__/memory-episode-dual-write.test.ts +0 -626
  317. package/src/__tests__/memory-observation-archive.test.ts +0 -375
  318. package/src/__tests__/memory-observation-dual-write.test.ts +0 -318
  319. package/src/__tests__/memory-reducer-job.test.ts +0 -538
  320. package/src/__tests__/memory-reducer-scheduling.test.ts +0 -473
  321. package/src/__tests__/memory-reducer-store.test.ts +0 -728
  322. package/src/__tests__/memory-reducer-types.test.ts +0 -707
  323. package/src/__tests__/memory-reducer.test.ts +0 -704
  324. package/src/__tests__/memory-simplified-config.test.ts +0 -281
  325. package/src/__tests__/secret-ingress-handler.test.ts +0 -120
  326. package/src/__tests__/simplified-memory-e2e.test.ts +0 -666
  327. package/src/__tests__/simplified-memory-runtime.test.ts +0 -616
  328. package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
  329. package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
  330. package/src/__tests__/swarm-orchestrator.test.ts +0 -463
  331. package/src/__tests__/swarm-plan-validator.test.ts +0 -384
  332. package/src/__tests__/swarm-recursion.test.ts +0 -197
  333. package/src/__tests__/swarm-router-planner.test.ts +0 -234
  334. package/src/__tests__/swarm-tool.test.ts +0 -185
  335. package/src/__tests__/swarm-worker-backend.test.ts +0 -144
  336. package/src/__tests__/swarm-worker-runner.test.ts +0 -288
  337. package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
  338. package/src/commands/cc-command-registry.ts +0 -248
  339. package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
  340. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
  341. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
  342. package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
  343. package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
  344. package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
  345. package/src/config/schemas/memory-simplified.ts +0 -101
  346. package/src/config/schemas/swarm.ts +0 -82
  347. package/src/logfire.ts +0 -135
  348. package/src/memory/archive-recall.ts +0 -516
  349. package/src/memory/archive-store.ts +0 -400
  350. package/src/memory/brief-formatting.ts +0 -33
  351. package/src/memory/brief-open-loops.ts +0 -266
  352. package/src/memory/brief-time.ts +0 -162
  353. package/src/memory/brief.ts +0 -75
  354. package/src/memory/job-handlers/backfill-simplified-memory.ts +0 -462
  355. package/src/memory/job-handlers/reduce-conversation-memory.ts +0 -229
  356. package/src/memory/migrations/185-memory-brief-state.ts +0 -52
  357. package/src/memory/migrations/186-memory-archive.ts +0 -109
  358. package/src/memory/migrations/187-memory-reducer-checkpoints.ts +0 -19
  359. package/src/memory/reducer-scheduler.ts +0 -242
  360. package/src/memory/reducer-store.ts +0 -271
  361. package/src/memory/reducer-types.ts +0 -106
  362. package/src/memory/reducer.ts +0 -467
  363. package/src/memory/schema/memory-archive.ts +0 -121
  364. package/src/memory/schema/memory-brief.ts +0 -55
  365. package/src/runtime/local-gateway-health.ts +0 -275
  366. package/src/security/secret-ingress.ts +0 -68
  367. package/src/swarm/backend-claude-code.ts +0 -225
  368. package/src/swarm/checkpoint.ts +0 -137
  369. package/src/swarm/graph-utils.ts +0 -53
  370. package/src/swarm/index.ts +0 -55
  371. package/src/swarm/limits.ts +0 -66
  372. package/src/swarm/orchestrator.ts +0 -424
  373. package/src/swarm/plan-validator.ts +0 -117
  374. package/src/swarm/router-planner.ts +0 -162
  375. package/src/swarm/router-prompts.ts +0 -39
  376. package/src/swarm/synthesizer.ts +0 -81
  377. package/src/swarm/types.ts +0 -72
  378. package/src/swarm/worker-backend.ts +0 -131
  379. package/src/swarm/worker-prompts.ts +0 -80
  380. package/src/swarm/worker-runner.ts +0 -170
  381. package/src/tools/claude-code/claude-code.ts +0 -610
  382. package/src/tools/swarm/delegate.ts +0 -205
@@ -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
- }
@@ -1,424 +0,0 @@
1
- import type { ModelIntent, Provider } from "../providers/types.js";
2
- import { getLogger } from "../util/logger.js";
3
- import {
4
- isCheckpointCompatible,
5
- loadCheckpoint,
6
- removeCheckpoint,
7
- writeCheckpoint,
8
- } from "./checkpoint.js";
9
- import { detectCycles } from "./graph-utils.js";
10
- import type { SwarmLimits } from "./limits.js";
11
- import { getTimeoutForRole } from "./limits.js";
12
- import { synthesizeResults } from "./synthesizer.js";
13
- import type {
14
- SwarmExecutionSummary,
15
- SwarmPlan,
16
- SwarmTaskNode,
17
- SwarmTaskResult,
18
- } from "./types.js";
19
- import type { SwarmWorkerBackend } from "./worker-backend.js";
20
- import { runWorkerTask } from "./worker-runner.js";
21
-
22
- const log = getLogger("swarm-orchestrator");
23
-
24
- export type OrchestratorEventKind =
25
- | "plan_created"
26
- | "task_started"
27
- | "task_completed"
28
- | "task_failed"
29
- | "task_blocked"
30
- | "synthesis_started"
31
- | "done";
32
-
33
- export interface OrchestratorEvent {
34
- kind: OrchestratorEventKind;
35
- taskId?: string;
36
- message?: string;
37
- }
38
-
39
- export type OrchestratorStatusCallback = (event: OrchestratorEvent) => void;
40
-
41
- export interface ExecuteSwarmOptions {
42
- plan: SwarmPlan;
43
- limits: SwarmLimits;
44
- backend: SwarmWorkerBackend;
45
- workingDir: string;
46
- modelIntent?: string;
47
- /** Provider + model intent for final synthesis. */
48
- synthesisProvider?: Provider;
49
- synthesisModelIntent?: ModelIntent;
50
- onStatus?: OrchestratorStatusCallback;
51
- signal?: AbortSignal;
52
- /** Stable identifier for this swarm run, used for checkpoint persistence. */
53
- runId?: string;
54
- /** When true, attempt to resume from the last checkpoint for this runId. */
55
- resume?: boolean;
56
- }
57
-
58
- /**
59
- * Execute a validated swarm plan with parallel DAG scheduling,
60
- * bounded concurrency, and per-task retries.
61
- */
62
- export async function executeSwarm(
63
- opts: ExecuteSwarmOptions,
64
- ): Promise<SwarmExecutionSummary> {
65
- const {
66
- plan,
67
- limits,
68
- backend,
69
- workingDir,
70
- modelIntent,
71
- onStatus,
72
- signal,
73
- runId,
74
- resume,
75
- } = opts;
76
- const startTime = Date.now();
77
-
78
- // Safety net: reject cyclic plans even if the caller skipped validation
79
- const cycleNodes = detectCycles(plan.tasks);
80
- if (cycleNodes) {
81
- throw new Error(
82
- `Swarm plan contains a dependency cycle: ${cycleNodes.join(" -> ")}`,
83
- );
84
- }
85
-
86
- onStatus?.({
87
- kind: "plan_created",
88
- message: `Plan with ${plan.tasks.length} tasks`,
89
- });
90
-
91
- const results = new Map<string, SwarmTaskResult>();
92
- const blocked = new Set<string>();
93
-
94
- // Restore from checkpoint if resuming
95
- if (runId && resume) {
96
- const checkpoint = loadCheckpoint(runId);
97
- if (checkpoint && isCheckpointCompatible(checkpoint, plan)) {
98
- for (const result of checkpoint.results) {
99
- results.set(result.taskId, result);
100
- }
101
- for (const taskId of checkpoint.blockedTaskIds) {
102
- blocked.add(taskId);
103
- }
104
- const restored = checkpoint.results.length;
105
- const restoredBlocked = checkpoint.blockedTaskIds.length;
106
- log.info({ runId, restored, restoredBlocked }, "Resumed from checkpoint");
107
- onStatus?.({
108
- kind: "plan_created",
109
- message: `Resumed ${restored} completed tasks from checkpoint`,
110
- });
111
- } else if (checkpoint) {
112
- log.warn(
113
- { runId },
114
- "Checkpoint incompatible with current plan, starting fresh",
115
- );
116
- }
117
- }
118
-
119
- // Build adjacency for dependency tracking
120
- const dependents = new Map<string, string[]>();
121
- for (const task of plan.tasks) {
122
- dependents.set(task.id, []);
123
- }
124
- for (const task of plan.tasks) {
125
- for (const dep of task.dependencies) {
126
- dependents.get(dep)?.push(task.id);
127
- }
128
- }
129
-
130
- // Determine initial ready tasks — skip tasks already completed or blocked
131
- // from a restored checkpoint
132
- const ready: SwarmTaskNode[] = [];
133
- const remaining = new Map<string, SwarmTaskNode>();
134
- const pendingDeps = new Map<string, Set<string>>();
135
-
136
- for (const task of plan.tasks) {
137
- if (results.has(task.id) || blocked.has(task.id)) continue;
138
- remaining.set(task.id, task);
139
- // Remove already-completed dependencies from this task's pending set
140
- const unresolvedDeps = task.dependencies.filter((d) => !results.has(d));
141
- if (unresolvedDeps.length === 0) {
142
- ready.push(task);
143
- } else {
144
- pendingDeps.set(task.id, new Set(unresolvedDeps));
145
- }
146
- }
147
-
148
- // Concurrent DAG executor — schedule tasks as soon as their prerequisites
149
- // finish, bounded by maxWorkers. Unlike wave/batch execution, a newly
150
- // unblocked task can start immediately when a worker slot opens up rather
151
- // than waiting for the entire previous batch to complete.
152
- let activeCount = 0;
153
- let resolve: (() => void) | null = null;
154
-
155
- // Resolves whenever a running task completes (or the ready queue is refilled)
156
- // so the main loop can re-evaluate whether to launch more work.
157
- function signalProgress(): void {
158
- if (resolve) {
159
- const r = resolve;
160
- resolve = null;
161
- r();
162
- }
163
- }
164
-
165
- function waitForProgress(): Promise<void> {
166
- return new Promise<void>((r) => {
167
- resolve = r;
168
- });
169
- }
170
-
171
- function processResult(result: SwarmTaskResult): void {
172
- results.set(result.taskId, result);
173
- remaining.delete(result.taskId);
174
-
175
- if (result.status === "completed") {
176
- onStatus?.({ kind: "task_completed", taskId: result.taskId });
177
- // Immediately unblock dependents so they enter the ready queue
178
- for (const depId of dependents.get(result.taskId) ?? []) {
179
- const pending = pendingDeps.get(depId);
180
- if (pending) {
181
- pending.delete(result.taskId);
182
- if (pending.size === 0) {
183
- pendingDeps.delete(depId);
184
- const task = plan.tasks.find((t) => t.id === depId);
185
- if (task && !blocked.has(depId)) {
186
- ready.push(task);
187
- }
188
- }
189
- }
190
- }
191
- } else {
192
- onStatus?.({ kind: "task_failed", taskId: result.taskId });
193
- blockDependents(result.taskId, dependents, blocked, onStatus);
194
- }
195
-
196
- if (runId) {
197
- writeCheckpoint(runId, plan, results, blocked);
198
- }
199
- }
200
-
201
- async function runTask(task: SwarmTaskNode): Promise<void> {
202
- onStatus?.({ kind: "task_started", taskId: task.id });
203
-
204
- const depOutputs = task.dependencies
205
- .map((depId) => {
206
- const r = results.get(depId);
207
- return r ? { taskId: depId, summary: r.summary } : null;
208
- })
209
- .filter((d): d is { taskId: string; summary: string } => d != null);
210
-
211
- let result: SwarmTaskResult;
212
- try {
213
- const taskTimeoutMs = getTimeoutForRole(limits, task.role) * 1000;
214
-
215
- result = await runWorkerTask({
216
- task,
217
- upstreamContext: plan.objective,
218
- dependencyOutputs: depOutputs,
219
- backend,
220
- workingDir,
221
- modelIntent,
222
- timeoutMs: taskTimeoutMs,
223
- signal,
224
- });
225
-
226
- let retries = 0;
227
- while (
228
- result.status === "failed" &&
229
- retries < limits.maxRetriesPerTask &&
230
- !signal?.aborted
231
- ) {
232
- retries++;
233
- // Exponential backoff with ±25% jitter to prevent thundering herd
234
- const baseDelayMs = 1000 * Math.pow(2, retries - 1);
235
- const jitter = baseDelayMs * 0.25 * (2 * Math.random() - 1);
236
- await abortableSleep(baseDelayMs + jitter, signal);
237
- if (signal?.aborted) break;
238
- result = await runWorkerTask({
239
- task,
240
- upstreamContext: plan.objective,
241
- dependencyOutputs: depOutputs,
242
- backend,
243
- workingDir,
244
- modelIntent,
245
- timeoutMs: taskTimeoutMs,
246
- signal,
247
- });
248
- }
249
- result.retryCount = retries;
250
-
251
- if (result.status === "failed") {
252
- log.error(
253
- { taskId: task.id, error: result.summary, retries },
254
- "Swarm task execution failed",
255
- );
256
- }
257
- } catch (err) {
258
- const error = err instanceof Error ? err : new Error(String(err));
259
- log.error(
260
- { taskId: task.id, error: error.message, stack: error.stack },
261
- "Swarm task execution failed unexpectedly",
262
- );
263
- result = {
264
- taskId: task.id,
265
- status: "failed",
266
- summary: `Unexpected error: ${error.message}`,
267
- artifacts: [],
268
- issues: [error.message],
269
- nextSteps: [],
270
- rawOutput: "",
271
- durationMs: 0,
272
- retryCount: 0,
273
- };
274
- }
275
-
276
- processResult(result);
277
- }
278
-
279
- while (ready.length > 0 || activeCount > 0) {
280
- if (signal?.aborted) break;
281
-
282
- // Launch as many ready tasks as worker slots allow
283
- while (ready.length > 0 && activeCount < limits.maxWorkers) {
284
- const task = ready.shift()!;
285
- activeCount++;
286
- // Fire-and-forget — completion is handled inside runTask.
287
- // .finally() ensures activeCount is decremented exactly once
288
- // regardless of where an error occurs (e.g. a throwing onStatus
289
- // callback inside processResult). .catch() suppresses the
290
- // unhandled rejection for fire-and-forget usage.
291
- runTask(task)
292
- .finally(() => {
293
- activeCount--;
294
- signalProgress();
295
- })
296
- .catch((err) => {
297
- const error = err instanceof Error ? err : new Error(String(err));
298
- log.error(
299
- { taskId: task.id, error: error.message, stack: error.stack },
300
- "Swarm task runner failed",
301
- );
302
- });
303
- }
304
-
305
- // Nothing left to launch and nothing running — we're done
306
- if (activeCount === 0 && ready.length === 0) break;
307
-
308
- // Wait until a running task completes (or a new task becomes ready)
309
- await waitForProgress();
310
- }
311
-
312
- // Let in-flight workers settle before finalizing — if we broke out of the
313
- // loop due to abort, workers may still be running and would otherwise emit
314
- // events (task_completed / task_failed) after the 'done' event.
315
- while (activeCount > 0) {
316
- await waitForProgress();
317
- }
318
-
319
- // Mark any remaining tasks that were never reached as blocked
320
- for (const [taskId] of remaining) {
321
- if (!results.has(taskId) && !blocked.has(taskId)) {
322
- blocked.add(taskId);
323
- onStatus?.({ kind: "task_blocked", taskId });
324
- }
325
- }
326
-
327
- // Synthesize final answer (skip LLM synthesis when aborted, but still
328
- // build the markdown fallback so partial results are preserved)
329
- const allResults = Array.from(results.values());
330
-
331
- let finalAnswer: string;
332
- if (opts.synthesisProvider && !signal?.aborted) {
333
- onStatus?.({ kind: "synthesis_started" });
334
- finalAnswer = await synthesizeResults({
335
- objective: plan.objective,
336
- results: allResults,
337
- provider: opts.synthesisProvider,
338
- modelIntent: opts.synthesisModelIntent ?? "quality-optimized",
339
- });
340
- } else {
341
- if (!signal?.aborted) onStatus?.({ kind: "synthesis_started" });
342
- finalAnswer = buildMarkdownFallback(plan.objective, allResults);
343
- }
344
-
345
- const totalDurationMs = Date.now() - startTime;
346
-
347
- // Clean up checkpoint on successful completion (not on abort, so it can be resumed)
348
- if (runId && !signal?.aborted) {
349
- removeCheckpoint(runId);
350
- }
351
-
352
- onStatus?.({ kind: "done", message: `Completed in ${totalDurationMs}ms` });
353
-
354
- return {
355
- objective: plan.objective,
356
- plan,
357
- results: allResults,
358
- finalAnswer,
359
- stats: {
360
- totalTasks: plan.tasks.length,
361
- completed: allResults.filter((r) => r.status === "completed").length,
362
- failed: allResults.filter((r) => r.status === "failed").length,
363
- blocked: blocked.size,
364
- totalDurationMs,
365
- },
366
- };
367
- }
368
-
369
- function blockDependents(
370
- taskId: string,
371
- dependents: Map<string, string[]>,
372
- blocked: Set<string>,
373
- onStatus?: OrchestratorStatusCallback,
374
- ): void {
375
- for (const depId of dependents.get(taskId) ?? []) {
376
- if (!blocked.has(depId)) {
377
- blocked.add(depId);
378
- onStatus?.({ kind: "task_blocked", taskId: depId });
379
- blockDependents(depId, dependents, blocked, onStatus);
380
- }
381
- }
382
- }
383
-
384
- /** Resolves after `ms` milliseconds, or immediately if the signal fires first. */
385
- function abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {
386
- if (signal?.aborted) return Promise.resolve();
387
- return new Promise<void>((resolve) => {
388
- const timer = setTimeout(done, ms);
389
- signal?.addEventListener("abort", done, { once: true });
390
- function done() {
391
- clearTimeout(timer);
392
- signal?.removeEventListener("abort", done);
393
- resolve();
394
- }
395
- });
396
- }
397
-
398
- function buildMarkdownFallback(
399
- objective: string,
400
- results: SwarmTaskResult[],
401
- ): string {
402
- const lines: string[] = [`## Swarm Results: ${objective}`, ""];
403
-
404
- const completed = results.filter((r) => r.status === "completed");
405
- const failed = results.filter((r) => r.status === "failed");
406
-
407
- if (completed.length > 0) {
408
- lines.push("### Completed Tasks");
409
- for (const r of completed) {
410
- lines.push(`- **${r.taskId}**: ${r.summary}`);
411
- }
412
- lines.push("");
413
- }
414
-
415
- if (failed.length > 0) {
416
- lines.push("### Failed Tasks");
417
- for (const r of failed) {
418
- lines.push(`- **${r.taskId}**: ${r.summary}`);
419
- }
420
- lines.push("");
421
- }
422
-
423
- return lines.join("\n");
424
- }