@vellumai/assistant 0.5.16 → 0.6.1

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 (592) hide show
  1. package/AGENTS.md +4 -0
  2. package/ARCHITECTURE.md +69 -16
  3. package/Dockerfile +2 -5
  4. package/bun.lock +6 -2
  5. package/docker-entrypoint.sh +32 -1
  6. package/docs/architecture/integrations.md +1 -1
  7. package/docs/architecture/memory.md +21 -24
  8. package/knip.json +2 -1
  9. package/openapi.yaml +1198 -83
  10. package/package.json +5 -1
  11. package/src/__tests__/actor-token-service.test.ts +68 -0
  12. package/src/__tests__/agent-loop.test.ts +0 -32
  13. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  14. package/src/__tests__/anthropic-provider.test.ts +217 -98
  15. package/src/__tests__/app-compiler.test.ts +120 -0
  16. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  17. package/src/__tests__/app-executors.test.ts +47 -1
  18. package/src/__tests__/app-source-watcher.test.ts +159 -0
  19. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  20. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  21. package/src/__tests__/call-domain.test.ts +2 -6
  22. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  23. package/src/__tests__/call-recovery.test.ts +2 -6
  24. package/src/__tests__/call-routes-http.test.ts +2 -6
  25. package/src/__tests__/call-store.test.ts +2 -6
  26. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  27. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  28. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  29. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  30. package/src/__tests__/checker.test.ts +63 -9
  31. package/src/__tests__/clawhub.test.ts +54 -24
  32. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  33. package/src/__tests__/config-schema.test.ts +6 -1
  34. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  35. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  36. package/src/__tests__/contacts-tools.test.ts +31 -0
  37. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  38. package/src/__tests__/context-token-estimator.test.ts +175 -10
  39. package/src/__tests__/conversation-agent-loop-overflow.test.ts +13 -6
  40. package/src/__tests__/conversation-agent-loop.test.ts +13 -51
  41. package/src/__tests__/conversation-attachments.test.ts +2 -6
  42. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  43. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  44. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  45. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  46. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  47. package/src/__tests__/conversation-error.test.ts +33 -2
  48. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  49. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  50. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  52. package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
  53. package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
  54. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  55. package/src/__tests__/conversation-store.test.ts +2 -6
  56. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
  57. package/src/__tests__/conversation-usage.test.ts +2 -6
  58. package/src/__tests__/conversation-wipe.test.ts +13 -414
  59. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
  60. package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
  61. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  62. package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
  63. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  64. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  65. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  66. package/src/__tests__/date-context.test.ts +76 -210
  67. package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
  68. package/src/__tests__/file-list-tool.test.ts +219 -0
  69. package/src/__tests__/first-greeting.test.ts +1 -1
  70. package/src/__tests__/followup-tools.test.ts +2 -6
  71. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  72. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  73. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  74. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  75. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  76. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  77. package/src/__tests__/guardian-action-store.test.ts +2 -6
  78. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  79. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  80. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  81. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  82. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  83. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  84. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  85. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  86. package/src/__tests__/heartbeat-service.test.ts +180 -3
  87. package/src/__tests__/identity-routes.test.ts +328 -0
  88. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  89. package/src/__tests__/injection-block.test.ts +178 -0
  90. package/src/__tests__/install-meta.test.ts +506 -0
  91. package/src/__tests__/install-skill-routing.test.ts +293 -0
  92. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  93. package/src/__tests__/invite-routes-http.test.ts +2 -6
  94. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +17 -28
  95. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  96. package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
  97. package/src/__tests__/llm-context-normalization.test.ts +18 -18
  98. package/src/__tests__/llm-context-route-provider.test.ts +103 -6
  99. package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
  100. package/src/__tests__/llm-usage-store.test.ts +2 -6
  101. package/src/__tests__/log-export-workspace.test.ts +74 -111
  102. package/src/__tests__/managed-store.test.ts +38 -11
  103. package/src/__tests__/mcp-abort-signal.test.ts +5 -0
  104. package/src/__tests__/mcp-client-auth.test.ts +5 -0
  105. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  106. package/src/__tests__/memory-recall-log-store.test.ts +134 -6
  107. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  108. package/src/__tests__/migration-export-streaming.test.ts +304 -0
  109. package/src/__tests__/migration-import-commit-http.test.ts +11 -10
  110. package/src/__tests__/mock-fetch.ts +87 -0
  111. package/src/__tests__/non-member-access-request.test.ts +2 -6
  112. package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
  113. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  114. package/src/__tests__/oauth-cli.test.ts +364 -2
  115. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  116. package/src/__tests__/onboarding-template-contract.test.ts +62 -14
  117. package/src/__tests__/outlook-attachments.test.ts +301 -0
  118. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  119. package/src/__tests__/outlook-categories.test.ts +212 -0
  120. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  121. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  122. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  123. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  124. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  125. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  126. package/src/__tests__/outlook-trash.test.ts +77 -0
  127. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  128. package/src/__tests__/parser.test.ts +32 -0
  129. package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
  130. package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
  131. package/src/__tests__/permission-mode-sse.test.ts +418 -0
  132. package/src/__tests__/permission-mode-store.test.ts +277 -0
  133. package/src/__tests__/permission-mode.test.ts +101 -0
  134. package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
  135. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  136. package/src/__tests__/playbook-execution.test.ts +76 -80
  137. package/src/__tests__/playbook-tools.test.ts +5 -7
  138. package/src/__tests__/profiler-routes.test.ts +502 -0
  139. package/src/__tests__/profiler-run-store.test.ts +441 -0
  140. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  141. package/src/__tests__/proxy-approval-callback.test.ts +4 -75
  142. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  143. package/src/__tests__/registry.test.ts +3 -3
  144. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  145. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  146. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  147. package/src/__tests__/sandbox-host-parity.test.ts +5 -4
  148. package/src/__tests__/schedule-store.test.ts +2 -6
  149. package/src/__tests__/schedule-tools.test.ts +2 -6
  150. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  151. package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
  152. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  153. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  154. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
  155. package/src/__tests__/search-skills-unified.test.ts +422 -0
  156. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  157. package/src/__tests__/send-endpoint-busy.test.ts +44 -9
  158. package/src/__tests__/sequence-store.test.ts +2 -6
  159. package/src/__tests__/server-history-render.test.ts +2 -6
  160. package/src/__tests__/set-permission-mode.test.ts +274 -0
  161. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  162. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  163. package/src/__tests__/skill-load-feature-flag.test.ts +23 -11
  164. package/src/__tests__/skill-memory.test.ts +2 -741
  165. package/src/__tests__/skills-uninstall.test.ts +2 -2
  166. package/src/__tests__/skills.test.ts +1 -1
  167. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  168. package/src/__tests__/strip-memory-injections.test.ts +187 -0
  169. package/src/__tests__/subagent-detail.test.ts +84 -0
  170. package/src/__tests__/subagent-disposal.test.ts +308 -0
  171. package/src/__tests__/subagent-manager-notify.test.ts +19 -10
  172. package/src/__tests__/subagent-notify-parent.test.ts +390 -0
  173. package/src/__tests__/subagent-role-registry.test.ts +108 -0
  174. package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
  175. package/src/__tests__/subagent-tools.test.ts +464 -4
  176. package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
  177. package/src/__tests__/task-compiler.test.ts +2 -6
  178. package/src/__tests__/task-management-tools.test.ts +2 -6
  179. package/src/__tests__/task-memory-cleanup.test.ts +185 -241
  180. package/src/__tests__/task-runner.test.ts +2 -6
  181. package/src/__tests__/task-scheduler.test.ts +2 -6
  182. package/src/__tests__/terminal-tools.test.ts +17 -27
  183. package/src/__tests__/test-preload.ts +7 -0
  184. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  185. package/src/__tests__/tool-executor.test.ts +4 -26
  186. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  187. package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
  188. package/src/__tests__/top-level-renderer.test.ts +10 -13
  189. package/src/__tests__/trust-store.test.ts +1 -1
  190. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  191. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
  192. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  193. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  194. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  195. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  196. package/src/__tests__/usage-routes.test.ts +2 -6
  197. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  198. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  199. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  200. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  201. package/src/__tests__/volume-security-guard.test.ts +2 -0
  202. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  203. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  204. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  205. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  206. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
  207. package/src/__tests__/workspace-policy.test.ts +1 -1
  208. package/src/agent/attachments.ts +7 -2
  209. package/src/agent/image-optimize.ts +165 -0
  210. package/src/agent/loop.ts +7 -15
  211. package/src/approvals/guardian-request-resolvers.ts +24 -0
  212. package/src/avatar/traits-png-sync.ts +3 -3
  213. package/src/bundler/app-compiler.ts +179 -2
  214. package/src/bundler/package-resolver.ts +3 -5
  215. package/src/cli/__tests__/notifications.test.ts +1 -2
  216. package/src/cli/__tests__/run-assistant-command.ts +29 -0
  217. package/src/cli/commands/__tests__/email-download.test.ts +245 -0
  218. package/src/cli/commands/__tests__/email-list.test.ts +192 -0
  219. package/src/cli/commands/__tests__/email-register.test.ts +186 -0
  220. package/src/cli/commands/__tests__/email-send.test.ts +291 -0
  221. package/src/cli/commands/__tests__/email-status.test.ts +181 -0
  222. package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
  223. package/src/cli/commands/__tests__/routes.test.ts +562 -0
  224. package/src/cli/commands/avatar.ts +3 -3
  225. package/src/cli/commands/config.ts +26 -13
  226. package/src/cli/commands/conversations.ts +1 -8
  227. package/src/cli/commands/doctor.ts +2 -2
  228. package/src/cli/commands/email.ts +584 -835
  229. package/src/cli/commands/memory.ts +37 -84
  230. package/src/cli/commands/notifications.ts +7 -2
  231. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  232. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  233. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  234. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  235. package/src/cli/commands/oauth/connect.ts +25 -11
  236. package/src/cli/commands/oauth/mode.ts +7 -0
  237. package/src/cli/commands/oauth/shared.ts +39 -3
  238. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  239. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  240. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  241. package/src/cli/commands/platform/index.ts +16 -16
  242. package/src/cli/commands/routes.ts +396 -0
  243. package/src/cli/commands/skills.ts +218 -36
  244. package/src/cli/commands/trust.ts +2 -2
  245. package/src/cli/lib/daemon-credential-client.ts +2 -3
  246. package/src/cli/program.ts +2 -0
  247. package/src/cli.ts +1 -120
  248. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  249. package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
  250. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  251. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  252. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  253. package/src/config/bundled-skills/gmail/SKILL.md +4 -12
  254. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  255. package/src/config/bundled-skills/messaging/SKILL.md +17 -18
  256. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  257. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  258. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  259. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  260. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  261. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  262. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  263. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  264. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  265. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  266. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  267. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  268. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  269. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  270. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  271. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  272. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  273. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  274. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  275. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  276. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  277. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  278. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  279. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  280. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  281. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  282. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  283. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  284. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  285. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  286. package/src/config/bundled-skills/schedule/SKILL.md +22 -2
  287. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  288. package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
  289. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
  290. package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
  291. package/src/config/bundled-skills/slack/SKILL.md +3 -7
  292. package/src/config/bundled-skills/subagent/SKILL.md +43 -3
  293. package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
  294. package/src/config/bundled-tool-registry.ts +56 -4
  295. package/src/config/env-registry.ts +78 -8
  296. package/src/config/feature-flag-registry.json +38 -125
  297. package/src/config/schema.ts +8 -0
  298. package/src/config/schemas/filing.ts +51 -0
  299. package/src/config/schemas/heartbeat.ts +15 -12
  300. package/src/config/schemas/memory-lifecycle.ts +12 -0
  301. package/src/config/schemas/platform.ts +8 -0
  302. package/src/config/schemas/security.ts +14 -0
  303. package/src/config/schemas/timeouts.ts +1 -1
  304. package/src/config/skills.ts +18 -7
  305. package/src/context/token-estimator.ts +25 -18
  306. package/src/context/window-manager.ts +6 -2
  307. package/src/credential-execution/process-manager.ts +3 -1
  308. package/src/daemon/app-source-watcher.ts +93 -0
  309. package/src/daemon/config-watcher.ts +79 -1
  310. package/src/daemon/context-overflow-reducer.ts +46 -2
  311. package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
  312. package/src/daemon/conversation-agent-loop.ts +236 -108
  313. package/src/daemon/conversation-error.ts +31 -8
  314. package/src/daemon/conversation-history.ts +4 -19
  315. package/src/daemon/conversation-lifecycle.ts +36 -9
  316. package/src/daemon/conversation-media-retry.ts +85 -7
  317. package/src/daemon/conversation-notifiers.ts +4 -1
  318. package/src/daemon/conversation-process.ts +13 -7
  319. package/src/daemon/conversation-runtime-assembly.ts +305 -306
  320. package/src/daemon/conversation-tool-setup.ts +44 -14
  321. package/src/daemon/conversation-workspace.ts +1 -2
  322. package/src/daemon/conversation.ts +59 -2
  323. package/src/daemon/daemon-control.ts +8 -2
  324. package/src/daemon/date-context.ts +26 -53
  325. package/src/daemon/first-greeting.ts +1 -1
  326. package/src/daemon/handlers/conversations.ts +4 -7
  327. package/src/daemon/handlers/shared.test.ts +143 -0
  328. package/src/daemon/handlers/shared.ts +85 -17
  329. package/src/daemon/handlers/skills.ts +416 -209
  330. package/src/daemon/lifecycle.ts +212 -131
  331. package/src/daemon/main.ts +5 -1
  332. package/src/daemon/message-types/conversations.ts +29 -7
  333. package/src/daemon/message-types/messages.ts +12 -2
  334. package/src/daemon/message-types/schedules.ts +1 -0
  335. package/src/daemon/message-types/settings.ts +6 -0
  336. package/src/daemon/message-types/skills.ts +97 -36
  337. package/src/daemon/profiler-run-store.ts +557 -0
  338. package/src/daemon/providers-setup.ts +5 -0
  339. package/src/daemon/server.ts +100 -11
  340. package/src/daemon/shutdown-handlers.ts +5 -0
  341. package/src/daemon/tool-side-effects.ts +50 -8
  342. package/src/export/transcript-formatter.ts +148 -0
  343. package/src/filing/filing-service.ts +228 -0
  344. package/src/heartbeat/heartbeat-service.ts +97 -7
  345. package/src/hooks/cli.ts +2 -2
  346. package/src/hooks/runner.ts +15 -38
  347. package/src/inbound/platform-callback-registration.ts +14 -14
  348. package/src/mcp/client.ts +6 -0
  349. package/src/mcp/mcp-oauth-provider.ts +149 -27
  350. package/src/memory/admin.ts +42 -75
  351. package/src/memory/app-store.ts +69 -0
  352. package/src/memory/conversation-bootstrap.ts +3 -1
  353. package/src/memory/conversation-crud.ts +211 -288
  354. package/src/memory/conversation-group-migration.ts +157 -0
  355. package/src/memory/conversation-queries.ts +61 -13
  356. package/src/memory/conversation-title-service.ts +1 -0
  357. package/src/memory/db-init.ts +194 -361
  358. package/src/memory/embed.ts +73 -0
  359. package/src/memory/embedding-backend.ts +8 -14
  360. package/src/memory/embedding-runtime-manager.ts +12 -114
  361. package/src/memory/fingerprint.ts +2 -2
  362. package/src/memory/graph/bootstrap.ts +521 -0
  363. package/src/memory/graph/capability-seed.ts +449 -0
  364. package/src/memory/graph/consolidation.ts +725 -0
  365. package/src/memory/graph/conversation-graph-memory.ts +659 -0
  366. package/src/memory/graph/decay.test.ts +208 -0
  367. package/src/memory/graph/decay.ts +195 -0
  368. package/src/memory/graph/extraction-job.ts +74 -0
  369. package/src/memory/graph/extraction.test.ts +936 -0
  370. package/src/memory/graph/extraction.ts +1297 -0
  371. package/src/memory/graph/graph-memory-state-store.ts +37 -0
  372. package/src/memory/graph/graph-search.ts +280 -0
  373. package/src/memory/graph/image-ref-utils.ts +29 -0
  374. package/src/memory/graph/injection.test.ts +513 -0
  375. package/src/memory/graph/injection.ts +469 -0
  376. package/src/memory/graph/inspect.ts +543 -0
  377. package/src/memory/graph/narrative.ts +267 -0
  378. package/src/memory/graph/pattern-scan.ts +269 -0
  379. package/src/memory/graph/retriever.ts +1111 -0
  380. package/src/memory/graph/scoring.test.ts +548 -0
  381. package/src/memory/graph/scoring.ts +232 -0
  382. package/src/memory/graph/serendipity.ts +65 -0
  383. package/src/memory/graph/store.test.ts +1098 -0
  384. package/src/memory/graph/store.ts +838 -0
  385. package/src/memory/graph/tool-handlers.ts +301 -0
  386. package/src/memory/graph/tools.ts +97 -0
  387. package/src/memory/graph/triggers.test.ts +487 -0
  388. package/src/memory/graph/triggers.ts +223 -0
  389. package/src/memory/graph/types.ts +295 -0
  390. package/src/memory/group-crud.ts +191 -0
  391. package/src/memory/indexer.ts +37 -19
  392. package/src/memory/job-handlers/cleanup.ts +32 -42
  393. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  394. package/src/memory/job-handlers/embedding.ts +5 -31
  395. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  396. package/src/memory/job-handlers/summarization.ts +32 -17
  397. package/src/memory/job-utils.ts +1 -1
  398. package/src/memory/jobs-store.ts +21 -31
  399. package/src/memory/jobs-worker.ts +180 -129
  400. package/src/memory/llm-request-log-store.ts +96 -12
  401. package/src/memory/memory-recall-log-store.ts +49 -5
  402. package/src/memory/message-content.ts +1 -0
  403. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  404. package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -0
  405. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  406. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  407. package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
  408. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
  409. package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
  410. package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
  411. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
  412. package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
  413. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
  414. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
  415. package/src/memory/migrations/index.ts +12 -0
  416. package/src/memory/migrations/registry.ts +16 -0
  417. package/src/memory/qdrant-client.ts +44 -17
  418. package/src/memory/schema/conversations.ts +14 -0
  419. package/src/memory/schema/index.ts +1 -0
  420. package/src/memory/schema/infrastructure.ts +8 -1
  421. package/src/memory/schema/memory-core.ts +0 -51
  422. package/src/memory/schema/memory-graph.ts +154 -0
  423. package/src/memory/search/semantic.ts +47 -91
  424. package/src/memory/task-memory-cleanup.ts +58 -61
  425. package/src/messaging/providers/outlook/adapter.ts +8 -1
  426. package/src/messaging/providers/outlook/client.ts +299 -0
  427. package/src/messaging/providers/outlook/types.ts +118 -0
  428. package/src/notifications/adapters/macos.ts +1 -0
  429. package/src/notifications/copy-composer.ts +95 -0
  430. package/src/notifications/decision-engine.ts +35 -0
  431. package/src/notifications/signal.ts +16 -0
  432. package/src/oauth/seed-providers.ts +2 -1
  433. package/src/permissions/checker.ts +36 -4
  434. package/src/permissions/defaults.ts +4 -4
  435. package/src/permissions/permission-mode-store.ts +180 -0
  436. package/src/permissions/permission-mode.ts +31 -0
  437. package/src/permissions/workspace-policy.ts +10 -1
  438. package/src/playbooks/playbook-compiler.ts +19 -18
  439. package/src/playbooks/types.ts +4 -3
  440. package/src/prompts/system-prompt.ts +62 -36
  441. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
  442. package/src/prompts/templates/BOOTSTRAP.md +70 -165
  443. package/src/prompts/templates/HEARTBEAT.md +3 -1
  444. package/src/prompts/templates/SOUL.md +25 -4
  445. package/src/prompts/templates/UPDATES.md +8 -0
  446. package/src/providers/anthropic/client.ts +136 -220
  447. package/src/providers/gemini/client.ts +1 -1
  448. package/src/providers/openai/client.ts +1 -1
  449. package/src/providers/registry.ts +1 -1
  450. package/src/providers/retry.ts +19 -3
  451. package/src/runtime/actor-trust-resolver.ts +5 -1
  452. package/src/runtime/auth/route-policy.ts +30 -0
  453. package/src/runtime/guardian-reply-router.ts +5 -1
  454. package/src/runtime/http-server.ts +55 -5
  455. package/src/runtime/http-types.ts +12 -1
  456. package/src/runtime/middleware/auth.ts +20 -0
  457. package/src/runtime/migrations/vbundle-builder.ts +389 -3
  458. package/src/runtime/migrations/vbundle-importer.ts +8 -6
  459. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
  460. package/src/runtime/routes/app-management-routes.ts +1 -11
  461. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
  462. package/src/runtime/routes/archive-utils.ts +29 -0
  463. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  464. package/src/runtime/routes/attachment-routes.ts +106 -16
  465. package/src/runtime/routes/avatar-routes.ts +2 -9
  466. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  467. package/src/runtime/routes/btw-routes.ts +22 -1
  468. package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
  469. package/src/runtime/routes/conversation-management-routes.ts +3 -14
  470. package/src/runtime/routes/conversation-query-routes.ts +49 -3
  471. package/src/runtime/routes/conversation-routes.ts +264 -44
  472. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  473. package/src/runtime/routes/debug-routes.ts +1 -1
  474. package/src/runtime/routes/global-search-routes.ts +21 -19
  475. package/src/runtime/routes/group-routes.ts +207 -0
  476. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  477. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  478. package/src/runtime/routes/heartbeat-routes.ts +4 -10
  479. package/src/runtime/routes/identity-routes.ts +53 -18
  480. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  481. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  482. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  483. package/src/runtime/routes/llm-context-normalization.ts +14 -10
  484. package/src/runtime/routes/log-export-routes.ts +23 -275
  485. package/src/runtime/routes/memory-item-routes.test.ts +170 -247
  486. package/src/runtime/routes/memory-item-routes.ts +341 -388
  487. package/src/runtime/routes/migration-routes.ts +18 -7
  488. package/src/runtime/routes/profiler-routes.ts +350 -0
  489. package/src/runtime/routes/schedule-routes.ts +28 -11
  490. package/src/runtime/routes/settings-routes.ts +95 -8
  491. package/src/runtime/routes/skills-routes.ts +103 -37
  492. package/src/runtime/routes/subagents-routes.ts +28 -7
  493. package/src/runtime/routes/user-route-dispatcher.ts +223 -0
  494. package/src/runtime/routes/user-routes.ts +41 -0
  495. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  496. package/src/runtime/routes/workspace-routes.ts +0 -1
  497. package/src/schedule/schedule-store.ts +30 -0
  498. package/src/schedule/scheduler.ts +52 -18
  499. package/src/security/oauth2.ts +1 -1
  500. package/src/security/secure-keys.ts +4 -8
  501. package/src/shared/provider-env-vars.ts +19 -0
  502. package/src/skills/catalog-cache.ts +5 -0
  503. package/src/skills/catalog-install.ts +25 -16
  504. package/src/skills/clawhub.ts +134 -154
  505. package/src/skills/install-meta.ts +208 -0
  506. package/src/skills/managed-store.ts +29 -18
  507. package/src/skills/skill-memory.ts +12 -229
  508. package/src/skills/skillssh-registry.ts +19 -17
  509. package/src/subagent/index.ts +13 -3
  510. package/src/subagent/manager.ts +308 -29
  511. package/src/subagent/types.ts +68 -0
  512. package/src/tasks/task-runner.ts +7 -5
  513. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  514. package/src/tools/apps/executors.ts +29 -4
  515. package/src/tools/browser/runtime-check.ts +3 -1
  516. package/src/tools/filesystem/list.ts +93 -0
  517. package/src/tools/memory/register.ts +63 -46
  518. package/src/tools/permission-checker.ts +85 -1
  519. package/src/tools/registry.ts +4 -0
  520. package/src/tools/schedule/create.ts +3 -0
  521. package/src/tools/schedule/list.ts +1 -0
  522. package/src/tools/schedule/update.ts +6 -0
  523. package/src/tools/shared/filesystem/errors.ts +5 -0
  524. package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
  525. package/src/tools/shared/filesystem/image-read.ts +22 -85
  526. package/src/tools/shared/filesystem/types.ts +17 -0
  527. package/src/tools/shared/shell-output.ts +31 -2
  528. package/src/tools/subagent/abort.ts +12 -2
  529. package/src/tools/subagent/message.ts +9 -2
  530. package/src/tools/subagent/notify-parent.ts +79 -0
  531. package/src/tools/subagent/read.ts +29 -8
  532. package/src/tools/subagent/resolve.ts +21 -0
  533. package/src/tools/subagent/spawn.ts +2 -0
  534. package/src/tools/subagent/status.ts +11 -1
  535. package/src/tools/system/avatar-generator.ts +3 -3
  536. package/src/tools/system/register.ts +23 -0
  537. package/src/tools/system/set-permission-mode.ts +103 -0
  538. package/src/tools/terminal/parser.ts +30 -5
  539. package/src/tools/terminal/safe-env.ts +17 -1
  540. package/src/tools/tool-manifest.ts +9 -3
  541. package/src/tools/types.ts +2 -0
  542. package/src/util/browser.ts +25 -10
  543. package/src/util/bun-runtime.ts +172 -0
  544. package/src/util/logger.ts +1 -1
  545. package/src/util/platform.ts +50 -17
  546. package/src/watcher/providers/outlook-calendar.ts +343 -0
  547. package/src/watcher/providers/outlook.ts +198 -0
  548. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
  549. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
  550. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  551. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  552. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  553. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
  554. package/src/workspace/migrations/029-seed-pkb.ts +84 -0
  555. package/src/workspace/migrations/registry.ts +10 -0
  556. package/src/workspace/top-level-renderer.ts +5 -9
  557. package/src/__tests__/cli-memory.test.ts +0 -372
  558. package/src/__tests__/clipboard.test.ts +0 -88
  559. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  560. package/src/__tests__/journal-context.test.ts +0 -268
  561. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  562. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  563. package/src/__tests__/memory-query-builder.test.ts +0 -59
  564. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  565. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  566. package/src/__tests__/memory-regressions.test.ts +0 -3696
  567. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  568. package/src/cli/cli-memory.ts +0 -176
  569. package/src/daemon/conversation-memory.ts +0 -207
  570. package/src/memory/conversation-starters-cadence.ts +0 -74
  571. package/src/memory/items-extractor.ts +0 -860
  572. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  573. package/src/memory/job-handlers/extraction.ts +0 -40
  574. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  575. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  576. package/src/memory/journal-memory.ts +0 -224
  577. package/src/memory/query-builder.ts +0 -47
  578. package/src/memory/query-expansion.ts +0 -83
  579. package/src/memory/retriever.test.ts +0 -1592
  580. package/src/memory/retriever.ts +0 -1331
  581. package/src/memory/search/formatting.test.ts +0 -140
  582. package/src/memory/search/formatting.ts +0 -262
  583. package/src/memory/search/mmr.ts +0 -139
  584. package/src/memory/search/ranking.ts +0 -15
  585. package/src/memory/search/staleness.ts +0 -40
  586. package/src/memory/search/tier-classifier.ts +0 -18
  587. package/src/memory/search/types.ts +0 -121
  588. package/src/prompts/journal-context.ts +0 -154
  589. package/src/tools/memory/definitions.ts +0 -69
  590. package/src/tools/memory/handlers.test.ts +0 -562
  591. package/src/tools/memory/handlers.ts +0 -434
  592. package/src/util/clipboard.ts +0 -34
