@vellumai/assistant 0.5.16 → 0.6.0

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 (407) hide show
  1. package/ARCHITECTURE.md +1 -1
  2. package/Dockerfile +0 -3
  3. package/knip.json +2 -1
  4. package/openapi.yaml +660 -80
  5. package/package.json +1 -1
  6. package/src/__tests__/actor-token-service.test.ts +68 -0
  7. package/src/__tests__/agent-loop.test.ts +0 -32
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  9. package/src/__tests__/anthropic-provider.test.ts +57 -3
  10. package/src/__tests__/app-compiler.test.ts +120 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  12. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  13. package/src/__tests__/call-domain.test.ts +2 -6
  14. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  15. package/src/__tests__/call-recovery.test.ts +2 -6
  16. package/src/__tests__/call-routes-http.test.ts +2 -6
  17. package/src/__tests__/call-store.test.ts +2 -6
  18. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  19. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  20. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  21. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  22. package/src/__tests__/checker.test.ts +25 -3
  23. package/src/__tests__/clawhub.test.ts +54 -24
  24. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  25. package/src/__tests__/cli-memory.test.ts +74 -69
  26. package/src/__tests__/config-schema.test.ts +1 -1
  27. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  28. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  29. package/src/__tests__/contacts-tools.test.ts +31 -0
  30. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  31. package/src/__tests__/context-token-estimator.test.ts +175 -10
  32. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  33. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  34. package/src/__tests__/conversation-attachments.test.ts +2 -6
  35. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  36. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  37. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  38. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  39. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  40. package/src/__tests__/conversation-error.test.ts +33 -2
  41. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  42. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  43. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  44. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  45. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  46. package/src/__tests__/conversation-store.test.ts +2 -6
  47. package/src/__tests__/conversation-usage.test.ts +2 -6
  48. package/src/__tests__/conversation-wipe.test.ts +11 -408
  49. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  50. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  51. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  52. package/src/__tests__/followup-tools.test.ts +2 -6
  53. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  54. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  55. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  56. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  57. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  58. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  59. package/src/__tests__/guardian-action-store.test.ts +2 -6
  60. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  61. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  62. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  63. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  64. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  65. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  66. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  67. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  68. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  69. package/src/__tests__/injection-block.test.ts +154 -0
  70. package/src/__tests__/install-meta.test.ts +506 -0
  71. package/src/__tests__/install-skill-routing.test.ts +292 -0
  72. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  73. package/src/__tests__/invite-routes-http.test.ts +2 -6
  74. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  75. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  76. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  77. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  78. package/src/__tests__/llm-usage-store.test.ts +2 -6
  79. package/src/__tests__/log-export-workspace.test.ts +2 -6
  80. package/src/__tests__/managed-store.test.ts +38 -11
  81. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  82. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  83. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  84. package/src/__tests__/non-member-access-request.test.ts +2 -6
  85. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  86. package/src/__tests__/oauth-cli.test.ts +364 -2
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  88. package/src/__tests__/outlook-attachments.test.ts +301 -0
  89. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  90. package/src/__tests__/outlook-categories.test.ts +212 -0
  91. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  92. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  93. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  94. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  95. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  96. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  97. package/src/__tests__/outlook-trash.test.ts +77 -0
  98. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  99. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  100. package/src/__tests__/playbook-execution.test.ts +76 -80
  101. package/src/__tests__/playbook-tools.test.ts +5 -7
  102. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  103. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  104. package/src/__tests__/registry.test.ts +2 -2
  105. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  106. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  107. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  108. package/src/__tests__/schedule-store.test.ts +2 -6
  109. package/src/__tests__/schedule-tools.test.ts +2 -6
  110. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  111. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  112. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  113. package/src/__tests__/search-skills-unified.test.ts +421 -0
  114. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  115. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  116. package/src/__tests__/sequence-store.test.ts +2 -6
  117. package/src/__tests__/server-history-render.test.ts +2 -6
  118. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  119. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  120. package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
  121. package/src/__tests__/skill-memory.test.ts +140 -98
  122. package/src/__tests__/skills-uninstall.test.ts +2 -2
  123. package/src/__tests__/skills.test.ts +1 -1
  124. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  125. package/src/__tests__/task-compiler.test.ts +2 -6
  126. package/src/__tests__/task-management-tools.test.ts +2 -6
  127. package/src/__tests__/task-memory-cleanup.test.ts +173 -229
  128. package/src/__tests__/task-runner.test.ts +2 -6
  129. package/src/__tests__/task-scheduler.test.ts +2 -6
  130. package/src/__tests__/test-preload.ts +3 -0
  131. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  132. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  133. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  134. package/src/__tests__/trust-store.test.ts +1 -1
  135. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  138. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  139. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  140. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  141. package/src/__tests__/usage-routes.test.ts +2 -6
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  143. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  145. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  146. package/src/__tests__/volume-security-guard.test.ts +2 -0
  147. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  148. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  149. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  150. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  151. package/src/__tests__/workspace-policy.test.ts +1 -1
  152. package/src/agent/attachments.ts +7 -2
  153. package/src/agent/image-optimize.ts +165 -0
  154. package/src/agent/loop.ts +1 -15
  155. package/src/bundler/app-compiler.ts +179 -2
  156. package/src/bundler/package-resolver.ts +3 -5
  157. package/src/cli/__tests__/notifications.test.ts +1 -2
  158. package/src/cli/cli-memory.ts +67 -64
  159. package/src/cli/commands/avatar.ts +3 -3
  160. package/src/cli/commands/config.ts +26 -13
  161. package/src/cli/commands/doctor.ts +2 -2
  162. package/src/cli/commands/memory.ts +41 -55
  163. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  164. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  165. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  166. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  167. package/src/cli/commands/oauth/connect.ts +11 -6
  168. package/src/cli/commands/oauth/mode.ts +7 -0
  169. package/src/cli/commands/oauth/shared.ts +39 -3
  170. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  171. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  172. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  173. package/src/cli/commands/platform/index.ts +16 -16
  174. package/src/cli/commands/skills.ts +88 -16
  175. package/src/cli/commands/trust.ts +2 -2
  176. package/src/cli/lib/daemon-credential-client.ts +2 -3
  177. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  178. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  179. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  180. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  181. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  182. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  183. package/src/config/bundled-skills/messaging/SKILL.md +10 -18
  184. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  185. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  186. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  187. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  188. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  189. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  190. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  191. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  192. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  193. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  194. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  195. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  196. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  197. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  198. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  199. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  200. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  201. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  202. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  203. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  204. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  205. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  206. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  207. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  208. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  209. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  210. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  211. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  212. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  213. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  214. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  215. package/src/config/bundled-tool-registry.ts +56 -4
  216. package/src/config/env-registry.ts +15 -8
  217. package/src/config/feature-flag-registry.json +21 -124
  218. package/src/config/schemas/platform.ts +8 -0
  219. package/src/config/schemas/timeouts.ts +1 -1
  220. package/src/config/skills.ts +18 -7
  221. package/src/context/token-estimator.ts +25 -18
  222. package/src/context/window-manager.ts +6 -2
  223. package/src/credential-execution/process-manager.ts +3 -1
  224. package/src/daemon/context-overflow-reducer.ts +46 -2
  225. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  226. package/src/daemon/conversation-agent-loop.ts +96 -61
  227. package/src/daemon/conversation-error.ts +31 -8
  228. package/src/daemon/conversation-lifecycle.ts +33 -0
  229. package/src/daemon/conversation-media-retry.ts +85 -7
  230. package/src/daemon/conversation-notifiers.ts +4 -1
  231. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  232. package/src/daemon/conversation.ts +41 -2
  233. package/src/daemon/daemon-control.ts +8 -2
  234. package/src/daemon/handlers/shared.ts +22 -12
  235. package/src/daemon/handlers/skills.ts +416 -202
  236. package/src/daemon/lifecycle.ts +40 -1
  237. package/src/daemon/main.ts +5 -1
  238. package/src/daemon/message-types/conversations.ts +4 -1
  239. package/src/daemon/message-types/messages.ts +3 -1
  240. package/src/daemon/message-types/skills.ts +97 -36
  241. package/src/daemon/providers-setup.ts +5 -0
  242. package/src/daemon/server.ts +11 -2
  243. package/src/daemon/tool-side-effects.ts +27 -5
  244. package/src/heartbeat/heartbeat-service.ts +1 -0
  245. package/src/hooks/cli.ts +2 -2
  246. package/src/hooks/runner.ts +15 -38
  247. package/src/inbound/platform-callback-registration.ts +14 -14
  248. package/src/memory/admin.ts +11 -45
  249. package/src/memory/conversation-bootstrap.ts +2 -0
  250. package/src/memory/conversation-crud.ts +242 -348
  251. package/src/memory/conversation-group-migration.ts +157 -0
  252. package/src/memory/conversation-queries.ts +4 -2
  253. package/src/memory/db-init.ts +30 -3
  254. package/src/memory/embed.ts +73 -0
  255. package/src/memory/embedding-backend.ts +8 -14
  256. package/src/memory/embedding-runtime-manager.ts +12 -114
  257. package/src/memory/fingerprint.ts +2 -2
  258. package/src/memory/graph/bootstrap.ts +512 -0
  259. package/src/memory/graph/capability-seed.ts +297 -0
  260. package/src/memory/graph/consolidation.ts +691 -0
  261. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  262. package/src/memory/graph/decay.test.ts +208 -0
  263. package/src/memory/graph/decay.ts +195 -0
  264. package/src/memory/graph/extraction-job.ts +69 -0
  265. package/src/memory/graph/extraction.test.ts +936 -0
  266. package/src/memory/graph/extraction.ts +1254 -0
  267. package/src/memory/graph/graph-search.ts +266 -0
  268. package/src/memory/graph/image-ref-utils.ts +29 -0
  269. package/src/memory/graph/injection.test.ts +513 -0
  270. package/src/memory/graph/injection.ts +439 -0
  271. package/src/memory/graph/inspect.ts +534 -0
  272. package/src/memory/graph/narrative.ts +267 -0
  273. package/src/memory/graph/pattern-scan.ts +269 -0
  274. package/src/memory/graph/retriever.ts +1008 -0
  275. package/src/memory/graph/scoring.test.ts +548 -0
  276. package/src/memory/graph/scoring.ts +232 -0
  277. package/src/memory/graph/serendipity.ts +65 -0
  278. package/src/memory/graph/store.test.ts +1050 -0
  279. package/src/memory/graph/store.ts +699 -0
  280. package/src/memory/graph/tool-handlers.ts +426 -0
  281. package/src/memory/graph/tools.ts +141 -0
  282. package/src/memory/graph/triggers.test.ts +487 -0
  283. package/src/memory/graph/triggers.ts +223 -0
  284. package/src/memory/graph/types.ts +271 -0
  285. package/src/memory/group-crud.ts +191 -0
  286. package/src/memory/indexer.ts +37 -19
  287. package/src/memory/job-handlers/cleanup.ts +0 -53
  288. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  289. package/src/memory/job-handlers/embedding.ts +5 -31
  290. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  291. package/src/memory/job-handlers/summarization.ts +32 -17
  292. package/src/memory/job-utils.ts +1 -1
  293. package/src/memory/jobs-store.ts +50 -70
  294. package/src/memory/jobs-worker.ts +147 -112
  295. package/src/memory/message-content.ts +1 -0
  296. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  297. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  298. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  299. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  300. package/src/memory/migrations/index.ts +4 -0
  301. package/src/memory/migrations/registry.ts +8 -0
  302. package/src/memory/qdrant-client.ts +44 -17
  303. package/src/memory/schema/index.ts +1 -0
  304. package/src/memory/schema/memory-graph.ts +139 -0
  305. package/src/memory/search/semantic.ts +47 -91
  306. package/src/memory/task-memory-cleanup.ts +28 -50
  307. package/src/messaging/providers/outlook/adapter.ts +8 -1
  308. package/src/messaging/providers/outlook/client.ts +299 -0
  309. package/src/messaging/providers/outlook/types.ts +118 -0
  310. package/src/notifications/adapters/macos.ts +1 -0
  311. package/src/notifications/copy-composer.ts +9 -0
  312. package/src/notifications/signal.ts +16 -0
  313. package/src/oauth/seed-providers.ts +2 -1
  314. package/src/permissions/checker.ts +24 -3
  315. package/src/permissions/defaults.ts +4 -4
  316. package/src/permissions/workspace-policy.ts +1 -1
  317. package/src/playbooks/playbook-compiler.ts +19 -18
  318. package/src/playbooks/types.ts +4 -3
  319. package/src/prompts/system-prompt.ts +3 -29
  320. package/src/providers/anthropic/client.ts +47 -19
  321. package/src/providers/gemini/client.ts +1 -1
  322. package/src/providers/openai/client.ts +1 -1
  323. package/src/providers/registry.ts +1 -1
  324. package/src/providers/retry.ts +19 -3
  325. package/src/runtime/actor-trust-resolver.ts +5 -1
  326. package/src/runtime/auth/route-policy.ts +7 -0
  327. package/src/runtime/guardian-reply-router.ts +5 -1
  328. package/src/runtime/http-server.ts +23 -3
  329. package/src/runtime/middleware/auth.ts +20 -0
  330. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  331. package/src/runtime/routes/attachment-routes.ts +106 -16
  332. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  333. package/src/runtime/routes/btw-routes.ts +8 -0
  334. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  335. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  336. package/src/runtime/routes/debug-routes.ts +1 -1
  337. package/src/runtime/routes/global-search-routes.ts +21 -19
  338. package/src/runtime/routes/group-routes.ts +207 -0
  339. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  340. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  341. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  342. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  343. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  344. package/src/runtime/routes/memory-item-routes.test.ts +2 -14
  345. package/src/runtime/routes/memory-item-routes.ts +341 -388
  346. package/src/runtime/routes/schedule-routes.ts +2 -0
  347. package/src/runtime/routes/skills-routes.ts +103 -37
  348. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  349. package/src/schedule/scheduler.ts +8 -1
  350. package/src/security/oauth2.ts +1 -1
  351. package/src/security/secure-keys.ts +4 -8
  352. package/src/shared/provider-env-vars.ts +19 -0
  353. package/src/skills/catalog-cache.ts +5 -0
  354. package/src/skills/catalog-install.ts +15 -14
  355. package/src/skills/clawhub.ts +134 -154
  356. package/src/skills/install-meta.ts +208 -0
  357. package/src/skills/managed-store.ts +27 -16
  358. package/src/skills/skill-memory.ts +152 -77
  359. package/src/skills/skillssh-registry.ts +19 -17
  360. package/src/tasks/task-runner.ts +3 -1
  361. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  362. package/src/tools/browser/runtime-check.ts +3 -1
  363. package/src/tools/memory/register.ts +63 -46
  364. package/src/tools/permission-checker.ts +7 -1
  365. package/src/tools/shared/filesystem/image-read.ts +22 -85
  366. package/src/tools/terminal/safe-env.ts +1 -0
  367. package/src/tools/tool-manifest.ts +3 -3
  368. package/src/util/browser.ts +25 -10
  369. package/src/util/bun-runtime.ts +172 -0
  370. package/src/watcher/providers/outlook-calendar.ts +343 -0
  371. package/src/watcher/providers/outlook.ts +198 -0
  372. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  373. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  374. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  375. package/src/workspace/migrations/registry.ts +6 -0
  376. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  377. package/src/__tests__/journal-context.test.ts +0 -268
  378. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  379. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  380. package/src/__tests__/memory-query-builder.test.ts +0 -59
  381. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  382. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  383. package/src/__tests__/memory-regressions.test.ts +0 -3696
  384. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  385. package/src/daemon/conversation-memory.ts +0 -207
  386. package/src/memory/conversation-starters-cadence.ts +0 -74
  387. package/src/memory/items-extractor.ts +0 -860
  388. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  389. package/src/memory/job-handlers/extraction.ts +0 -40
  390. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  391. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  392. package/src/memory/journal-memory.ts +0 -224
  393. package/src/memory/query-builder.ts +0 -47
  394. package/src/memory/query-expansion.ts +0 -83
  395. package/src/memory/retriever.test.ts +0 -1592
  396. package/src/memory/retriever.ts +0 -1331
  397. package/src/memory/search/formatting.test.ts +0 -140
  398. package/src/memory/search/formatting.ts +0 -262
  399. package/src/memory/search/mmr.ts +0 -139
  400. package/src/memory/search/ranking.ts +0 -15
  401. package/src/memory/search/staleness.ts +0 -40
  402. package/src/memory/search/tier-classifier.ts +0 -18
  403. package/src/memory/search/types.ts +0 -121
  404. package/src/prompts/journal-context.ts +0 -154
  405. package/src/tools/memory/definitions.ts +0 -69
  406. package/src/tools/memory/handlers.test.ts +0 -562
  407. package/src/tools/memory/handlers.ts +0 -434
