@vellumai/assistant 0.5.16 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/ARCHITECTURE.md +1 -1
  2. package/Dockerfile +0 -3
  3. package/knip.json +2 -1
  4. package/openapi.yaml +660 -80
  5. package/package.json +1 -1
  6. package/src/__tests__/actor-token-service.test.ts +68 -0
  7. package/src/__tests__/agent-loop.test.ts +0 -32
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  9. package/src/__tests__/anthropic-provider.test.ts +57 -3
  10. package/src/__tests__/app-compiler.test.ts +120 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  12. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  13. package/src/__tests__/call-domain.test.ts +2 -6
  14. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  15. package/src/__tests__/call-recovery.test.ts +2 -6
  16. package/src/__tests__/call-routes-http.test.ts +2 -6
  17. package/src/__tests__/call-store.test.ts +2 -6
  18. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  19. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  20. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  21. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  22. package/src/__tests__/checker.test.ts +25 -3
  23. package/src/__tests__/clawhub.test.ts +54 -24
  24. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  25. package/src/__tests__/cli-memory.test.ts +74 -69
  26. package/src/__tests__/config-schema.test.ts +1 -1
  27. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  28. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  29. package/src/__tests__/contacts-tools.test.ts +31 -0
  30. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  31. package/src/__tests__/context-token-estimator.test.ts +175 -10
  32. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  33. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  34. package/src/__tests__/conversation-attachments.test.ts +2 -6
  35. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  36. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  37. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  38. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  39. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  40. package/src/__tests__/conversation-error.test.ts +33 -2
  41. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  42. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  43. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  44. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  45. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  46. package/src/__tests__/conversation-store.test.ts +2 -6
  47. package/src/__tests__/conversation-usage.test.ts +2 -6
  48. package/src/__tests__/conversation-wipe.test.ts +11 -408
  49. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  50. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  51. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  52. package/src/__tests__/followup-tools.test.ts +2 -6
  53. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  54. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  55. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  56. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  57. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  58. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  59. package/src/__tests__/guardian-action-store.test.ts +2 -6
  60. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  61. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  62. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  63. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  64. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  65. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  66. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  67. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  68. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  69. package/src/__tests__/injection-block.test.ts +154 -0
  70. package/src/__tests__/install-meta.test.ts +506 -0
  71. package/src/__tests__/install-skill-routing.test.ts +292 -0
  72. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  73. package/src/__tests__/invite-routes-http.test.ts +2 -6
  74. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  75. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  76. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  77. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  78. package/src/__tests__/llm-usage-store.test.ts +2 -6
  79. package/src/__tests__/log-export-workspace.test.ts +2 -6
  80. package/src/__tests__/managed-store.test.ts +38 -11
  81. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  82. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  83. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  84. package/src/__tests__/non-member-access-request.test.ts +2 -6
  85. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  86. package/src/__tests__/oauth-cli.test.ts +364 -2
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  88. package/src/__tests__/outlook-attachments.test.ts +301 -0
  89. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  90. package/src/__tests__/outlook-categories.test.ts +212 -0
  91. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  92. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  93. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  94. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  95. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  96. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  97. package/src/__tests__/outlook-trash.test.ts +77 -0
  98. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  99. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  100. package/src/__tests__/playbook-execution.test.ts +76 -80
  101. package/src/__tests__/playbook-tools.test.ts +5 -7
  102. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  103. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  104. package/src/__tests__/registry.test.ts +2 -2
  105. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  106. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  107. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  108. package/src/__tests__/schedule-store.test.ts +2 -6
  109. package/src/__tests__/schedule-tools.test.ts +2 -6
  110. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  111. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  112. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  113. package/src/__tests__/search-skills-unified.test.ts +421 -0
  114. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  115. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  116. package/src/__tests__/sequence-store.test.ts +2 -6
  117. package/src/__tests__/server-history-render.test.ts +2 -6
  118. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  119. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  120. package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
  121. package/src/__tests__/skill-memory.test.ts +140 -98
  122. package/src/__tests__/skills-uninstall.test.ts +2 -2
  123. package/src/__tests__/skills.test.ts +1 -1
  124. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  125. package/src/__tests__/task-compiler.test.ts +2 -6
  126. package/src/__tests__/task-management-tools.test.ts +2 -6
  127. package/src/__tests__/task-memory-cleanup.test.ts +173 -229
  128. package/src/__tests__/task-runner.test.ts +2 -6
  129. package/src/__tests__/task-scheduler.test.ts +2 -6
  130. package/src/__tests__/test-preload.ts +3 -0
  131. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  132. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  133. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  134. package/src/__tests__/trust-store.test.ts +1 -1
  135. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  138. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  139. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  140. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  141. package/src/__tests__/usage-routes.test.ts +2 -6
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  143. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  145. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  146. package/src/__tests__/volume-security-guard.test.ts +2 -0
  147. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  148. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  149. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  150. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  151. package/src/__tests__/workspace-policy.test.ts +1 -1
  152. package/src/agent/attachments.ts +7 -2
  153. package/src/agent/image-optimize.ts +165 -0
  154. package/src/agent/loop.ts +1 -15
  155. package/src/bundler/app-compiler.ts +179 -2
  156. package/src/bundler/package-resolver.ts +3 -5
  157. package/src/cli/__tests__/notifications.test.ts +1 -2
  158. package/src/cli/cli-memory.ts +67 -64
  159. package/src/cli/commands/avatar.ts +3 -3
  160. package/src/cli/commands/config.ts +26 -13
  161. package/src/cli/commands/doctor.ts +2 -2
  162. package/src/cli/commands/memory.ts +41 -55
  163. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  164. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  165. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  166. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  167. package/src/cli/commands/oauth/connect.ts +11 -6
  168. package/src/cli/commands/oauth/mode.ts +7 -0
  169. package/src/cli/commands/oauth/shared.ts +39 -3
  170. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  171. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  172. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  173. package/src/cli/commands/platform/index.ts +16 -16
  174. package/src/cli/commands/skills.ts +88 -16
  175. package/src/cli/commands/trust.ts +2 -2
  176. package/src/cli/lib/daemon-credential-client.ts +2 -3
  177. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  178. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  179. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  180. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  181. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  182. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  183. package/src/config/bundled-skills/messaging/SKILL.md +10 -18
  184. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  185. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  186. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  187. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  188. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  189. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  190. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  191. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  192. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  193. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  194. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  195. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  196. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  197. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  198. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  199. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  200. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  201. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  202. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  203. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  204. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  205. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  206. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  207. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  208. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  209. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  210. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  211. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  212. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  213. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  214. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  215. package/src/config/bundled-tool-registry.ts +56 -4
  216. package/src/config/env-registry.ts +15 -8
  217. package/src/config/feature-flag-registry.json +21 -124
  218. package/src/config/schemas/platform.ts +8 -0
  219. package/src/config/schemas/timeouts.ts +1 -1
  220. package/src/config/skills.ts +18 -7
  221. package/src/context/token-estimator.ts +25 -18
  222. package/src/context/window-manager.ts +6 -2
  223. package/src/credential-execution/process-manager.ts +3 -1
  224. package/src/daemon/context-overflow-reducer.ts +46 -2
  225. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  226. package/src/daemon/conversation-agent-loop.ts +96 -61
  227. package/src/daemon/conversation-error.ts +31 -8
  228. package/src/daemon/conversation-lifecycle.ts +33 -0
  229. package/src/daemon/conversation-media-retry.ts +85 -7
  230. package/src/daemon/conversation-notifiers.ts +4 -1
  231. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  232. package/src/daemon/conversation.ts +41 -2
  233. package/src/daemon/daemon-control.ts +8 -2
  234. package/src/daemon/handlers/shared.ts +22 -12
  235. package/src/daemon/handlers/skills.ts +416 -202
  236. package/src/daemon/lifecycle.ts +40 -1
  237. package/src/daemon/main.ts +5 -1
  238. package/src/daemon/message-types/conversations.ts +4 -1
  239. package/src/daemon/message-types/messages.ts +3 -1
  240. package/src/daemon/message-types/skills.ts +97 -36
  241. package/src/daemon/providers-setup.ts +5 -0
  242. package/src/daemon/server.ts +11 -2
  243. package/src/daemon/tool-side-effects.ts +27 -5
  244. package/src/heartbeat/heartbeat-service.ts +1 -0
  245. package/src/hooks/cli.ts +2 -2
  246. package/src/hooks/runner.ts +15 -38
  247. package/src/inbound/platform-callback-registration.ts +14 -14
  248. package/src/memory/admin.ts +11 -45
  249. package/src/memory/conversation-bootstrap.ts +2 -0
  250. package/src/memory/conversation-crud.ts +242 -348
  251. package/src/memory/conversation-group-migration.ts +157 -0
  252. package/src/memory/conversation-queries.ts +4 -2
  253. package/src/memory/db-init.ts +30 -3
  254. package/src/memory/embed.ts +73 -0
  255. package/src/memory/embedding-backend.ts +8 -14
  256. package/src/memory/embedding-runtime-manager.ts +12 -114
  257. package/src/memory/fingerprint.ts +2 -2
  258. package/src/memory/graph/bootstrap.ts +512 -0
  259. package/src/memory/graph/capability-seed.ts +297 -0
  260. package/src/memory/graph/consolidation.ts +691 -0
  261. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  262. package/src/memory/graph/decay.test.ts +208 -0
  263. package/src/memory/graph/decay.ts +195 -0
  264. package/src/memory/graph/extraction-job.ts +69 -0
  265. package/src/memory/graph/extraction.test.ts +936 -0
  266. package/src/memory/graph/extraction.ts +1254 -0
  267. package/src/memory/graph/graph-search.ts +266 -0
  268. package/src/memory/graph/image-ref-utils.ts +29 -0
  269. package/src/memory/graph/injection.test.ts +513 -0
  270. package/src/memory/graph/injection.ts +439 -0
  271. package/src/memory/graph/inspect.ts +534 -0
  272. package/src/memory/graph/narrative.ts +267 -0
  273. package/src/memory/graph/pattern-scan.ts +269 -0
  274. package/src/memory/graph/retriever.ts +1008 -0
  275. package/src/memory/graph/scoring.test.ts +548 -0
  276. package/src/memory/graph/scoring.ts +232 -0
  277. package/src/memory/graph/serendipity.ts +65 -0
  278. package/src/memory/graph/store.test.ts +1050 -0
  279. package/src/memory/graph/store.ts +699 -0
  280. package/src/memory/graph/tool-handlers.ts +426 -0
  281. package/src/memory/graph/tools.ts +141 -0
  282. package/src/memory/graph/triggers.test.ts +487 -0
  283. package/src/memory/graph/triggers.ts +223 -0
  284. package/src/memory/graph/types.ts +271 -0
  285. package/src/memory/group-crud.ts +191 -0
  286. package/src/memory/indexer.ts +37 -19
  287. package/src/memory/job-handlers/cleanup.ts +0 -53
  288. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  289. package/src/memory/job-handlers/embedding.ts +5 -31
  290. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  291. package/src/memory/job-handlers/summarization.ts +32 -17
  292. package/src/memory/job-utils.ts +1 -1
  293. package/src/memory/jobs-store.ts +50 -70
  294. package/src/memory/jobs-worker.ts +147 -112
  295. package/src/memory/message-content.ts +1 -0
  296. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  297. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  298. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  299. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  300. package/src/memory/migrations/index.ts +4 -0
  301. package/src/memory/migrations/registry.ts +8 -0
  302. package/src/memory/qdrant-client.ts +44 -17
  303. package/src/memory/schema/index.ts +1 -0
  304. package/src/memory/schema/memory-graph.ts +139 -0
  305. package/src/memory/search/semantic.ts +47 -91
  306. package/src/memory/task-memory-cleanup.ts +28 -50
  307. package/src/messaging/providers/outlook/adapter.ts +8 -1
  308. package/src/messaging/providers/outlook/client.ts +299 -0
  309. package/src/messaging/providers/outlook/types.ts +118 -0
  310. package/src/notifications/adapters/macos.ts +1 -0
  311. package/src/notifications/copy-composer.ts +9 -0
  312. package/src/notifications/signal.ts +16 -0
  313. package/src/oauth/seed-providers.ts +2 -1
  314. package/src/permissions/checker.ts +24 -3
  315. package/src/permissions/defaults.ts +4 -4
  316. package/src/permissions/workspace-policy.ts +1 -1
  317. package/src/playbooks/playbook-compiler.ts +19 -18
  318. package/src/playbooks/types.ts +4 -3
  319. package/src/prompts/system-prompt.ts +3 -29
  320. package/src/providers/anthropic/client.ts +47 -19
  321. package/src/providers/gemini/client.ts +1 -1
  322. package/src/providers/openai/client.ts +1 -1
  323. package/src/providers/registry.ts +1 -1
  324. package/src/providers/retry.ts +19 -3
  325. package/src/runtime/actor-trust-resolver.ts +5 -1
  326. package/src/runtime/auth/route-policy.ts +7 -0
  327. package/src/runtime/guardian-reply-router.ts +5 -1
  328. package/src/runtime/http-server.ts +23 -3
  329. package/src/runtime/middleware/auth.ts +20 -0
  330. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  331. package/src/runtime/routes/attachment-routes.ts +106 -16
  332. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  333. package/src/runtime/routes/btw-routes.ts +8 -0
  334. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  335. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  336. package/src/runtime/routes/debug-routes.ts +1 -1
  337. package/src/runtime/routes/global-search-routes.ts +21 -19
  338. package/src/runtime/routes/group-routes.ts +207 -0
  339. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  340. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  341. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  342. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  343. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  344. package/src/runtime/routes/memory-item-routes.test.ts +2 -14
  345. package/src/runtime/routes/memory-item-routes.ts +341 -388
  346. package/src/runtime/routes/schedule-routes.ts +2 -0
  347. package/src/runtime/routes/skills-routes.ts +103 -37
  348. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  349. package/src/schedule/scheduler.ts +8 -1
  350. package/src/security/oauth2.ts +1 -1
  351. package/src/security/secure-keys.ts +4 -8
  352. package/src/shared/provider-env-vars.ts +19 -0
  353. package/src/skills/catalog-cache.ts +5 -0
  354. package/src/skills/catalog-install.ts +15 -14
  355. package/src/skills/clawhub.ts +134 -154
  356. package/src/skills/install-meta.ts +208 -0
  357. package/src/skills/managed-store.ts +27 -16
  358. package/src/skills/skill-memory.ts +152 -77
  359. package/src/skills/skillssh-registry.ts +19 -17
  360. package/src/tasks/task-runner.ts +3 -1
  361. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  362. package/src/tools/browser/runtime-check.ts +3 -1
  363. package/src/tools/memory/register.ts +63 -46
  364. package/src/tools/permission-checker.ts +7 -1
  365. package/src/tools/shared/filesystem/image-read.ts +22 -85
  366. package/src/tools/terminal/safe-env.ts +1 -0
  367. package/src/tools/tool-manifest.ts +3 -3
  368. package/src/util/browser.ts +25 -10
  369. package/src/util/bun-runtime.ts +172 -0
  370. package/src/watcher/providers/outlook-calendar.ts +343 -0
  371. package/src/watcher/providers/outlook.ts +198 -0
  372. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  373. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  374. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  375. package/src/workspace/migrations/registry.ts +6 -0
  376. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  377. package/src/__tests__/journal-context.test.ts +0 -268
  378. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  379. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  380. package/src/__tests__/memory-query-builder.test.ts +0 -59
  381. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  382. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  383. package/src/__tests__/memory-regressions.test.ts +0 -3696
  384. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  385. package/src/daemon/conversation-memory.ts +0 -207
  386. package/src/memory/conversation-starters-cadence.ts +0 -74
  387. package/src/memory/items-extractor.ts +0 -860
  388. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  389. package/src/memory/job-handlers/extraction.ts +0 -40
  390. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  391. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  392. package/src/memory/journal-memory.ts +0 -224
  393. package/src/memory/query-builder.ts +0 -47
  394. package/src/memory/query-expansion.ts +0 -83
  395. package/src/memory/retriever.test.ts +0 -1592
  396. package/src/memory/retriever.ts +0 -1331
  397. package/src/memory/search/formatting.test.ts +0 -140
  398. package/src/memory/search/formatting.ts +0 -262
  399. package/src/memory/search/mmr.ts +0 -139
  400. package/src/memory/search/ranking.ts +0 -15
  401. package/src/memory/search/staleness.ts +0 -40
  402. package/src/memory/search/tier-classifier.ts +0 -18
  403. package/src/memory/search/types.ts +0 -121
  404. package/src/prompts/journal-context.ts +0 -154
  405. package/src/tools/memory/definitions.ts +0 -69
  406. package/src/tools/memory/handlers.test.ts +0 -562
  407. package/src/tools/memory/handlers.ts +0 -434
