@vellumai/assistant 0.5.15 → 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 (503) hide show
  1. package/ARCHITECTURE.md +3 -3
  2. package/Dockerfile +0 -3
  3. package/docs/architecture/integrations.md +15 -14
  4. package/knip.json +4 -1
  5. package/openapi.yaml +670 -122
  6. package/package.json +1 -1
  7. package/src/__tests__/actor-token-service.test.ts +68 -0
  8. package/src/__tests__/agent-loop.test.ts +0 -32
  9. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  10. package/src/__tests__/anthropic-provider.test.ts +57 -3
  11. package/src/__tests__/app-compiler.test.ts +120 -0
  12. package/src/__tests__/assistant-feature-flags-integration.test.ts +5 -377
  13. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  14. package/src/__tests__/call-domain.test.ts +2 -6
  15. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  16. package/src/__tests__/call-recovery.test.ts +2 -6
  17. package/src/__tests__/call-routes-http.test.ts +2 -6
  18. package/src/__tests__/call-store.test.ts +2 -6
  19. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  20. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  21. package/src/__tests__/ces-rpc-credential-backend.test.ts +4 -1
  22. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  23. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  24. package/src/__tests__/checker.test.ts +84 -3
  25. package/src/__tests__/clawhub.test.ts +54 -24
  26. package/src/__tests__/cli-command-risk-guard.test.ts +108 -6
  27. package/src/__tests__/cli-memory.test.ts +377 -0
  28. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -2
  29. package/src/__tests__/config-schema.test.ts +1 -3
  30. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  31. package/src/__tests__/config-watcher-feature-flags.test.ts +211 -0
  32. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  33. package/src/__tests__/contacts-tools.test.ts +31 -0
  34. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  35. package/src/__tests__/context-token-estimator.test.ts +175 -10
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  37. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  38. package/src/__tests__/conversation-attachments.test.ts +2 -6
  39. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  40. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  41. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  42. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  43. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  44. package/src/__tests__/conversation-error.test.ts +33 -2
  45. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  46. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  47. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  48. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  49. package/src/__tests__/conversation-runtime-assembly.test.ts +7 -4
  50. package/src/__tests__/conversation-slash-commands.test.ts +2 -6
  51. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  52. package/src/__tests__/conversation-store.test.ts +2 -6
  53. package/src/__tests__/conversation-usage.test.ts +3 -6
  54. package/src/__tests__/conversation-wipe.test.ts +11 -408
  55. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  56. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  57. package/src/__tests__/credential-security-e2e.test.ts +6 -1
  58. package/src/__tests__/docker-signing-key-bootstrap.test.ts +7 -73
  59. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -7
  60. package/src/__tests__/followup-tools.test.ts +2 -6
  61. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  62. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  63. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  64. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  65. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  66. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  67. package/src/__tests__/guardian-action-store.test.ts +2 -6
  68. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  69. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  70. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  71. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  72. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  73. package/src/__tests__/guardian-routing-invariants.test.ts +343 -6
  74. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  75. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  76. package/src/__tests__/heartbeat-service.test.ts +1 -3
  77. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  78. package/src/__tests__/injection-block.test.ts +154 -0
  79. package/src/__tests__/install-meta.test.ts +506 -0
  80. package/src/__tests__/install-skill-routing.test.ts +292 -0
  81. package/src/__tests__/intent-routing.test.ts +6 -18
  82. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  83. package/src/__tests__/invite-routes-http.test.ts +2 -6
  84. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  85. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  86. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  87. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  88. package/src/__tests__/llm-usage-store.test.ts +2 -6
  89. package/src/__tests__/log-export-workspace.test.ts +4 -34
  90. package/src/__tests__/managed-skill-lifecycle.test.ts +7 -37
  91. package/src/__tests__/managed-store.test.ts +40 -21
  92. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  93. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  94. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  95. package/src/__tests__/messaging-send-tool.test.ts +6 -6
  96. package/src/__tests__/migration-cross-version-compatibility.test.ts +1 -29
  97. package/src/__tests__/migration-export-http.test.ts +3 -34
  98. package/src/__tests__/migration-import-commit-http.test.ts +1 -29
  99. package/src/__tests__/migration-import-preflight-http.test.ts +3 -34
  100. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +2 -1
  101. package/src/__tests__/non-member-access-request.test.ts +2 -6
  102. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  103. package/src/__tests__/oauth-apps-routes.test.ts +120 -10
  104. package/src/__tests__/oauth-cli.test.ts +364 -2
  105. package/src/__tests__/oauth-connect-orchestrator.test.ts +709 -0
  106. package/src/__tests__/oauth-provider-serializer.test.ts +2 -1
  107. package/src/__tests__/oauth-provider-visibility.test.ts +149 -0
  108. package/src/__tests__/oauth-providers-routes.test.ts +5 -2
  109. package/src/__tests__/oauth-store.test.ts +0 -5
  110. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  111. package/src/__tests__/outlook-attachments.test.ts +301 -0
  112. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  113. package/src/__tests__/outlook-categories.test.ts +212 -0
  114. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  115. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  116. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  117. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  118. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  119. package/src/__tests__/outlook-messaging-provider.test.ts +1071 -0
  120. package/src/__tests__/outlook-trash.test.ts +77 -0
  121. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  122. package/src/__tests__/path-policy.test.ts +2 -17
  123. package/src/__tests__/permission-types.test.ts +0 -1
  124. package/src/__tests__/platform-callback-registration.test.ts +7 -11
  125. package/src/__tests__/playbook-execution.test.ts +76 -80
  126. package/src/__tests__/playbook-tools.test.ts +5 -7
  127. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  128. package/src/__tests__/provider-error-scenarios.test.ts +21 -2
  129. package/src/__tests__/qdrant-manager.test.ts +68 -21
  130. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  131. package/src/__tests__/registry.test.ts +2 -2
  132. package/src/__tests__/require-fresh-approval.test.ts +64 -3
  133. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  134. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  135. package/src/__tests__/sandbox-diagnostics.test.ts +20 -29
  136. package/src/__tests__/scaffold-managed-skill-tool.test.ts +2 -10
  137. package/src/__tests__/schedule-store.test.ts +2 -6
  138. package/src/__tests__/schedule-tools.test.ts +2 -6
  139. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  140. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  141. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  142. package/src/__tests__/search-skills-unified.test.ts +421 -0
  143. package/src/__tests__/secret-allowlist.test.ts +20 -35
  144. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  145. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  146. package/src/__tests__/sequence-store.test.ts +2 -6
  147. package/src/__tests__/server-history-render.test.ts +2 -6
  148. package/src/__tests__/shell-credential-ref.test.ts +0 -5
  149. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  150. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  151. package/src/__tests__/skill-load-feature-flag.test.ts +13 -54
  152. package/src/__tests__/skill-load-inline-command.test.ts +3 -65
  153. package/src/__tests__/skill-load-inline-includes.test.ts +3 -65
  154. package/src/__tests__/skill-load-tool.test.ts +3 -67
  155. package/src/__tests__/skill-memory.test.ts +480 -195
  156. package/src/__tests__/skills-uninstall.test.ts +2 -2
  157. package/src/__tests__/skills.test.ts +23 -50
  158. package/src/__tests__/slack-channel-config.test.ts +2 -21
  159. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  160. package/src/__tests__/starter-bundle.test.ts +2 -8
  161. package/src/__tests__/stt-hints.test.ts +7 -2
  162. package/src/__tests__/system-prompt.test.ts +25 -45
  163. package/src/__tests__/task-compiler.test.ts +2 -27
  164. package/src/__tests__/task-management-tools.test.ts +2 -27
  165. package/src/__tests__/task-memory-cleanup.test.ts +173 -250
  166. package/src/__tests__/task-runner.test.ts +2 -27
  167. package/src/__tests__/task-scheduler.test.ts +2 -27
  168. package/src/__tests__/terminal-tools.test.ts +1 -17
  169. package/src/__tests__/test-preload.ts +3 -0
  170. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +0 -79
  171. package/src/__tests__/tool-approval-handler.test.ts +4 -27
  172. package/src/__tests__/tool-execution-abort-cleanup.test.ts +2 -11
  173. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -25
  174. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  175. package/src/__tests__/tool-executor.test.ts +0 -1
  176. package/src/__tests__/tool-grant-request-escalation.test.ts +4 -27
  177. package/src/__tests__/tool-preview-lifecycle.test.ts +0 -20
  178. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  179. package/src/__tests__/trust-store.test.ts +10 -42
  180. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -30
  181. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +3 -27
  182. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -28
  183. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -28
  184. package/src/__tests__/trusted-contact-verification.test.ts +2 -28
  185. package/src/__tests__/turn-boundary-resolution.test.ts +2 -34
  186. package/src/__tests__/twilio-provider.test.ts +0 -16
  187. package/src/__tests__/twilio-routes-twiml.test.ts +7 -12
  188. package/src/__tests__/twilio-routes.test.ts +0 -24
  189. package/src/__tests__/update-bulletin.test.ts +17 -89
  190. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -26
  191. package/src/__tests__/usage-routes.test.ts +2 -27
  192. package/src/__tests__/user-reference.test.ts +1 -5
  193. package/src/__tests__/vbundle-pax-and-symlink.test.ts +4 -34
  194. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -53
  195. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  196. package/src/__tests__/voice-invite-redemption.test.ts +2 -27
  197. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -30
  198. package/src/__tests__/voice-session-bridge.test.ts +2 -27
  199. package/src/__tests__/volume-security-guard.test.ts +2 -0
  200. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  201. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +4 -29
  202. package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +2 -2
  203. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +4 -29
  204. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  205. package/src/__tests__/workspace-migration-down-functions.test.ts +0 -6
  206. package/src/__tests__/workspace-policy.test.ts +1 -1
  207. package/src/acp/client-handler.ts +1 -2
  208. package/src/agent/attachments.ts +7 -2
  209. package/src/agent/image-optimize.ts +165 -0
  210. package/src/agent/loop.ts +1 -15
  211. package/src/bundler/app-compiler.ts +179 -2
  212. package/src/bundler/package-resolver.ts +3 -5
  213. package/src/cli/__tests__/notifications.test.ts +1 -24
  214. package/src/cli/cli-memory.ts +179 -0
  215. package/src/cli/commands/avatar.ts +3 -3
  216. package/src/cli/commands/config.ts +26 -13
  217. package/src/cli/commands/doctor.ts +2 -2
  218. package/src/cli/commands/memory.ts +41 -55
  219. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  220. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  221. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  222. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
  223. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  224. package/src/cli/commands/oauth/connect.ts +26 -6
  225. package/src/cli/commands/oauth/mode.ts +7 -0
  226. package/src/cli/commands/oauth/providers.ts +49 -42
  227. package/src/cli/commands/oauth/shared.ts +39 -3
  228. package/src/cli/commands/platform/__tests__/connect.test.ts +3 -49
  229. package/src/cli/commands/platform/__tests__/disconnect.test.ts +3 -49
  230. package/src/cli/commands/platform/__tests__/status.test.ts +5 -55
  231. package/src/cli/commands/platform/index.ts +16 -16
  232. package/src/cli/commands/skills.ts +88 -16
  233. package/src/cli/commands/trust.ts +2 -2
  234. package/src/cli/lib/daemon-credential-client.ts +2 -3
  235. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  236. package/src/config/bundled-skills/computer-use/TOOLS.json +7 -7
  237. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  238. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  239. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  240. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  241. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  242. package/src/config/bundled-skills/messaging/SKILL.md +26 -19
  243. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  244. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  245. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  246. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  247. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  248. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  249. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  250. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  251. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  252. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  253. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  254. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  255. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  256. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  257. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  258. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  259. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  260. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  261. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  262. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  263. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  264. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  265. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  266. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  267. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  268. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  269. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  270. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  271. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  272. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  273. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  274. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  275. package/src/config/bundled-tool-registry.ts +56 -4
  276. package/src/config/env-registry.ts +15 -8
  277. package/src/config/feature-flag-registry.json +29 -116
  278. package/src/config/loader.ts +4 -0
  279. package/src/config/schemas/platform.ts +8 -0
  280. package/src/config/schemas/security.ts +0 -6
  281. package/src/config/schemas/services.ts +8 -0
  282. package/src/config/schemas/timeouts.ts +1 -1
  283. package/src/config/skills.ts +18 -7
  284. package/src/context/token-estimator.ts +25 -18
  285. package/src/context/window-manager.ts +32 -9
  286. package/src/credential-execution/approval-bridge.ts +0 -1
  287. package/src/credential-execution/process-manager.ts +3 -1
  288. package/src/daemon/config-watcher.ts +51 -0
  289. package/src/daemon/context-overflow-reducer.ts +46 -2
  290. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  291. package/src/daemon/conversation-agent-loop.ts +99 -63
  292. package/src/daemon/conversation-error.ts +31 -8
  293. package/src/daemon/conversation-lifecycle.ts +33 -0
  294. package/src/daemon/conversation-media-retry.ts +85 -7
  295. package/src/daemon/conversation-notifiers.ts +4 -1
  296. package/src/daemon/conversation-process.ts +1 -0
  297. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  298. package/src/daemon/conversation-usage.ts +1 -0
  299. package/src/daemon/conversation.ts +41 -2
  300. package/src/daemon/daemon-control.ts +8 -2
  301. package/src/daemon/handlers/shared.ts +22 -12
  302. package/src/daemon/handlers/skills.ts +423 -201
  303. package/src/daemon/lifecycle.ts +52 -4
  304. package/src/daemon/main.ts +5 -1
  305. package/src/daemon/message-types/conversations.ts +5 -1
  306. package/src/daemon/message-types/messages.ts +3 -1
  307. package/src/daemon/message-types/skills.ts +97 -36
  308. package/src/daemon/providers-setup.ts +7 -0
  309. package/src/daemon/server.ts +35 -22
  310. package/src/daemon/tool-side-effects.ts +27 -5
  311. package/src/events/domain-events.ts +1 -2
  312. package/src/heartbeat/heartbeat-service.ts +1 -0
  313. package/src/hooks/cli.ts +2 -2
  314. package/src/hooks/runner.ts +15 -38
  315. package/src/inbound/platform-callback-registration.ts +14 -14
  316. package/src/memory/admin.ts +11 -45
  317. package/src/memory/conversation-bootstrap.ts +2 -0
  318. package/src/memory/conversation-crud.ts +242 -348
  319. package/src/memory/conversation-group-migration.ts +157 -0
  320. package/src/memory/conversation-queries.ts +4 -2
  321. package/src/memory/db-init.ts +39 -3
  322. package/src/memory/embed.ts +73 -0
  323. package/src/memory/embedding-backend.ts +8 -14
  324. package/src/memory/embedding-runtime-manager.ts +12 -114
  325. package/src/memory/fingerprint.ts +2 -2
  326. package/src/memory/graph/bootstrap.ts +512 -0
  327. package/src/memory/graph/capability-seed.ts +297 -0
  328. package/src/memory/graph/consolidation.ts +691 -0
  329. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  330. package/src/memory/graph/decay.test.ts +208 -0
  331. package/src/memory/graph/decay.ts +195 -0
  332. package/src/memory/graph/extraction-job.ts +69 -0
  333. package/src/memory/graph/extraction.test.ts +936 -0
  334. package/src/memory/graph/extraction.ts +1254 -0
  335. package/src/memory/graph/graph-search.ts +266 -0
  336. package/src/memory/graph/image-ref-utils.ts +29 -0
  337. package/src/memory/graph/injection.test.ts +513 -0
  338. package/src/memory/graph/injection.ts +439 -0
  339. package/src/memory/graph/inspect.ts +534 -0
  340. package/src/memory/graph/narrative.ts +267 -0
  341. package/src/memory/graph/pattern-scan.ts +269 -0
  342. package/src/memory/graph/retriever.ts +1008 -0
  343. package/src/memory/graph/scoring.test.ts +548 -0
  344. package/src/memory/graph/scoring.ts +232 -0
  345. package/src/memory/graph/serendipity.ts +65 -0
  346. package/src/memory/graph/store.test.ts +1050 -0
  347. package/src/memory/graph/store.ts +699 -0
  348. package/src/memory/graph/tool-handlers.ts +426 -0
  349. package/src/memory/graph/tools.ts +141 -0
  350. package/src/memory/graph/triggers.test.ts +487 -0
  351. package/src/memory/graph/triggers.ts +223 -0
  352. package/src/memory/graph/types.ts +271 -0
  353. package/src/memory/group-crud.ts +191 -0
  354. package/src/memory/indexer.ts +37 -19
  355. package/src/memory/job-handlers/cleanup.ts +0 -53
  356. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  357. package/src/memory/job-handlers/embedding.test.ts +3 -27
  358. package/src/memory/job-handlers/embedding.ts +5 -31
  359. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  360. package/src/memory/job-handlers/summarization.ts +32 -17
  361. package/src/memory/job-utils.ts +1 -1
  362. package/src/memory/jobs-store.ts +50 -70
  363. package/src/memory/jobs-worker.ts +147 -112
  364. package/src/memory/llm-usage-store.ts +35 -2
  365. package/src/memory/message-content.ts +1 -0
  366. package/src/memory/migrations/201-oauth-providers-feature-flag.ts +11 -0
  367. package/src/memory/migrations/202-drop-callback-transport-column.ts +13 -0
  368. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  369. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  370. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  371. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  372. package/src/memory/migrations/index.ts +6 -0
  373. package/src/memory/migrations/registry.ts +8 -0
  374. package/src/memory/qdrant-client.ts +44 -17
  375. package/src/memory/qdrant-manager.ts +26 -5
  376. package/src/memory/schema/index.ts +1 -0
  377. package/src/memory/schema/memory-graph.ts +139 -0
  378. package/src/memory/schema/oauth.ts +1 -1
  379. package/src/memory/search/semantic.ts +47 -91
  380. package/src/memory/slack-thread-store.ts +17 -0
  381. package/src/memory/task-memory-cleanup.ts +28 -50
  382. package/src/messaging/providers/outlook/adapter.ts +200 -0
  383. package/src/messaging/providers/outlook/client.ts +610 -0
  384. package/src/messaging/providers/outlook/types.ts +201 -0
  385. package/src/notifications/adapters/macos.ts +1 -0
  386. package/src/notifications/adapters/slack.ts +1 -1
  387. package/src/notifications/copy-composer.ts +9 -0
  388. package/src/notifications/signal.ts +16 -0
  389. package/src/oauth/__tests__/identity-verifier.test.ts +1 -1
  390. package/src/oauth/connect-orchestrator.ts +10 -3
  391. package/src/oauth/oauth-store.ts +10 -11
  392. package/src/oauth/provider-serializer.ts +3 -0
  393. package/src/oauth/provider-visibility.ts +16 -0
  394. package/src/oauth/seed-providers.ts +50 -17
  395. package/src/permissions/checker.ts +62 -9
  396. package/src/permissions/defaults.ts +4 -4
  397. package/src/permissions/types.ts +2 -4
  398. package/src/permissions/workspace-policy.ts +1 -1
  399. package/src/playbooks/playbook-compiler.ts +19 -18
  400. package/src/playbooks/types.ts +4 -3
  401. package/src/prompts/system-prompt.ts +6 -93
  402. package/src/prompts/templates/UPDATES.md +6 -0
  403. package/src/providers/anthropic/client.ts +47 -19
  404. package/src/providers/gemini/client.ts +1 -1
  405. package/src/providers/openai/client.ts +1 -1
  406. package/src/providers/registry.ts +1 -1
  407. package/src/providers/retry.ts +19 -3
  408. package/src/runtime/actor-trust-resolver.ts +5 -1
  409. package/src/runtime/auth/__tests__/credential-service.test.ts +1 -27
  410. package/src/runtime/auth/__tests__/token-service.test.ts +1 -25
  411. package/src/runtime/auth/route-policy.ts +7 -4
  412. package/src/runtime/guardian-reply-router.ts +10 -2
  413. package/src/runtime/http-server.ts +23 -3
  414. package/src/runtime/middleware/auth.ts +20 -0
  415. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  416. package/src/runtime/routes/attachment-routes.ts +106 -16
  417. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  418. package/src/runtime/routes/btw-routes.ts +8 -0
  419. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  420. package/src/runtime/routes/conversation-query-routes.ts +2 -58
  421. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  422. package/src/runtime/routes/debug-routes.ts +1 -1
  423. package/src/runtime/routes/global-search-routes.ts +21 -19
  424. package/src/runtime/routes/group-routes.ts +207 -0
  425. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  426. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  427. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  428. package/src/runtime/routes/inbound-stages/background-dispatch.ts +43 -2
  429. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  430. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  431. package/src/runtime/routes/memory-item-routes.test.ts +2 -31
  432. package/src/runtime/routes/memory-item-routes.ts +385 -341
  433. package/src/runtime/routes/oauth-apps.ts +18 -1
  434. package/src/runtime/routes/oauth-providers.ts +13 -1
  435. package/src/runtime/routes/schedule-routes.ts +2 -0
  436. package/src/runtime/routes/settings-routes.ts +1 -0
  437. package/src/runtime/routes/skills-routes.ts +103 -37
  438. package/src/runtime/routes/usage-routes.ts +19 -2
  439. package/src/runtime/routes/work-items-routes.test.ts +2 -27
  440. package/src/runtime/routes/workspace-routes.test.ts +3 -27
  441. package/src/schedule/scheduler.ts +8 -1
  442. package/src/security/oauth2.ts +1 -1
  443. package/src/security/secret-allowlist.ts +4 -4
  444. package/src/security/secure-keys.ts +4 -8
  445. package/src/shared/provider-env-vars.ts +19 -0
  446. package/src/skills/catalog-cache.ts +5 -0
  447. package/src/skills/catalog-install.ts +15 -14
  448. package/src/skills/clawhub.ts +134 -154
  449. package/src/skills/install-meta.ts +208 -0
  450. package/src/skills/managed-store.ts +27 -16
  451. package/src/skills/skill-memory.ts +210 -96
  452. package/src/skills/skillssh-registry.ts +19 -17
  453. package/src/tasks/task-runner.ts +3 -1
  454. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  455. package/src/tools/browser/runtime-check.ts +3 -1
  456. package/src/tools/memory/register.ts +63 -46
  457. package/src/tools/permission-checker.ts +7 -19
  458. package/src/tools/shared/filesystem/image-read.ts +22 -85
  459. package/src/tools/skills/skill-script-runner.ts +1 -1
  460. package/src/tools/terminal/safe-env.ts +1 -0
  461. package/src/tools/tool-manifest.ts +3 -3
  462. package/src/util/browser.ts +25 -10
  463. package/src/util/bun-runtime.ts +172 -0
  464. package/src/util/device-id.ts +3 -65
  465. package/src/watcher/providers/outlook-calendar.ts +343 -0
  466. package/src/watcher/providers/outlook.ts +198 -0
  467. package/src/workspace/git-service.ts +27 -6
  468. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  469. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  470. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  471. package/src/workspace/migrations/registry.ts +6 -0
  472. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  473. package/src/__tests__/journal-context.test.ts +0 -268
  474. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  475. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  476. package/src/__tests__/memory-query-builder.test.ts +0 -59
  477. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  478. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  479. package/src/__tests__/memory-regressions.test.ts +0 -3696
  480. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  481. package/src/daemon/conversation-memory.ts +0 -207
  482. package/src/memory/conversation-starters-cadence.ts +0 -74
  483. package/src/memory/items-extractor.ts +0 -860
  484. package/src/memory/job-handlers/batch-extraction.ts +0 -741
  485. package/src/memory/job-handlers/extraction.ts +0 -40
  486. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -383
  487. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  488. package/src/memory/journal-memory.ts +0 -224
  489. package/src/memory/query-builder.ts +0 -47
  490. package/src/memory/query-expansion.ts +0 -83
  491. package/src/memory/retriever.test.ts +0 -1590
  492. package/src/memory/retriever.ts +0 -1323
  493. package/src/memory/search/formatting.test.ts +0 -140
  494. package/src/memory/search/formatting.ts +0 -262
  495. package/src/memory/search/mmr.ts +0 -136
  496. package/src/memory/search/ranking.ts +0 -15
  497. package/src/memory/search/staleness.ts +0 -40
  498. package/src/memory/search/tier-classifier.ts +0 -18
  499. package/src/memory/search/types.ts +0 -121
  500. package/src/prompts/journal-context.ts +0 -156
  501. package/src/tools/memory/definitions.ts +0 -69
  502. package/src/tools/memory/handlers.test.ts +0 -590
  503. package/src/tools/memory/handlers.ts +0 -434