@@ -0,0 +1,130 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+
4
+ /**
5
+ * Create the memory graph tables: nodes, edges, and triggers.
6
+ *
7
+ * Uses CREATE TABLE IF NOT EXISTS so this is inherently idempotent
8
+ * and does not need a registry entry.
9
+ */
10
+ export function migrateCreateMemoryGraphTables(database: DrizzleDb): void {
11
+ const raw = getSqliteFrom(database);
12
+
13
+ // -- Nodes --
14
+ raw.exec(`
15
+ CREATE TABLE IF NOT EXISTS memory_graph_nodes (
16
+ id TEXT PRIMARY KEY,
17
+ content TEXT NOT NULL,
18
+ type TEXT NOT NULL,
19
+ created INTEGER NOT NULL,
20
+ last_accessed INTEGER NOT NULL,
21
+ last_consolidated INTEGER NOT NULL,
22
+ emotional_charge TEXT NOT NULL,
23
+ fidelity TEXT NOT NULL DEFAULT 'vivid',
24
+ confidence REAL NOT NULL,
25
+ significance REAL NOT NULL,
26
+ stability REAL NOT NULL DEFAULT 14,
27
+ reinforcement_count INTEGER NOT NULL DEFAULT 0,
28
+ last_reinforced INTEGER NOT NULL,
29
+ source_conversations TEXT NOT NULL DEFAULT '[]',
30
+ source_type TEXT NOT NULL DEFAULT 'inferred',
31
+ narrative_role TEXT,
32
+ part_of_story TEXT,
33
+ scope_id TEXT NOT NULL DEFAULT 'default'
34
+ )
35
+ `);
36
+
37
+ // -- Edges --
38
+ raw.exec(`
39
+ CREATE TABLE IF NOT EXISTS memory_graph_edges (
40
+ id TEXT PRIMARY KEY,
41
+ source_node_id TEXT NOT NULL REFERENCES memory_graph_nodes(id) ON DELETE CASCADE,
42
+ target_node_id TEXT NOT NULL REFERENCES memory_graph_nodes(id) ON DELETE CASCADE,
43
+ relationship TEXT NOT NULL,
44
+ weight REAL NOT NULL DEFAULT 1.0,
45
+ created INTEGER NOT NULL
46
+ )
47
+ `);
48
+
49
+ // -- Triggers --
50
+ raw.exec(`
51
+ CREATE TABLE IF NOT EXISTS memory_graph_triggers (
52
+ id TEXT PRIMARY KEY,
53
+ node_id TEXT NOT NULL REFERENCES memory_graph_nodes(id) ON DELETE CASCADE,
54
+ type TEXT NOT NULL,
55
+ schedule TEXT,
56
+ condition TEXT,
57
+ condition_embedding BLOB,
58
+ threshold REAL,
59
+ event_date INTEGER,
60
+ ramp_days INTEGER,
61
+ follow_up_days INTEGER,
62
+ recurring INTEGER NOT NULL DEFAULT 0,
63
+ consumed INTEGER NOT NULL DEFAULT 0,
64
+ cooldown_ms INTEGER,
65
+ last_fired INTEGER
66
+ )
67
+ `);
68
+
69
+ // -- Indexes (IF NOT EXISTS for idempotency) --
70
+ raw.exec(
71
+ `CREATE INDEX IF NOT EXISTS idx_graph_nodes_scope_id ON memory_graph_nodes(scope_id)`,
72
+ );
73
+ raw.exec(
74
+ `CREATE INDEX IF NOT EXISTS idx_graph_nodes_type ON memory_graph_nodes(type)`,
75
+ );
76
+ raw.exec(
77
+ `CREATE INDEX IF NOT EXISTS idx_graph_nodes_fidelity ON memory_graph_nodes(fidelity)`,
78
+ );
79
+ raw.exec(
80
+ `CREATE INDEX IF NOT EXISTS idx_graph_nodes_created ON memory_graph_nodes(created)`,
81
+ );
82
+ raw.exec(
83
+ `CREATE INDEX IF NOT EXISTS idx_graph_nodes_significance ON memory_graph_nodes(significance)`,
84
+ );
85
+ raw.exec(
86
+ `CREATE INDEX IF NOT EXISTS idx_graph_edges_source ON memory_graph_edges(source_node_id)`,
87
+ );
88
+ raw.exec(
89
+ `CREATE INDEX IF NOT EXISTS idx_graph_edges_target ON memory_graph_edges(target_node_id)`,
90
+ );
91
+ raw.exec(
92
+ `CREATE INDEX IF NOT EXISTS idx_graph_triggers_node_id ON memory_graph_triggers(node_id)`,
93
+ );
94
+ raw.exec(
95
+ `CREATE INDEX IF NOT EXISTS idx_graph_triggers_type ON memory_graph_triggers(type)`,
96
+ );
97
+
98
+ // -- Add event_date column to nodes (idempotent) --
99
+ try {
100
+ raw.exec(
101
+ `ALTER TABLE memory_graph_nodes ADD COLUMN event_date INTEGER`,
102
+ );
103
+ } catch {
104
+ // Column already exists — safe to ignore.
105
+ }
106
+
107
+ raw.exec(
108
+ `CREATE INDEX IF NOT EXISTS idx_graph_nodes_event_date ON memory_graph_nodes(event_date)`,
109
+ );
110
+
111
+ // -- Backfill event_date from existing event triggers --
112
+ raw.exec(`
113
+ UPDATE memory_graph_nodes
114
+ SET event_date = (
115
+ SELECT t.event_date
116
+ FROM memory_graph_triggers t
117
+ WHERE t.node_id = memory_graph_nodes.id
118
+ AND t.type = 'event'
119
+ AND t.event_date IS NOT NULL
120
+ LIMIT 1
121
+ )
122
+ WHERE event_date IS NULL
123
+ AND id IN (
124
+ SELECT t2.node_id
125
+ FROM memory_graph_triggers t2
126
+ WHERE t2.type = 'event'
127
+ AND t2.event_date IS NOT NULL
128
+ )
129
+ `);
130
+ }
@@ -0,0 +1,23 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+
4
+ /**
5
+ * Drop the legacy memory_items and memory_item_sources tables.
6
+ *
7
+ * All consumers have been migrated to memory_graph_nodes (#22698).
8
+ * These tables are now dead weight.
9
+ */
10
+ export function migrateDropMemoryItemsTables(database: DrizzleDb): void {
11
+ const raw = getSqliteFrom(database);
12
+
13
+ // Drop indexes first (idempotent — IF EXISTS).
14
+ raw.exec(
15
+ /*sql*/ `DROP INDEX IF EXISTS idx_memory_item_sources_memory_item_id`
16
+ );
17
+ raw.exec(/*sql*/ `DROP INDEX IF EXISTS idx_memory_items_scope_id`);
18
+ raw.exec(/*sql*/ `DROP INDEX IF EXISTS idx_memory_items_fingerprint`);
19
+
20
+ // Drop tables (idempotent — IF EXISTS). Child table first.
21
+ raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_item_sources`);
22
+ raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_items`);
23
+ }
@@ -0,0 +1,46 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ /**
6
+ * One-shot migration: rename legacy memory graph node type values.
7
+ *
8
+ * The PR that introduced the memory graph used "style" and "relationship"
9
+ * as type values. These were renamed to "behavioral" and "semantic" in
10
+ * code, but existing rows in the database still carry the old values.
11
+ */
12
+ export function migrateRenameMemoryGraphTypeValues(database: DrizzleDb): void {
13
+ withCrashRecovery(
14
+ database,
15
+ "migration_rename_memory_graph_type_values_v1",
16
+ () => {
17
+ const raw = getSqliteFrom(database);
18
+ raw
19
+ .prepare(
20
+ /*sql*/ `UPDATE memory_graph_nodes SET type = 'behavioral' WHERE type = 'style'`,
21
+ )
22
+ .run();
23
+ raw
24
+ .prepare(
25
+ /*sql*/ `UPDATE memory_graph_nodes SET type = 'semantic' WHERE type = 'relationship'`,
26
+ )
27
+ .run();
28
+ },
29
+ );
30
+ }
31
+
32
+ /**
33
+ * Reverse: no-op.
34
+ *
35
+ * A blanket revert (`behavioral` → `style`, `semantic` → `relationship`) is
36
+ * unsafe because normal runtime may have created new `behavioral` / `semantic`
37
+ * nodes after the forward migration ran. Those nodes were never `style` /
38
+ * `relationship` and reverting them would corrupt data. Since the forward
39
+ * migration is idempotent and the old type values are no longer referenced in
40
+ * code, a no-op rollback is the safest option.
41
+ */
42
+ export function migrateRenameMemoryGraphTypeValuesDown(
43
+ _database: DrizzleDb,
44
+ ): void {
45
+ // intentional no-op — see comment above
46
+ }
@@ -0,0 +1,11 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+
4
+ export function migrateMemoryGraphImageRefs(database: DrizzleDb): void {
5
+ const raw = getSqliteFrom(database);
6
+ try {
7
+ raw.exec(`ALTER TABLE memory_graph_nodes ADD COLUMN image_refs TEXT`);
8
+ } catch {
9
+ // Column already exists — idempotent
10
+ }
11
+ }
@@ -142,6 +142,10 @@ export { migrateGuardianRequestEnrichmentColumns } from "./199-guardian-request-
142
142
  export { migrateUsageLlmCallCount } from "./200-usage-llm-call-count.js";