@@ -4,15 +4,7 @@
4
4
  * Covers: list with filters, get by ID, create + duplicate rejection,
5
5
  * update + fingerprint collision, delete + 404.
6
6
  */
7
- import {
8
- afterAll,
9
- beforeAll,
10
- beforeEach,
11
- describe,
12
- expect,
13
- mock,
14
- test,
15
- } from "bun:test";
7
+ import { beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
16
8
 
17
9
  mock.module("../../util/logger.js", () => ({
18
10
  getLogger: () =>
@@ -70,14 +62,10 @@ mock.module("../../memory/qdrant-circuit-breaker.js", () => ({
70
62
  withQdrantBreaker: async (fn: () => Promise<unknown>) => fn(),
71
63
  }));
72
64
 
73
- import { and, eq } from "drizzle-orm";
65
+ import { eq } from "drizzle-orm";
74
66
 
75
- import { getDb, initializeDb, resetDb } from "../../memory/db.js";
76
- import {
77
- memoryEmbeddings,
78
- memoryItems,
79
- memoryJobs,
80
- } from "../../memory/schema.js";
67
+ import { getDb, initializeDb } from "../../memory/db.js";
68
+ import { memoryGraphNodes, memoryJobs } from "../../memory/schema.js";
81
69
  import type { RouteContext } from "../http-router.js";
82
70
  import { memoryItemRouteDefinitions } from "./memory-item-routes.js";
83
71
 
@@ -133,42 +121,45 @@ function makeJsonCtx(
133
121
 
134
122
  function insertItem(opts: {
135
123
  id: string;
136
- kind: string;
137
- subject: string;
138
- statement: string;
139
- status?: string;
140
- importance?: number;
141
- firstSeenAt?: number;
142
- lastSeenAt?: number;
143
- supersedes?: string;
144
- supersededBy?: string;
124
+ type: string;
125
+ content: string;
126
+ fidelity?: string;
127
+ significance?: number;
128
+ created?: number;
129
+ lastAccessed?: number;
145
130
  }) {
146
131
  const db = getDb();
147
132
  const now = Date.now();
148
- db.insert(memoryItems)
133
+ db.insert(memoryGraphNodes)
149
134
  .values({
150
135
  id: opts.id,
151
- kind: opts.kind,
152
- subject: opts.subject,
153
- statement: opts.statement,
154
- status: opts.status ?? "active",
136
+ content: opts.content,
137
+ type: opts.type,
138
+ created: opts.created ?? now,
139
+ lastAccessed: opts.lastAccessed ?? now,
140
+ lastConsolidated: now,
141
+ eventDate: null,
142
+ emotionalCharge: JSON.stringify({
143
+ valence: 0,
144
+ intensity: 0.1,
145
+ decayCurve: "linear",
146
+ decayRate: 0.05,
147
+ originalIntensity: 0.1,
148
+ }),
149
+ fidelity: opts.fidelity ?? "vivid",
155
150
  confidence: 0.95,
156
- importance: opts.importance ?? 0.8,
157
- fingerprint: `fp-${opts.id}`,
158
- verificationState: "user_confirmed",
151
+ significance: opts.significance ?? 0.8,
152
+ stability: 14,
153
+ reinforcementCount: 0,
154
+ lastReinforced: now,
155
+ sourceConversations: JSON.stringify([]),
156
+ sourceType: "direct",
157
+ narrativeRole: null,
158
+ partOfStory: null,
159
+ imageRefs: null,
159
160
  scopeId: "default",
160
- firstSeenAt: opts.firstSeenAt ?? now,
161
- lastSeenAt: opts.lastSeenAt ?? now,
162
- lastUsedAt: null,
163
161
  })
164
162
  .run();
165
-
166
- if (opts.supersedes || opts.supersededBy) {
167
- const set: Record<string, unknown> = {};
168
- if (opts.supersedes) set.supersedes = opts.supersedes;
169
- if (opts.supersededBy) set.supersededBy = opts.supersededBy;
170
- db.update(memoryItems).set(set).where(eq(memoryItems.id, opts.id)).run();
171
- }
172
163
  }
173
164
 
174
165
  // ---------------------------------------------------------------------------
@@ -182,16 +173,13 @@ describe("Memory Item Routes", () => {
182
173
 
183
174
  beforeEach(() => {
184
175
  const db = getDb();
185
- db.run("DELETE FROM memory_embeddings");
186
- db.run("DELETE FROM memory_item_sources");
187
- db.run("DELETE FROM memory_items");
176
+ db.run("DELETE FROM memory_graph_node_edits");
177
+ db.run("DELETE FROM memory_graph_triggers");
178
+ db.run("DELETE FROM memory_graph_edges");
179
+ db.run("DELETE FROM memory_graph_nodes");
188
180
  db.run("DELETE FROM memory_jobs");
189
181
  });
190
182
 
191
- afterAll(() => {
192
- resetDb();
193
- });
194
-
195
183
  // =========================================================================
196
184
  // GET /v1/memory-items (list)
197
185
  // =========================================================================
@@ -211,16 +199,14 @@ describe("Memory Item Routes", () => {
211
199
  test("returns all active items by default", async () => {
212
200
  insertItem({
213
201
  id: "i1",
214
- kind: "preference",
215
- subject: "s1",
216
- statement: "st1",
202
+ type: "semantic",
203
+ content: "s1\nst1",
217
204
  });
218
205
  insertItem({
219
206
  id: "i2",
220
- kind: "identity",
221
- subject: "s2",
222
- statement: "st2",
223
- status: "deleted",
207
+ type: "episodic",
208
+ content: "s2\nst2",
209
+ fidelity: "gone",
224
210
  });
225
211
 
226
212
  const ctx = makeCtx();
@@ -238,17 +224,15 @@ describe("Memory Item Routes", () => {
238
224
  test("returns items of all statuses when status=all", async () => {
239
225
  insertItem({
240
226
  id: "i1",
241
- kind: "preference",
242
- subject: "s1",
243
- statement: "st1",
244
- status: "active",
227
+ type: "semantic",
228
+ content: "s1\nst1",
229
+ fidelity: "vivid",
245
230
  });
246
231
  insertItem({
247
232
  id: "i2",
248
- kind: "identity",
249
- subject: "s2",
250
- statement: "st2",
251
- status: "deleted",
233
+ type: "episodic",
234
+ content: "s2\nst2",
235
+ fidelity: "gone",
252
236
  });
253
237
 
254
238
  const ctx = makeCtx({ status: "all" });
@@ -267,18 +251,16 @@ describe("Memory Item Routes", () => {
267
251
  test("filters by kind", async () => {
268
252
  insertItem({
269
253
  id: "i1",
270
- kind: "preference",
271
- subject: "s1",
272
- statement: "st1",
254
+ type: "semantic",
255
+ content: "s1\nst1",
273
256
  });
274
257
  insertItem({
275
258
  id: "i2",
276
- kind: "identity",
277
- subject: "s2",
278
- statement: "st2",
259
+ type: "episodic",
260
+ content: "s2\nst2",
279
261
  });
280
262
 
281
- const ctx = makeCtx({ kind: "preference" });
263
+ const ctx = makeCtx({ kind: "semantic" });
282
264
  const res = await handler(ctx);
283
265
  const body = (await res.json()) as {
284
266
  items: Array<{ id: string }>;
@@ -288,18 +270,16 @@ describe("Memory Item Routes", () => {
288
270
  expect(body.items[0].id).toBe("i1");
289
271
  });
290
272
 
291
- test("filters by search on subject and statement", async () => {
273
+ test("filters by search on content", async () => {
292
274
  insertItem({
293
275
  id: "i1",
294
- kind: "preference",
295
- subject: "dark mode",
296
- statement: "User prefers dark mode",
276
+ type: "semantic",
277
+ content: "dark mode\nUser prefers dark mode",
297
278
  });
298
279
  insertItem({
299
280
  id: "i2",
300
- kind: "identity",
301
- subject: "name",
302
- statement: "User name is Alice",
281
+ type: "episodic",
282
+ content: "name\nUser name is Alice",
303
283
  });
304
284
 
305
285
  const ctx = makeCtx({ search: "dark" });
@@ -315,24 +295,21 @@ describe("Memory Item Routes", () => {
315
295
  test("supports pagination with limit and offset", async () => {
316
296
  insertItem({
317
297
  id: "i1",
318
- kind: "preference",
319
- subject: "s1",
320
- statement: "st1",
321
- lastSeenAt: 1000,
298
+ type: "semantic",
299
+ content: "s1\nst1",
300
+ lastAccessed: 1000,
322
301
  });
323
302
  insertItem({
324
303
  id: "i2",
325
- kind: "preference",
326
- subject: "s2",
327
- statement: "st2",
328
- lastSeenAt: 2000,
304
+ type: "semantic",
305
+ content: "s2\nst2",
306
+ lastAccessed: 2000,
329
307
  });
330
308
  insertItem({
331
309
  id: "i3",
332
- kind: "preference",
333
- subject: "s3",
334
- statement: "st3",
335
- lastSeenAt: 3000,
310
+ type: "semantic",
311
+ content: "s3\nst3",
312
+ lastAccessed: 3000,
336
313
  });
337
314
 
338
315
  const ctx = makeCtx({ limit: "1", offset: "1" });
@@ -350,17 +327,15 @@ describe("Memory Item Routes", () => {
350
327
  test("supports sort by firstSeenAt ascending", async () => {
351
328
  insertItem({
352
329
  id: "i1",
353
- kind: "preference",
354
- subject: "s1",
355
- statement: "st1",
356
- firstSeenAt: 3000,
330
+ type: "semantic",
331
+ content: "s1\nst1",
332
+ created: 3000,
357
333
  });
358
334
  insertItem({
359
335
  id: "i2",
360
- kind: "preference",
361
- subject: "s2",
362
- statement: "st2",
363
- firstSeenAt: 1000,
336
+ type: "semantic",
337
+ content: "s2\nst2",
338
+ created: 1000,
364
339
  });
365
340
 
366
341
  const ctx = makeCtx({ sort: "firstSeenAt", order: "asc" });
@@ -372,32 +347,21 @@ describe("Memory Item Routes", () => {
372
347
  expect(body.items[1].id).toBe("i1");
373
348
  });
374
349
 
375
- test("supports sort by accessCount descending", async () => {
350
+ test("supports sort by importance descending", async () => {
376
351
  insertItem({
377
352
  id: "i1",
378
- kind: "preference",
379
- subject: "s1",
380
- statement: "st1",
353
+ type: "semantic",
354
+ content: "s1\nst1",
355
+ significance: 0.3,
381
356
  });
382
357
  insertItem({
383
358
  id: "i2",
384
- kind: "preference",
385
- subject: "s2",
386
- statement: "st2",
387
- });
388
-
389
- getDb()
390
- .update(memoryItems)
391
- .set({ accessCount: 2 })
392
- .where(eq(memoryItems.id, "i1"))
393
- .run();
394
- getDb()
395
- .update(memoryItems)
396
- .set({ accessCount: 7 })
397
- .where(eq(memoryItems.id, "i2"))
398
- .run();
399
-
400
- const ctx = makeCtx({ sort: "accessCount", order: "desc" });
359
+ type: "semantic",
360
+ content: "s2\nst2",
361
+ significance: 0.9,
362
+ });
363
+
364
+ const ctx = makeCtx({ sort: "importance", order: "desc" });
401
365
  const res = await handler(ctx);
402
366
  const body = (await res.json()) as {
403
367
  items: Array<{ id: string }>;
@@ -423,15 +387,13 @@ describe("Memory Item Routes", () => {
423
387
  test("uses semantic search when embedding backend is available", async () => {
424
388
  insertItem({
425
389
  id: "i1",
426
- kind: "preference",
427
- subject: "dark mode",
428
- statement: "User prefers dark mode",
390
+ type: "semantic",
391
+ content: "dark mode\nUser prefers dark mode",
429
392
  });
430
393
  insertItem({
431
394
  id: "i2",
432
- kind: "identity",
433
- subject: "name",
434
- statement: "User name is Alice",
395
+ type: "episodic",
396
+ content: "name\nUser name is Alice",
435
397
  });
436
398
 
437
399
  // Enable semantic search
@@ -445,12 +407,12 @@ describe("Memory Item Routes", () => {
445
407
  {
446
408
  id: "pt-2",
447
409
  score: 0.95,
448
- payload: { target_type: "item", target_id: "i2" },
410
+ payload: { target_type: "graph_node", target_id: "i2" },
449
411
  },
450
412
  {
451
413
  id: "pt-1",
452
414
  score: 0.7,
453
- payload: { target_type: "item", target_id: "i1" },
415
+ payload: { target_type: "graph_node", target_id: "i1" },
454
416
  },
455
417
  ];
456
418
 
@@ -475,15 +437,13 @@ describe("Memory Item Routes", () => {
475
437
  test("falls back to SQL LIKE when backend is unavailable", async () => {
476
438
  insertItem({
477
439
  id: "i1",
478
- kind: "preference",
479
- subject: "dark mode",
480
- statement: "User prefers dark mode",
440
+ type: "semantic",
441
+ content: "dark mode\nUser prefers dark mode",
481
442
  });
482
443
  insertItem({
483
444
  id: "i2",
484
- kind: "identity",
485
- subject: "name",
486
- statement: "User name is Alice",
445
+ type: "episodic",
446
+ content: "name\nUser name is Alice",
487
447
  });
488
448
 
489
449
  // Backend unavailable
@@ -505,21 +465,18 @@ describe("Memory Item Routes", () => {
505
465
  test("semantic search respects pagination", async () => {
506
466
  insertItem({
507
467
  id: "i1",
508
- kind: "preference",
509
- subject: "s1",
510
- statement: "first item",
468
+ type: "semantic",
469
+ content: "s1\nfirst item",
511
470
  });
512
471
  insertItem({
513
472
  id: "i2",
514
- kind: "preference",
515
- subject: "s2",
516
- statement: "second item",
473
+ type: "semantic",
474
+ content: "s2\nsecond item",
517
475
  });
518
476
  insertItem({
519
477
  id: "i3",
520
- kind: "preference",
521
- subject: "s3",
522
- statement: "third item",
478
+ type: "semantic",
479
+ content: "s3\nthird item",
523
480
  });
524
481
 
525
482
  mockBackendStatus = {
@@ -531,17 +488,17 @@ describe("Memory Item Routes", () => {
531
488
  {
532
489
  id: "pt-1",
533
490
  score: 0.9,
534
- payload: { target_type: "item", target_id: "i1" },
491
+ payload: { target_type: "graph_node", target_id: "i1" },
535
492
  },
536
493
  {
537
494
  id: "pt-2",
538
495
  score: 0.8,
539
- payload: { target_type: "item", target_id: "i2" },
496
+ payload: { target_type: "graph_node", target_id: "i2" },
540
497
  },
541
498
  {
542
499
  id: "pt-3",
543
500
  score: 0.7,
544
- payload: { target_type: "item", target_id: "i3" },
501
+ payload: { target_type: "graph_node", target_id: "i3" },
545
502
  },
546
503
  ];
547
504
 
@@ -565,9 +522,8 @@ describe("Memory Item Routes", () => {
565
522
  test("falls back to SQL when semantic returns empty results", async () => {
566
523
  insertItem({
567
524
  id: "i1",
568
- kind: "preference",
569
- subject: "dark mode",
570
- statement: "User prefers dark mode",
525
+ type: "semantic",
526
+ content: "dark mode\nUser prefers dark mode",
571
527
  });
572
528
 
573
529
  mockBackendStatus = {
@@ -605,9 +561,8 @@ describe("Memory Item Routes", () => {
605
561
  test("returns item by ID", async () => {
606
562
  insertItem({
607
563
  id: "i1",
608
- kind: "preference",
609
- subject: "dark mode",
610
- statement: "Prefers dark mode",
564
+ type: "semantic",
565
+ content: "dark mode\nPrefers dark mode",
611
566
  });
612
567
 
613
568
  const ctx = makeCtx({}, { id: "i1" });
@@ -626,33 +581,20 @@ describe("Memory Item Routes", () => {
626
581
  expect(res.status).toBe(404);
627
582
  });
628
583
 
629
- test("includes supersedesSubject when supersedes is set", async () => {
630
- insertItem({
631
- id: "old",
632
- kind: "preference",
633
- subject: "old pref",
634
- statement: "old",
635
- });
584
+ test("returns null for legacy supersedes/supersededBy fields", async () => {
636
585
  insertItem({
637
- id: "new",
638
- kind: "preference",
639
- subject: "new pref",
640
- statement: "new",
586
+ id: "i1",
587
+ type: "semantic",
588
+ content: "some content\nsome statement",
641
589
  });
642
590
 
643
- // Set supersedes relationship manually
644
- getDb()
645
- .update(memoryItems)
646
- .set({ supersedes: "old" })
647
- .where(eq(memoryItems.id, "new"))
648
- .run();
649
-
650
- const ctx = makeCtx({}, { id: "new" });
591
+ const ctx = makeCtx({}, { id: "i1" });
651
592
  const res = await handler(ctx);
652
593
  const body = (await res.json()) as {
653
- item: { supersedesSubject?: string };
594
+ item: { supersedes: unknown; supersededBy: unknown };
654
595
  };
655
- expect(body.item.supersedesSubject).toBe("old pref");
596
+ expect(body.item.supersedes).toBeNull();
597
+ expect(body.item.supersededBy).toBeNull();
656
598
  });
657
599
  });
658
600
 
@@ -665,7 +607,7 @@ describe("Memory Item Routes", () => {
665
607
 
666
608
  test("creates a new memory item", async () => {
667
609
  const ctx = makeJsonCtx("memory-items", "POST", {
668
- kind: "preference",
610
+ kind: "semantic",
669
611
  subject: "dark mode",
670
612
  statement: "User prefers dark mode",
671
613
  });
@@ -674,14 +616,14 @@ describe("Memory Item Routes", () => {
674
616
  const body = (await res.json()) as {
675
617
  item: { id: string; kind: string; subject: string; statement: string };
676
618
  };
677
- expect(body.item.kind).toBe("preference");
619
+ expect(body.item.kind).toBe("semantic");
678
620
  expect(body.item.subject).toBe("dark mode");
679
621
  expect(body.item.statement).toBe("User prefers dark mode");
680
622
  });
681
623
 
682
624
  test("uses custom importance when provided", async () => {
683
625
  const ctx = makeJsonCtx("memory-items", "POST", {
684
- kind: "preference",
626
+ kind: "semantic",
685
627
  subject: "importance test",
686
628
  statement: "Testing custom importance",
687
629
  importance: 0.5,
@@ -694,9 +636,9 @@ describe("Memory Item Routes", () => {
694
636
  expect(body.item.importance).toBe(0.5);
695
637
  });
696
638
 
697
- test("rejects duplicate fingerprint", async () => {
639
+ test("rejects duplicate content", async () => {
698
640
  const payload = {
699
- kind: "preference",
641
+ kind: "semantic",
700
642
  subject: "dark mode",
701
643
  statement: "User prefers dark mode",
702
644
  };
@@ -719,18 +661,24 @@ describe("Memory Item Routes", () => {
719
661
  expect(res.status).toBe(400);
720
662
  });
721
663
 
722
- test("rejects missing subject", async () => {
664
+ test("accepts missing subject (optional)", async () => {
723
665
  const ctx = makeJsonCtx("memory-items", "POST", {
724
- kind: "preference",
725
- statement: "test",
666
+ kind: "semantic",
667
+ statement: "test content without subject",
726
668
  });
727
669
  const res = await handler(ctx);
728
- expect(res.status).toBe(400);
670
+ expect(res.status).toBe(201);
671
+ const body = (await res.json()) as {
672
+ item: { subject: string; statement: string };
673
+ };
674
+ // When no subject, content has no newline, so subject and statement are the same
675
+ expect(body.item.subject).toBe("test content without subject");
676
+ expect(body.item.statement).toBe("test content without subject");
729
677
  });
730
678
 
731
679
  test("rejects missing statement", async () => {
732
680
  const ctx = makeJsonCtx("memory-items", "POST", {
733
- kind: "preference",
681
+ kind: "semantic",
734
682
  subject: "test",
735
683
  });
736
684
  const res = await handler(ctx);
@@ -741,7 +689,7 @@ describe("Memory Item Routes", () => {
741
689
  const longSubject = "a".repeat(200);
742
690
  const longStatement = "b".repeat(1000);
743
691
  const ctx = makeJsonCtx("memory-items", "POST", {
744
- kind: "preference",
692
+ kind: "semantic",
745
693
  subject: longSubject,
746
694
  statement: longStatement,
747
695
  });
@@ -756,7 +704,7 @@ describe("Memory Item Routes", () => {
756
704
 
757
705
  test("enqueues embed job on create", async () => {
758
706
  const ctx = makeJsonCtx("memory-items", "POST", {
759
- kind: "preference",
707
+ kind: "semantic",
760
708
  subject: "embed test",
761
709
  statement: "Should enqueue embed job",
762
710
  });
@@ -766,7 +714,7 @@ describe("Memory Item Routes", () => {
766
714
  const db = getDb();
767
715
  const jobs = db.select().from(memoryJobs).all();
768
716
  const embedJobs = jobs.filter(
769
- (j) => j.type === "embed_item" && j.status === "pending",
717
+ (j) => j.type === "embed_graph_node" && j.status === "pending",
770
718
  );
771
719
  expect(embedJobs.length).toBeGreaterThanOrEqual(1);
772
720
  });
@@ -782,9 +730,8 @@ describe("Memory Item Routes", () => {
782
730
  test("updates subject and statement", async () => {
783
731
  insertItem({
784
732
  id: "i1",
785
- kind: "preference",
786
- subject: "old subject",
787
- statement: "old statement",
733
+ type: "semantic",
734
+ content: "old subject\nold statement",
788
735
  });
789
736
 
790
737
  const ctx = makeJsonCtx(
@@ -813,17 +760,16 @@ describe("Memory Item Routes", () => {
813
760
  expect(res.status).toBe(404);
814
761
  });
815
762
 
816
- test("detects fingerprint collision on update", async () => {
763
+ test("detects content collision on update", async () => {
817
764
  insertItem({
818
765
  id: "i1",
819
- kind: "preference",
820
- subject: "first",
821
- statement: "first statement",
766
+ type: "semantic",
767
+ content: "first\nfirst statement",
822
768
  });
823
- // Insert a second item using the create handler to get a real fingerprint
769
+ // Insert a second item using the create handler to get a real node
824
770
  const createHandler = getHandler("memory-items", "POST");
825
771
  const createCtx = makeJsonCtx("memory-items", "POST", {
826
- kind: "preference",
772
+ kind: "semantic",
827
773
  subject: "second",
828
774
  statement: "second statement",
829
775
  });
@@ -844,29 +790,27 @@ describe("Memory Item Routes", () => {
844
790
  test("allows updating kind", async () => {
845
791
  insertItem({
846
792
  id: "i1",
847
- kind: "preference",
848
- subject: "test",
849
- statement: "test",
793
+ type: "semantic",
794
+ content: "test\ntest",
850
795
  });
851
796
 
852
797
  const ctx = makeJsonCtx(
853
798
  "memory-items/i1",
854
799
  "PATCH",
855
- { kind: "identity" },
800
+ { kind: "episodic" },
856
801
  { id: "i1" },
857
802
  );
858
803
  const res = await handler(ctx);
859
804
  expect(res.status).toBe(200);
860
805
  const body = (await res.json()) as { item: { kind: string } };
861
- expect(body.item.kind).toBe("identity");
806
+ expect(body.item.kind).toBe("episodic");
862
807
  });
863
808
 
864
809
  test("rejects invalid kind on update", async () => {
865
810
  insertItem({
866
811
  id: "i1",
867
- kind: "preference",
868
- subject: "test",
869
- statement: "test",
812
+ type: "semantic",
813
+ content: "test\ntest",
870
814
  });
871
815
 
872
816
  const ctx = makeJsonCtx(
@@ -882,9 +826,8 @@ describe("Memory Item Routes", () => {
882
826
  test("enqueues embed job when statement changes", async () => {
883
827
  insertItem({
884
828
  id: "i1",
885
- kind: "preference",
886
- subject: "test",
887
- statement: "old statement",
829
+ type: "semantic",
830
+ content: "test\nold statement",
888
831
  });
889
832
 
890
833
  // Clear jobs first
@@ -901,7 +844,7 @@ describe("Memory Item Routes", () => {
901
844
  const db = getDb();
902
845
  const jobs = db.select().from(memoryJobs).all();
903
846
  const embedJobs = jobs.filter(
904
- (j) => j.type === "embed_item" && j.status === "pending",
847
+ (j) => j.type === "embed_graph_node" && j.status === "pending",
905
848
  );
906
849
  expect(embedJobs.length).toBe(1);
907
850
  });
@@ -917,23 +860,22 @@ describe("Memory Item Routes", () => {
917
860
  test("deletes item and returns 204", async () => {
918
861
  insertItem({
919
862
  id: "i1",
920
- kind: "preference",
921
- subject: "test",
922
- statement: "test",
863
+ type: "semantic",
864
+ content: "test\ntest",
923
865
  });
924
866
 
925
867
  const ctx = makeJsonCtx("memory-items/i1", "DELETE", null, { id: "i1" });
926
868
  const res = await handler(ctx);
927
869
  expect(res.status).toBe(204);
928
870
 
929
- // Verify the item is gone
871
+ // Verify the node is gone
930
872
  const db = getDb();
931
- const item = db
873
+ const node = db
932
874
  .select()
933
- .from(memoryItems)
934
- .where(eq(memoryItems.id, "i1"))
875
+ .from(memoryGraphNodes)
876
+ .where(eq(memoryGraphNodes.id, "i1"))
935
877
  .get();
936
- expect(item).toBeUndefined();
878
+ expect(node).toBeUndefined();
937
879
  });
938
880
 
939
881
  test("returns 404 for non-existent item", async () => {
@@ -944,46 +886,27 @@ describe("Memory Item Routes", () => {
944
886
  expect(res.status).toBe(404);
945
887
  });
946
888
 
947
- test("also deletes associated embeddings", async () => {
889
+ test("enqueues delete_qdrant_vectors job on delete", async () => {
948
890
  insertItem({
949
891
  id: "i1",
950
- kind: "preference",
951
- subject: "test",
952
- statement: "test",
892
+ type: "semantic",
893
+ content: "test\ntest",
953
894
  });
954
895
 
955
- // Insert an embedding for this item
956
- const db = getDb();
957
- db.insert(memoryEmbeddings)
958
- .values({
959
- id: "emb-1",
960
- targetType: "item",
961
- targetId: "i1",
962
- provider: "test",
963
- model: "test-model",
964
- dimensions: 384,
965
- vectorJson: "[]",
966
- createdAt: Date.now(),
967
- updatedAt: Date.now(),
968
- })
969
- .run();
970
-
971
896
  const ctx = makeJsonCtx("memory-items/i1", "DELETE", null, { id: "i1" });
972
897
  const res = await handler(ctx);
973
898
  expect(res.status).toBe(204);
974
899
 
975
- // Verify embedding is also gone
976
- const emb = db
977
- .select()
978
- .from(memoryEmbeddings)
979
- .where(
980
- and(
981
- eq(memoryEmbeddings.targetType, "item"),
982
- eq(memoryEmbeddings.targetId, "i1"),
983
- ),
984
- )
985
- .get();
986
- expect(emb).toBeUndefined();
900
+ // Verify a delete_qdrant_vectors job was enqueued with graph_node targetType
901
+ const db = getDb();
902
+ const jobs = db.select().from(memoryJobs).all();
903
+ const deleteJobs = jobs.filter(
904
+ (j) => j.type === "delete_qdrant_vectors" && j.status === "pending",
905
+ );
906
+ expect(deleteJobs.length).toBe(1);
907
+ const payload = JSON.parse(deleteJobs[0].payload);
908
+ expect(payload.targetType).toBe("graph_node");
909
+ expect(payload.targetId).toBe("i1");
987
910
  });
988
911
  });
989
912
  });