@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,467 +0,0 @@
1
- /**
2
- * Simplified memory reducer — provider-backed conversation turn processor.
3
- *
4
- * This module owns:
5
- * 1. ReducerPromptInput — structured input for the provider call
6
- * 2. runReducer — send the transcript span to the LLM and return a typed result
7
- * 3. parseReducerOutput — raw string -> validated ReducerResult
8
- * 4. Fallback to EMPTY_REDUCER_RESULT on unparseable output (parse failures only)
9
- *
10
- * The reducer is intentionally side-effect-free: it never writes to the
11
- * database. Callers are responsible for applying the returned ReducerResult.
12
- */
13
-
14
- import {
15
- createTimeout,
16
- extractText,
17
- getConfiguredProvider,
18
- } from "../providers/provider-send-message.js";
19
- import { getLogger } from "../util/logger.js";
20
- import {
21
- type ArchiveEpisodeCandidate,
22
- type ArchiveObservationCandidate,
23
- EMPTY_REDUCER_RESULT,
24
- type OpenLoopCreate,
25
- type OpenLoopOp,
26
- type OpenLoopUpdate,
27
- type ReducerResult,
28
- type TimeContextOp,
29
- type TimeContextUpdate,
30
- } from "./reducer-types.js";
31
-
32
- const log = getLogger("memory-reducer");
33
-
34
- /** Timeout for the reducer provider call (ms). */
35
- const REDUCER_TIMEOUT_MS = 30_000;
36
-
37
- // ── Prompt input type ──────────────────────────────────────────────────
38
-
39
- /** The structured input that will be fed to the reducer provider call. */
40
- export interface ReducerPromptInput {
41
- /** Conversation ID being reduced. */
42
- conversationId: string;
43
- /** New messages since the last reduction checkpoint (role + content). */
44
- newMessages: Array<{ role: string; content: string }>;
45
- /** Current time-context rows the model can reference for updates. */
46
- existingTimeContexts: Array<{ id: string; summary: string }>;
47
- /** Current open-loop rows the model can reference for updates. */
48
- existingOpenLoops: Array<{ id: string; summary: string; status: string }>;
49
- /** Current time as epoch ms — injected for deterministic tests. */
50
- nowMs: number;
51
- /** Memory scope identifier (e.g. assistant instance ID). */
52
- scopeId: string;
53
- }
54
-
55
- // ── System prompt ─────────────────────────────────────────────────────
56
-
57
- /**
58
- * Build the reducer system prompt. Extracted as a named function so tests can
59
- * assert on prompt content without coupling to string literals.
60
- */
61
- export function buildReducerSystemPrompt(): string {
62
- return [
63
- "You are a memory reducer for a personal assistant. Your job is to analyze",
64
- "a span of new conversation messages and produce structured JSON output that",
65
- "captures important information for the assistant's long-term memory.",
66
- "",
67
- "You output a single JSON object with four optional arrays:",
68
- "",
69
- "1. `timeContexts` — time-bounded situational context (e.g. 'user traveling next week').",
70
- " Each entry has: action ('create'|'update'|'resolve'), and fields depending on the action.",
71
- " - create: summary (string), source (string), activeFrom (epoch ms), activeUntil (epoch ms)",
72
- " - update: id (string), and at least one of: summary, activeFrom, activeUntil",
73
- " - resolve: id (string)",
74
- "",
75
- "2. `openLoops` — unresolved items to track (e.g. 'waiting for Bob's reply').",
76
- " Each entry has: action ('create'|'update'|'resolve'), and fields depending on the action.",
77
- " - create: summary (string), source (string), optional dueAt (epoch ms)",
78
- " - update: id (string), and at least one of: summary, dueAt",
79
- " - resolve: id (string), status ('resolved'|'expired')",
80
- "",
81
- "3. `archiveObservations` — factual statements extracted from the conversation.",
82
- " Each entry has: content (string), role (string), optional modality (string), optional source (string)",
83
- "",
84
- "4. `archiveEpisodes` — coherent narrative summaries of interaction spans.",
85
- " Each entry has: title (string), summary (string), optional source (string)",
86
- "",
87
- "Rules:",
88
- "- Output ONLY valid JSON. No markdown, no explanation, no wrapping.",
89
- "- Omit arrays that would be empty rather than including empty arrays.",
90
- "- For updates and resolves, reference existing IDs from the provided context.",
91
- "- Be selective: only extract genuinely important or actionable information.",
92
- "- Timestamps are in epoch milliseconds.",
93
- "- If there is nothing meaningful to extract, output: {}",
94
- ].join("\n");
95
- }
96
-
97
- /**
98
- * Build the user-message content for the reducer prompt from the structured input.
99
- */
100
- export function buildReducerUserMessage(input: ReducerPromptInput): string {
101
- const parts: string[] = [];
102
-
103
- parts.push(
104
- `Current time: ${new Date(input.nowMs).toISOString()} (${input.nowMs}ms)`,
105
- );
106
- parts.push(`Conversation: ${input.conversationId}`);
107
- parts.push(`Scope: ${input.scopeId}`);
108
- parts.push("");
109
-
110
- // Existing state the model can reference for updates/resolves
111
- if (input.existingTimeContexts.length > 0) {
112
- parts.push("## Active time contexts");
113
- for (const tc of input.existingTimeContexts) {
114
- parts.push(`- [${tc.id}] ${tc.summary}`);
115
- }
116
- parts.push("");
117
- }
118
-
119
- if (input.existingOpenLoops.length > 0) {
120
- parts.push("## Active open loops");
121
- for (const ol of input.existingOpenLoops) {
122
- parts.push(`- [${ol.id}] (${ol.status}) ${ol.summary}`);
123
- }
124
- parts.push("");
125
- }
126
-
127
- // The unreduced transcript span
128
- parts.push("## New messages to process");
129
- for (const msg of input.newMessages) {
130
- parts.push(`[${msg.role}]: ${msg.content}`);
131
- }
132
-
133
- return parts.join("\n");
134
- }
135
-
136
- // ── Provider-backed reducer call ──────────────────────────────────────
137
-
138
- /**
139
- * Run the memory reducer against a transcript span.
140
- *
141
- * Sends the unreduced messages, active time contexts, active open loops,
142
- * current time, and scope metadata to the configured LLM provider. Parses
143
- * the response into a typed {@link ReducerResult}.
144
- *
145
- * This function is **side-effect-free**: it never writes to the database.
146
- * The caller is responsible for applying the returned result.
147
- *
148
- * Returns {@link EMPTY_REDUCER_RESULT} when:
149
- * - No provider is configured/available
150
- * - The provider call fails or times out
151
- * - The model output is unparseable
152
- *
153
- * @param input Structured reducer input
154
- * @param signal Optional external abort signal
155
- */
156
- export async function runReducer(
157
- input: ReducerPromptInput,
158
- signal?: AbortSignal,
159
- ): Promise<ReducerResult> {
160
- const provider = await getConfiguredProvider();
161
- if (!provider) {
162
- log.warn(
163
- "No provider available for memory reducer — returning empty result",
164
- );
165
- return EMPTY_REDUCER_RESULT;
166
- }
167
-
168
- const systemPrompt = buildReducerSystemPrompt();
169
- const userText = buildReducerUserMessage(input);
170
-
171
- const { signal: timeoutSignal, cleanup } = createTimeout(REDUCER_TIMEOUT_MS);
172
- const combinedSignal = signal
173
- ? AbortSignal.any([signal, timeoutSignal])
174
- : timeoutSignal;
175
-
176
- try {
177
- const response = await provider.sendMessage(
178
- [{ role: "user", content: [{ type: "text", text: userText }] }],
179
- undefined,
180
- systemPrompt,
181
- {
182
- signal: combinedSignal,
183
- config: {
184
- modelIntent: "latency-optimized" as const,
185
- max_tokens: 4096,
186
- },
187
- },
188
- );
189
-
190
- const rawText = extractText(response);
191
- if (!rawText) {
192
- log.warn("Reducer provider returned empty text — returning empty result");
193
- return EMPTY_REDUCER_RESULT;
194
- }
195
-
196
- return parseReducerOutput(rawText);
197
- } catch (err) {
198
- if (combinedSignal.aborted) {
199
- log.warn("Memory reducer provider call timed out or was aborted");
200
- } else {
201
- log.warn({ err }, "Memory reducer provider call failed");
202
- }
203
- return EMPTY_REDUCER_RESULT;
204
- } finally {
205
- cleanup();
206
- }
207
- }
208
-
209
- // ── Validation helpers ─────────────────────────────────────────────────
210
-
211
- const VALID_TIME_CONTEXT_ACTIONS = new Set(["create", "update", "resolve"]);
212
- const VALID_OPEN_LOOP_ACTIONS = new Set(["create", "update", "resolve"]);
213
- const VALID_OPEN_LOOP_RESOLVE_STATUSES = new Set(["resolved", "expired"]);
214
-
215
- function isNonEmptyString(v: unknown): v is string {
216
- return typeof v === "string" && v.length > 0;
217
- }
218
-
219
- function isPositiveNumber(v: unknown): v is number {
220
- return typeof v === "number" && Number.isFinite(v) && v > 0;
221
- }
222
-
223
- function isNonNegativeNumber(v: unknown): v is number {
224
- return typeof v === "number" && Number.isFinite(v) && v >= 0;
225
- }
226
-
227
- function validateTimeContextOp(raw: unknown): TimeContextOp | null {
228
- if (raw == null || typeof raw !== "object") return null;
229
- const obj = raw as Record<string, unknown>;
230
- const action = obj.action;
231
-
232
- if (!isNonEmptyString(action) || !VALID_TIME_CONTEXT_ACTIONS.has(action)) {
233
- return null;
234
- }
235
-
236
- if (action === "create") {
237
- if (
238
- !isNonEmptyString(obj.summary) ||
239
- !isNonEmptyString(obj.source) ||
240
- !isNonNegativeNumber(obj.activeFrom) ||
241
- !isPositiveNumber(obj.activeUntil)
242
- ) {
243
- return null;
244
- }
245
- return {
246
- action: "create",
247
- summary: obj.summary,
248
- source: obj.source,
249
- activeFrom: obj.activeFrom,
250
- activeUntil: obj.activeUntil,
251
- };
252
- }
253
-
254
- if (action === "update") {
255
- if (!isNonEmptyString(obj.id)) return null;
256
- // Extract and narrow optional fields
257
- const summary = isNonEmptyString(obj.summary) ? obj.summary : undefined;
258
- const activeFrom = isNonNegativeNumber(obj.activeFrom)
259
- ? obj.activeFrom
260
- : undefined;
261
- const activeUntil = isPositiveNumber(obj.activeUntil)
262
- ? obj.activeUntil
263
- : undefined;
264
- // At least one field must be provided for the update to be meaningful
265
- if (
266
- summary === undefined &&
267
- activeFrom === undefined &&
268
- activeUntil === undefined
269
- ) {
270
- return null;
271
- }
272
- const result: TimeContextUpdate = {
273
- action: "update",
274
- id: obj.id,
275
- };
276
- if (summary !== undefined) result.summary = summary;
277
- if (activeFrom !== undefined) result.activeFrom = activeFrom;
278
- if (activeUntil !== undefined) result.activeUntil = activeUntil;
279
- return result;
280
- }
281
-
282
- // resolve
283
- if (!isNonEmptyString(obj.id)) return null;
284
- return { action: "resolve", id: obj.id };
285
- }
286
-
287
- function validateOpenLoopOp(raw: unknown): OpenLoopOp | null {
288
- if (raw == null || typeof raw !== "object") return null;
289
- const obj = raw as Record<string, unknown>;
290
- const action = obj.action;
291
-
292
- if (!isNonEmptyString(action) || !VALID_OPEN_LOOP_ACTIONS.has(action)) {
293
- return null;
294
- }
295
-
296
- if (action === "create") {
297
- if (!isNonEmptyString(obj.summary) || !isNonEmptyString(obj.source)) {
298
- return null;
299
- }
300
- const result: OpenLoopCreate = {
301
- action: "create",
302
- summary: obj.summary,
303
- source: obj.source,
304
- };
305
- const dueAt = isNonNegativeNumber(obj.dueAt) ? obj.dueAt : undefined;
306
- if (dueAt !== undefined) result.dueAt = dueAt;
307
- return result;
308
- }
309
-
310
- if (action === "update") {
311
- if (!isNonEmptyString(obj.id)) return null;
312
- const summary = isNonEmptyString(obj.summary) ? obj.summary : undefined;
313
- const dueAt = isNonNegativeNumber(obj.dueAt) ? obj.dueAt : undefined;
314
- if (summary === undefined && dueAt === undefined) return null;
315
-
316
- const result: OpenLoopUpdate = {
317
- action: "update",
318
- id: obj.id,
319
- };
320
- if (summary !== undefined) result.summary = summary;
321
- if (dueAt !== undefined) result.dueAt = dueAt;
322
- return result;
323
- }
324
-
325
- // resolve
326
- if (!isNonEmptyString(obj.id)) return null;
327
- if (
328
- !isNonEmptyString(obj.status) ||
329
- !VALID_OPEN_LOOP_RESOLVE_STATUSES.has(obj.status)
330
- ) {
331
- return null;
332
- }
333
- return {
334
- action: "resolve",
335
- id: obj.id,
336
- status: obj.status as "resolved" | "expired",
337
- };
338
- }
339
-
340
- function validateArchiveObservation(
341
- raw: unknown,
342
- ): ArchiveObservationCandidate | null {
343
- if (raw == null || typeof raw !== "object") return null;
344
- const obj = raw as Record<string, unknown>;
345
- if (!isNonEmptyString(obj.content) || !isNonEmptyString(obj.role)) {
346
- return null;
347
- }
348
- const result: ArchiveObservationCandidate = {
349
- content: obj.content,
350
- role: obj.role,
351
- };
352
- if (isNonEmptyString(obj.modality)) result.modality = obj.modality;
353
- if (isNonEmptyString(obj.source)) result.source = obj.source;
354
- return result;
355
- }
356
-
357
- function validateArchiveEpisode(raw: unknown): ArchiveEpisodeCandidate | null {
358
- if (raw == null || typeof raw !== "object") return null;
359
- const obj = raw as Record<string, unknown>;
360
- if (!isNonEmptyString(obj.title) || !isNonEmptyString(obj.summary)) {
361
- return null;
362
- }
363
- const result: ArchiveEpisodeCandidate = {
364
- title: obj.title,
365
- summary: obj.summary,
366
- };
367
- if (isNonEmptyString(obj.source)) result.source = obj.source;
368
- return result;
369
- }
370
-
371
- // ── Public API ─────────────────────────────────────────────────────────
372
-
373
- /**
374
- * Parse raw model output into a validated ReducerResult.
375
- *
376
- * On any structural error (non-JSON, not a JSON object) the function returns
377
- * {@link EMPTY_REDUCER_RESULT} rather than throwing — callers use identity
378
- * comparison (`=== EMPTY_REDUCER_RESULT`) to detect true parse failures and
379
- * skip checkpoint advancement.
380
- *
381
- * A valid JSON object with no recognized top-level arrays (e.g. `{}`) is
382
- * treated as a **valid-but-empty** response — the model simply had nothing
383
- * to extract. In this case a normal `ReducerResult` with all empty arrays
384
- * is returned so that callers advance the checkpoint and clear the dirty
385
- * tail, avoiding an infinite retry loop.
386
- *
387
- * Individual invalid operations within an otherwise valid structure are
388
- * silently dropped to preserve the rest of the result.
389
- */
390
- export function parseReducerOutput(raw: string): ReducerResult {
391
- let parsed: unknown;
392
- try {
393
- parsed = JSON.parse(raw);
394
- } catch {
395
- log.warn("reducer output is not valid JSON — falling back to empty result");
396
- return EMPTY_REDUCER_RESULT;
397
- }
398
-
399
- if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
400
- log.warn(
401
- "reducer output is not a JSON object — falling back to empty result",
402
- );
403
- return EMPTY_REDUCER_RESULT;
404
- }
405
-
406
- const obj = parsed as Record<string, unknown>;
407
-
408
- // Check which top-level array keys are present
409
- const hasTimeContexts = Array.isArray(obj.timeContexts);
410
- const hasOpenLoops = Array.isArray(obj.openLoops);
411
- const hasArchiveObservations = Array.isArray(obj.archiveObservations);
412
- const hasArchiveEpisodes = Array.isArray(obj.archiveEpisodes);
413
-
414
- // A valid JSON object with no recognized arrays (e.g. `{}`) means the
415
- // model had nothing to extract — return a normal (non-sentinel) empty
416
- // result so the checkpoint advances.
417
- if (
418
- !hasTimeContexts &&
419
- !hasOpenLoops &&
420
- !hasArchiveObservations &&
421
- !hasArchiveEpisodes
422
- ) {
423
- log.debug(
424
- "reducer output is valid JSON with no extractions — advancing with empty result",
425
- );
426
- return {
427
- timeContexts: [],
428
- openLoops: [],
429
- archiveObservations: [],
430
- archiveEpisodes: [],
431
- };
432
- }
433
-
434
- const timeContexts: TimeContextOp[] = [];
435
- if (hasTimeContexts) {
436
- for (const item of obj.timeContexts as unknown[]) {
437
- const validated = validateTimeContextOp(item);
438
- if (validated) timeContexts.push(validated);
439
- }
440
- }
441
-
442
- const openLoops: OpenLoopOp[] = [];
443
- if (hasOpenLoops) {
444
- for (const item of obj.openLoops as unknown[]) {
445
- const validated = validateOpenLoopOp(item);
446
- if (validated) openLoops.push(validated);
447
- }
448
- }
449
-
450
- const archiveObservations: ArchiveObservationCandidate[] = [];
451
- if (hasArchiveObservations) {
452
- for (const item of obj.archiveObservations as unknown[]) {
453
- const validated = validateArchiveObservation(item);
454
- if (validated) archiveObservations.push(validated);
455
- }
456
- }
457
-
458
- const archiveEpisodes: ArchiveEpisodeCandidate[] = [];
459
- if (hasArchiveEpisodes) {
460
- for (const item of obj.archiveEpisodes as unknown[]) {
461
- const validated = validateArchiveEpisode(item);
462
- if (validated) archiveEpisodes.push(validated);
463
- }
464
- }
465
-
466
- return { timeContexts, openLoops, archiveObservations, archiveEpisodes };
467
- }
@@ -1,121 +0,0 @@
1
- import {
2
- index,
3
- integer,
4
- sqliteTable,
5
- text,
6
- uniqueIndex,
7
- } from "drizzle-orm/sqlite-core";
8
-
9
- import { conversations, messages } from "./conversations.js";
10
-
11
- /**
12
- * Raw observation records captured from conversation turns. Each observation
13
- * is a single factual statement extracted from user or assistant messages,
14
- * annotated with modality and source metadata for downstream recall.
15
- */
16
- export const memoryObservations = sqliteTable(
17
- "memory_observations",
18
- {
19
- id: text("id").primaryKey(),
20
- scopeId: text("scope_id").notNull().default("default"),
21
- conversationId: text("conversation_id")
22
- .notNull()
23
- .references(() => conversations.id, { onDelete: "cascade" }),
24
- messageId: text("message_id").references(() => messages.id, {
25
- onDelete: "set null",
26
- }),
27
- /** The role that produced the observation (e.g. "user", "assistant"). */
28
- role: text("role").notNull(),
29
- /** Free-text statement capturing the observed fact. */
30
- content: text("content").notNull(),
31
- /**
32
- * Modality of the source material: "text", "voice", "image", etc.
33
- * Enables downstream filters for recall relevance.
34
- */
35
- modality: text("modality").notNull().default("text"),
36
- /**
37
- * Source channel or interface that produced the observation
38
- * (e.g. "vellum", "telegram", "phone").
39
- */
40
- source: text("source"),
41
- createdAt: integer("created_at").notNull(),
42
- },
43
- (table) => [
44
- index("idx_memory_observations_scope_id").on(table.scopeId),
45
- index("idx_memory_observations_conversation_id").on(table.conversationId),
46
- index("idx_memory_observations_created_at").on(table.createdAt),
47
- ],
48
- );
49
-
50
- /**
51
- * Deduplicated content chunks derived from observations. Chunks are the unit
52
- * of embedding and recall — each chunk carries a contentHash for idempotent
53
- * dual-write safety so the same content is never stored twice.
54
- */
55
- export const memoryChunks = sqliteTable(
56
- "memory_chunks",
57
- {
58
- id: text("id").primaryKey(),
59
- scopeId: text("scope_id").notNull().default("default"),
60
- observationId: text("observation_id")
61
- .notNull()
62
- .references(() => memoryObservations.id, { onDelete: "cascade" }),
63
- /** The chunk text used for embedding and recall. */
64
- content: text("content").notNull(),
65
- /** Token count estimate for context-window budgeting. */
66
- tokenEstimate: integer("token_estimate").notNull(),
67
- /**
68
- * SHA-256 hash of the normalized content, used to skip duplicate inserts
69
- * during dual-write windows.
70
- */
71
- contentHash: text("content_hash").notNull(),
72
- createdAt: integer("created_at").notNull(),
73
- },
74
- (table) => [
75
- index("idx_memory_chunks_scope_id").on(table.scopeId),
76
- index("idx_memory_chunks_observation_id").on(table.observationId),
77
- uniqueIndex("idx_memory_chunks_content_hash").on(
78
- table.scopeId,
79
- table.contentHash,
80
- ),
81
- index("idx_memory_chunks_created_at").on(table.createdAt),
82
- ],
83
- );
84
-
85
- /**
86
- * Episode records that group related observations into coherent narrative
87
- * units. An episode represents a meaningful interaction or topic span,
88
- * with source-link metadata for provenance tracking.
89
- */
90
- export const memoryEpisodes = sqliteTable(
91
- "memory_episodes",
92
- {
93
- id: text("id").primaryKey(),
94
- scopeId: text("scope_id").notNull().default("default"),
95
- conversationId: text("conversation_id")
96
- .notNull()
97
- .references(() => conversations.id, { onDelete: "cascade" }),
98
- /** Human-readable title summarizing the episode. */
99
- title: text("title").notNull(),
100
- /** Longer narrative summary of the episode content. */
101
- summary: text("summary").notNull(),
102
- /** Token count estimate for the summary. */
103
- tokenEstimate: integer("token_estimate").notNull(),
104
- /**
105
- * Source channel or interface that produced the episode
106
- * (mirrors observation.source for episode-level filtering).
107
- */
108
- source: text("source"),
109
- /** Epoch-ms timestamp of the earliest observation in the episode. */
110
- startAt: integer("start_at").notNull(),
111
- /** Epoch-ms timestamp of the latest observation in the episode. */
112
- endAt: integer("end_at").notNull(),
113
- createdAt: integer("created_at").notNull(),
114
- updatedAt: integer("updated_at").notNull(),
115
- },
116
- (table) => [
117
- index("idx_memory_episodes_scope_id").on(table.scopeId),
118
- index("idx_memory_episodes_conversation_id").on(table.conversationId),
119
- index("idx_memory_episodes_created_at").on(table.createdAt),
120
- ],
121
- );
@@ -1,55 +0,0 @@
1
- import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
2
-
3
- /**
4
- * Time contexts represent bounded temporal windows that are relevant to the
5
- * assistant's current awareness — e.g. "user is traveling next week",
6
- * "quarterly planning period ends Friday". Each row captures one window
7
- * with an activation range and a human-readable summary the brief can surface.
8
- */
9
- export const timeContexts = sqliteTable(
10
- "time_contexts",
11
- {
12
- id: text("id").primaryKey(),
13
- scopeId: text("scope_id").notNull(),
14
- summary: text("summary").notNull(),
15
- source: text("source").notNull(), // e.g. 'conversation', 'schedule', 'manual'
16
- activeFrom: integer("active_from").notNull(), // epoch ms — window start
17
- activeUntil: integer("active_until").notNull(), // epoch ms — window end
18
- createdAt: integer("created_at").notNull(),
19
- updatedAt: integer("updated_at").notNull(),
20
- },
21
- (table) => [
22
- index("idx_time_contexts_scope_active_until").on(
23
- table.scopeId,
24
- table.activeUntil,
25
- ),
26
- ],
27
- );
28
-
29
- /**
30
- * Open loops track unresolved items the assistant should follow up on —
31
- * e.g. "waiting for Bob's reply", "need to file taxes before April 15".
32
- * Each row carries a status and an optional due date so the brief can
33
- * prioritise which loops to surface.
34
- */
35
- export const openLoops = sqliteTable(
36
- "open_loops",
37
- {
38
- id: text("id").primaryKey(),
39
- scopeId: text("scope_id").notNull(),
40
- summary: text("summary").notNull(),
41
- status: text("status").notNull().default("open"), // 'open' | 'resolved' | 'expired'
42
- source: text("source").notNull(), // e.g. 'conversation', 'followup', 'manual'
43
- dueAt: integer("due_at"), // epoch ms — optional deadline
44
- surfacedAt: integer("surfaced_at"), // epoch ms — last time shown in brief
45
- createdAt: integer("created_at").notNull(),
46
- updatedAt: integer("updated_at").notNull(),
47
- },
48
- (table) => [
49
- index("idx_open_loops_scope_status_due").on(
50
- table.scopeId,
51
- table.status,
52
- table.dueAt,
53
- ),
54
- ],
55
- );