143
143
  export { migrateOAuthProvidersFeatureFlag } from "./201-oauth-providers-feature-flag.js";
144
144
  export { migrateDropCallbackTransportColumn } from "./202-drop-callback-transport-column.js";
145
+ export { migrateCreateMemoryGraphTables } from "./202-memory-graph-tables.js";
146
+ export { migrateDropMemoryItemsTables } from "./203-drop-memory-items-tables.js";
147
+ export { migrateRenameMemoryGraphTypeValues } from "./204-rename-memory-graph-type-values.js";
148
+ export { migrateMemoryGraphImageRefs } from "./205-memory-graph-image-refs.js";
145
149
  export {
146
150
  MIGRATION_REGISTRY,
147
151
  type MigrationRegistryEntry,
@@ -39,6 +39,7 @@ import { migrateRenameThreadStartersCheckpointsDown } from "./181-rename-thread-
39
39
  import { migrateBackfillAudioAttachmentMimeTypesDown } from "./191-backfill-audio-attachment-mime-types.js";
40
40
  import { migrateAddSourceTypeColumnsDown } from "./193-add-source-type-columns.js";
41
41
  import { migrateStripIntegrationPrefixFromProviderKeysDown } from "./196-strip-integration-prefix-from-provider-keys.js";
42
+ import { migrateRenameMemoryGraphTypeValuesDown } from "./204-rename-memory-graph-type-values.js";
42
43
 
43
44
  export interface MigrationRegistryEntry {
44
45
  /** The checkpoint key written to memory_checkpoints on completion. */
@@ -341,6 +342,13 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
341
342
  "Strip integration: prefix from provider_key across oauth_providers, oauth_apps, and oauth_connections",
342
343
  down: migrateStripIntegrationPrefixFromProviderKeysDown,
343
344
  },
345
+ {
346
+ key: "migration_rename_memory_graph_type_values_v1",
347
+ version: 39,
348
+ description:
349
+ "Rename legacy memory graph node type values: style → behavioral, relationship → semantic",
350
+ down: migrateRenameMemoryGraphTypeValuesDown,
351
+ },
344
352
  ];
