@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
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Workspace commit endpoint — creates a git commit in the workspace
3
+ * directory with all pending changes.
4
+ *
5
+ * Protected by a route policy restricting access to gateway service
6
+ * principals only (`svc_gateway` with `internal.write` scope), following
7
+ * the same pattern as other gateway-forwarded control-plane endpoints.
8
+ */
9
+
10
+ import { getWorkspaceDir } from "../../util/platform.js";
11
+ import { getWorkspaceGitService } from "../../workspace/git-service.js";
12
+ import { httpError } from "../http-errors.js";
13
+ import type { RouteDefinition } from "../http-router.js";
14
+
15
+ export function workspaceCommitRouteDefinitions(): RouteDefinition[] {
16
+ return [
17
+ {
18
+ endpoint: "admin/workspace-commit",
19
+ method: "POST",
20
+ handler: async ({ req }) => {
21
+ let body: unknown;
22
+ try {
23
+ body = await req.json();
24
+ } catch {
25
+ return httpError("BAD_REQUEST", "Invalid JSON body", 400);
26
+ }
27
+
28
+ if (!body || typeof body !== "object") {
29
+ return httpError(
30
+ "BAD_REQUEST",
31
+ "Request body must be a JSON object",
32
+ 400,
33
+ );
34
+ }
35
+
36
+ const { message } = body as { message?: unknown };
37
+
38
+ if (typeof message !== "string" || message.length === 0) {
39
+ return httpError(
40
+ "BAD_REQUEST",
41
+ "message is required and must be a non-empty string",
42
+ 400,
43
+ );
44
+ }
45
+
46
+ try {
47
+ await getWorkspaceGitService(getWorkspaceDir()).commitChanges(
48
+ message,
49
+ );
50
+ return Response.json({ ok: true });
51
+ } catch (err) {
52
+ const detail = err instanceof Error ? err.message : "Unknown error";
53
+ return httpError(
54
+ "INTERNAL_ERROR",
55
+ `Workspace commit failed: ${detail}`,
56
+ 500,
57
+ );
58
+ }
59
+ },
60
+ },
61
+ ];
62
+ }
@@ -190,9 +190,30 @@ describe("isTextMimeType", () => {
190
190
  expect(isTextMimeType("video/mp4")).toBe(false);
191
191
  });
192
192
 
193
- test("application/octet-stream is not text", () => {
193
+ test("application/octet-stream is not text without filename", () => {
194
194
  expect(isTextMimeType("application/octet-stream")).toBe(false);
195
195
  });
196
+
197
+ test("application/octet-stream with .py filename is text", () => {
198
+ expect(isTextMimeType("application/octet-stream", "script.py")).toBe(true);
199
+ });
200
+
201
+ test("application/octet-stream with .go filename is text", () => {
202
+ expect(isTextMimeType("application/octet-stream", "main.go")).toBe(true);
203
+ });
204
+
205
+ test("application/octet-stream with .rs filename is text", () => {
206
+ expect(isTextMimeType("application/octet-stream", "lib.rs")).toBe(true);
207
+ });
208
+
209
+ test("application/octet-stream with unknown extension is not text", () => {
210
+ expect(isTextMimeType("application/octet-stream", "data.bin")).toBe(false);
211
+ });
212
+
213
+ test("extension fallback only applies to application/octet-stream", () => {
214
+ // A binary plist has a specific MIME type — extension should not override it
215
+ expect(isTextMimeType("application/x-plist", "Info.plist")).toBe(false);
216
+ });
196
217
  });
197
218
 
198
219
  // ===========================================================================
@@ -119,7 +119,7 @@ function handleWorkspaceFile(ctx: RouteContext): Response {
119
119
  }
120
120
 
121
121
  const mimeType = Bun.file(resolved).type;
122
- const isText = isTextMimeType(mimeType);
122
+ const isText = isTextMimeType(mimeType, basename(resolved));
123
123
  const isBinary = !isText;
124
124
 
125
125
  let content: string | undefined = undefined;
@@ -85,10 +85,94 @@ const TEXT_MIME_PREFIXES = [
85
85
  "application/x-yaml",
86
86
  "application/toml",
87
87
  "application/x-sh",
88
+ "application/x-httpd-php",
89
+ "application/x-perl",
90
+ "application/x-sql",
91
+ "application/x-tex",
92
+ "application/vnd.dart",
88
93
  ];
89
94
 
