@vellumai/assistant 0.7.2 → 0.8.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 (424) hide show
  1. package/ARCHITECTURE.md +45 -29
  2. package/Dockerfile +1 -0
  3. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  4. package/bun.lock +3 -0
  5. package/docs/architecture/memory.md +5 -2
  6. package/knip.json +1 -0
  7. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
  8. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  9. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  10. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  11. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  12. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  13. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  14. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  16. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  17. package/openapi.yaml +470 -25
  18. package/package.json +3 -1
  19. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  20. package/src/__tests__/app-control-flow.test.ts +21 -11
  21. package/src/__tests__/approval-cascade.test.ts +8 -16
  22. package/src/__tests__/approval-routes-http.test.ts +6 -0
  23. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  24. package/src/__tests__/assistant-event.test.ts +0 -10
  25. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
  26. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  29. package/src/__tests__/call-constants.test.ts +10 -1
  30. package/src/__tests__/call-controller.test.ts +127 -0
  31. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  32. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  33. package/src/__tests__/channel-readiness-service.test.ts +4 -2
  34. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
  35. package/src/__tests__/config-loader-backfill.test.ts +379 -0
  36. package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
  37. package/src/__tests__/config-schema.test.ts +1 -0
  38. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
  39. package/src/__tests__/config-watcher.test.ts +140 -69
  40. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  41. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  42. package/src/__tests__/context-search-fanout.test.ts +0 -1
  43. package/src/__tests__/context-search-memory-source.test.ts +6 -33
  44. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  45. package/src/__tests__/context-search-pkb-source.test.ts +12 -7
  46. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  47. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
  48. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  51. package/src/__tests__/conversation-agent-loop.test.ts +457 -8
  52. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  53. package/src/__tests__/conversation-error.test.ts +150 -3
  54. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  55. package/src/__tests__/conversation-process-callsite.test.ts +38 -0
  56. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
  57. package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
  58. package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
  59. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  60. package/src/__tests__/conversation-store.test.ts +0 -18
  61. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  62. package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
  63. package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
  65. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  66. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  67. package/src/__tests__/credentials-cli.test.ts +7 -0
  68. package/src/__tests__/cu-unified-flow.test.ts +176 -10
  69. package/src/__tests__/date-context.test.ts +164 -2
  70. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  71. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  72. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  73. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  74. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  75. package/src/__tests__/disk-usage.test.ts +150 -0
  76. package/src/__tests__/events-client-registration.test.ts +52 -0
  77. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  78. package/src/__tests__/file-write-tool.test.ts +4 -10
  79. package/src/__tests__/filing-service.test.ts +2 -20
  80. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  82. package/src/__tests__/heartbeat-service.test.ts +260 -11
  83. package/src/__tests__/host-app-control-proxy.test.ts +195 -25
  84. package/src/__tests__/host-bash-proxy.test.ts +227 -34
  85. package/src/__tests__/host-bash-routes.test.ts +178 -13
  86. package/src/__tests__/host-cu-proxy.test.ts +210 -3
  87. package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
  88. package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
  89. package/src/__tests__/host-file-proxy.test.ts +268 -6
  90. package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
  91. package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
  92. package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
  93. package/src/__tests__/http-user-message-parity.test.ts +107 -1
  94. package/src/__tests__/injector-chain.test.ts +36 -16
  95. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  96. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  97. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
  98. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  99. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  100. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  101. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  102. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  103. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  104. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  105. package/src/__tests__/oauth-cli.test.ts +121 -0
  106. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  107. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  108. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  109. package/src/__tests__/openai-provider.test.ts +45 -8
  110. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  111. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  112. package/src/__tests__/platform.test.ts +2 -1
  113. package/src/__tests__/playbook-execution.test.ts +0 -43
  114. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  115. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
  116. package/src/__tests__/provider-tool-name.test.ts +23 -0
  117. package/src/__tests__/relay-server.test.ts +60 -5
  118. package/src/__tests__/runtime-events-sse.test.ts +4 -8
  119. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  120. package/src/__tests__/secret-ingress-http.test.ts +0 -1
  121. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  122. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  123. package/src/__tests__/secret-response-routing.test.ts +7 -5
  124. package/src/__tests__/server-history-render.test.ts +82 -0
  125. package/src/__tests__/skill-include-graph.test.ts +31 -0
  126. package/src/__tests__/skill-load-tool.test.ts +44 -16
  127. package/src/__tests__/skills.test.ts +39 -0
  128. package/src/__tests__/suggestion-routes.test.ts +46 -0
  129. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  130. package/src/__tests__/tool-executor.test.ts +155 -0
  131. package/src/__tests__/twilio-validation.test.ts +2 -2
  132. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  133. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  134. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  136. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +120 -0
  137. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  138. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
  139. package/src/agent/loop.ts +11 -0
  140. package/src/approvals/guardian-request-resolvers.ts +3 -32
  141. package/src/backup/snapshot-lock.ts +2 -27
  142. package/src/bundler/compiler-tools.ts +3 -2
  143. package/src/calls/call-constants.ts +5 -8
  144. package/src/calls/call-controller.ts +130 -67
  145. package/src/calls/call-conversation-messages.ts +46 -10
  146. package/src/calls/relay-server.ts +7 -1
  147. package/src/calls/voice-session-bridge.ts +1 -1
  148. package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
  149. package/src/cli/commands/bash.ts +35 -108
  150. package/src/cli/commands/contacts.ts +64 -25
  151. package/src/cli/commands/credentials.ts +56 -0
  152. package/src/cli/commands/memory-v2.ts +11 -10
  153. package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
  154. package/src/cli/commands/oauth/connect.ts +124 -40
  155. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
  156. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
  157. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  158. package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
  159. package/src/cli/commands/platform/index.ts +16 -7
  160. package/src/cli/commands/status.ts +57 -0
  161. package/src/cli/program.ts +4 -2
  162. package/src/config/assistant-feature-flags.ts +13 -3
  163. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  164. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  165. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
  166. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  167. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  168. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  169. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  170. package/src/config/env.ts +0 -8
  171. package/src/config/feature-flag-registry.json +13 -5
  172. package/src/config/loader.ts +199 -27
  173. package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
  174. package/src/config/schemas/call-site-catalog.ts +14 -0
  175. package/src/config/schemas/channels.ts +0 -5
  176. package/src/config/schemas/heartbeat.ts +1 -1
  177. package/src/config/schemas/llm.ts +2 -0
  178. package/src/config/schemas/memory-lifecycle.ts +13 -0
  179. package/src/config/schemas/memory-v2.ts +76 -12
  180. package/src/config/schemas/platform.ts +43 -3
  181. package/src/config/schemas/services.ts +28 -0
  182. package/src/config/seed-inference-profiles.ts +230 -33
  183. package/src/contacts/contact-store.ts +0 -25
  184. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
  185. package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
  186. package/src/daemon/assistant-attachments.ts +4 -4
  187. package/src/daemon/config-watcher.ts +85 -57
  188. package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
  189. package/src/daemon/conversation-agent-loop.ts +183 -43
  190. package/src/daemon/conversation-error.ts +87 -15
  191. package/src/daemon/conversation-lifecycle.ts +22 -10
  192. package/src/daemon/conversation-process.ts +8 -0
  193. package/src/daemon/conversation-runtime-assembly.ts +26 -0
  194. package/src/daemon/conversation-store.ts +2 -2
  195. package/src/daemon/conversation-surfaces.ts +211 -29
  196. package/src/daemon/conversation-tool-setup.ts +66 -19
  197. package/src/daemon/conversation.ts +18 -23
  198. package/src/daemon/date-context.ts +71 -22
  199. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  200. package/src/daemon/disk-pressure-guard.ts +343 -0
  201. package/src/daemon/disk-pressure-policy.ts +163 -0
  202. package/src/daemon/handlers/shared.ts +26 -1
  203. package/src/daemon/handlers/skills.ts +3 -4
  204. package/src/daemon/host-app-control-proxy.ts +137 -41
  205. package/src/daemon/host-bash-proxy.ts +47 -22
  206. package/src/daemon/host-browser-proxy.ts +1 -1
  207. package/src/daemon/host-cu-proxy.ts +50 -4
  208. package/src/daemon/host-file-proxy.ts +44 -8
  209. package/src/daemon/host-transfer-proxy.ts +97 -6
  210. package/src/daemon/lifecycle.ts +167 -101
  211. package/src/daemon/meet-host-supervisor.ts +4 -4
  212. package/src/daemon/meet-manifest-loader.ts +0 -1
  213. package/src/daemon/memory-v2-startup.ts +66 -15
  214. package/src/daemon/message-protocol.ts +3 -0
  215. package/src/daemon/message-types/conversations.ts +4 -0
  216. package/src/daemon/message-types/disk-pressure.ts +9 -0
  217. package/src/daemon/message-types/messages.ts +22 -1
  218. package/src/daemon/profiler-run-store.ts +5 -5
  219. package/src/daemon/tool-setup-types.ts +2 -2
  220. package/src/documents/document-store.ts +119 -0
  221. package/src/filing/filing-service.ts +29 -5
  222. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
  223. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
  224. package/src/heartbeat/heartbeat-run-store.ts +13 -0
  225. package/src/heartbeat/heartbeat-service.ts +205 -31
  226. package/src/home/feed-scheduler.ts +18 -0
  227. package/src/inbound/platform-callback-registration.ts +8 -15
  228. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  229. package/src/ipc/assistant-server.ts +149 -38
  230. package/src/ipc/gateway-client.ts +37 -3
  231. package/src/ipc/skill-server.ts +99 -42
  232. package/src/live-voice/live-voice-archive.ts +4 -4
  233. package/src/live-voice/protocol.ts +5 -7
  234. package/src/media/image-service.ts +1 -7
  235. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  236. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +34 -51
  237. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  238. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  239. package/src/memory/admin.ts +5 -9
  240. package/src/memory/context-search/agent-runner.ts +19 -2
  241. package/src/memory/context-search/sources/conversations.ts +2 -11
  242. package/src/memory/context-search/sources/memory-v2.ts +1 -16
  243. package/src/memory/context-search/sources/memory.ts +2 -3
  244. package/src/memory/context-search/sources/pkb.ts +2 -3
  245. package/src/memory/context-search/types.ts +0 -1
  246. package/src/memory/conversation-crud.ts +4 -12
  247. package/src/memory/db-init.ts +2 -0
  248. package/src/memory/embedding-runtime-manager.ts +119 -5
  249. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
  250. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  251. package/src/memory/graph/conversation-graph-memory.ts +72 -61
  252. package/src/memory/graph/extraction.ts +1 -3
  253. package/src/memory/graph/graph-search.test.ts +11 -67
  254. package/src/memory/graph/graph-search.ts +4 -24
  255. package/src/memory/graph/retriever.test.ts +12 -1
  256. package/src/memory/graph/retriever.ts +10 -15
  257. package/src/memory/graph/tool-handlers.ts +3 -4
  258. package/src/memory/graph/tools.ts +4 -4
  259. package/src/memory/indexer.ts +53 -45
  260. package/src/memory/job-handlers/backfill.ts +2 -11
  261. package/src/memory/job-handlers/cleanup.ts +43 -0
  262. package/src/memory/job-handlers/embedding.ts +6 -8
  263. package/src/memory/job-handlers/summarization.ts +2 -7
  264. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +116 -0
  265. package/src/memory/jobs/embed-concept-page.ts +223 -87
  266. package/src/memory/jobs-store.ts +48 -0
  267. package/src/memory/jobs-worker.ts +85 -43
  268. package/src/memory/memory-v2-activation-log-store.ts +32 -14
  269. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  270. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  271. package/src/memory/migrations/index.ts +1 -0
  272. package/src/memory/pkb/pkb-search.test.ts +7 -0
  273. package/src/memory/pkb/pkb-search.ts +4 -5
  274. package/src/memory/qdrant-client.ts +3 -13
  275. package/src/memory/rerank-local.ts +374 -0
  276. package/src/memory/search/semantic.ts +10 -72
  277. package/src/memory/trace-event-store.ts +1 -17
  278. package/src/memory/v2/__tests__/activation.test.ts +346 -255
  279. package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
  280. package/src/memory/v2/__tests__/injection.test.ts +297 -190
  281. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  282. package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
  283. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  284. package/src/memory/v2/__tests__/sim.test.ts +113 -196
  285. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  286. package/src/memory/v2/__tests__/static-context.test.ts +77 -14
  287. package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
  288. package/src/memory/v2/activation.ts +149 -156
  289. package/src/memory/v2/consolidation-job.ts +69 -20
  290. package/src/memory/v2/injection.ts +75 -68
  291. package/src/memory/v2/page-store.ts +39 -0
  292. package/src/memory/v2/prompts/consolidation.ts +41 -1
  293. package/src/memory/v2/qdrant.ts +306 -46
  294. package/src/memory/v2/reranker.ts +177 -0
  295. package/src/memory/v2/sim.ts +77 -110
  296. package/src/memory/v2/skill-content.ts +4 -3
  297. package/src/memory/v2/skill-store.ts +82 -59
  298. package/src/memory/v2/static-context.ts +26 -8
  299. package/src/memory/v2/sweep-job.ts +5 -6
  300. package/src/memory/v2/types.ts +17 -10
  301. package/src/notifications/copy-composer.ts +47 -0
  302. package/src/notifications/decision-engine.ts +46 -0
  303. package/src/notifications/signal.ts +4 -0
  304. package/src/oauth/AGENTS.md +3 -1
  305. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  306. package/src/oauth/connect-orchestrator.ts +2 -0
  307. package/src/oauth/connection-resolver.test.ts +66 -1
  308. package/src/oauth/connection-resolver.ts +55 -1
  309. package/src/oauth/oauth-connect-state.ts +77 -0
  310. package/src/oauth/seed-providers.ts +58 -1
  311. package/src/permissions/gateway-threshold-reader.ts +116 -8
  312. package/src/permissions/prompter.ts +86 -96
  313. package/src/permissions/secret-prompter.ts +31 -31
  314. package/src/plugins/defaults/injectors.ts +36 -4
  315. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  316. package/src/plugins/types.ts +7 -0
  317. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  318. package/src/proactive-artifact/decision.test.ts +226 -0
  319. package/src/proactive-artifact/decision.ts +165 -0
  320. package/src/proactive-artifact/index.ts +7 -0
  321. package/src/proactive-artifact/job.test.ts +914 -0
  322. package/src/proactive-artifact/job.ts +366 -0
  323. package/src/proactive-artifact/message-copy.ts +58 -0
  324. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  325. package/src/proactive-artifact/trigger-state.ts +119 -0
  326. package/src/prompts/normalize-onboarding.ts +80 -0
  327. package/src/prompts/persona-resolver.ts +101 -9
  328. package/src/prompts/system-prompt.ts +21 -7
  329. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  330. package/src/prompts/templates/SOUL.md +13 -28
  331. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  332. package/src/providers/model-intents.ts +7 -0
  333. package/src/providers/openrouter/client.ts +8 -0
  334. package/src/providers/retry.ts +50 -0
  335. package/src/providers/types.ts +1 -0
  336. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  337. package/src/runtime/agent-wake.ts +238 -100
  338. package/src/runtime/assistant-event-hub.ts +36 -6
  339. package/src/runtime/assistant-event.ts +0 -1
  340. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  341. package/src/runtime/auth/route-policy.ts +15 -1
  342. package/src/runtime/auth/same-actor.ts +216 -0
  343. package/src/runtime/channel-approvals.ts +3 -2
  344. package/src/runtime/channel-retry-sweep.ts +65 -1
  345. package/src/runtime/local-actor-identity.ts +52 -11
  346. package/src/runtime/pending-interactions.ts +27 -15
  347. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  348. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
  349. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  350. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  351. package/src/runtime/routes/approval-routes.ts +7 -3
  352. package/src/runtime/routes/client-routes.ts +20 -2
  353. package/src/runtime/routes/consolidation-routes.ts +8 -9
  354. package/src/runtime/routes/contact-routes.ts +0 -25
  355. package/src/runtime/routes/conversation-query-routes.ts +44 -1
  356. package/src/runtime/routes/conversation-routes.ts +35 -26
  357. package/src/runtime/routes/debug-bash-routes.ts +165 -0
  358. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  359. package/src/runtime/routes/document-pdf-renderer.ts +6 -2
  360. package/src/runtime/routes/documents-routes.ts +2 -75
  361. package/src/runtime/routes/events-routes.ts +41 -9
  362. package/src/runtime/routes/filing-routes.ts +2 -3
  363. package/src/runtime/routes/host-bash-routes.ts +23 -3
  364. package/src/runtime/routes/host-cu-routes.ts +33 -6
  365. package/src/runtime/routes/host-file-routes.ts +32 -6
  366. package/src/runtime/routes/host-transfer-routes.ts +79 -16
  367. package/src/runtime/routes/identity-routes.ts +7 -138
  368. package/src/runtime/routes/inbound-message-handler.ts +77 -12
  369. package/src/runtime/routes/index.ts +6 -0
  370. package/src/runtime/routes/memory-item-routes.test.ts +37 -17
  371. package/src/runtime/routes/memory-item-routes.ts +5 -6
  372. package/src/runtime/routes/memory-v2-routes.ts +136 -17
  373. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  374. package/src/runtime/verification-outbound-actions.ts +4 -4
  375. package/src/schedule/run-script.ts +37 -5
  376. package/src/schedule/scheduler.ts +20 -1
  377. package/src/security/encrypted-store.ts +2 -0
  378. package/src/security/secure-keys.ts +55 -0
  379. package/src/skills/include-graph.ts +35 -13
  380. package/src/skills/remote-skill-policy.ts +4 -10
  381. package/src/subagent/index.ts +1 -7
  382. package/src/subagent/manager.ts +1 -15
  383. package/src/tasks/task-runner.ts +0 -1
  384. package/src/tasks/task-store.ts +0 -3
  385. package/src/tools/background-tool-registry.ts +17 -3
  386. package/src/tools/document/document-tool.ts +20 -0
  387. package/src/tools/executor.ts +18 -2
  388. package/src/tools/host-filesystem/edit.test.ts +151 -0
  389. package/src/tools/host-filesystem/edit.ts +43 -1
  390. package/src/tools/host-filesystem/read.test.ts +129 -0
  391. package/src/tools/host-filesystem/read.ts +43 -1
  392. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  393. package/src/tools/host-filesystem/transfer.ts +56 -11
  394. package/src/tools/host-filesystem/write.test.ts +134 -0
  395. package/src/tools/host-filesystem/write.ts +43 -1
  396. package/src/tools/host-terminal/host-shell.ts +13 -6
  397. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  398. package/src/tools/memory/register.test.ts +14 -9
  399. package/src/tools/memory/register.ts +1 -2
  400. package/src/tools/permission-checker.ts +15 -0
  401. package/src/tools/provider-tool-name.ts +28 -0
  402. package/src/tools/registry.ts +30 -9
  403. package/src/tools/skills/load.ts +24 -20
  404. package/src/tools/terminal/shell.ts +9 -1
  405. package/src/tools/tool-approval-handler.ts +31 -6
  406. package/src/tools/tool-name-aliases.ts +19 -0
  407. package/src/tools/types.ts +43 -3
  408. package/src/tts/provider-catalog.ts +3 -5
  409. package/src/util/disk-usage.ts +138 -0
  410. package/src/util/platform.ts +21 -11
  411. package/src/util/process-liveness.ts +26 -0
  412. package/src/workspace/heartbeat-service.ts +19 -0
  413. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  414. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  415. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +14 -0
  416. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  417. package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
  418. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  419. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  420. package/src/workspace/migrations/registry.ts +14 -0
  421. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  422. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  423. package/src/memory/v2/skill-qdrant.ts +0 -404
  424. package/src/signals/bash.ts +0 -198