@@ -445,6 +445,15 @@ function makeCtx(
445
445
  assistantMessageChannel: "vellum" as const,
446
446
  }),
447
447
 
448
+ graphMemory: {
449
+ onCompacted: () => {},
450
+ prepareMemory: async () => ({ runMessages: [], injectedTokens: 0, latencyMs: 0, mode: "none" as const }),
451
+ reinjectCachedMemory: (messages: Message[]) => ({
452
+ runMessages: messages,
453
+ injectedTokens: 0,
454
+ }),
455
+ } as unknown as AgentLoopConversationContext["graphMemory"],
456
+
448
457
  ...overrides,
449
458
  } as AgentLoopConversationContext;
450
459
  }
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from "node:fs";
2
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
2
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
3
3
 
4
4
  mock.module("../util/logger.js", () => ({
5
5
  getLogger: () =>
@@ -48,14 +48,10 @@ mock.module("../permissions/types.js", () => ({
48
48
  import type { AssistantAttachmentDraft } from "../daemon/assistant-attachments.js";
49
49
  import { getFilePathForAttachment } from "../memory/attachments-store.js";
50
50
  import { addMessage, createConversation } from "../memory/conversation-crud.js";
51
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
51
+ import { getDb, initializeDb } from "../memory/db.js";
52
52
 
53
53
  initializeDb();
54
54
 
55
- afterAll(() => {
56
- resetDb();
57
- });
58
-
59
55
  function resetTables() {
60
56
  const db = getDb();
61
57
  db.run("DELETE FROM message_attachments");
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  mock.module("../util/logger.js", () => ({
4
4
  getLogger: () =>
@@ -17,7 +17,7 @@ import {
17
17
  projectAssistantMessage,
18
18
  recordConversationSeenSignal,
19
19
  } from "../memory/conversation-attention-store.js";
20
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
20
+ import { getDb, initializeDb } from "../memory/db.js";
21
21
  import {
22
22
  conversationAssistantAttentionState,
23
23
  conversationAttentionEvents,
@@ -66,10 +66,6 @@ function insertAssistantMessage(
66
66
  .run();
67
67
  }
68
68
 
69
- afterAll(() => {
70
- resetDb();
71
- });
72
-
73
69
  describe("conversation-attention-store", () => {
74
70
  beforeEach(() => {
75
71
  clearTables();
@@ -9,7 +9,7 @@
9
9
  * - lifecycle_events contains `conversations_clear_all` audit entry after clear
10
10
  */
11
11
 
12
- import { afterAll, describe, expect, mock, test } from "bun:test";
12
+ import { describe, expect, mock, test } from "bun:test";
13
13
 
14
14
  mock.module("../util/logger.js", () => ({
15
15
  getLogger: () =>
@@ -31,17 +31,13 @@ import {
31
31
  createConversation,
32
32
  getConversation,
33
33
  } from "../memory/conversation-crud.js";
34
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
34
+ import { getDb, initializeDb } from "../memory/db.js";
35
35
  import { enforcePolicy, getPolicy } from "../runtime/auth/route-policy.js";
36
36
  import type { AuthContext, Scope } from "../runtime/auth/types.js";
37
37
  import { conversationManagementRouteDefinitions } from "../runtime/routes/conversation-management-routes.js";
38
38
 
39
39
  initializeDb();
40
40
 
41
- afterAll(() => {
42
- resetDb();
43
- });
44
-
45
41
  /** Build a synthetic AuthContext for testing. */
46
42
  function buildAuthContext(overrides?: {
47
43
  principalType?: AuthContext["principalType"];
@@ -3,7 +3,7 @@
3
3
  * job also deletes the schedule, preventing orphaned scheduled automations.
4
4
  */
5
5
 
6
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
6
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
7
7
 
8
8
  mock.module("../util/logger.js", () => ({
9
9
  getLogger: () =>
@@ -23,16 +23,12 @@ import {
23
23
  createConversation,
24
24
  getConversation,
25
25
  } from "../memory/conversation-crud.js";
26
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
26
+ import { getDb, initializeDb } from "../memory/db.js";
27
27
  import { conversationManagementRouteDefinitions } from "../runtime/routes/conversation-management-routes.js";
28
28
  import { createSchedule, getSchedule } from "../schedule/schedule-store.js";
29
29
 
30
30
  initializeDb();
31
31
 
32
- afterAll(() => {
33
- resetDb();
34
- });
35
-
36
32
  function getRawDb(): Database {
37
33
  return (getDb() as unknown as { $client: Database }).$client;
38
34
  }
@@ -72,9 +68,8 @@ describe("DELETE /conversations/:id — schedule cleanup", () => {
72
68
  beforeEach(() => {
73
69
  getRawDb().run("DELETE FROM cron_runs");
74
70
  getRawDb().run("DELETE FROM cron_jobs");
75
- getRawDb().run("DELETE FROM memory_item_sources");
71
+ getRawDb().run("DELETE FROM memory_graph_nodes");
76
72
  getRawDb().run("DELETE FROM memory_segments");
77
- getRawDb().run("DELETE FROM memory_items");
78
73
  getRawDb().run("DELETE FROM memory_summaries");
79
74
  getRawDb().run("DELETE FROM memory_embeddings");
80
75
  getRawDb().run("DELETE FROM memory_jobs");
@@ -297,9 +292,8 @@ describe("POST /conversations/:id/wipe — schedule cleanup", () => {
297
292
  beforeEach(() => {
298
293
  getRawDb().run("DELETE FROM cron_runs");
299
294
  getRawDb().run("DELETE FROM cron_jobs");
300
- getRawDb().run("DELETE FROM memory_item_sources");
295
+ getRawDb().run("DELETE FROM memory_graph_nodes");
301
296
  getRawDb().run("DELETE FROM memory_segments");
302
- getRawDb().run("DELETE FROM memory_items");
303
297
  getRawDb().run("DELETE FROM memory_summaries");
304
298
  getRawDb().run("DELETE FROM memory_embeddings");
305
299
  getRawDb().run("DELETE FROM memory_jobs");
@@ -13,7 +13,7 @@ import {
13
13
  rmSync,
14
14
  } from "node:fs";
15
15
  import { join } from "node:path";
16
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
16
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
17
17
 
18
18
  // ---------------------------------------------------------------------------
19
19
  // Mocks — must come before any imports that depend on them
@@ -59,14 +59,10 @@ import {
59
59
  getConversationDirPath,
60
60
  syncMessageToDisk,
61
61
  } from "../memory/conversation-disk-view.js";
62
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
62
+ import { getDb, initializeDb } from "../memory/db.js";
63
63
 
64
64
  initializeDb();
65
65
 
66
- afterAll(() => {
67
- resetDb();
68
- });
69
-
70
66
  function resetTables() {
71
67
  const db = getDb();
72
68
  db.run("DELETE FROM message_attachments");
@@ -8,7 +8,7 @@ import {
8
8
  } from "node:fs";
9
9
  import { tmpdir } from "node:os";
10
10
  import { join } from "node:path";
11
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
11
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
12
12
 
13
13
  // ---------------------------------------------------------------------------
14
14
  // Mocks — must come before any imports that depend on them
@@ -61,14 +61,10 @@ import {
61
61
  syncMessageToDisk,
62
62
  updateMetaFile,
63
63
  } from "../memory/conversation-disk-view.js";
64
- import { getDb, initializeDb, rawRun, resetDb } from "../memory/db.js";
64
+ import { getDb, initializeDb, rawRun } from "../memory/db.js";
65
65
 
66
66
  initializeDb();
67
67
 
68
- afterAll(() => {
69
- resetDb();
70
- });
71
-
72
68
  function resetTables() {
73
69
  const db = getDb();
74
70
  db.run("DELETE FROM message_attachments");
@@ -90,7 +90,6 @@ describe("classifyConversationError", () => {
90
90
  "rate limit exceeded",
91
91
  "Rate-limit hit",
92
92
  "too many requests",
93
- "overloaded",
94
93
  ];
95
94
 
96
95
  for (const msg of cases) {
@@ -98,12 +97,44 @@ describe("classifyConversationError", () => {
98
97
  const result = classifyConversationError(new Error(msg), baseCtx);
99
98
  expect(result.code).toBe("PROVIDER_RATE_LIMIT");
100
99
  expect(result.retryable).toBe(true);
101
- expect(result.userMessage).toContain("busy");
100
+ expect(result.userMessage).toContain("rate limited");
102
101
  expect(result.errorCategory).toBe("rate_limit");
103
102
  });
104
103
  }
105
104
  });
106
105
 
106
+ describe("provider overloaded errors", () => {
107
+ it('classifies "overloaded" as PROVIDER_OVERLOADED', () => {
108
+ const result = classifyConversationError(
109
+ new Error("overloaded"),
110
+ baseCtx,
111
+ );
112
+ expect(result.code).toBe("PROVIDER_OVERLOADED");
113
+ expect(result.retryable).toBe(true);
114
+ expect(result.userMessage).toContain("overloaded");
115
+ expect(result.errorCategory).toBe("provider_overloaded");
116
+ });
117
+
118
+ it("classifies Anthropic overloaded_error (no statusCode) as PROVIDER_OVERLOADED", () => {
119
+ const err = new ProviderError(
120
+ 'Anthropic API error (undefined): {"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}',
121
+ "anthropic",
122
+ );
123
+ const result = classifyConversationError(err, baseCtx);
124
+ expect(result.code).toBe("PROVIDER_OVERLOADED");
125
+ expect(result.retryable).toBe(true);
126
+ expect(result.errorCategory).toBe("provider_overloaded");
127
+ });
128
+
129
+ it("classifies ProviderError with 529 as PROVIDER_OVERLOADED", () => {
130
+ const err = new ProviderError("Overloaded", "anthropic", 529);
131
+ const result = classifyConversationError(err, baseCtx);
132
+ expect(result.code).toBe("PROVIDER_OVERLOADED");
133
+ expect(result.retryable).toBe(true);
134
+ expect(result.errorCategory).toBe("provider_overloaded");
135
+ });
136
+ });
137
+
107
138
  describe("provider API errors", () => {
108
139
  const cases = [
109
140
  "HTTP 500 Internal Server Error",
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
3
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
4
4
 
5
5
  import { eq, like } from "drizzle-orm";
6
6
 
@@ -39,7 +39,7 @@ import {
39
39
  PRIVATE_CONVERSATION_FORK_ERROR,
40
40
  } from "../memory/conversation-crud.js";
41
41
  import { getConversationDirPath } from "../memory/conversation-disk-view.js";
42
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
42
+ import { getDb, initializeDb } from "../memory/db.js";
43
43
  import { getRequestLogsByMessageId } from "../memory/llm-request-log-store.js";
44
44
  import {
45
45
  channelInboundEvents,
@@ -71,10 +71,6 @@ function parseMetadata(metadata: string | null): unknown {
71
71
  return metadata == null ? null : JSON.parse(metadata);
72
72
  }
73
73
 
74
- afterAll(() => {
75
- resetDb();
76
- });
77
-
78
74
  describe("forkConversation", () => {
79
75
  beforeEach(() => {
80
76
  resetTables();
@@ -782,6 +782,11 @@ describe("web_search_tool_result structural guard", () => {
782
782
  // Extracts tool results from persisted message content for work-item
783
783
  // display. web_search_tool_result blocks are not relevant here.
784
784
  "runtime/routes/work-items-routes.ts",
785
+
786
+ // Media token counting iterates tool_result.contentBlocks for nested
787
+ // image/file blocks. web_search_tool_result has opaque content with no
788
+ // contentBlocks property, so it cannot contain nested media.
789
+ "daemon/context-overflow-reducer.ts",
785
790
  ]);
786
791
 
787
792
  /**
@@ -106,7 +106,7 @@ function makeConversation(): Conversation {
106
106
  stopReason: "end_turn",
107
107
  }),
108
108
  };
109
- return new Conversation(
109
+ const conv = new Conversation(
110
110
  "conv-1",
111
111
  provider,
112
112
  "system prompt",
@@ -114,6 +114,10 @@ function makeConversation(): Conversation {
114
114
  () => {},
115
115
  "/tmp",
116
116
  );
117
+ // Default to guardian trust so history repair tests load all messages.
118
+ // Tests that exercise untrusted-actor filtering override this explicitly.
119
+ conv.setTrustContext({ trustClass: "guardian", sourceChannel: "vellum" });
120
+ return conv;
117
121
  }
118
122
 
119
123
  describe("loadFromDb history repair", () => {
@@ -18,6 +18,15 @@ function makeImageBlock(
18
18
  };
19
19
  }
20
20
 
21
+ function makeImageBlockWithSize(
22
+ dataLength: number,
23
+ ): Extract<ContentBlock, { type: "image" }> {
24
+ return {
25
+ type: "image",
26
+ source: { type: "base64", media_type: "image/png", data: "A".repeat(dataLength) },
27
+ };
28
+ }
29
+
21
30
  function makeUserMessage(...blocks: ContentBlock[]): Message {
22
31
  return { role: "user", content: blocks };
23
32
  }
@@ -88,4 +97,86 @@ describe("stripMediaPayloadsForRetry", () => {
88
97
  const latestBlocks = result.messages[3].content;
89
98
  expect(latestBlocks.filter((b) => b.type === "image").length).toBe(1);
90
99
  });
100
+
101
+ // ---------------------------------------------------------------------------
102
+ // Budget-aware media retention
103
+ // ---------------------------------------------------------------------------
104
+
105
+ test("budget-aware: keeps images that fit within token budget", () => {
106
+ // Non-Anthropic estimation: estimateTextTokens(base64Data) + overhead (~19 tokens).
107
+ // Data length 4000 → 1000 data tokens + 19 overhead ≈ 1019 tokens/image.
108
+ // Budget of 3500 allows 3 images (3 * 1019 = 3057 <= 3500) but not 4.
109
+ const images = Array.from({ length: 5 }, () => makeImageBlockWithSize(4000));
110
+ const messages: Message[] = [
111
+ makeUserMessage({ type: "text", text: "describe these" }, ...images),
112
+ ];
113
+
114
+ const result = stripMediaPayloadsForRetry(messages, {
115
+ mediaTokenBudget: 3500,
116
+ providerName: "mock",
117
+ });
118
+ expect(result.modified).toBe(true);
119
+
120
+ const content = result.messages[0].content;
121
+ const keptImages = content.filter((b) => b.type === "image");
122
+ const stubs = content.filter(
123
+ (b) => b.type === "text" && (b as { text: string }).text.includes("Image omitted"),
124
+ );
125
+ expect(keptImages.length).toBe(3);
126
+ expect(stubs.length).toBe(2);
127
+ });
128
+
129
+ test("budget-aware: keeps all images when budget is generous", () => {
130
+ const images = Array.from({ length: 3 }, () => makeImageBlockWithSize(100));
131
+ const messages: Message[] = [
132
+ makeUserMessage({ type: "text", text: "describe these" }, ...images),
133
+ ];
134
+
135
+ const result = stripMediaPayloadsForRetry(messages, {
136
+ mediaTokenBudget: 100_000,
137
+ providerName: "mock",
138
+ });
139
+ expect(result.modified).toBe(false);
140
+ expect(result.replacedBlocks).toBe(0);
141
+
142
+ const content = result.messages[0].content;
143
+ const keptImages = content.filter((b) => b.type === "image");
144
+ expect(keptImages.length).toBe(3);
145
+ });
146
+
147
+ test("budget-aware: stubs all when budget is zero", () => {
148
+ const images = Array.from({ length: 3 }, () => makeImageBlockWithSize(100));
149
+ const messages: Message[] = [
150
+ makeUserMessage({ type: "text", text: "describe these" }, ...images),
151
+ ];
152
+
153
+ const result = stripMediaPayloadsForRetry(messages, {
154
+ mediaTokenBudget: 0,
155
+ providerName: "mock",
156
+ });
157
+ expect(result.modified).toBe(true);
158
+ expect(result.replacedBlocks).toBe(3);
159
+
160
+ const content = result.messages[0].content;
161
+ const keptImages = content.filter((b) => b.type === "image");
162
+ expect(keptImages.length).toBe(0);
163
+ });
164
+
165
+ test("no options falls back to hardcoded limit", () => {
166
+ const images = Array.from({ length: 5 }, () => makeImageBlockWithSize(100));
167
+ const messages: Message[] = [
168
+ makeUserMessage({ type: "text", text: "describe these" }, ...images),
169
+ ];
170
+
171
+ const result = stripMediaPayloadsForRetry(messages);
172
+ expect(result.modified).toBe(true);
173
+
174
+ const content = result.messages[0].content;
175
+ const keptImages = content.filter((b) => b.type === "image");
176
+ const stubs = content.filter(
177
+ (b) => b.type === "text" && (b as { text: string }).text.includes("Image omitted"),
178
+ );
179
+ expect(keptImages.length).toBe(3);
180
+ expect(stubs.length).toBe(2);
181
+ });
91
182
  });
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import { v4 as uuid } from "uuid";
4
4
 
@@ -9,7 +9,7 @@ mock.module("../util/logger.js", () => ({
9
9
  }),
10
10
  }));
11
11
 
12
- import { getSqlite, initializeDb, resetDb } from "../memory/db.js";
12
+ import { getSqlite, initializeDb } from "../memory/db.js";
13
13
  import {
14
14
  conversationStarterRouteDefinitions,
15
15
  orderStrongestFirst,
@@ -17,10 +17,6 @@ import {
17
17
 
18
18
  initializeDb();
19
19
 
20
- afterAll(() => {
21
- resetDb();
22
- });
23
-
24
20
  const routes = conversationStarterRouteDefinitions();
25
21
 
26
22
  function dispatch(path: string): Response | Promise<Response> {
@@ -41,7 +37,7 @@ function dispatch(path: string): Response | Promise<Response> {
41
37
 
42
38
  function clearTables() {
43
39
  getSqlite().run("DELETE FROM conversation_starters");
44
- getSqlite().run("DELETE FROM memory_items");
40
+ getSqlite().run("DELETE FROM memory_graph_nodes");
45
41
  getSqlite().run("DELETE FROM memory_jobs");
46
42
  getSqlite().run("DELETE FROM memory_checkpoints");
47
43
  }
@@ -73,10 +69,23 @@ function insertStarter(overrides: {
73
69
  function insertMemoryItem(scopeId = "default") {
74
70
  const now = Date.now();
75
71
  getSqlite().run(
76
- `INSERT INTO memory_items (
77
- id, kind, subject, statement, status, confidence, fingerprint, scope_id, first_seen_at, last_seen_at
78
- ) VALUES (?, 'fact', 'test', 'test statement', 'active', 0.9, ?, ?, ?, ?)`,
79
- [uuid(), `fingerprint-${uuid()}`, scopeId, now, now],
72
+ `INSERT INTO memory_graph_nodes (
73
+ id, content, type, created, last_accessed, last_consolidated,
74
+ emotional_charge, fidelity, confidence, significance,
75
+ stability, reinforcement_count, last_reinforced,
76
+ source_conversations, source_type, scope_id
77
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, 'vivid', 0.8, 0.5, 14, 0, ?, '[]', 'inferred', ?)`,
78
+ [
79
+ uuid(),
80
+ "test\ntest statement",
81
+ "semantic",
82
+ now,
83
+ now,
84
+ now,
85
+ '{"valence":0,"intensity":0.1,"decayCurve":"linear","decayRate":0.05,"originalIntensity":0.1}',
86
+ now,
87
+ scopeId,
88
+ ],
80
89
  );
81
90
  }
82
91
 
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  mock.module("../util/logger.js", () => ({
4
4
  getLogger: () =>
@@ -24,15 +24,11 @@ import {
24
24
  getMessages,
25
25
  } from "../memory/conversation-crud.js";
26
26
  import { isLastUserMessageToolResult } from "../memory/conversation-queries.js";
27
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
27
+ import { getDb, initializeDb } from "../memory/db.js";
28
28
 
29
29
  // Initialize db once before all tests
30
30
  initializeDb();
31
31
 
32
- afterAll(() => {
33
- resetDb();
34
- });
35
-
36
32
  describe("deleteLastExchange", () => {
37
33
  beforeEach(() => {
38
34
  // Reset database between tests by dropping and recreating tables
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  const updateConversationUsageCalls: Array<{
4
4
  conversationId: string;
@@ -37,17 +37,13 @@ mock.module("../memory/conversation-crud.js", () => ({
37
37
  }));
38
38
 
39
39
  import { recordUsage } from "../daemon/conversation-usage.js";
40
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
40
+ import { getDb, initializeDb } from "../memory/db.js";
41
41
  import { listUsageEvents } from "../memory/llm-usage-store.js";
42
42
  import type { PricingUsage } from "../usage/types.js";
43
43
  import { resolvePricingForUsageWithOverrides } from "../util/pricing.js";
44
44
 
45
45
  initializeDb();
46
46
 
47
- afterAll(() => {
48
- resetDb();
49
- });
50
-
51
47
  describe("recordUsage", () => {
52
48
  beforeEach(() => {
53
49
  const db = getDb();