@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/assistant",
3
- "version": "0.5.16",
3
+ "version": "0.6.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -75,6 +75,9 @@ const loopbackServer = mockServer("127.0.0.1");
75
75
  /** Mock non-loopback server -- returns a public IP for all requests. */
76
76
  const nonLoopbackServer = mockServer("203.0.113.50");
77
77
 
78
+ /** Mock LAN peer -- returns a private RFC 1918 IP (not loopback). */
79
+ const lanPeerServer = mockServer("192.168.1.100");
80
+
78
81
  initializeDb();
79
82
 
80
83
  beforeEach(() => {
@@ -649,6 +652,25 @@ describe("pairing credential flow", () => {
649
652
  // ---------------------------------------------------------------------------
650
653
 
651
654
  describe("bootstrap private-network guard", () => {
655
+ test("rejects bootstrap request with private X-Forwarded-For", async () => {
656
+ const { handleGuardianBootstrap } =
657
+ await import("../runtime/routes/guardian-bootstrap-routes.js");
658
+
659
+ const req = new Request("http://localhost/v1/guardian/init", {
660
+ method: "POST",
661
+ headers: {
662
+ "Content-Type": "application/json",
663
+ "X-Forwarded-For": "192.168.1.10",
664
+ },
665
+ body: JSON.stringify({ platform: "macos", deviceId: "test-device" }),
666
+ });
667
+
668
+ const res = await handleGuardianBootstrap(req, loopbackServer);
669
+ expect(res.status).toBe(403);
670
+ const body = (await res.json()) as { error: { message: string } };
671
+ expect(body.error.message).toContain("local-only");
672
+ });
673
+
652
674
  test("rejects bootstrap request with public X-Forwarded-For", async () => {
653
675
  const { handleGuardianBootstrap } =
654
676
  await import("../runtime/routes/guardian-bootstrap-routes.js");
@@ -697,4 +719,50 @@ describe("bootstrap private-network guard", () => {
697
719
  const res = await handleGuardianBootstrap(req, loopbackServer);
698
720
  expect(res.status).toBe(200);
699
721
  });
722
+
723
+ test("rejects LAN peer in non-containerized mode", async () => {
724
+ // Default IS_CONTAINERIZED is unset (non-containerized).
725
+ delete process.env.IS_CONTAINERIZED;
726
+
727
+ const { handleGuardianBootstrap } =
728
+ await import("../runtime/routes/guardian-bootstrap-routes.js");
729
+
730
+ const req = new Request("http://localhost/v1/guardian/init", {
731
+ method: "POST",
732
+ headers: { "Content-Type": "application/json" },
733
+ body: JSON.stringify({ platform: "macos", deviceId: "test-device-lan" }),
734
+ });
735
+
736
+ const res = await handleGuardianBootstrap(req, lanPeerServer);
737
+ expect(res.status).toBe(403);
738
+ const body = (await res.json()) as { error: { message: string } };
739
+ expect(body.error.message).toContain("local-only");
740
+ });
741
+
742
+ test("accepts LAN peer in containerized mode", async () => {
743
+ const prev = process.env.IS_CONTAINERIZED;
744
+ process.env.IS_CONTAINERIZED = "true";
745
+ try {
746
+ const { handleGuardianBootstrap } =
747
+ await import("../runtime/routes/guardian-bootstrap-routes.js");
748
+
749
+ const req = new Request("http://localhost/v1/guardian/init", {
750
+ method: "POST",
751
+ headers: { "Content-Type": "application/json" },
752
+ body: JSON.stringify({
753
+ platform: "macos",
754
+ deviceId: "test-device-docker",
755
+ }),
756
+ });
757
+
758
+ const res = await handleGuardianBootstrap(req, lanPeerServer);
759
+ expect(res.status).toBe(200);
760
+ } finally {
761
+ if (prev === undefined) {
762
+ delete process.env.IS_CONTAINERIZED;
763
+ } else {
764
+ process.env.IS_CONTAINERIZED = prev;
765
+ }
766
+ }
767
+ });
700
768
  });
@@ -468,38 +468,6 @@ describe("AgentLoop", () => {
468
468
  ).toBe(false);
469
469
  });
470
470
 
471
- // 8. Progress reminder injection every 5 tool-use turns
472
- test("injects progress reminder after every 5 tool-use turns", async () => {
473
- // Create 6 tool responses followed by a text response
474
- const responses: ProviderResponse[] = [];
475
- for (let i = 0; i < 6; i++) {
476
- responses.push(
477
- toolUseResponse(`t${i}`, "read_file", { path: `/file${i}.txt` }),
478
- );
479
- }
480
- responses.push(textResponse("Finally done"));
481
-
482
- const { provider, calls } = createMockProvider(responses);
483
- const toolExecutor = async () => ({ content: "data", isError: false });
484
- const loop = new AgentLoop(
485
- provider,
486
- "system",
487
- {},
488
- dummyTools,
489
- toolExecutor,
490
- );
491
-
492
- await loop.run([userMessage], () => {});
493
-
494
- // After the 5th tool-use turn, the user message should contain a progress reminder
495
- // calls[5] is the 6th provider call; its messages[-1] should have the reminder
496
- const fifthTurnResultMsg = calls[5].messages[calls[5].messages.length - 1];
497
- const reminderBlock = fifthTurnResultMsg.content.find(
498
- (b): b is Extract<ContentBlock, { type: "text" }> =>
499
- b.type === "text" && b.text.includes("making meaningful progress"),
500
- );
501
- expect(reminderBlock).toBeDefined();
502
- });
503
471
 
504
472
  // 9. Tool executor error results are forwarded correctly
505
473
  test("forwards tool error results to provider", async () => {
@@ -56,8 +56,8 @@ describe("always-loaded tool count", () => {
56
56
  "file_edit",
57
57
  "file_read",
58
58
  "file_write",
59
- "memory_manage",
60
- "memory_recall",
59
+ "recall",
60
+ "remember",
61
61
  "skill_execute",
62
62
  "skill_load",
63
63
  "web_fetch",
@@ -931,7 +931,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
931
931
 
932
932
  // Assistant message should have tool_use in paired portion, server_tool_use in carryover
933
933
  // ensureToolPairing splits: paired = [tool_use(tu_a)], carryover = [server_tool_use(srvtoolu_b)]
934
- // Result: assistant(tool_use) → user(tool_result) → assistant(server_tool_use) → user(continue)
934
+ // Result: assistant(tool_use) → user(tool_result) → assistant(server_tool_use) → user(synthetic_continuation)
935
935
  const assistantMsg = sent[1];
936
936
  expect(assistantMsg.role).toBe("assistant");
937
937
  expect(assistantMsg.content[0].type).toBe("tool_use");
@@ -1258,7 +1258,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1258
1258
  // 2. assistant(tool_use)
1259
1259
  // 3. user(tool_result)
1260
1260
  // 4. assistant(Checking the file now.)
1261
- // 5. user((continue)) <-- synthetic user message to maintain alternation
1261
+ // 5. user(<synthetic_continuation __injected />) <-- synthetic user message to maintain alternation
1262
1262
  // 6. assistant(Next response)
1263
1263
  expect(sent).toHaveLength(6);
1264
1264
  expect(sent[0].role).toBe("user");
@@ -1271,11 +1271,65 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1271
1271
  expect(sent[3].content[0].text).toBe("Checking the file now.");
1272
1272
  expect(sent[4].role).toBe("user");
1273
1273
  expect(sent[4].content[0].type).toBe("text");
1274
- expect(sent[4].content[0].text).toBe("(continue)");
1274
+ expect(sent[4].content[0].text).toBe(
1275
+ "<synthetic_continuation __injected />",
1276
+ );
1275
1277
  expect(sent[5].role).toBe("assistant");
1276
1278
  expect(sent[5].content[0].text).toBe("Next response");
1277
1279
  });
1278
1280
 
1281
+ test("carryover with tool_result-only user turn skips synthetic when next message is user", async () => {
1282
+ // When the user turn after the consumed pair is already a user message,
1283
+ // the synthetic continuation is unnecessary — the next user message
1284
+ // naturally maintains alternation after the carryover assistant message.
1285
+ const messages: Message[] = [
1286
+ userMsg("Read file"),
1287
+ {
1288
+ role: "assistant",
1289
+ content: [
1290
+ { type: "tool_use", id: "tu_1", name: "file_read", input: {} },
1291
+ { type: "text", text: "Checking the file now." }, // carryover content
1292
+ ],
1293
+ },
1294
+ {
1295
+ role: "user",
1296
+ content: [
1297
+ // ONLY tool_result, no other content
1298
+ {
1299
+ type: "tool_result",
1300
+ tool_use_id: "tu_1",
1301
+ content: "file contents",
1302
+ is_error: false,
1303
+ },
1304
+ ],
1305
+ },
1306
+ userMsg("Follow-up question"), // next message is user — no synthetic needed
1307
+ ];
1308
+ await provider.sendMessage(messages);
1309
+
1310
+ const sent = lastStreamParams!.messages as Array<{
1311
+ role: string;
1312
+ content: Array<{ type: string; text?: string; tool_use_id?: string }>;
1313
+ }>;
1314
+
1315
+ // Expected structure:
1316
+ // 1. user(Read file)
1317
+ // 2. assistant(tool_use)
1318
+ // 3. user(tool_result)
1319
+ // 4. assistant(Checking the file now.)
1320
+ // 5. user(Follow-up question) <-- real user message, NO synthetic continuation
1321
+ expect(sent).toHaveLength(5);
1322
+ expect(sent[0].role).toBe("user");
1323
+ expect(sent[1].role).toBe("assistant");
1324
+ expect(sent[1].content[0].type).toBe("tool_use");
1325
+ expect(sent[2].role).toBe("user");
1326
+ expect(sent[2].content[0].type).toBe("tool_result");
1327
+ expect(sent[3].role).toBe("assistant");
1328
+ expect(sent[3].content[0].text).toBe("Checking the file now.");
1329
+ expect(sent[4].role).toBe("user");
1330
+ expect(sent[4].content[0].text).toBe("Follow-up question");
1331
+ });
1332
+
1279
1333
  test("multi-turn with workspace injection: cache on second-to-last user turn only", async () => {
1280
1334
  const messages: Message[] = [
1281
1335
  // Turn 1: workspace + user text (no cache - 3rd-to-last)
@@ -214,6 +214,126 @@ console.log("styled");`,
214
214
  expect(js.length).toBeGreaterThan(100);
215
215
  }, 30_000);
216
216
 
217
+ test("rejects relative import that escapes app directory", async () => {
218
+ const appDir = await scaffold("escape-relative", {
219
+ "main.tsx": `import data from "../../../../etc/passwd";\nconsole.log(data);`,
220
+ "index.html": MINIMAL_HTML,
221
+ });
222
+
223
+ const result = await compileApp(appDir);
224
+
225
+ expect(result.ok).toBe(false);
226
+ expect(result.errors.length).toBeGreaterThan(0);
227
+ expect(result.errors[0].text).toContain(
228
+ "resolves outside the app directory",
229
+ );
230
+ });
231
+
232
+ test("rejects absolute path import", async () => {
233
+ const appDir = await scaffold("escape-absolute", {
234
+ "main.tsx": `import data from "/etc/passwd";\nconsole.log(data);`,
235
+ "index.html": MINIMAL_HTML,
236
+ });
237
+
238
+ const result = await compileApp(appDir);
239
+
240
+ expect(result.ok).toBe(false);
241
+ expect(result.errors.length).toBeGreaterThan(0);
242
+ expect(result.errors[0].text).toContain(
243
+ "resolves outside the app directory",
244
+ );
245
+ });
246
+
247
+ test("allows relative imports within app directory", async () => {
248
+ const appDir = await scaffold("local-relative", {
249
+ "main.tsx": `import { helper } from "./utils";\nconsole.log(helper);`,
250
+ "utils.ts": `export const helper = "ok";`,
251
+ "index.html": MINIMAL_HTML,
252
+ });
253
+
254
+ const result = await compileApp(appDir);
255
+
256
+ expect(result.ok).toBe(true);
257
+ expect(result.errors).toHaveLength(0);
258
+ });
259
+
260
+ test("rejects hex-escaped import that decodes to path traversal", async () => {
261
+ const appDir = await scaffold("escape-hex", {
262
+ // \x2e = '.', so this decodes to ../../../../etc/passwd
263
+ "main.tsx": `import data from "\\x2e\\x2e/\\x2e\\x2e/\\x2e\\x2e/\\x2e\\x2e/etc/passwd";\nconsole.log(data);`,
264
+ "index.html": MINIMAL_HTML,
265
+ });
266
+
267
+ const result = await compileApp(appDir);
268
+
269
+ expect(result.ok).toBe(false);
270
+ expect(result.errors.length).toBeGreaterThan(0);
271
+ expect(result.errors[0].text).toContain(
272
+ "resolves outside the app directory",
273
+ );
274
+ });
275
+
276
+ test("rejects unicode-escaped import that decodes to path traversal", async () => {
277
+ const appDir = await scaffold("escape-unicode", {
278
+ // \u002e = '.', \u002f = '/'
279
+ "main.tsx": `import data from "\\u002e\\u002e\\u002f\\u002e\\u002e/etc/passwd";\nconsole.log(data);`,
280
+ "index.html": MINIMAL_HTML,
281
+ });
282
+
283
+ const result = await compileApp(appDir);
284
+
285
+ expect(result.ok).toBe(false);
286
+ expect(result.errors.length).toBeGreaterThan(0);
287
+ expect(result.errors[0].text).toContain(
288
+ "resolves outside the app directory",
289
+ );
290
+ });
291
+
292
+ test("rejects import hidden behind block comment", async () => {
293
+ const appDir = await scaffold("escape-block-comment", {
294
+ "main.tsx": `import data from /* bypass */ "../../../../etc/passwd";\nconsole.log(data);`,
295
+ "index.html": MINIMAL_HTML,
296
+ });
297
+
298
+ const result = await compileApp(appDir);
299
+
300
+ expect(result.ok).toBe(false);
301
+ expect(result.errors.length).toBeGreaterThan(0);
302
+ expect(result.errors[0].text).toContain(
303
+ "resolves outside the app directory",
304
+ );
305
+ });
306
+
307
+ test("rejects import hidden behind line comment", async () => {
308
+ const appDir = await scaffold("escape-line-comment", {
309
+ "main.tsx": `import data from // bypass\n"../../../../etc/passwd";\nconsole.log(data);`,
310
+ "index.html": MINIMAL_HTML,
311
+ });
312
+
313
+ const result = await compileApp(appDir);
314
+
315
+ expect(result.ok).toBe(false);
316
+ expect(result.errors.length).toBeGreaterThan(0);
317
+ expect(result.errors[0].text).toContain(
318
+ "resolves outside the app directory",
319
+ );
320
+ });
321
+
322
+ test("rejects dynamic import escaping app directory", async () => {
323
+ const appDir = await scaffold("escape-dynamic", {
324
+ "main.tsx": `const data = await import("../../../../etc/hosts");\nconsole.log(data);`,
325
+ "index.html": MINIMAL_HTML,
326
+ });
327
+
328
+ const result = await compileApp(appDir);
329
+
330
+ expect(result.ok).toBe(false);
331
+ expect(result.errors.length).toBeGreaterThan(0);
332
+ expect(result.errors[0].text).toContain(
333
+ "resolves outside the app directory",
334
+ );
335
+ });
336
+
217
337
  test("allowed package uses shared cache on second build", async () => {
218
338
  // First build installs the package
219
339
  const appDir1 = await scaffold("cache-test-1", {
@@ -12,7 +12,7 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
12
  // Test-scoped config state
13
13
  // ---------------------------------------------------------------------------
14
14
 
15
- const DECLARED_FLAG_ID = "contacts";
15
+ const DECLARED_FLAG_ID = "sounds";
16
16
  const DECLARED_FLAG_KEY = DECLARED_FLAG_ID;
17
17
 
18
18
  const { isAssistantFeatureFlagEnabled, _setOverridesForTesting } =
@@ -54,7 +54,7 @@ describe("isAssistantFeatureFlagEnabled", () => {
54
54
 
55
55
  test("missing persisted value falls back to defaults registry defaultEnabled", () => {
56
56
  // No explicit config at all — should fall back to defaults registry
57
- // which has defaultEnabled: true for contacts
57
+ // which has defaultEnabled: true for sounds
58
58
  const config = {} as any;
59
59
 
60
60
  expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(true);
@@ -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
  updateCallSession,
18
18
  } from "../calls/call-store.js";
19
19
  import { getMessages } from "../memory/conversation-crud.js";
20
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
20
+ import { getDb, initializeDb } from "../memory/db.js";
21
21
  import { conversations } from "../memory/schema.js";
22
22
 
23
23
  initializeDb();
@@ -65,10 +65,6 @@ describe("call-conversation-messages", () => {
65
65
  resetTables();
66
66
  });
67
67
 
68
- afterAll(() => {
69
- resetDb();
70
- });
71
-
72
68
  test("buildCallCompletionMessage labels failed calls correctly", () => {
73
69
  const conversationId = "conv-call-msg-failed";
74
70
  ensureConversation(conversationId);
@@ -7,7 +7,7 @@
7
7
  * - Voice-ingress preflight blocks doomed outbound calls before Twilio dialing.
8
8
  * - Pointer messages are written on successful call start and on failure.
9
9
  */
10
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
10
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
11
11
 
12
12
  mock.module("../util/logger.js", () => ({
13
13
  getLogger: () =>
@@ -120,7 +120,7 @@ import {
120
120
  } from "../calls/call-domain.js";
121
121
  import type { AssistantConfig } from "../config/types.js";
122
122
  import { getMessages } from "../memory/conversation-crud.js";
123
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
123
+ import { getDb, initializeDb } from "../memory/db.js";
124
124
  import { conversations } from "../memory/schema.js";
125
125
 
126
126
  initializeDb();
@@ -185,10 +185,6 @@ function getLatestAssistantText(conversationId: string): string | null {
185
185
  return latest.content;
186
186
  }
187
187
 
188
- afterAll(() => {
189
- resetDb();
190
- });
191
-
192
188
  function makeConfig(
193
189
  overrides: {
194
190
  allowPerCallOverride?: boolean;
@@ -1,12 +1,4 @@
1
- import {
2
- afterAll,
3
- afterEach,
4
- beforeEach,
5
- describe,
6
- expect,
7
- mock,
8
- test,
9
- } from "bun:test";
1
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
10
2
 
11
3
  mock.module("../util/logger.js", () => ({
12
4
  getLogger: () =>
@@ -22,7 +14,7 @@ import {
22
14
  setPointerMessageProcessor,
23
15
  } from "../calls/call-pointer-messages.js";
24
16
  import { addMessage, getMessages } from "../memory/conversation-crud.js";
25
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
17
+ import { getDb, initializeDb } from "../memory/db.js";
26
18
  import { conversations } from "../memory/schema.js";
27
19
 
28
20
  initializeDb();
@@ -110,10 +102,6 @@ describe("addPointerMessage", () => {
110
102
  resetPointerMessageProcessor();
111
103
  });
112
104
 
113
- afterAll(() => {
114
- resetDb();
115
- });
116
-
117
105
  test("adds a started pointer message", () => {
118
106
  const convId = "conv-ptr-started";
119
107
  ensureConversation(convId);
@@ -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: () =>
@@ -26,15 +26,11 @@ import {
26
26
  updateCallSession,
27
27
  } from "../calls/call-store.js";
28
28
  import type { VoiceProvider } from "../calls/voice-provider.js";
29
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
29
+ import { getDb, initializeDb } from "../memory/db.js";
30
30
  import { conversations } from "../memory/schema.js";
31
31
 
32
32
  initializeDb();
33
33
 
34
- afterAll(() => {
35
- resetDb();
36
- });
37
-
38
34
  /** Ensure a conversation row exists for the given ID so FK constraints pass. */
39
35
  let ensuredConvIds = new Set<string>();
40
36
  function ensureConversation(id: string): void {
@@ -5,7 +5,7 @@
5
5
  * POST /v1/calls/:id/cancel, and POST /v1/calls/:id/answer
6
6
  * through RuntimeHttpServer.
7
7
  */
8
- import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
8
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
9
9
 
10
10
  mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
11
11
 
@@ -105,7 +105,7 @@ import {
105
105
  createPendingQuestion,
106
106
  updateCallSession,
107
107
  } from "../calls/call-store.js";
108
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
108
+ import { getDb, initializeDb } from "../memory/db.js";
109
109
  import { conversations } from "../memory/schema.js";
110
110
  import { RuntimeHttpServer } from "../runtime/http-server.js";
111
111
 
@@ -162,10 +162,6 @@ describe("runtime call routes — HTTP layer", () => {
162
162
  resetTables();
163
163
  });
164
164
 
165
- afterAll(() => {
166
- resetDb();
167
- });
168
-
169
165
  async function startServer(): Promise<void> {
170
166
  server = new RuntimeHttpServer({ port: 0, bearerToken: TEST_TOKEN });
171
167
  await server.start();
@@ -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: () =>
@@ -23,15 +23,11 @@ import {
23
23
  releaseCallbackClaim,
24
24
  updateCallSession,
25
25
  } from "../calls/call-store.js";
26
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
26
+ import { getDb, initializeDb } from "../memory/db.js";
27
27
  import { conversations } from "../memory/schema.js";
28
28
 
29
29
  initializeDb();
30
30
 
31
- afterAll(() => {
32
- resetDb();
33
- });
34
-
35
31
  /** Ensure a conversation row exists for the given ID so FK constraints pass. */
36
32
  let ensuredConvIds = new Set<string>();
37
33
  function ensureConversation(id: string): void {
@@ -6,7 +6,7 @@
6
6
  * from the daemon's internal ID), fails to find the conversation, and
7
7
  * silently ignores the cancel — leaving the stream running.
8
8
  */
9
- import { afterAll, describe, expect, mock, test } from "bun:test";
9
+ import { describe, expect, mock, test } from "bun:test";
10
10
 
11
11
  mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
12
12
 
@@ -43,15 +43,11 @@ mock.module("../config/loader.js", () => ({
43
43
  }));
44
44
 
45
45
  import { getOrCreateConversation } from "../memory/conversation-key-store.js";
46
- import { initializeDb, resetDb } from "../memory/db.js";
46
+ import { initializeDb } from "../memory/db.js";
47
47
  import { conversationManagementRouteDefinitions } from "../runtime/routes/conversation-management-routes.js";
48
48
 
49
49
  initializeDb();
50
50
 
51
- afterAll(() => {
52
- resetDb();
53
- });
54
-
55
51
  describe("POST /v1/conversations/:id/cancel", () => {
56
52
  test("resolves conversation key to internal ID before cancelling", () => {
57
53
  // Create a conversation via key — this assigns an internal ID that
@@ -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: () =>
@@ -21,7 +21,7 @@ import {
21
21
  updateCanonicalGuardianDelivery,
22
22
  updateCanonicalGuardianRequest,
23
23
  } from "../memory/canonical-guardian-store.js";
24
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
24
+ import { getDb, initializeDb } from "../memory/db.js";
25
25
 
26
26
  initializeDb();
27
27
 
@@ -40,10 +40,6 @@ describe("canonical-guardian-store", () => {
40
40
  resetTables();
41
41
  });
42
42
 
43
- afterAll(() => {
44
- resetDb();
45
- });
46
-
47
43
  // ── createCanonicalGuardianRequest ────────────────────────────────
48
44
 
49
45
  test("creates a request with all fields populated", () => {
@@ -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: () =>
@@ -13,7 +13,7 @@ import {
13
13
  getConversationByKey,
14
14
  setConversationKey,
15
15
  } from "../memory/conversation-key-store.js";
16
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
16
+ import { getDb, initializeDb } from "../memory/db.js";
17
17
  import {
18
18
  clearPayload,
19
19
  findMessageBySourceId,
@@ -40,10 +40,6 @@ import { handleDeleteConversation } from "../runtime/routes/channel-routes.js";
40
40
 
41
41
  initializeDb();
42
42
 
43
- afterAll(() => {
44
- resetDb();
45
- });
46
-
47
43
  function resetTables() {
48
44
  const db = getDb();
49
45
  db.run("DELETE FROM channel_inbound_events");
@@ -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 { eq } from "drizzle-orm";
4
4
 
@@ -9,17 +9,13 @@ mock.module("../util/logger.js", () => ({
9
9
  }),
10
10
  }));
11
11
 
12
- import { getDb, initializeDb, resetDb } from "../memory/db.js";
12
+ import { getDb, initializeDb } from "../memory/db.js";
13
13
  import * as deliveryCrud from "../memory/delivery-crud.js";
14
14
  import { channelInboundEvents, messages } from "../memory/schema.js";
15
15
  import { sweepFailedEvents } from "../runtime/channel-retry-sweep.js";
16
16
 
17
17
  initializeDb();
18
18
 
19
- afterAll(() => {
20
- resetDb();
21
- });
22
-
23
19
  function resetTables(): void {
24
20
  const db = getDb();
25
21
  db.run("DELETE FROM channel_inbound_events");