345
353
 
346
354
  export function getMaxMigrationVersion(): number {
@@ -20,7 +20,7 @@ export interface QdrantClientConfig {
20
20
  }
21
21
 
22
22
  export interface QdrantPointPayload {
23
- target_type: "segment" | "item" | "summary" | "media";
23
+ target_type: "segment" | "item" | "summary" | "media" | "graph_node";
24
24
  target_id: string;
25
25
  text: string;
26
26
  kind?: string;
@@ -47,14 +47,14 @@ let _instance: VellumQdrantClient | null = null;
47
47
  export function getQdrantClient(): VellumQdrantClient {
48
48
  if (!_instance) {
49
49
  throw new Error(
50
- "Qdrant client not initialized. Call initQdrantClient() first.",
50
+ "Qdrant client not initialized. Call initQdrantClient() first."
51
51
  );
52
52
  }
53
53
  return _instance;
54
54
  }
55
55
 
56
56
  export function initQdrantClient(
57
- config: QdrantClientConfig,
57
+ config: QdrantClientConfig
58
58
  ): VellumQdrantClient {
59
59
  _instance = new VellumQdrantClient(config);
60
60
  return _instance;
@@ -125,7 +125,7 @@ export class VellumQdrantClient {
125
125
  currentSize,
126
126
  expectedSize: this.vectorSize,
127
127
  },
128
- "Qdrant collection uses unnamed vectors (legacy) — deleting and recreating with named vectors. Embeddings will be re-indexed.",
128
+ "Qdrant collection uses unnamed vectors (legacy) — deleting and recreating with named vectors. Embeddings will be re-indexed."
129
129
  );
130
130
  await this.client.deleteCollection(this.collection);
131
131
  migrated = true;
@@ -138,7 +138,7 @@ export class VellumQdrantClient {
138
138
  expectedSize: this.vectorSize,
139
139
  modelMismatch,
140
140
  },
141
- "Qdrant collection incompatible (dimension or model change) — deleting and recreating. Embeddings will be regenerated on demand.",
141
+ "Qdrant collection incompatible (dimension or model change) — deleting and recreating. Embeddings will be regenerated on demand."
142
142
  );
143
143
  await this.client.deleteCollection(this.collection);
144
144
  migrated = true;
@@ -152,7 +152,7 @@ export class VellumQdrantClient {
152
152
  } catch (err) {
153
153
  log.warn(
154
154
  { err },
155
- "Failed to verify collection compatibility, assuming compatible",
155
+ "Failed to verify collection compatibility, assuming compatible"
156
156
  );
157
157
  if (await this.ensurePayloadIndexesSafe()) {
158
158
  this.collectionReady = true;
@@ -166,7 +166,7 @@ export class VellumQdrantClient {
166
166
 
167
167
  log.info(
168
168
  { collection: this.collection, vectorSize: this.vectorSize },
169
- "Creating Qdrant collection with named vectors (dense + sparse)",
169
+ "Creating Qdrant collection with named vectors (dense + sparse)"
170
170
  );
171
171
 
172
172
  try {
@@ -222,7 +222,7 @@ export class VellumQdrantClient {
222
222
  this.collectionReady = true;
223
223
  log.info(
224
224
  { collection: this.collection },
225
- "Qdrant collection created with payload indexes",
225
+ "Qdrant collection created with payload indexes"
226
226
  );
227
227
  }
228
228
 
@@ -230,11 +230,11 @@ export class VellumQdrantClient {
230
230
  }
231
231
 
232
232
  async upsert(
233
- targetType: "segment" | "item" | "summary" | "media",
233
+ targetType: QdrantPointPayload["target_type"],
234
234
  targetId: string,
235
235
  vector: number[],
236
236
  payload: Omit<QdrantPointPayload, "target_type" | "target_id">,
237
- sparseVector?: QdrantSparseVector,
237
+ sparseVector?: QdrantSparseVector
238
238
  ): Promise<string> {
239
239
  await this.ensureCollection();
240
240
 
@@ -289,7 +289,7 @@ export class VellumQdrantClient {
289
289
  async search(
290
290
  vector: number[],
291
291
  limit: number,
292
- filter?: Record<string, unknown>,
292
+ filter?: Record<string, unknown>
293
293
  ): Promise<QdrantSearchResult[]> {
294
294
  await this.ensureCollection();
295
295
 
@@ -317,7 +317,7 @@ export class VellumQdrantClient {
317
317
  return results.map((result) => ({
318
318
  id: typeof result.id === "string" ? result.id : String(result.id),
319
319
  score: result.score,
320
- payload: result.payload as unknown as QdrantPointPayload,
320
+ payload: (result.payload as unknown) as QdrantPointPayload,
321
321
  }));
322
322
  }
323
323
 
@@ -326,7 +326,7 @@ export class VellumQdrantClient {
326
326
  limit: number,
327
327
  targetTypes: Array<"segment" | "item" | "summary" | "media">,
328
328
  excludeMessageIds?: string[],
329
- scopeIds?: string[],
329
+ scopeIds?: string[]
330
330
  ): Promise<QdrantSearchResult[]> {
331
331
  const mustConditions: Array<Record<string, unknown>> = [
332
332
  {
@@ -403,7 +403,7 @@ export class VellumQdrantClient {
403
403
  const queryParams = {
404
404
  prefetch: [
405
405
  {
406
- query: denseVector as unknown as number[],
406
+ query: (denseVector as unknown) as number[],
407
407
  using: "dense",
408
408
  limit: effectivePrefetchLimit,
409
409
  },
@@ -438,7 +438,7 @@ export class VellumQdrantClient {
438
438
  return (results.points ?? []).map((point) => ({
439
439
  id: typeof point.id === "string" ? point.id : String(point.id),
440
440
  score: point.score ?? 0,
441
- payload: point.payload as unknown as QdrantPointPayload,
441
+ payload: (point.payload as unknown) as QdrantPointPayload,
442
442
  }));
443
443
  }
444
444
 
@@ -469,6 +469,33 @@ export class VellumQdrantClient {
469
469
  }
470
470
  }
471
471
 
472
+ /**
473
+ * Delete all vectors matching a given target_type (bulk cleanup).
474
+ */
475
+ async deleteByTargetType(targetType: string): Promise<void> {
476
+ await this.ensureCollection();
477
+
478
+ const doDelete = () =>
479
+ this.client.delete(this.collection, {
480
+ wait: true,
481
+ filter: {
482
+ must: [{ key: "target_type", match: { value: targetType } }],
483
+ },
484
+ });
485
+
486
+ try {
487
+ await doDelete();
488
+ } catch (err) {
489
+ if (this.isCollectionMissing(err)) {
490
+ this.collectionReady = false;
491
+ await this.ensureCollection();
492
+ await doDelete();
493
+ } else {
494
+ throw err;
495
+ }
496
+ }
497
+ }
498
+
472
499
  async count(): Promise<number> {
473
500
  await this.ensureCollection();
474
501
 
@@ -498,7 +525,7 @@ export class VellumQdrantClient {
498
525
  } catch (err) {
499
526
  log.warn(
500
527
  { err, collection: this.collection },
501
- "Failed to delete Qdrant collection",
528
+ "Failed to delete Qdrant collection"
502
529
  );
503
530
  return false;
504
531
  }
@@ -615,7 +642,7 @@ export class VellumQdrantClient {
615
642
 
616
643
  private async findByTarget(
617
644
  targetType: string,
618
- targetId: string,
645
+ targetId: string
619
646
  ): Promise<string | null> {
620
647
  try {
621
648
  const results = await this.client.scroll(this.collection, {
@@ -4,6 +4,7 @@ export * from "./conversations.js";
4
4
  export * from "./guardian.js";
5
5
  export * from "./infrastructure.js";
6
6
  export * from "./memory-core.js";
7
+ export * from "./memory-graph.js";
7
8
  export * from "./notifications.js";
8
9
  export * from "./oauth.js";
9
10
  export * from "./tasks.js";
@@ -0,0 +1,139 @@
1
+ import {
2
+ blob,
3
+ index,
4
+ integer,
5
+ real,
6
+ sqliteTable,
7
+ text,
8
+ } from "drizzle-orm/sqlite-core";
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // Memory Graph — Drizzle ORM schema
12
+ // ---------------------------------------------------------------------------
13
+
14
+ export const memoryGraphNodes = sqliteTable(
15
+ "memory_graph_nodes",
16
+ {
17
+ id: text("id").primaryKey(),
18
+
19
+ /** First-person prose — how the assistant naturally remembers this. */
20
+ content: text("content").notNull(),
21
+ /** Memory type: episodic, semantic, procedural, emotional, prospective, behavioral, narrative, shared. */
22
+ type: text("type").notNull(),
23
+
24
+ // -- Temporal --
25
+ /** Epoch ms. Hour/dayOfWeek/month derived at query time via Date. */
26
+ created: integer("created").notNull(),
27
+ /** Epoch ms. Decay-rate modifier only — NOT a retrieval signal. */
28
+ lastAccessed: integer("last_accessed").notNull(),
29
+ /** Epoch ms of last consolidation pass. */
30
+ lastConsolidated: integer("last_consolidated").notNull(),
31
+ /** Epoch ms of the event this memory describes (null for non-event memories). */
32
+ eventDate: integer("event_date"),
33
+
34
+ // -- Energy --
35
+ /** JSON-serialized EmotionalCharge object. Read/written atomically. */
36
+ emotionalCharge: text("emotional_charge").notNull(),
37
+ /** vivid | clear | faded | gist | gone */
38
+ fidelity: text("fidelity").notNull().default("vivid"),
39
+ /** 0–1. How sure the assistant is this is accurate. */
40
+ confidence: real("confidence").notNull(),
41
+ /** 0–1. How important. Subject to Ebbinghaus decay. */
42
+ significance: real("significance").notNull(),
43
+
44
+ // -- Reinforcement --
45
+ /** Resistance to decay. Grows ×1.5 per reinforcement. */
46
+ stability: real("stability").notNull().default(14),
47
+ /** How many times confirmed/reinforced. */
48
+ reinforcementCount: integer("reinforcement_count").notNull().default(0),
49
+ /** Epoch ms. */
50
+ lastReinforced: integer("last_reinforced").notNull(),
51
+
52
+ // -- Provenance --
53
+ /** JSON array of conversation IDs. */
54
+ sourceConversations: text("source_conversations").notNull().default("[]"),
55
+ /** direct | inferred | observed | told-by-other */
56
+ sourceType: text("source_type").notNull().default("inferred"),
57
+
58
+ // -- Narrative --
59
+ narrativeRole: text("narrative_role"),
60
+ partOfStory: text("part_of_story"),
61
+
62
+ /** Memory scope for multi-scope isolation. */
63
+ scopeId: text("scope_id").notNull().default("default"),
64
+
65
+ /** JSON array of ImageRef objects — images attached to this memory. */
66
+ imageRefs: text("image_refs"),
67
+ },
68
+ (table) => [
69
+ index("idx_graph_nodes_scope_id").on(table.scopeId),
70
+ index("idx_graph_nodes_type").on(table.type),
71
+ index("idx_graph_nodes_fidelity").on(table.fidelity),
72
+ index("idx_graph_nodes_created").on(table.created),
73
+ index("idx_graph_nodes_significance").on(table.significance),
74
+ index("idx_graph_nodes_event_date").on(table.eventDate),
75
+ ],
76
+ );
77
+
78
+ export const memoryGraphEdges = sqliteTable(
79
+ "memory_graph_edges",
80
+ {
81
+ id: text("id").primaryKey(),
82
+ sourceNodeId: text("source_node_id")
83
+ .notNull()
84
+ .references(() => memoryGraphNodes.id, { onDelete: "cascade" }),
85
+ targetNodeId: text("target_node_id")
86
+ .notNull()
87
+ .references(() => memoryGraphNodes.id, { onDelete: "cascade" }),
88
+ /** caused-by | reminds-of | contradicts | depends-on | part-of | supersedes | resolved-by */
89
+ relationship: text("relationship").notNull(),
90
+ /** Connection strength 0–1. */
91
+ weight: real("weight").notNull().default(1.0),
92
+ /** Epoch ms. */
93
+ created: integer("created").notNull(),
94
+ },
95
+ (table) => [
96
+ index("idx_graph_edges_source").on(table.sourceNodeId),
97
+ index("idx_graph_edges_target").on(table.targetNodeId),
98
+ ],
99
+ );
100
+
101
+ export const memoryGraphTriggers = sqliteTable(
102
+ "memory_graph_triggers",
103
+ {
104
+ id: text("id").primaryKey(),
105
+ nodeId: text("node_id")
106
+ .notNull()
107
+ .references(() => memoryGraphNodes.id, { onDelete: "cascade" }),
108
+ /** temporal | semantic | event */
109
+ type: text("type").notNull(),
110
+
111
+ // -- Temporal --
112
+ schedule: text("schedule"),
113
+
114
+ // -- Semantic --
115
+ condition: text("condition"),
116
+ /** Pre-computed embedding stored as binary blob. */
117
+ conditionEmbedding: blob("condition_embedding"),
118
+ /** Cosine similarity threshold (0–1). */
119
+ threshold: real("threshold"),
120
+
121
+ // -- Event --
122
+ /** Epoch ms of the event date. */
123
+ eventDate: integer("event_date"),
124
+ rampDays: integer("ramp_days"),
125
+ followUpDays: integer("follow_up_days"),
126
+
127
+ // -- State --
128
+ recurring: integer("recurring", { mode: "boolean" })
129
+ .notNull()
130
+ .default(false),
131
+ consumed: integer("consumed", { mode: "boolean" }).notNull().default(false),
132
+ cooldownMs: integer("cooldown_ms"),
133
+ lastFired: integer("last_fired"),
134
+ },
135
+ (table) => [
136
+ index("idx_graph_triggers_node_id").on(table.nodeId),
137
+ index("idx_graph_triggers_type").on(table.type),
138
+ ],
139
+ );