@@ -0,0 +1,374 @@
1
+ /** Local cross-encoder rerank backend — drives the rerank-worker subprocess. */
2
+ import { existsSync } from "node:fs";
3
+
4
+ import type { RerankDtype } from "../config/schemas/memory-v2.js";
5
+ import { getLogger } from "../util/logger.js";
6
+ import { getEmbeddingModelsDir } from "../util/platform.js";
7
+ import { PromiseGuard } from "../util/promise-guard.js";
8
+ import { EmbeddingRuntimeManager } from "./embedding-runtime-manager.js";
9
+
10
+ const log = getLogger("memory-rerank-local");
11
+
12
+ interface WorkerResponse {
13
+ id?: number;
14
+ type?: string;
15
+ scores?: number[];
16
+ error?: string;
17
+ }
18
+
19
+ export class LocalRerankBackend {
20
+ readonly model: string;
21
+ readonly dtype: RerankDtype;
22
+
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ private workerProc: any = null;
25
+ private stdoutBuffer = "";
26
+ private requestCounter = 0;
27
+ private pendingRequests = new Map<
28
+ number,
29
+ { resolve: (response: WorkerResponse) => void }
30
+ >();
31
+ private stdoutReaderActive = false;
32
+ private activeRequests = 0;
33
+ private disposeRequested = false;
34
+
35
+ private readyResolve: (() => void) | null = null;
36
+ private readyReject: ((err: Error) => void) | null = null;
37
+
38
+ private readonly initGuard = new PromiseGuard<void>();
39
+
40
+ constructor(model: string, dtype: RerankDtype) {
41
+ this.model = model;
42
+ this.dtype = dtype;
43
+ }
44
+
45
+ /**
46
+ * Score paired `(queries[i], passages[i])` tuples in one batched ONNX
47
+ * inference call. Multiple distinct queries can ride in a single batch
48
+ * so callers can score the user-channel and assistant-channel queries
49
+ * against a shared candidate set in one tokenizer + forward pass.
50
+ */
51
+ async score(queries: string[], passages: string[]): Promise<number[]> {
52
+ if (this.disposeRequested) {
53
+ throw new Error("Local rerank backend is shutting down");
54
+ }
55
+ if (passages.length === 0) return [];
56
+ if (queries.length !== passages.length) {
57
+ throw new Error(
58
+ `Rerank backend got ${queries.length} queries for ${passages.length} passages`,
59
+ );
60
+ }
61
+
62
+ this.activeRequests++;
63
+ try {
64
+ await this.ensureInitialized();
65
+ const response = await this.sendRequest({ queries, passages });
66
+ if (response.error) {
67
+ throw new Error(`Rerank worker error: ${response.error}`);
68
+ }
69
+ if (!response.scores) {
70
+ throw new Error("Rerank worker returned no scores");
71
+ }
72
+ if (response.scores.length !== passages.length) {
73
+ throw new Error(
74
+ `Rerank worker returned ${response.scores.length} scores for ${passages.length} passages`,
75
+ );
76
+ }
77
+ return response.scores;
78
+ } finally {
79
+ this.activeRequests--;
80
+ this.disposeIfIdle();
81
+ }
82
+ }
83
+
84
+ dispose(): void {
85
+ this.disposeRequested = true;
86
+ this.disposeIfIdle();
87
+ }
88
+
89
+ private sendRequest(payload: {
90
+ queries: string[];
91
+ passages: string[];
92
+ }): Promise<WorkerResponse> {
93
+ const id = ++this.requestCounter;
94
+ return new Promise((resolve) => {
95
+ if (!this.workerProc) {
96
+ resolve({ error: "Worker not initialized" });
97
+ return;
98
+ }
99
+ this.pendingRequests.set(id, { resolve });
100
+ this.workerProc.stdin.write(JSON.stringify({ id, ...payload }) + "\n");
101
+ try {
102
+ this.workerProc.stdin.flush();
103
+ } catch {
104
+ // Worker may have exited — stdout reader cleanup resolves pending requests.
105
+ }
106
+ });
107
+ }
108
+
109
+ private async ensureInitialized(): Promise<void> {
110
+ if (this.workerProc) return;
111
+ await this.initGuard.run(() => this.initialize());
112
+ }
113
+
114
+ private async initialize(): Promise<void> {
115
+ log.info({ model: this.model }, "Initializing local rerank backend");
116
+
117
+ const runtimeManager = new EmbeddingRuntimeManager();
118
+ if (!runtimeManager.isReady()) {
119
+ log.info("Embedding runtime not yet available, waiting for download...");
120
+ await runtimeManager.ensureInstalled();
121
+ }
122
+
123
+ const bunPath = runtimeManager.getBunPath();
124
+ const workerPath = runtimeManager.getRerankWorkerPath();
125
+
126
+ if (!bunPath) {
127
+ throw new Error("Local rerank backend unavailable: no bun binary found");
128
+ }
129
+ if (!existsSync(workerPath)) {
130
+ throw new Error(
131
+ `Local rerank backend unavailable: worker script not found at ${workerPath}`,
132
+ );
133
+ }
134
+
135
+ await this.startWorker(bunPath, workerPath);
136
+ }
137
+
138
+ private async startWorker(
139
+ bunPath: string,
140
+ workerPath: string,
141
+ ): Promise<void> {
142
+ const embeddingModelsDir = getEmbeddingModelsDir();
143
+ const modelCacheDir = `${embeddingModelsDir}/model-cache`;
144
+
145
+ log.info(
146
+ { bunPath, workerPath, model: this.model, dtype: this.dtype },
147
+ "Spawning rerank worker process",
148
+ );
149
+
150
+ const proc = Bun.spawn({
151
+ cmd: [
152
+ bunPath,
153
+ "--smol",
154
+ workerPath,
155
+ this.model,
156
+ modelCacheDir,
157
+ this.dtype,
158
+ ],
159
+ stdin: "pipe",
160
+ stdout: "pipe",
161
+ stderr: "pipe",
162
+ cwd: embeddingModelsDir,
163
+ });
164
+
165
+ this.workerProc = proc;
166
+ this.startStdoutReader();
167
+
168
+ try {
169
+ await this.waitForReady();
170
+ } catch (err) {
171
+ this.workerProc = null;
172
+ this.stdoutReaderActive = false;
173
+ try {
174
+ proc.kill();
175
+ } catch {
176
+ /* may already be dead */
177
+ }
178
+ const exitCode = await proc.exited.catch(() => undefined);
179
+ const stderr = await new Response(proc.stderr).text().catch(() => "");
180
+ if (stderr.trim()) {
181
+ log.warn({ stderr: stderr.trim(), exitCode }, "Rerank worker stderr");
182
+ }
183
+ throw new Error(
184
+ `Rerank worker exited (code ${exitCode ?? "unknown"}): ${
185
+ stderr.trim() || (err instanceof Error ? err.message : String(err))
186
+ }`,
187
+ );
188
+ }
189
+
190
+ this.drainStderr(proc.stderr);
191
+ log.info(
192
+ { pid: proc.pid, model: this.model },
193
+ "Rerank worker process started",
194
+ );
195
+ this.disposeIfIdle();
196
+ }
197
+
198
+ private drainStderr(stderr: ReadableStream<Uint8Array>): void {
199
+ const reader = stderr.getReader();
200
+ const decoder = new TextDecoder();
201
+ (async () => {
202
+ try {
203
+ while (true) {
204
+ const { done, value } = await reader.read();
205
+ if (done) break;
206
+ const text = decoder.decode(value, { stream: true }).trim();
207
+ if (text) log.debug({ workerStderr: text }, "Rerank worker stderr");
208
+ }
209
+ } catch {
210
+ /* expected on shutdown */
211
+ }
212
+ })();
213
+ }
214
+
215
+ private startStdoutReader(): void {
216
+ if (this.stdoutReaderActive || !this.workerProc) return;
217
+ this.stdoutReaderActive = true;
218
+
219
+ const proc = this.workerProc;
220
+ const reader = proc.stdout.getReader();
221
+ const decoder = new TextDecoder();
222
+
223
+ (async () => {
224
+ try {
225
+ while (true) {
226
+ const { done, value } = await reader.read();
227
+ if (done) break;
228
+ this.stdoutBuffer += decoder.decode(value, { stream: true });
229
+ this.processStdoutBuffer();
230
+ }
231
+ } catch {
232
+ /* reader cancelled or stream errored */
233
+ }
234
+
235
+ if (this.workerProc === proc) {
236
+ for (const pending of this.pendingRequests.values()) {
237
+ pending.resolve({
238
+ error: "Rerank worker process exited unexpectedly",
239
+ });
240
+ }
241
+ this.pendingRequests.clear();
242
+ this.workerProc = null;
243
+ this.stdoutReaderActive = false;
244
+ this.stdoutBuffer = "";
245
+ this.initGuard.reset();
246
+ }
247
+ })();
248
+ }
249
+
250
+ private processStdoutBuffer(): void {
251
+ let idx: number;
252
+ while ((idx = this.stdoutBuffer.indexOf("\n")) !== -1) {
253
+ const line = this.stdoutBuffer.slice(0, idx);
254
+ this.stdoutBuffer = this.stdoutBuffer.slice(idx + 1);
255
+ if (!line.trim()) continue;
256
+
257
+ let msg: WorkerResponse;
258
+ try {
259
+ msg = JSON.parse(line);
260
+ } catch {
261
+ continue;
262
+ }
263
+
264
+ if (msg.type === "ready") {
265
+ this.readyResolve?.();
266
+ this.readyResolve = null;
267
+ this.readyReject = null;
268
+ continue;
269
+ }
270
+ if (msg.type === "error" && this.readyReject) {
271
+ this.readyReject(
272
+ new Error(msg.error ?? "Worker initialization failed"),
273
+ );
274
+ this.readyResolve = null;
275
+ this.readyReject = null;
276
+ continue;
277
+ }
278
+
279
+ if (msg.id !== undefined) {
280
+ const pending = this.pendingRequests.get(msg.id);
281
+ if (pending) {
282
+ this.pendingRequests.delete(msg.id);
283
+ pending.resolve(msg);
284
+ this.disposeIfIdle();
285
+ }
286
+ }
287
+ }
288
+ }
289
+
290
+ private waitForReady(): Promise<void> {
291
+ return new Promise<void>((resolve, reject) => {
292
+ // First-call timeout. Generous because the first run downloads the
293
+ // ONNX weights (~280 MB to ~1 GB depending on model) before loading.
294
+ const timeout = setTimeout(() => {
295
+ this.readyResolve = null;
296
+ this.readyReject = null;
297
+ reject(new Error("Rerank worker timed out waiting for model to load"));
298
+ }, 120_000);
299
+
300
+ this.readyResolve = () => {
301
+ clearTimeout(timeout);
302
+ resolve();
303
+ };
304
+ this.readyReject = (err: Error) => {
305
+ clearTimeout(timeout);
306
+ reject(err);
307
+ };
308
+
309
+ this.workerProc?.exited.then(() => {
310
+ if (this.readyResolve) {
311
+ clearTimeout(timeout);
312
+ this.readyResolve = null;
313
+ this.readyReject = null;
314
+ reject(
315
+ new Error("Rerank worker process exited before becoming ready"),
316
+ );
317
+ }
318
+ });
319
+ });
320
+ }
321
+
322
+ private disposeIfIdle(): void {
323
+ if (!this.disposeRequested) return;
324
+ if (this.activeRequests > 0) return;
325
+ if (this.pendingRequests.size > 0) return;
326
+ if (this.readyResolve || this.readyReject) return;
327
+
328
+ const proc = this.workerProc;
329
+ this.workerProc = null;
330
+ this.stdoutReaderActive = false;
331
+ this.stdoutBuffer = "";
332
+ this.initGuard.reset();
333
+
334
+ if (!proc) return;
335
+
336
+ try {
337
+ proc.kill();
338
+ } catch {
339
+ /* may already be exiting */
340
+ }
341
+ }
342
+ }
343
+
344
+ // ── Module-level singleton management ─────────────────────────────────
345
+
346
+ let _backend: LocalRerankBackend | null = null;
347
+
348
+ export function getOrCreateRerankBackend(
349
+ model: string,
350
+ dtype: RerankDtype,
351
+ ): LocalRerankBackend {
352
+ if (_backend?.model === model && _backend.dtype === dtype) return _backend;
353
+ if (_backend) {
354
+ try {
355
+ _backend.dispose();
356
+ } catch {
357
+ /* best effort */
358
+ }
359
+ }
360
+ _backend = new LocalRerankBackend(model, dtype);
361
+ return _backend;
362
+ }
363
+
364
+ /** @internal Test-only: reset the cached backend. */
365
+ export function _resetRerankBackendForTests(): void {
366
+ if (_backend) {
367
+ try {
368
+ _backend.dispose();
369
+ } catch {
370
+ /* best effort */
371
+ }
372
+ }
373
+ _backend = null;
374
+ }
@@ -1,7 +1,6 @@
1
1
  import { inArray } from "drizzle-orm";