90
- export function isTextMimeType(mimeType: string): boolean {
91
- return TEXT_MIME_PREFIXES.some((prefix) => mimeType.startsWith(prefix));
95
+ /**
96
+ * File extensions that are known text/code files but that Bun's MIME
97
+ * detection reports as `application/octet-stream`.
98
+ */
99
+ const TEXT_FILE_EXTENSIONS = new Set([
100
+ // Programming languages
101
+ "py",
102
+ "rb",
103
+ "go",
104
+ "rs",
105
+ "swift",
106
+ "kt",
107
+ "kts",
108
+ "cs",
109
+ "scala",
110
+ "ex",
111
+ "exs",
112
+ "erl",
113
+ "hs",
114
+ "clj",
115
+ "cljs",
116
+ "jl",
117
+ "zig",
118
+ "nim",
119
+ "v",
120
+ "sol",
121
+ "r",
122
+ "java",
123
+ "lua",
124
+ // Shell / scripting
125
+ "bash",
126
+ "zsh",
127
+ "fish",
128
+ "ps1",
129
+ "bat",
130
+ "cmd",
131
+ "awk",
132
+ // Web frameworks
133
+ "vue",
134
+ "svelte",
135
+ "scss",
136
+ "sass",
137
+ "less",
138
+ // Config / data
139
+ "cfg",
140
+ "conf",
141
+ "ini",
142
+ "properties",
143
+ "env",
144
+ "gradle",
145
+ "cmake",
146
+ // Markup / docs
147
+ "rst",
148
+ "adoc",
149
+ "org",
150
+ "tex",
151
+ "latex",
152
+ // Other text formats
153
+ "graphql",
154
+ "gql",
155
+ "proto",
156
+ "tf",
157
+ "hcl",
158
+ "diff",
159
+ "patch",
160
+ "log",
161
+ "lock",
162
+ ]);
163
+
164
+ export function isTextMimeType(mimeType: string, fileName?: string): boolean {
165
+ if (TEXT_MIME_PREFIXES.some((prefix) => mimeType.startsWith(prefix))) {
166
+ return true;
167
+ }
168
+ // Only fall back to extension check when the MIME type is genuinely unknown.
169
+ // Specific MIME types (e.g. application/x-plist for binary plists) should be
170
+ // trusted over the extension — overriding them risks corrupting binary files.
171
+ if (fileName && mimeType === "application/octet-stream") {
172
+ const ext = fileName.split(".").pop()?.toLowerCase();
173
+ if (ext && TEXT_FILE_EXTENSIONS.has(ext)) return true;
174
+ }
175
+ return false;
92
176
  }
93
177
 
94
178
  export const MAX_INLINE_TEXT_SIZE = 2 * 1024 * 1024; // 2 MB
@@ -206,27 +206,6 @@ export function listSchedules(options?: {
206
206
  return rows.map(parseJobRow);
207
207
  }
208
208
 
209
- /**
210
- * Return enabled schedules whose next run falls within a time window.
211
- * Used by the memory brief compiler to surface due-soon schedule entries.
212
- */
213
- export function getDueSoonSchedules(
214
- now: number,
215
- horizonMs: number,
216
- ): ScheduleJob[] {
217
- const db = getDb();
218
- const cutoff = now + horizonMs;
219
- const rows = db
220
- .select()
221
- .from(scheduleJobs)
222
- .where(
223
- and(eq(scheduleJobs.enabled, true), lte(scheduleJobs.nextRunAt, cutoff)),
224
- )
225
- .orderBy(asc(scheduleJobs.nextRunAt))
226
- .all();
227
- return rows.map(parseJobRow);
228
- }
229
-
230
209
  export function updateSchedule(
231
210
  id: string,
232
211
  updates: {
@@ -16,11 +16,17 @@
16
16
  */
17
17
 
18
18
  import { getLogger } from "../util/logger.js";
19
- import type { CredentialBackend, DeleteResult } from "./credential-backend.js";
19
+ import type {
20
+ CredentialBackend,
21
+ CredentialGetResult,
22
+ DeleteResult,
23
+ } from "./credential-backend.js";
20
24
 
21
25
  const log = getLogger("ces-credential-client");
22
26
 
23
27
  const REQUEST_TIMEOUT_MS = 10_000;
28
+ const SET_MAX_RETRIES = 3;
29
+ const SET_RETRY_DELAY_MS = 2_000;
24
30
 
25
31
  // ---------------------------------------------------------------------------
26
32
  // Env helpers
@@ -77,49 +83,80 @@ export class CesCredentialBackend implements CredentialBackend {
77
83
  return !!getBaseUrl() && !!getServiceToken();
78
84
  }
79
85
 
80
- async get(account: string): Promise<string | undefined> {
86
+ async get(account: string): Promise<CredentialGetResult> {
81
87
  try {
82
88
  const res = await cesRequest(
83
89
  "GET",
84
90
  `/v1/credentials/${encodeURIComponent(account)}`,
85
91
  );
86
- if (!res) return undefined;
87
- if (res.status === 404) return undefined;
92
+ if (!res) return { value: undefined, unreachable: true };
93
+ if (res.status === 404) return { value: undefined, unreachable: false };
88
94
  if (!res.ok) {
89
95
  log.warn(
90
96
  { account, status: res.status },
91
97
  "CES credential get returned non-OK status",
92
98
  );
93
- return undefined;
99
+ return { value: undefined, unreachable: true };
94
100
  }
95
101
  const data = (await res.json()) as { value?: string };
96
- return data.value;
102
+ return { value: data.value, unreachable: false };
97
103
  } catch (err) {
98
104
  log.warn({ err, account }, "CES credential get threw unexpectedly");
99
- return undefined;
105
+ return { value: undefined, unreachable: true };
100
106
  }
101
107
  }
102
108
 
103
109
  async set(account: string, value: string): Promise<boolean> {
104
- try {
105
- const res = await cesRequest(
106
- "POST",
107
- `/v1/credentials/${encodeURIComponent(account)}`,
108
- { value },
109
- );
110
- if (!res) return false;
111
- if (!res.ok) {
112
- log.warn(
113
- { account, status: res.status },
114
- "CES credential set returned non-OK status",
110
+ for (let attempt = 0; attempt < SET_MAX_RETRIES; attempt++) {
111
+ try {
112
+ const res = await cesRequest(
113
+ "POST",
114
+ `/v1/credentials/${encodeURIComponent(account)}`,
115
+ { value },
115
116
  );
117
+ if (!res) {
118
+ // CES not reachable or env vars missing — retry in case sidecar
119
+ // is still starting up after pod creation.
120
+ if (attempt < SET_MAX_RETRIES - 1) {
121
+ log.warn(
122
+ { account, attempt },
123
+ "CES credential set got no response, retrying",
124
+ );
125
+ await new Promise((r) => setTimeout(r, SET_RETRY_DELAY_MS));
126
+ continue;
127
+ }
128
+ return false;
129
+ }
130
+ if (!res.ok) {
131
+ if (attempt < SET_MAX_RETRIES - 1) {
132
+ log.warn(
133
+ { account, status: res.status, attempt },
134
+ "CES credential set returned non-OK status, retrying",
135
+ );
136
+ await new Promise((r) => setTimeout(r, SET_RETRY_DELAY_MS));
137
+ continue;
138
+ }
139
+ log.warn(
140
+ { account, status: res.status },
141
+ "CES credential set returned non-OK status",
142
+ );
143
+ return false;
144
+ }
145
+ return true;
146
+ } catch (err) {
147
+ if (attempt < SET_MAX_RETRIES - 1) {
148
+ log.warn(
149
+ { err, account, attempt },
150
+ "CES credential set threw, retrying",
151
+ );
152
+ await new Promise((r) => setTimeout(r, SET_RETRY_DELAY_MS));
153
+ continue;
154
+ }
155
+ log.warn({ err, account }, "CES credential set threw unexpectedly");
116
156
  return false;
117
157
  }
118
- return true;
119
- } catch (err) {
120
- log.warn({ err, account }, "CES credential set threw unexpectedly");
121
- return false;
122
158
  }
159
+ return false;
123
160
  }
124
161
 
125
162
  async delete(account: string): Promise<DeleteResult> {
@@ -0,0 +1,85 @@
1
+ /**
2
+ * CesRpcCredentialBackend — a CredentialBackend that delegates all credential
3
+ * operations to the Credential Execution Service (CES) via stdio RPC.
4
+ *
5
+ * Maps RPC responses to the existing CredentialGetResult and DeleteResult
6
+ * types. Errors are caught and mapped to unreachable/error states for
7
+ * graceful fallback.
8
+ */
9
+
10
+ import { CesRpcMethod } from "@vellumai/ces-contracts";
11
+
12
+ import type { CesClient } from "../credential-execution/client.js";
13
+ import { getLogger } from "../util/logger.js";
14
+ import type {
15
+ CredentialBackend,
16
+ CredentialGetResult,
17
+ DeleteResult,
18
+ } from "./credential-backend.js";
19
+
20
+ const log = getLogger("ces-rpc-credential-backend");
21
+
22
+ export class CesRpcCredentialBackend implements CredentialBackend {
23
+ readonly name = "ces-rpc";
24
+
25
+ constructor(private readonly client: CesClient) {}
26
+
27
+ isAvailable(): boolean {
28
+ return this.client.isReady();
29
+ }
30
+
31
+ async get(account: string): Promise<CredentialGetResult> {
32
+ try {
33
+ const result = await this.client.call(
34
+ CesRpcMethod.GetCredential,
35
+ { account },
36
+ );
37
+ return {
38
+ value: result.found ? result.value : undefined,
39
+ unreachable: false,
40
+ };
41
+ } catch (err) {
42
+ log.warn({ err, account }, "CES RPC credential get failed");
43
+ return { value: undefined, unreachable: true };
44
+ }
45
+ }
46
+
47
+ async set(account: string, value: string): Promise<boolean> {
48
+ try {
49
+ const result = await this.client.call(
50
+ CesRpcMethod.SetCredential,
51
+ { account, value },
52
+ );
53
+ return result.ok;
54
+ } catch (err) {
55
+ log.warn({ err, account }, "CES RPC credential set failed");
56
+ return false;
57
+ }
58
+ }
59
+
60
+ async delete(account: string): Promise<DeleteResult> {
61
+ try {
62
+ const result = await this.client.call(
63
+ CesRpcMethod.DeleteCredential,
64
+ { account },
65
+ );
66
+ return result.result;
67
+ } catch (err) {
68
+ log.warn({ err, account }, "CES RPC credential delete failed");
69
+ return "error";
70
+ }
71
+ }
72
+
73
+ async list(): Promise<string[]> {
74
+ try {
75
+ const result = await this.client.call(
76
+ CesRpcMethod.ListCredentials,
77
+ {},
78
+ );
79
+ return result.accounts;
80
+ } catch (err) {
81
+ log.warn({ err }, "CES RPC credential list failed");
82
+ return [];
83
+ }
84
+ }
85
+ }
@@ -1,15 +1,10 @@
1
1
  /**
2
2
  * CredentialBackend interface and adapters — abstracts credential storage
3
3
  * behind a unified async API so callers don't need to know which backend
4
- * (macOS Keychain, encrypted file store, etc.) is in use.
4
+ * is in use.
5
5
  */
6
6
 
7
- import { getLogger } from "../util/logger.js";
8
7
  import * as encryptedStore from "./encrypted-store.js";
9
- import type { KeychainBrokerClient } from "./keychain-broker-client.js";
10
- import { createBrokerClient } from "./keychain-broker-client.js";
11
-
12
- const log = getLogger("credential-backend");
13
8
 
14
9
  // ---------------------------------------------------------------------------
15
10
  // Types
@@ -18,6 +13,12 @@ const log = getLogger("credential-backend");
18
13
  /** Result of a delete operation — distinguishes success, not-found, and error. */
19
14
  export type DeleteResult = "deleted" | "not-found" | "error";
20
15
 
16
+ /** Result of a get operation — distinguishes unreachable from not-found. */
17
+ export interface CredentialGetResult {
18
+ value: string | undefined;
19
+ unreachable: boolean;
20
+ }
21
+
21
22
  // ---------------------------------------------------------------------------
22
23
  // Interface
23
24
  // ---------------------------------------------------------------------------
@@ -29,8 +30,8 @@ export interface CredentialBackend {
29
30
  /** Whether this backend is currently reachable. Sync and cheap. */
30
31
  isAvailable(): boolean;
31
32
 
32
- /** Retrieve a secret. Returns undefined if not found or on error. */
33
- get(account: string): Promise<string | undefined>;
33
+ /** Retrieve a secret. Returns a result distinguishing unreachable from not-found. */
34
+ get(account: string): Promise<CredentialGetResult>;
34
35
 
35
36
  /** Store a secret. Returns true on success. */
36
37
  set(account: string, value: string): Promise<boolean>;
@@ -42,79 +43,6 @@ export interface CredentialBackend {
42
43
  list(): Promise<string[]>;
43
44
  }
44
45
 
45
- // ---------------------------------------------------------------------------
46
- // KeychainBackend
47
- // ---------------------------------------------------------------------------
48
-
49
- export class KeychainBackend implements CredentialBackend {
50
- readonly name = "keychain";
51
-
52
- constructor(private readonly client: KeychainBrokerClient) {}
53
-
54
- isAvailable(): boolean {
55
- return this.client.isAvailable();
56
- }
57
-
58
- async get(account: string): Promise<string | undefined> {
59
- try {
60
- const result = await this.client.get(account);
61
- if (result == null) {
62
- log.warn(
63
- { account },
64
- "Keychain broker unreachable during get — falling back",
65
- );
66
- return undefined;
67
- }
68
- if (!result.found) return undefined;
69
- return result.value;
70
- } catch (err) {
71
- log.warn({ err, account }, "Keychain get threw unexpectedly");
72
- return undefined;
73
- }
74
- }
75
-
76
- async set(account: string, value: string): Promise<boolean> {
77
- try {
78
- const result = await this.client.set(account, value);
79
- if (result.status === "ok") return true;
80
- log.warn(
81
- {
82
- account,
83
- status: result.status,
84
- ...(result.status === "rejected"
85
- ? { code: result.code, message: result.message }
86
- : {}),
87
- },
88
- "Keychain broker set failed",
89
- );
90
- return false;
91
- } catch (err) {
92
- log.warn({ err, account }, "Keychain set threw unexpectedly");
93
- return false;
94
- }
95
- }
96
-
97
- async delete(account: string): Promise<DeleteResult> {
98
- try {
99
- const ok = await this.client.del(account);
100
- // The keychain broker returns a boolean — it does not distinguish
101
- // "not found" from a genuine error, so we map false → "error".
102
- return ok ? "deleted" : "error";
103
- } catch {
104
- return "error";
105
- }
106
- }
107
-
108
- async list(): Promise<string[]> {
109
- try {
110
- return await this.client.list();
111
- } catch (err) {
112
- log.warn({ err }, "Keychain list threw unexpectedly");
113
- return [];
114
- }
115
- }
116
- }
117
-
118
46
  // ---------------------------------------------------------------------------
119
47
  // EncryptedStoreBackend
120
48
  // ---------------------------------------------------------------------------
@@ -126,11 +54,11 @@ export class EncryptedStoreBackend implements CredentialBackend {
126
54
  return true;
127
55
  }
128
56
 
129
- async get(account: string): Promise<string | undefined> {
57
+ async get(account: string): Promise<CredentialGetResult> {
130
58
  try {
131
- return encryptedStore.getKey(account);
59
+ return { value: encryptedStore.getKey(account), unreachable: false };
132
60
  } catch {
133
- return undefined;
61
+ return { value: undefined, unreachable: false };
134
62
  }
135
63
  }
136
64
 
@@ -163,10 +91,6 @@ export class EncryptedStoreBackend implements CredentialBackend {
163
91
  // Factory functions
164
92
  // ---------------------------------------------------------------------------
165
93
 
166
- export function createKeychainBackend(): KeychainBackend {
167
- return new KeychainBackend(createBrokerClient());
168
- }
169
-
170
94
  export function createEncryptedStoreBackend(): EncryptedStoreBackend {
171
95
  return new EncryptedStoreBackend();
172
96
  }
@@ -24,9 +24,10 @@ import { getRootDir } from "../util/platform.js";
24
24
  const log = getLogger("keychain-broker-client");
25
25
 
26
26
  const REQUEST_TIMEOUT_MS = 5_000;
27
+ const CONNECT_TIMEOUT_MS = 3_000;
27
28
 
28
- /** Cooldown periods (ms) after consecutive connection failures: 30s, 60s, 2min, 5min, then cap at 5min. */
29
- const RECONNECT_COOLDOWN_MS = [30_000, 60_000, 120_000, 300_000];
29
+ /** Cooldown periods (ms) after consecutive connection failures: 5s, 15s, 30s, 60s, 5min, then cap at 5min. */
30
+ const RECONNECT_COOLDOWN_MS = [5_000, 15_000, 30_000, 60_000, 300_000];
30
31
 
31
32
  // ---------------------------------------------------------------------------
32
33
  // Types
@@ -191,7 +192,13 @@ export function createBrokerClient(): KeychainBrokerClient {
191
192
 
192
193
  const sock = createConnection({ path: socketPath });
193
194
 
195
+ const connectTimer = setTimeout(() => {
196
+ sock.destroy();
197
+ reject(new Error("Connect timeout"));
198
+ }, CONNECT_TIMEOUT_MS);
199
+
194
200
  sock.on("connect", () => {
201
+ clearTimeout(connectTimer);
195
202
  socket = sock;
196
203
  consecutiveFailures = 0;
197
204
  unavailableSince = null;
@@ -199,6 +206,7 @@ export function createBrokerClient(): KeychainBrokerClient {
199
206
  });
200
207
 
201
208
  sock.on("error", (err) => {
209
+ clearTimeout(connectTimer);
202
210
  log.warn({ err }, "Keychain broker socket error");
203
211
  cleanupSocket();
204
212
  reject(err);