@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,538 +0,0 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
5
-
6
- // ── Test directory & platform mocks ───────────────────────────────
7
-
8
- const testDir = mkdtempSync(join(tmpdir(), "reducer-job-test-"));
9
-
10
- mock.module("../util/platform.js", () => ({
11
- getDataDir: () => testDir,
12
- getRootDir: () => testDir,
13
- isMacOS: () => process.platform === "darwin",
14
- isLinux: () => process.platform === "linux",
15
- isWindows: () => process.platform === "win32",
16
- getPidPath: () => join(testDir, "test.pid"),
17
- getDbPath: () => join(testDir, "test.db"),
18
- getLogPath: () => join(testDir, "test.log"),
19
- ensureDataDir: () => {},
20
- }));
21
-
22
- mock.module("../util/logger.js", () => ({
23
- getLogger: () =>
24
- new Proxy({} as Record<string, unknown>, {
25
- get: () => () => {},
26
- }),
27
- }));
28
-
29
- // ── Mock the reducer ──────────────────────────────────────────────
30
-
31
- import type { ReducerPromptInput } from "../memory/reducer.js";
32
- import type { ReducerResult } from "../memory/reducer-types.js";
33
- import { EMPTY_REDUCER_RESULT } from "../memory/reducer-types.js";
34
-
35
- let mockReducerResult: ReducerResult = EMPTY_REDUCER_RESULT;
36
- let lastReducerInput: ReducerPromptInput | null = null;
37
-
38
- mock.module("../memory/reducer.js", () => ({
39
- runReducer: async (input: ReducerPromptInput) => {
40
- lastReducerInput = input;
41
- return mockReducerResult;
42
- },
43
- }));
44
-
45
- // ── Imports (after mocks) ─────────────────────────────────────────
46
-
47
- import { initializeDb, resetDb } from "../memory/db.js";
48
- import { getSqlite } from "../memory/db-connection.js";
49
- import { reduceConversationMemoryJob } from "../memory/job-handlers/reduce-conversation-memory.js";
50
- import type { MemoryJob } from "../memory/jobs-store.js";
51
- import { resetTestTables } from "../memory/raw-query.js";
52
-
53
- initializeDb();
54
-
55
- // ── Helpers ───────────────────────────────────────────────────────
56
-
57
- const SCOPE = "test-scope";
58
- const NOW = 1_700_000_000_000;
59
- const HOUR = 60 * 60 * 1000;
60
-
61
- function insertConversation(
62
- id: string,
63
- opts?: {
64
- dirtyTailMessageId?: string;
65
- reducedThroughMessageId?: string;
66
- contextSummary?: string;
67
- memoryScopeId?: string;
68
- },
69
- ): void {
70
- const raw = getSqlite();
71
- raw.run(
72
- `INSERT INTO conversations (id, title, created_at, updated_at, conversation_type, source, memory_scope_id, is_auto_title,
73
- memory_dirty_tail_since_message_id, memory_reduced_through_message_id, context_summary)
74
- VALUES (?, 'Test', ?, ?, 'standard', 'user', ?, 1, ?, ?, ?)`,
75
- [
76
- id,
77
- NOW,
78
- NOW,
79
- opts?.memoryScopeId ?? SCOPE,
80
- opts?.dirtyTailMessageId ?? null,
81
- opts?.reducedThroughMessageId ?? null,
82
- opts?.contextSummary ?? null,
83
- ],
84
- );
85
- }
86
-
87
- function insertMessage(opts: {
88
- id: string;
89
- conversationId: string;
90
- role?: string;
91
- content?: string;
92
- createdAt?: number;
93
- }): void {
94
- const raw = getSqlite();
95
- raw.run(
96
- `INSERT INTO messages (id, conversation_id, role, content, created_at)
97
- VALUES (?, ?, ?, ?, ?)`,
98
- [
99
- opts.id,
100
- opts.conversationId,
101
- opts.role ?? "user",
102
- opts.content ?? "test message",
103
- opts.createdAt ?? NOW,
104
- ],
105
- );
106
- }
107
-
108
- function getRawConversation(conversationId: string): Record<string, unknown> {
109
- const raw = getSqlite();
110
- return raw
111
- .query(`SELECT * FROM conversations WHERE id = ?`)
112
- .get(conversationId) as Record<string, unknown>;
113
- }
114
-
115
- function makeJob(conversationId: string): MemoryJob {
116
- return {
117
- id: "job-1",
118
- type: "reduce_conversation_memory",
119
- payload: { conversationId },
120
- status: "running",
121
- attempts: 0,
122
- deferrals: 0,
123
- runAfter: NOW,
124
- lastError: null,
125
- startedAt: NOW,
126
- createdAt: NOW,
127
- updatedAt: NOW,
128
- };
129
- }
130
-
131
- function makeReducerResult(overrides?: Partial<ReducerResult>): ReducerResult {
132
- return {
133
- timeContexts: [],
134
- openLoops: [],
135
- archiveObservations: [],
136
- archiveEpisodes: [],
137
- ...overrides,
138
- };
139
- }
140
-
141
- // ── Teardown ──────────────────────────────────────────────────────
142
-
143
- afterAll(() => {
144
- resetDb();
145
- try {
146
- rmSync(testDir, { recursive: true });
147
- } catch {
148
- /* best effort */
149
- }
150
- });
151
-
152
- beforeEach(() => {
153
- resetTestTables("messages", "conversations", "time_contexts", "open_loops");
154
- mockReducerResult = EMPTY_REDUCER_RESULT;
155
- lastReducerInput = null;
156
- });
157
-
158
- // ── Tests ─────────────────────────────────────────────────────────
159
-
160
- describe("reduceConversationMemoryJob", () => {
161
- describe("successful reduction", () => {
162
- test("reduces dirty conversation and advances checkpoint", async () => {
163
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
164
- insertMessage({
165
- id: "msg-1",
166
- conversationId: "conv-1",
167
- role: "user",
168
- content: "Hello there",
169
- createdAt: NOW,
170
- });
171
- insertMessage({
172
- id: "msg-2",
173
- conversationId: "conv-1",
174
- role: "assistant",
175
- content: "Hi! How can I help?",
176
- createdAt: NOW + 1000,
177
- });
178
-
179
- mockReducerResult = makeReducerResult({
180
- openLoops: [
181
- {
182
- action: "create",
183
- summary: "User needs help with something",
184
- source: "conversation",
185
- },
186
- ],
187
- });
188
-
189
- await reduceConversationMemoryJob(makeJob("conv-1"));
190
-
191
- // Checkpoint should advance to the last message
192
- const conv = getRawConversation("conv-1");
193
- expect(conv.memory_reduced_through_message_id).toBe("msg-2");
194
- expect(conv.memory_last_reduced_at).toBeGreaterThan(0);
195
- // Dirty tail should be cleared since all messages are now reduced
196
- expect(conv.memory_dirty_tail_since_message_id).toBeNull();
197
- });
198
-
199
- test("passes unreduced messages to the reducer", async () => {
200
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
201
- insertMessage({
202
- id: "msg-1",
203
- conversationId: "conv-1",
204
- role: "user",
205
- content: "First message",
206
- createdAt: NOW,
207
- });
208
- insertMessage({
209
- id: "msg-2",
210
- conversationId: "conv-1",
211
- role: "assistant",
212
- content: "Second message",
213
- createdAt: NOW + 1000,
214
- });
215
-
216
- mockReducerResult = makeReducerResult();
217
-
218
- await reduceConversationMemoryJob(makeJob("conv-1"));
219
-
220
- expect(lastReducerInput).not.toBeNull();
221
- expect(lastReducerInput!.conversationId).toBe("conv-1");
222
- expect(lastReducerInput!.newMessages).toHaveLength(2);
223
- expect(lastReducerInput!.newMessages[0].role).toBe("user");
224
- expect(lastReducerInput!.newMessages[0].content).toBe("First message");
225
- expect(lastReducerInput!.newMessages[1].role).toBe("assistant");
226
- expect(lastReducerInput!.newMessages[1].content).toBe("Second message");
227
- });
228
-
229
- test("includes contextSummary as synthetic system message when present", async () => {
230
- insertConversation("conv-1", {
231
- dirtyTailMessageId: "msg-1",
232
- contextSummary: "User is working on a TypeScript project",
233
- });
234
- insertMessage({
235
- id: "msg-1",
236
- conversationId: "conv-1",
237
- role: "user",
238
- content: "Can you help with this bug?",
239
- createdAt: NOW,
240
- });
241
-
242
- mockReducerResult = makeReducerResult();
243
-
244
- await reduceConversationMemoryJob(makeJob("conv-1"));
245
-
246
- expect(lastReducerInput).not.toBeNull();
247
- // contextSummary should be prepended as a system message
248
- expect(lastReducerInput!.newMessages).toHaveLength(2);
249
- expect(lastReducerInput!.newMessages[0].role).toBe("system");
250
- expect(lastReducerInput!.newMessages[0].content).toContain(
251
- "User is working on a TypeScript project",
252
- );
253
- // Real message follows
254
- expect(lastReducerInput!.newMessages[1].role).toBe("user");
255
- expect(lastReducerInput!.newMessages[1].content).toBe(
256
- "Can you help with this bug?",
257
- );
258
- });
259
-
260
- test("loads active time contexts and open loops for the reducer", async () => {
261
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
262
- insertMessage({
263
- id: "msg-1",
264
- conversationId: "conv-1",
265
- role: "user",
266
- content: "test",
267
- createdAt: NOW,
268
- });
269
-
270
- // Insert pre-existing active time context.
271
- // Use a far-future activeUntil so it is still active at Date.now().
272
- const farFuture = Date.now() + 365 * 24 * HOUR;
273
- const raw = getSqlite();
274
- raw.run(
275
- `INSERT INTO time_contexts (id, scope_id, summary, source, active_from, active_until, created_at, updated_at)
276
- VALUES ('tc-1', ?, 'User on vacation next week', 'conversation', ?, ?, ?, ?)`,
277
- [SCOPE, NOW, farFuture, NOW, NOW],
278
- );
279
-
280
- // Insert pre-existing open loop
281
- raw.run(
282
- `INSERT INTO open_loops (id, scope_id, summary, status, source, created_at, updated_at)
283
- VALUES ('ol-1', ?, 'Waiting for deploy', 'open', 'conversation', ?, ?)`,
284
- [SCOPE, NOW, NOW],
285
- );
286
-
287
- mockReducerResult = makeReducerResult();
288
-
289
- await reduceConversationMemoryJob(makeJob("conv-1"));
290
-
291
- expect(lastReducerInput).not.toBeNull();
292
- expect(lastReducerInput!.existingTimeContexts).toHaveLength(1);
293
- expect(lastReducerInput!.existingTimeContexts[0].id).toBe("tc-1");
294
- expect(lastReducerInput!.existingTimeContexts[0].summary).toBe(
295
- "User on vacation next week",
296
- );
297
- expect(lastReducerInput!.existingOpenLoops).toHaveLength(1);
298
- expect(lastReducerInput!.existingOpenLoops[0].id).toBe("ol-1");
299
- expect(lastReducerInput!.existingOpenLoops[0].summary).toBe(
300
- "Waiting for deploy",
301
- );
302
- });
303
-
304
- test("creates time contexts and open loops from reducer output", async () => {
305
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
306
- insertMessage({
307
- id: "msg-1",
308
- conversationId: "conv-1",
309
- role: "user",
310
- content: "I'm going on vacation next week",
311
- createdAt: NOW,
312
- });
313
-
314
- mockReducerResult = makeReducerResult({
315
- timeContexts: [
316
- {
317
- action: "create",
318
- summary: "User on vacation next week",
319
- source: "conversation",
320
- activeFrom: NOW,
321
- activeUntil: NOW + 7 * 24 * HOUR,
322
- },
323
- ],
324
- openLoops: [
325
- {
326
- action: "create",
327
- summary: "Set up OOO auto-reply",
328
- source: "conversation",
329
- },
330
- ],
331
- });
332
-
333
- await reduceConversationMemoryJob(makeJob("conv-1"));
334
-
335
- // Verify time context was created
336
- const raw = getSqlite();
337
- const contexts = raw
338
- .query(`SELECT * FROM time_contexts WHERE scope_id = ?`)
339
- .all(SCOPE) as Array<Record<string, unknown>>;
340
- expect(contexts).toHaveLength(1);
341
- expect(contexts[0].summary).toBe("User on vacation next week");
342
-
343
- // Verify open loop was created
344
- const loops = raw
345
- .query(`SELECT * FROM open_loops WHERE scope_id = ?`)
346
- .all(SCOPE) as Array<Record<string, unknown>>;
347
- expect(loops).toHaveLength(1);
348
- expect(loops[0].summary).toBe("Set up OOO auto-reply");
349
- expect(loops[0].status).toBe("open");
350
- });
351
- });
352
-
353
- describe("empty dirty tails", () => {
354
- test("no-ops when conversation has no dirty tail marker", async () => {
355
- insertConversation("conv-1"); // no dirtyTailMessageId
356
- insertMessage({
357
- id: "msg-1",
358
- conversationId: "conv-1",
359
- role: "user",
360
- content: "test",
361
- createdAt: NOW,
362
- });
363
-
364
- await reduceConversationMemoryJob(makeJob("conv-1"));
365
-
366
- // Reducer should not have been called
367
- expect(lastReducerInput).toBeNull();
368
-
369
- // Conversation unchanged
370
- const conv = getRawConversation("conv-1");
371
- expect(conv.memory_reduced_through_message_id).toBeNull();
372
- });
373
-
374
- test("no-ops when dirty tail message no longer exists", async () => {
375
- insertConversation("conv-1", {
376
- dirtyTailMessageId: "deleted-msg",
377
- });
378
- // No messages inserted — the dirty tail message doesn't exist
379
-
380
- await reduceConversationMemoryJob(makeJob("conv-1"));
381
-
382
- // Reducer should not have been called
383
- expect(lastReducerInput).toBeNull();
384
-
385
- // Conversation unchanged
386
- const conv = getRawConversation("conv-1");
387
- expect(conv.memory_reduced_through_message_id).toBeNull();
388
- });
389
-
390
- test("no-ops when conversation does not exist", async () => {
391
- await reduceConversationMemoryJob(makeJob("nonexistent-conv"));
392
-
393
- expect(lastReducerInput).toBeNull();
394
- });
395
-
396
- test("no-ops when payload has no conversationId", async () => {
397
- const job: MemoryJob = {
398
- id: "job-1",
399
- type: "reduce_conversation_memory",
400
- payload: {},
401
- status: "running",
402
- attempts: 0,
403
- deferrals: 0,
404
- runAfter: NOW,
405
- lastError: null,
406
- startedAt: NOW,
407
- createdAt: NOW,
408
- updatedAt: NOW,
409
- };
410
-
411
- await reduceConversationMemoryJob(job);
412
-
413
- expect(lastReducerInput).toBeNull();
414
- });
415
- });
416
-
417
- describe("reducer failure safety", () => {
418
- test("does not advance checkpoint when reducer returns EMPTY_REDUCER_RESULT", async () => {
419
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
420
- insertMessage({
421
- id: "msg-1",
422
- conversationId: "conv-1",
423
- role: "user",
424
- content: "test",
425
- createdAt: NOW,
426
- });
427
-
428
- // The default mockReducerResult is EMPTY_REDUCER_RESULT
429
- mockReducerResult = EMPTY_REDUCER_RESULT;
430
-
431
- await reduceConversationMemoryJob(makeJob("conv-1"));
432
-
433
- // Checkpoint should NOT have advanced
434
- const conv = getRawConversation("conv-1");
435
- expect(conv.memory_reduced_through_message_id).toBeNull();
436
- expect(conv.memory_last_reduced_at).toBeNull();
437
- // Dirty tail stays in place for retry
438
- expect(conv.memory_dirty_tail_since_message_id).toBe("msg-1");
439
- });
440
-
441
- test("does not advance checkpoint when reducer throws", async () => {
442
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
443
- insertMessage({
444
- id: "msg-1",
445
- conversationId: "conv-1",
446
- role: "user",
447
- content: "test",
448
- createdAt: NOW,
449
- });
450
-
451
- // Temporarily replace the mock to throw
452
- mock.module("../memory/reducer.js", () => ({
453
- runReducer: async (input: ReducerPromptInput) => {
454
- lastReducerInput = input;
455
- throw new Error("Provider timeout");
456
- },
457
- }));
458
-
459
- try {
460
- await reduceConversationMemoryJob(makeJob("conv-1"));
461
- } catch {
462
- // Error propagation is expected — the job worker handles classification
463
- }
464
-
465
- // Restore the normal mock for subsequent tests
466
- mock.module("../memory/reducer.js", () => ({
467
- runReducer: async (input: ReducerPromptInput) => {
468
- lastReducerInput = input;
469
- return mockReducerResult;
470
- },
471
- }));
472
-
473
- // Regardless of error handling, checkpoint must not advance
474
- const conv = getRawConversation("conv-1");
475
- expect(conv.memory_reduced_through_message_id).toBeNull();
476
- expect(conv.memory_dirty_tail_since_message_id).toBe("msg-1");
477
- });
478
-
479
- test("partial dirty tail preserved when more messages arrive during reduction", async () => {
480
- insertConversation("conv-1", { dirtyTailMessageId: "msg-1" });
481
- insertMessage({
482
- id: "msg-1",
483
- conversationId: "conv-1",
484
- role: "user",
485
- content: "First",
486
- createdAt: NOW,
487
- });
488
- insertMessage({
489
- id: "msg-2",
490
- conversationId: "conv-1",
491
- role: "assistant",
492
- content: "Response",
493
- createdAt: NOW + 1000,
494
- });
495
- // msg-3 arrives "later" — simulates a message added during/after reduction
496
- insertMessage({
497
- id: "msg-3",
498
- conversationId: "conv-1",
499
- role: "user",
500
- content: "Follow-up",
501
- createdAt: NOW + 5000,
502
- });
503
-
504
- mockReducerResult = makeReducerResult();
505
-
506
- await reduceConversationMemoryJob(makeJob("conv-1"));
507
-
508
- const conv = getRawConversation("conv-1");
509
- // All three messages were loaded (they all exist at query time), so
510
- // checkpoint advances through msg-3
511
- expect(conv.memory_reduced_through_message_id).toBe("msg-3");
512
- });
513
- });
514
-
515
- describe("scope isolation", () => {
516
- test("uses the conversation's memoryScopeId for context lookups", async () => {
517
- const customScope = "custom-scope";
518
- insertConversation("conv-1", {
519
- dirtyTailMessageId: "msg-1",
520
- memoryScopeId: customScope,
521
- });
522
- insertMessage({
523
- id: "msg-1",
524
- conversationId: "conv-1",
525
- role: "user",
526
- content: "test",
527
- createdAt: NOW,
528
- });
529
-
530
- mockReducerResult = makeReducerResult();
531
-
532
- await reduceConversationMemoryJob(makeJob("conv-1"));
533
-
534
- expect(lastReducerInput).not.toBeNull();
535
- expect(lastReducerInput!.scopeId).toBe(customScope);
536
- });
537
- });
538
- });