@@ -1,33 +1,9 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import {
5
- afterAll,
6
- beforeAll,
7
- beforeEach,
8
- describe,
9
- expect,
10
- mock,
11
- test,
12
- } from "bun:test";
1
+ import { beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
13
2
 
14
3
  import { eq } from "drizzle-orm";
15
4
 
16
5
  import { DEFAULT_CONFIG } from "../config/defaults.js";
17
6
 
18
- const testDir = mkdtempSync(join(tmpdir(), "task-memory-cleanup-"));
19
-
20
- mock.module("../util/platform.js", () => ({
21
- getDataDir: () => testDir,
22
- isMacOS: () => process.platform === "darwin",
23
- isLinux: () => process.platform === "linux",
24
- isWindows: () => process.platform === "win32",
25
- getPidPath: () => join(testDir, "test.pid"),
26
- getDbPath: () => join(testDir, "test.db"),
27
- getLogPath: () => join(testDir, "test.log"),
28
- ensureDataDir: () => {},
29
- }));
30
-
31
7
  mock.module("../util/logger.js", () => ({
32
8
  getLogger: () =>
33
9
  new Proxy({} as Record<string, unknown>, {
@@ -63,14 +39,13 @@ mock.module("../config/loader.js", () => ({
63
39
  invalidateConfigCache: () => {},
64
40
  }));
65
41
 
66
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
42
+ import { getDb, initializeDb } from "../memory/db.js";
67
43
  import { enqueueMemoryJob } from "../memory/jobs-store.js";
68
44
  import {
69
45
  conversations,
70
46
  cronJobs,
71
47
  cronRuns,
72
- memoryItems,
73
- memoryItemSources,
48
+ memoryGraphNodes,
74
49
  memoryJobs,
75
50
  messages,
76
51
  taskRuns,
@@ -81,6 +56,9 @@ import {
81
56
  isConversationFailed,
82
57
  } from "../memory/task-memory-cleanup.js";
83
58
 
59
+ const DEFAULT_EMOTIONAL_CHARGE =
60
+ '{"valence":0,"intensity":0.1,"decayCurve":"linear","decayRate":0.05,"originalIntensity":0.1}';
61
+
84
62
  describe("invalidateAssistantInferredItemsForConversation", () => {
85
63
  const now = 1_701_100_000_000;
86
64
  const convId = "conv-task-cleanup";
@@ -92,8 +70,7 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
92
70
 
93
71
  beforeEach(() => {
94
72
  const db = getDb();
95
- db.run("DELETE FROM memory_item_sources");
96
- db.run("DELETE FROM memory_items");
73
+ db.run("DELETE FROM memory_graph_nodes");
97
74
  db.run("DELETE FROM memory_jobs");
98
75
  db.run("DELETE FROM messages");
99
76
  db.run("DELETE FROM cron_runs");
@@ -103,15 +80,6 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
103
80
  db.run("DELETE FROM conversations");
104
81
  });
105
82
 
106
- afterAll(() => {
107
- resetDb();
108
- try {
109
- rmSync(testDir, { recursive: true });
110
- } catch {
111
- // best effort
112
- }
113
- });
114
-
115
83
  function seedConversations() {
116
84
  const db = getDb();
117
85
  for (const id of [convId, otherConvId]) {
@@ -161,165 +129,161 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
161
129
  .run();
162
130
  }
163
131
 
164
- function seedMemoryItems() {
132
+ function seedMemoryGraphNodes() {
165
133
  const db = getDb();
166
- db.insert(memoryItems)
134
+ db.insert(memoryGraphNodes)
167
135
  .values([
168
136
  {
169
137
  id: "item-assistant-inferred",
170
- kind: "fact",
171
- subject: "DMV appointment",
172
- statement: "Booked a DMV appointment at 9 AM.",
173
- status: "active",
138
+ content: "DMV appointment\nBooked a DMV appointment at 9 AM.",
139
+ type: "semantic",
140
+ created: now + 10,
141
+ lastAccessed: now + 10,
142
+ lastConsolidated: now + 10,
143
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
144
+ fidelity: "vivid",
174
145
  confidence: 0.8,
175
- importance: 0.7,
176
- fingerprint: "fp-assistant-inferred",
177
- verificationState: "assistant_inferred",
178
- sourceType: "extraction",
179
- sourceMessageRole: "assistant",
146
+ significance: 0.7,
147
+ stability: 14,
148
+ reinforcementCount: 0,
149
+ lastReinforced: now + 10,
150
+ sourceConversations: JSON.stringify([convId]),
151
+ sourceType: "inferred",
152
+ narrativeRole: null,
153
+ partOfStory: null,
180
154
  scopeId: "default",
181
- firstSeenAt: now + 10,
182
- lastSeenAt: now + 10,
183
155
  },
184
156
  {
185
157
  id: "item-user-reported",
186
- kind: "preference",
187
- subject: "notification pref",
188
- statement: "User prefers email notifications.",
189
- status: "active",
158
+ content: "notification pref\nUser prefers email notifications.",
159
+ type: "semantic",
160
+ created: now + 20,
161
+ lastAccessed: now + 20,
162
+ lastConsolidated: now + 20,
163
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
164
+ fidelity: "vivid",
190
165
  confidence: 0.9,
191
- importance: 0.8,
192
- fingerprint: "fp-user-reported",
193
- verificationState: "user_reported",
194
- sourceType: "extraction",
195
- sourceMessageRole: "user",
166
+ significance: 0.8,
167
+ stability: 14,
168
+ reinforcementCount: 0,
169
+ lastReinforced: now + 20,
170
+ sourceConversations: JSON.stringify([convId]),
171
+ sourceType: "direct",
172
+ narrativeRole: null,
173
+ partOfStory: null,
196
174
  scopeId: "default",
197
- firstSeenAt: now + 20,
198
- lastSeenAt: now + 20,
199
175
  },
200
176
  {
201
177
  id: "item-other-conv",
202
- kind: "fact",
203
- subject: "weather check",
204
- statement: "Checked weather for tomorrow.",
205
- status: "active",
178
+ content: "weather check\nChecked weather for tomorrow.",
179
+ type: "semantic",
180
+ created: now + 30,
181
+ lastAccessed: now + 30,
182
+ lastConsolidated: now + 30,
183
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
184
+ fidelity: "vivid",
206
185
  confidence: 0.7,
207
- importance: 0.5,
208
- fingerprint: "fp-other-conv",
209
- verificationState: "assistant_inferred",
210
- sourceType: "extraction",
211
- sourceMessageRole: "assistant",
186
+ significance: 0.5,
187
+ stability: 14,
188
+ reinforcementCount: 0,
189
+ lastReinforced: now + 30,
190
+ sourceConversations: JSON.stringify([otherConvId]),
191
+ sourceType: "inferred",
192
+ narrativeRole: null,
193
+ partOfStory: null,
212
194
  scopeId: "default",
213
- firstSeenAt: now + 30,
214
- lastSeenAt: now + 30,
215
195
  },
216
196
  {
217
- id: "item-already-superseded",
218
- kind: "fact",
219
- subject: "old claim",
220
- statement: "Old assistant claim already superseded.",
221
- status: "superseded",
197
+ id: "item-already-gone",
198
+ content: "old claim\nOld assistant claim already gone.",
199
+ type: "semantic",
200
+ created: now + 5,
201
+ lastAccessed: now + 5,
202
+ lastConsolidated: now + 5,
203
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
204
+ fidelity: "gone",
222
205
  confidence: 0.6,
223
- importance: 0.4,
224
- fingerprint: "fp-already-superseded",
225
- verificationState: "assistant_inferred",
226
- sourceType: "extraction",
227
- sourceMessageRole: "assistant",
206
+ significance: 0.4,
207
+ stability: 14,
208
+ reinforcementCount: 0,
209
+ lastReinforced: now + 5,
210
+ sourceConversations: JSON.stringify([convId]),
211
+ sourceType: "inferred",
212
+ narrativeRole: null,
213
+ partOfStory: null,
228
214
  scopeId: "default",
229
- firstSeenAt: now + 5,
230
- lastSeenAt: now + 5,
231
- },
232
- ])
233
- .run();
234
-
235
- db.insert(memoryItemSources)
236
- .values([
237
- {
238
- memoryItemId: "item-assistant-inferred",
239
- messageId: "msg-task-1",
240
- evidence: "booking claim",
241
- createdAt: now + 10,
242
- },
243
- {
244
- memoryItemId: "item-user-reported",
245
- messageId: "msg-task-2",
246
- evidence: "user stated",
247
- createdAt: now + 20,
248
- },
249
- {
250
- memoryItemId: "item-other-conv",
251
- messageId: "msg-other",
252
- evidence: "weather",
253
- createdAt: now + 30,
254
- },
255
- {
256
- memoryItemId: "item-already-superseded",
257
- messageId: "msg-task-1",
258
- evidence: "old claim",
259
- createdAt: now + 5,
260
215
  },
261
216
  ])
262
217
  .run();
263
218
  }
264
219
 
265
- test("only invalidates assistant_inferred items, not user_reported", () => {
220
+ test("only invalidates inferred items, not direct (user-reported)", () => {
266
221
  seedConversations();
267
222
  seedMessages();
268
- seedMemoryItems();
223
+ seedMemoryGraphNodes();
269
224
 
270
225
  const affected = invalidateAssistantInferredItemsForConversation(convId);
271
226
 
272
227
  expect(affected).toBe(1);
273
228
 
274
229
  const db = getDb();
275
- const assistantItem = db
230
+ const inferredItem = db
276
231
  .select()
277
- .from(memoryItems)
278
- .where(eq(memoryItems.id, "item-assistant-inferred"))
232
+ .from(memoryGraphNodes)
233
+ .where(eq(memoryGraphNodes.id, "item-assistant-inferred"))
279
234
  .get();
280
- expect(assistantItem?.status).toBe("invalidated");
281
- expect(assistantItem?.invalidAt).not.toBeNull();
235
+ expect(inferredItem?.fidelity).toBe("gone");
282
236
 
283
- const userItem = db
237
+ const directItem = db
284
238
  .select()
285
- .from(memoryItems)
286
- .where(eq(memoryItems.id, "item-user-reported"))
239
+ .from(memoryGraphNodes)
240
+ .where(eq(memoryGraphNodes.id, "item-user-reported"))
287
241
  .get();
288
- expect(userItem?.status).toBe("active");
289
- expect(userItem?.invalidAt).toBeNull();
242
+ expect(directItem?.fidelity).toBe("vivid");
290
243
  });
291
244
 
292
245
  test("does not affect items from other conversations", () => {
293
246
  seedConversations();
294
247
  seedMessages();
295
- seedMemoryItems();
248
+ seedMemoryGraphNodes();
296
249
 
297
250
  invalidateAssistantInferredItemsForConversation(convId);
298
251
 
299
252
  const db = getDb();
300
253
  const otherItem = db
301
254
  .select()
302
- .from(memoryItems)
303
- .where(eq(memoryItems.id, "item-other-conv"))
255
+ .from(memoryGraphNodes)
256
+ .where(eq(memoryGraphNodes.id, "item-other-conv"))
304
257
  .get();
305
- expect(otherItem?.status).toBe("active");
306
- expect(otherItem?.invalidAt).toBeNull();
258
+ expect(otherItem?.fidelity).toBe("vivid");
307
259
  });
308
260
 
309
261
  test("does not invalidate items also sourced from another conversation", () => {
310
262
  seedConversations();
311
263
  seedMessages();
312
- seedMemoryItems();
313
264
 
314
- // Add a second source from the other conversation to the assistant-inferred item.
315
- // This simulates deduplication: the same fact was extracted from both conversations.
265
+ // Insert a node sourced from both conversations (corroboration).
316
266
  const db = getDb();
317
- db.insert(memoryItemSources)
267
+ db.insert(memoryGraphNodes)
318
268
  .values({
319
- memoryItemId: "item-assistant-inferred",
320
- messageId: "msg-other",
321
- evidence: "corroborating source from other conversation",
322
- createdAt: now + 40,
269
+ id: "item-corroborated",
270
+ content: "DMV appointment\nBooked a DMV appointment at 9 AM.",
271
+ type: "semantic",
272
+ created: now + 10,
273
+ lastAccessed: now + 10,
274
+ lastConsolidated: now + 10,
275
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
276
+ fidelity: "vivid",
277
+ confidence: 0.8,
278
+ significance: 0.7,
279
+ stability: 14,
280
+ reinforcementCount: 0,
281
+ lastReinforced: now + 10,
282
+ sourceConversations: JSON.stringify([convId, otherConvId]),
283
+ sourceType: "inferred",
284
+ narrativeRole: null,
285
+ partOfStory: null,
286
+ scopeId: "default",
323
287
  })
324
288
  .run();
325
289
 
@@ -330,33 +294,32 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
330
294
 
331
295
  const item = db
332
296
  .select()
333
- .from(memoryItems)
334
- .where(eq(memoryItems.id, "item-assistant-inferred"))
297
+ .from(memoryGraphNodes)
298
+ .where(eq(memoryGraphNodes.id, "item-corroborated"))
335
299
  .get();
336
- expect(item?.status).toBe("active");
337
- expect(item?.invalidAt).toBeNull();
300
+ expect(item?.fidelity).toBe("vivid");
338
301
  });
339
302
 
340
- test("does not affect already-superseded items", () => {
303
+ test("does not affect already-gone items", () => {
341
304
  seedConversations();
342
305
  seedMessages();
343
- seedMemoryItems();
306
+ seedMemoryGraphNodes();
344
307
 
345
308
  invalidateAssistantInferredItemsForConversation(convId);
346
309
 
347
310
  const db = getDb();
348
- const supersededItem = db
311
+ const goneItem = db
349
312
  .select()
350
- .from(memoryItems)
351
- .where(eq(memoryItems.id, "item-already-superseded"))
313
+ .from(memoryGraphNodes)
314
+ .where(eq(memoryGraphNodes.id, "item-already-gone"))
352
315
  .get();
353
- expect(supersededItem?.status).toBe("superseded");
316
+ expect(goneItem?.fidelity).toBe("gone");
354
317
  });
355
318
 
356
319
  test("returns 0 when no matching items exist", () => {
357
320
  seedConversations();
358
321
  seedMessages();
359
- // No memory items seeded
322
+ // No memory graph nodes seeded
360
323
 
361
324
  const affected = invalidateAssistantInferredItemsForConversation(convId);
362
325
  expect(affected).toBe(0);
@@ -365,7 +328,7 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
365
328
  test("returns 0 for unknown conversation", () => {
366
329
  seedConversations();
367
330
  seedMessages();
368
- seedMemoryItems();
331
+ seedMemoryGraphNodes();
369
332
 
370
333
  const affected =
371
334
  invalidateAssistantInferredItemsForConversation("conv-nonexistent");
@@ -445,54 +408,40 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
445
408
  ])
446
409
  .run();
447
410
 
448
- // A memory item sourced from both conversations
449
- db.insert(memoryItems)
411
+ // A memory node sourced from both failed conversations
412
+ db.insert(memoryGraphNodes)
450
413
  .values({
451
414
  id: "item-cross-sourced",
452
- kind: "fact",
453
- subject: "cross-sourced claim",
454
- statement: "Claim from two failed tasks.",
455
- status: "active",
415
+ content: "cross-sourced claim\nClaim from two failed tasks.",
416
+ type: "semantic",
417
+ created: now + 10,
418
+ lastAccessed: now + 20,
419
+ lastConsolidated: now + 10,
420
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
421
+ fidelity: "vivid",
456
422
  confidence: 0.8,
457
- importance: 0.7,
458
- fingerprint: "fp-cross-sourced",
459
- verificationState: "assistant_inferred",
460
- sourceType: "extraction",
461
- sourceMessageRole: "assistant",
423
+ significance: 0.7,
424
+ stability: 14,
425
+ reinforcementCount: 0,
426
+ lastReinforced: now + 10,
427
+ sourceConversations: JSON.stringify([convA, convB]),
428
+ sourceType: "inferred",
429
+ narrativeRole: null,
430
+ partOfStory: null,
462
431
  scopeId: "default",
463
- firstSeenAt: now + 10,
464
- lastSeenAt: now + 20,
465
432
  })
466
433
  .run();
467
434
 
468
- db.insert(memoryItemSources)
469
- .values([
470
- {
471
- memoryItemId: "item-cross-sourced",
472
- messageId: "msg-a",
473
- evidence: "claim from A",
474
- createdAt: now + 10,
475
- },
476
- {
477
- memoryItemId: "item-cross-sourced",
478
- messageId: "msg-b",
479
- evidence: "claim from B",
480
- createdAt: now + 20,
481
- },
482
- ])
483
- .run();
484
-
485
435
  // Invalidating for convA should succeed because convB is also from a failed task
486
436
  const affected = invalidateAssistantInferredItemsForConversation(convA);
487
437
  expect(affected).toBe(1);
488
438
 
489
439
  const item = db
490
440
  .select()
491
- .from(memoryItems)
492
- .where(eq(memoryItems.id, "item-cross-sourced"))
441
+ .from(memoryGraphNodes)
442
+ .where(eq(memoryGraphNodes.id, "item-cross-sourced"))
493
443
  .get();
494
- expect(item?.status).toBe("invalidated");
495
- expect(item?.invalidAt).not.toBeNull();
444
+ expect(item?.fidelity).toBe("gone");
496
445
  });
497
446
 
498
447
  test("invalidates items when corroborating conversation is from a failed schedule run", () => {
@@ -571,51 +520,38 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
571
520
  ])
572
521
  .run();
573
522
 
574
- db.insert(memoryItems)
523
+ db.insert(memoryGraphNodes)
575
524
  .values({
576
525
  id: "item-cross-sched",
577
- kind: "fact",
578
- subject: "cross-sourced schedule claim",
579
- statement: "Claim from two failed schedules.",
580
- status: "active",
526
+ content: "cross-sourced schedule claim\nClaim from two failed schedules.",
527
+ type: "semantic",
528
+ created: now + 10,
529
+ lastAccessed: now + 20,
530
+ lastConsolidated: now + 10,
531
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
532
+ fidelity: "vivid",
581
533
  confidence: 0.8,
582
- importance: 0.7,
583
- fingerprint: "fp-cross-sched",
584
- verificationState: "assistant_inferred",
585
- sourceType: "extraction",
586
- sourceMessageRole: "assistant",
534
+ significance: 0.7,
535
+ stability: 14,
536
+ reinforcementCount: 0,
537
+ lastReinforced: now + 10,
538
+ sourceConversations: JSON.stringify([convA, convB]),
539
+ sourceType: "inferred",
540
+ narrativeRole: null,
541
+ partOfStory: null,
587
542
  scopeId: "default",
588
- firstSeenAt: now + 10,
589
- lastSeenAt: now + 20,
590
543
  })
591
544
  .run();
592
545
 
593
- db.insert(memoryItemSources)
594
- .values([
595
- {
596
- memoryItemId: "item-cross-sched",
597
- messageId: "msg-sched-a",
598
- evidence: "claim from A",
599
- createdAt: now + 10,
600
- },
601
- {
602
- memoryItemId: "item-cross-sched",
603
- messageId: "msg-sched-b",
604
- evidence: "claim from B",
605
- createdAt: now + 20,
606
- },
607
- ])
608
- .run();
609
-
610
546
  const affected = invalidateAssistantInferredItemsForConversation(convA);
611
547
  expect(affected).toBe(1);
612
548
 
613
549
  const item = db
614
550
  .select()
615
- .from(memoryItems)
616
- .where(eq(memoryItems.id, "item-cross-sched"))
551
+ .from(memoryGraphNodes)
552
+ .where(eq(memoryGraphNodes.id, "item-cross-sched"))
617
553
  .get();
618
- expect(item?.status).toBe("invalidated");
554
+ expect(item?.fidelity).toBe("gone");
619
555
  });
620
556
 
621
557
  test("preserves items when corroborating conversation is from a successful task run", () => {
@@ -689,42 +625,29 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
689
625
  ])
690
626
  .run();
691
627
 
692
- db.insert(memoryItems)
628
+ db.insert(memoryGraphNodes)
693
629
  .values({
694
630
  id: "item-with-good-corroboration",
695
- kind: "fact",
696
- subject: "corroborated claim",
697
- statement: "Claim corroborated by successful task.",
698
- status: "active",
631
+ content: "corroborated claim\nClaim corroborated by successful task.",
632
+ type: "semantic",
633
+ created: now + 10,
634
+ lastAccessed: now + 20,
635
+ lastConsolidated: now + 10,
636
+ emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
637
+ fidelity: "vivid",
699
638
  confidence: 0.8,
700
- importance: 0.7,
701
- fingerprint: "fp-good-corroboration",
702
- verificationState: "assistant_inferred",
703
- sourceType: "extraction",
704
- sourceMessageRole: "assistant",
639
+ significance: 0.7,
640
+ stability: 14,
641
+ reinforcementCount: 0,
642
+ lastReinforced: now + 10,
643
+ sourceConversations: JSON.stringify([convFailed, convSuccess]),
644
+ sourceType: "inferred",
645
+ narrativeRole: null,
646
+ partOfStory: null,
705
647
  scopeId: "default",
706
- firstSeenAt: now + 10,
707
- lastSeenAt: now + 20,
708
648
  })
709
649
  .run();
710
650
 
711
- db.insert(memoryItemSources)
712
- .values([
713
- {
714
- memoryItemId: "item-with-good-corroboration",
715
- messageId: "msg-failed",
716
- evidence: "claim from failed",
717
- createdAt: now + 10,
718
- },
719
- {
720
- memoryItemId: "item-with-good-corroboration",
721
- messageId: "msg-success",
722
- evidence: "claim from success",
723
- createdAt: now + 20,
724
- },
725
- ])
726
- .run();
727
-
728
651
  // The successful task run corroborates the claim, so it should NOT be invalidated
729
652
  const affected =
730
653
  invalidateAssistantInferredItemsForConversation(convFailed);
@@ -732,10 +655,10 @@ describe("invalidateAssistantInferredItemsForConversation", () => {
732
655
 
733
656
  const item = db
734
657
  .select()
735
- .from(memoryItems)
736
- .where(eq(memoryItems.id, "item-with-good-corroboration"))
658
+ .from(memoryGraphNodes)
659
+ .where(eq(memoryGraphNodes.id, "item-with-good-corroboration"))
737
660
  .get();
738
- expect(item?.status).toBe("active");
661
+ expect(item?.fidelity).toBe("vivid");
739
662
  });
740
663
 
741
664
  test("isConversationFailed derives state from durable task_runs/cron_runs", () => {
@@ -1,20 +1,4 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
5
-
6
- const testDir = mkdtempSync(join(tmpdir(), "task-runner-test-"));
7
-
8
- mock.module("../util/platform.js", () => ({
9
- getDataDir: () => testDir,
10
- isMacOS: () => process.platform === "darwin",
11
- isLinux: () => process.platform === "linux",
12
- isWindows: () => process.platform === "win32",
13
- getPidPath: () => join(testDir, "test.pid"),
14
- getDbPath: () => join(testDir, "test.db"),
15
- getLogPath: () => join(testDir, "test.log"),
16
- ensureDataDir: () => {},
17
- }));
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
18
2
 
19
3
  mock.module("../util/logger.js", () => ({
20
4
  getLogger: () =>
@@ -23,22 +7,13 @@ mock.module("../util/logger.js", () => ({
23
7
  }),
24
8
  }));
25
9
 
26
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
10
+ import { getDb, initializeDb } from "../memory/db.js";
27
11
  import { getTaskRunRules } from "../tasks/ephemeral-permissions.js";
28
12
  import { renderTemplate, runTask } from "../tasks/task-runner.js";
29
13
  import { createTask } from "../tasks/task-store.js";
30
14
 
31
15
  initializeDb();
32
16
 
33
- afterAll(() => {
34
- resetDb();
35
- try {
36
- rmSync(testDir, { recursive: true });
37
- } catch {
38
- /* best effort */
39
- }
40
- });
41
-
42
17
  // ── renderTemplate ──────────────────────────────────────────────────
43
18
 
44
19
  describe("renderTemplate", () => {