2
2
 
3
3
  import { getConfig } from "../../config/loader.js";
4
- import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
5
4
  import { getDb } from "../db-connection.js";
6
5
  import { withQdrantBreaker } from "../qdrant-circuit-breaker.js";
7
6
  import type {
@@ -9,7 +8,7 @@ import type {
9
8
  QdrantSparseVector,
10
9
  } from "../qdrant-client.js";
11
10
  import { getQdrantClient } from "../qdrant-client.js";
12
- import { conversations, memorySegments, memorySummaries } from "../schema.js";
11
+ import { memorySegments, memorySummaries } from "../schema.js";
13
12
  // ── Types (inlined from deleted types.ts) ──────────────────────────
14
13
 
15
14
  type CandidateType = "segment" | "item" | "summary" | "media";
@@ -52,15 +51,14 @@ export async function semanticSearch(
52
51
  _model: string,
53
52
  limit: number,
54
53
  excludedMessageIds: string[] = [],
55
- scopeIds?: string[],
56
54
  sparseVector?: QdrantSparseVector,
57
55
  ): Promise<Candidate[]> {
58
56
  if (limit <= 0) return [];
59
57
 
60
- // v2 owns the read path when both gates are on; the v1 `memory` collection
61
- // is in active retirement, and routing semantic recall there would re-enter
62
- // the same corrupted sparse segments that can OOM-crash Qdrant.
63
- if (isMemoryV2ReadActive(getConfig())) return [];
58
+ // v2 owns the read path when enabled; the v1 `memory` collection is in
59
+ // active retirement, and routing semantic recall there would re-enter the
60
+ // same corrupted sparse segments that can OOM-crash Qdrant.
61
+ if (getConfig().memory.v2.enabled) return [];
64
62
 
65
63
  const qdrant = getQdrantClient();
66
64
 
@@ -75,7 +73,7 @@ export async function semanticSearch(
75
73
  let isHybrid = false;
76
74
  if (sparseVector && sparseVector.indices.length > 0) {
77
75
  isHybrid = true;
78
- const filter = buildHybridFilter(excludedMessageIds, scopeIds);
76
+ const filter = buildHybridFilter(excludedMessageIds);
79
77
  results = await withQdrantBreaker(() =>
80
78
  qdrant.hybridSearch({
81
79
  denseVector: queryVector,
@@ -92,7 +90,6 @@ export async function semanticSearch(
92
90
  fetchLimit,
93
91
  ["summary", "segment", "media"],
94
92
  excludedMessageIds,
95
- scopeIds,
96
93
  ),
97
94
  );
98
95
  }
@@ -102,18 +99,15 @@ export async function semanticSearch(
102
99
  // Batch-fetch all backing records upfront to avoid N+1 queries per result
103
100
  const summaryTargetIds: string[] = [];
104
101
  const segmentTargetIds: string[] = [];
105
- const mediaConversationIds: string[] = [];
106
102
  for (const r of results) {
107
103
  if (r.payload.target_type === "summary")
108
104
  summaryTargetIds.push(r.payload.target_id);
109
105
  else if (r.payload.target_type === "segment")
110
106
  segmentTargetIds.push(r.payload.target_id);
111
- else if (r.payload.target_type === "media" && r.payload.conversation_id)
112
- mediaConversationIds.push(r.payload.conversation_id);
113
107
  }
114
108
 
115
109
  const summariesMap = new Map<string, typeof memorySummaries.$inferSelect>();
116
- if (scopeIds && summaryTargetIds.length > 0) {
110
+ if (summaryTargetIds.length > 0) {
117
111
  const allSummaries = db
118
112
  .select()
119
113
  .from(memorySummaries)
@@ -123,7 +117,7 @@ export async function semanticSearch(
123
117
  }
124
118
 
125
119
  const segmentsMap = new Map<string, typeof memorySegments.$inferSelect>();
126
- if (scopeIds && segmentTargetIds.length > 0) {
120
+ if (segmentTargetIds.length > 0) {
127
121
  const allSegments = db
128
122
  .select()
129
123
  .from(memorySegments)
@@ -132,23 +126,6 @@ export async function semanticSearch(
132
126
  for (const seg of allSegments) segmentsMap.set(seg.id, seg);
133
127
  }
134
128
 
135
- // Batch-fetch conversation scope IDs for media results to avoid N+1 queries.
136
- // When a conversation is not found (deleted), its media is excluded rather than
137
- // falling back to "default" scope, which would leak private media.
138
- const mediaScopeMap = new Map<string, string>();
139
- if (scopeIds && mediaConversationIds.length > 0) {
140
- const unique = [...new Set(mediaConversationIds)];
141
- const rows = db
142
- .select({
143
- id: conversations.id,
144
- memoryScopeId: conversations.memoryScopeId,
145
- })
146
- .from(conversations)
147
- .where(inArray(conversations.id, unique))
148
- .all();
149
- for (const row of rows) mediaScopeMap.set(row.id, row.memoryScopeId);
150
- }
151
-
152
129
  const candidates: Candidate[] = [];
153
130
  for (const result of results) {
154
131
  const { payload, score } = result;
@@ -160,10 +137,7 @@ export async function semanticSearch(
160
137
  // Legacy item vectors — skip (table dropped, Qdrant cleanup pending)
161
138
  continue;
162
139
  } else if (payload.target_type === "summary") {
163
- if (scopeIds) {
164
- const summary = summariesMap.get(payload.target_id);
165
- if (!summary || !scopeIds.includes(summary.scopeId)) continue;
166
- }
140
+ if (!summariesMap.has(payload.target_id)) continue;
167
141
  candidates.push({
168
142
  key: `summary:${payload.target_id}`,
169
143
  type: "summary",
@@ -180,22 +154,6 @@ export async function semanticSearch(
180
154
  finalScore: 0,
181
155
  });
182
156
  } else if (payload.target_type === "media") {
183
- // Use stored memory_scope_id when available; fall back to deriving
184
- // scope from conversation_id for legacy media points.
185
- // If the conversation was deleted, skip the media to avoid leaking
186
- // private media into the default scope.
187
- if (scopeIds) {
188
- let mediaScopeId: string | undefined;
189
- if (payload.memory_scope_id) {
190
- mediaScopeId = payload.memory_scope_id;
191
- } else if (payload.conversation_id) {
192
- mediaScopeId = mediaScopeMap.get(payload.conversation_id);
193
- if (!mediaScopeId) continue; // conversation deleted — skip
194
- } else {
195
- mediaScopeId = "default";
196
- }
197
- if (!scopeIds.includes(mediaScopeId)) continue;
198
- }
199
157
  candidates.push({
200
158
  key: `media:${payload.target_id}`,
201
159
  type: "media",
@@ -212,10 +170,7 @@ export async function semanticSearch(
212
170
  finalScore: 0,
213
171
  });
214
172
  } else {
215
- if (scopeIds) {
216
- const segment = segmentsMap.get(payload.target_id);
217
- if (!segment || !scopeIds.includes(segment.scopeId)) continue;
218
- }
173
+ if (!segmentsMap.has(payload.target_id)) continue;
219
174
  candidates.push({
220
175
  key: `segment:${payload.target_id}`,
221
176
  type: "segment",
@@ -254,14 +209,9 @@ export async function semanticSearch(
254
209
  /**
255
210
  * Build a Qdrant filter for hybrid search. Mirrors the logic in
256
211
  * `searchWithFilter` but as a standalone object for the query API.
257
- *
258
- * Scope filtering: points with a `memory_scope_id` payload field are
259
- * filtered at the Qdrant level. Legacy points without the field pass
260
- * through and are caught by post-query DB filtering.
261
212
  */
262
213
  function buildHybridFilter(
263
214
  excludeMessageIds: string[],
264
- scopeIds?: string[],
265
215
  ): Record<string, unknown> {
266
216
  const mustConditions: Array<Record<string, unknown>> = [
267
217
  {
@@ -270,18 +220,6 @@ function buildHybridFilter(
270
220
  },
271
221
  ];
272
222
 
273
- // Scope filtering: accept points whose memory_scope_id matches one of the
274
- // allowed scopes, OR points that lack the field entirely (legacy data).
275
- // Post-query DB filtering remains as defense-in-depth for legacy points.
276
- if (scopeIds && scopeIds.length > 0) {
277
- mustConditions.push({
278
- should: [
279
- { key: "memory_scope_id", match: { any: scopeIds } },
280
- { is_empty: { key: "memory_scope_id" } },
281
- ],
282
- });
283
- }
284
-
285
223
  const mustNotConditions: Array<Record<string, unknown>> = [
286
224
  { key: "_meta", match: { value: true } },
287
225
  ];
@@ -1,11 +1,10 @@
1
- import { and, asc, eq, gt, lt, sql } from "drizzle-orm";
1
+ import { and, asc, eq, gt, sql } from "drizzle-orm";
2
2
 
3
3
  import type {
4
4
  TraceEvent,
5
5
  TraceEventKind,
6
6
  } from "../daemon/message-types/messages.js";
7
7
  import { getDb } from "./db-connection.js";
8
- import { rawChanges } from "./raw-query.js";
9
8
  import { traceEvents } from "./schema.js";
10
9
 
11
10
  // ---------------------------------------------------------------------------
@@ -115,21 +114,6 @@ export function getTraceEvents(
115
114
  return rows.map(rowToTraceEventRow);
116
115
  }
117
116
 
118
- // ---------------------------------------------------------------------------
119
- // Cleanup
120
- // ---------------------------------------------------------------------------
121
-
122
- /**
123
- * Delete trace events older than `maxAgeDays` based on `created_at`.
124
- * Returns the count of deleted rows.
125
- */
126
- export function deleteOldTraceEvents(maxAgeDays: number): number {
127
- const db = getDb();
128
- const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
129
- db.delete(traceEvents).where(lt(traceEvents.createdAt, cutoff)).run();
130
- return rawChanges();
131
- }
132
-
133
117
  // ---------------------------------------------------------------------------
134
118
  // Sequence
135
119
  // ---------------------------------------------------------------------------