@vellumai/assistant 0.7.1 → 0.7.3

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 (739) hide show
  1. package/ARCHITECTURE.md +48 -50
  2. package/Dockerfile +1 -0
  3. package/README.md +1 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
  5. package/bun.lock +26 -26
  6. package/docs/architecture/memory.md +5 -2
  7. package/docs/architecture/security.md +20 -0
  8. package/docs/plugins.md +7 -9
  9. package/knip.json +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  11. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
  12. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  13. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  15. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  16. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  17. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  18. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  19. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  20. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  21. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  22. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  23. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  24. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  25. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  26. package/openapi.yaml +1020 -40
  27. package/package.json +6 -3
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  29. package/src/__tests__/app-bundler.test.ts +170 -1
  30. package/src/__tests__/app-control-flow.test.ts +384 -0
  31. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  32. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  33. package/src/__tests__/app-executors.test.ts +30 -43
  34. package/src/__tests__/approval-routes-http.test.ts +23 -6
  35. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  36. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +157 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
  39. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  40. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  41. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  42. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  43. package/src/__tests__/btw-routes.test.ts +13 -4
  44. package/src/__tests__/call-controller.test.ts +49 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  46. package/src/__tests__/call-domain.test.ts +0 -2
  47. package/src/__tests__/call-routes-http.test.ts +0 -2
  48. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  49. package/src/__tests__/channel-readiness-service.test.ts +62 -2
  50. package/src/__tests__/checker.test.ts +3 -4
  51. package/src/__tests__/config-loader-backfill.test.ts +461 -147
  52. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  53. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  54. package/src/__tests__/config-schema.test.ts +1 -0
  55. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  56. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
  57. package/src/__tests__/config-watcher.test.ts +142 -71
  58. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  59. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  60. package/src/__tests__/context-search-fanout.test.ts +0 -1
  61. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  62. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  63. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  64. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  65. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  66. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  67. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  68. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  70. package/src/__tests__/conversation-error.test.ts +150 -3
  71. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  72. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  74. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  80. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  81. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  82. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  83. package/src/__tests__/conversation-store.test.ts +0 -18
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  85. package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
  86. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  87. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  88. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  89. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  90. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  91. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  92. package/src/__tests__/credentials-cli.test.ts +12 -12
  93. package/src/__tests__/cu-unified-flow.test.ts +351 -23
  94. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  95. package/src/__tests__/date-context.test.ts +164 -2
  96. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  97. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  98. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  99. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  100. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  101. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  102. package/src/__tests__/disk-usage.test.ts +150 -0
  103. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  104. package/src/__tests__/events-client-registration.test.ts +52 -0
  105. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  106. package/src/__tests__/file-write-tool.test.ts +4 -10
  107. package/src/__tests__/filing-service.test.ts +3 -4
  108. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  110. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  112. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  113. package/src/__tests__/heartbeat-service.test.ts +968 -2
  114. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  115. package/src/__tests__/host-app-control-proxy.test.ts +772 -0
  116. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +439 -47
  118. package/src/__tests__/host-bash-routes.test.ts +459 -0
  119. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  120. package/src/__tests__/host-browser-routes.test.ts +39 -13
  121. package/src/__tests__/host-cu-proxy.test.ts +248 -52
  122. package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
  123. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  124. package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
  125. package/src/__tests__/host-file-proxy.test.ts +301 -45
  126. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  127. package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
  128. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  129. package/src/__tests__/host-proxy-base.test.ts +312 -0
  130. package/src/__tests__/host-shell-tool.test.ts +22 -4
  131. package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
  132. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  133. package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
  134. package/src/__tests__/http-user-message-parity.test.ts +108 -1
  135. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  136. package/src/__tests__/identity-routes.test.ts +103 -1
  137. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  138. package/src/__tests__/injector-chain.test.ts +18 -6
  139. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  140. package/src/__tests__/inline-command-runner.test.ts +0 -1
  141. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  142. package/src/__tests__/integration-status.test.ts +85 -5
  143. package/src/__tests__/intent-routing.test.ts +0 -1
  144. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  145. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  146. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  147. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  148. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  149. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  150. package/src/__tests__/mcp-cli.test.ts +338 -2
  151. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  153. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  155. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  156. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  157. package/src/__tests__/oauth-cli.test.ts +0 -2
  158. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  160. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  161. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  162. package/src/__tests__/openai-provider.test.ts +45 -8
  163. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  164. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  165. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  166. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  167. package/src/__tests__/platform.test.ts +2 -1
  168. package/src/__tests__/playbook-execution.test.ts +0 -43
  169. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  170. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
  171. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  172. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  173. package/src/__tests__/provider-tool-name.test.ts +23 -0
  174. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  175. package/src/__tests__/relay-server.test.ts +15 -4
  176. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  177. package/src/__tests__/retry-backoff.test.ts +87 -0
  178. package/src/__tests__/runtime-events-sse.test.ts +2 -2
  179. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  180. package/src/__tests__/schedule-retry.test.ts +715 -0
  181. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  182. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  183. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  184. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  185. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  186. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  187. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  188. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  189. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  190. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  191. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  192. package/src/__tests__/slack-channel-config.test.ts +9 -14
  193. package/src/__tests__/suggestion-routes.test.ts +46 -0
  194. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  195. package/src/__tests__/system-prompt.test.ts +0 -1
  196. package/src/__tests__/telegram-config.test.ts +0 -1
  197. package/src/__tests__/test-preload.ts +8 -0
  198. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  199. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  200. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  201. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  202. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  203. package/src/__tests__/tool-executor.test.ts +0 -1
  204. package/src/__tests__/twilio-config.test.ts +3 -16
  205. package/src/__tests__/twilio-routes.test.ts +3 -5
  206. package/src/__tests__/twilio-validation.test.ts +93 -0
  207. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  208. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  209. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  210. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  211. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  212. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  213. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  214. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  215. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  216. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  217. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  218. package/src/approvals/guardian-decision-primitive.ts +13 -0
  219. package/src/approvals/guardian-request-resolvers.ts +16 -17
  220. package/src/backup/__tests__/paths.test.ts +0 -22
  221. package/src/backup/__tests__/restore.test.ts +51 -151
  222. package/src/backup/paths.ts +2 -18
  223. package/src/backup/restore.ts +107 -231
  224. package/src/backup/snapshot-lock.ts +2 -27
  225. package/src/bundler/app-bundler.ts +51 -3
  226. package/src/bundler/compiler-tools.ts +3 -2
  227. package/src/calls/call-conversation-messages.ts +46 -10
  228. package/src/calls/relay-server.ts +4 -44
  229. package/src/calls/twilio-config.ts +2 -17
  230. package/src/calls/twilio-rest.ts +33 -105
  231. package/src/calls/twilio-routes.ts +11 -12
  232. package/src/channels/types.ts +8 -7
  233. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  234. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  235. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  236. package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
  237. package/src/cli/commands/backup.ts +6 -331
  238. package/src/cli/commands/bash.ts +35 -108
  239. package/src/cli/commands/clients.ts +36 -37
  240. package/src/cli/commands/contacts.ts +137 -25
  241. package/src/cli/commands/conversations.ts +2 -5
  242. package/src/cli/commands/credentials.ts +71 -7
  243. package/src/cli/commands/domain.ts +66 -15
  244. package/src/cli/commands/gateway.ts +183 -0
  245. package/src/cli/commands/keys.ts +9 -6
  246. package/src/cli/commands/mcp.ts +116 -156
  247. package/src/cli/commands/memory-v2.ts +303 -7
  248. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  249. package/src/cli/commands/oauth/connect.ts +127 -1
  250. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
  251. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
  252. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
  253. package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
  254. package/src/cli/commands/platform/disconnect.ts +5 -4
  255. package/src/cli/commands/platform/index.ts +16 -25
  256. package/src/cli/commands/status.ts +57 -0
  257. package/src/cli/lib/daemon-credential-client.ts +110 -28
  258. package/src/cli/program.ts +6 -2
  259. package/src/config/assistant-feature-flags.ts +79 -12
  260. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  261. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  262. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  263. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  264. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  265. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  266. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  267. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  268. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  269. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  270. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  271. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  272. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  273. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  274. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  275. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  276. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  277. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  278. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  279. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  280. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  281. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  282. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  283. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  284. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  285. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  286. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  287. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
  288. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  289. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  290. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  291. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  292. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  293. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  294. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  295. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  296. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  297. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  298. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  299. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  300. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  301. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  302. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  303. package/src/config/bundled-tool-registry.ts +21 -0
  304. package/src/config/env-registry.ts +0 -2
  305. package/src/config/env.ts +19 -20
  306. package/src/config/feature-flag-registry.json +47 -135
  307. package/src/config/loader.ts +197 -104
  308. package/src/config/sanitize-for-transfer.ts +2 -0
  309. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  310. package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
  311. package/src/config/schemas/call-site-catalog.ts +14 -0
  312. package/src/config/schemas/calls.ts +0 -9
  313. package/src/config/schemas/channels.ts +0 -5
  314. package/src/config/schemas/heartbeat.ts +64 -1
  315. package/src/config/schemas/ingress.ts +10 -6
  316. package/src/config/schemas/llm.ts +7 -10
  317. package/src/config/schemas/memory-lifecycle.ts +90 -24
  318. package/src/config/schemas/memory-v2.ts +121 -13
  319. package/src/config/schemas/platform.ts +49 -3
  320. package/src/config/schemas/services.ts +29 -15
  321. package/src/config/schemas/skills.ts +0 -6
  322. package/src/config/seed-inference-profiles.ts +230 -33
  323. package/src/contacts/contact-store.ts +0 -55
  324. package/src/contacts/contacts-write.ts +0 -27
  325. package/src/context/window-manager.ts +1 -2
  326. package/src/credential-execution/feature-gates.ts +10 -10
  327. package/src/credential-execution/process-manager.ts +12 -41
  328. package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
  329. package/src/daemon/assistant-attachments.ts +4 -4
  330. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  331. package/src/daemon/config-watcher.ts +89 -60
  332. package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
  333. package/src/daemon/conversation-agent-loop.ts +202 -61
  334. package/src/daemon/conversation-error.ts +87 -15
  335. package/src/daemon/conversation-lifecycle.ts +9 -4
  336. package/src/daemon/conversation-process.ts +24 -11
  337. package/src/daemon/conversation-runtime-assembly.ts +28 -2
  338. package/src/daemon/conversation-store.ts +2 -2
  339. package/src/daemon/conversation-surfaces.ts +305 -4
  340. package/src/daemon/conversation-tool-setup.ts +66 -62
  341. package/src/daemon/conversation.ts +38 -24
  342. package/src/daemon/date-context.ts +71 -22
  343. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  344. package/src/daemon/disk-pressure-guard.ts +343 -0
  345. package/src/daemon/disk-pressure-policy.ts +163 -0
  346. package/src/daemon/doordash-steps.ts +1 -1
  347. package/src/daemon/handlers/shared.ts +4 -2
  348. package/src/daemon/handlers/skills.ts +3 -4
  349. package/src/daemon/host-app-control-proxy.ts +389 -0
  350. package/src/daemon/host-bash-proxy.ts +117 -82
  351. package/src/daemon/host-browser-proxy.ts +67 -82
  352. package/src/daemon/host-cu-proxy.ts +127 -86
  353. package/src/daemon/host-file-proxy.ts +129 -69
  354. package/src/daemon/host-proxy-base.ts +294 -0
  355. package/src/daemon/host-proxy-preactivation.ts +82 -0
  356. package/src/daemon/host-transfer-proxy.ts +338 -129
  357. package/src/daemon/lifecycle.ts +194 -145
  358. package/src/daemon/meet-host-supervisor.ts +4 -4
  359. package/src/daemon/meet-manifest-loader.ts +0 -1
  360. package/src/daemon/memory-v2-startup.ts +14 -4
  361. package/src/daemon/message-protocol.ts +6 -8
  362. package/src/daemon/message-types/contacts.ts +23 -1
  363. package/src/daemon/message-types/conversations.ts +15 -8
  364. package/src/daemon/message-types/disk-pressure.ts +9 -0
  365. package/src/daemon/message-types/host-app-control.ts +150 -0
  366. package/src/daemon/message-types/host-bash.ts +4 -0
  367. package/src/daemon/message-types/host-cu.ts +2 -0
  368. package/src/daemon/message-types/host-file.ts +4 -0
  369. package/src/daemon/message-types/host-transfer.ts +3 -0
  370. package/src/daemon/message-types/messages.ts +3 -0
  371. package/src/daemon/message-types/schedules.ts +8 -3
  372. package/src/daemon/message-types/skills.ts +2 -2
  373. package/src/daemon/process-message.ts +18 -1
  374. package/src/daemon/profiler-run-store.ts +5 -5
  375. package/src/daemon/shutdown-handlers.ts +0 -3
  376. package/src/daemon/tool-setup-types.ts +51 -0
  377. package/src/daemon/tool-side-effects.ts +1 -1
  378. package/src/documents/document-store.ts +85 -0
  379. package/src/events/tool-audit-listener.ts +2 -1
  380. package/src/filing/filing-service.ts +30 -5
  381. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
  382. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
  383. package/src/heartbeat/heartbeat-run-store.ts +249 -0
  384. package/src/heartbeat/heartbeat-service.ts +459 -54
  385. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  386. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  387. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  388. package/src/home/feed-scheduler.ts +18 -0
  389. package/src/home/post-connect-feed.ts +68 -0
  390. package/src/home/relationship-state-writer.ts +17 -92
  391. package/src/home/suggested-prompts.ts +46 -10
  392. package/src/inbound/platform-callback-registration.ts +8 -15
  393. package/src/inbound/public-ingress-urls.ts +32 -34
  394. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  395. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  396. package/src/ipc/assistant-server.ts +70 -3
  397. package/src/ipc/cli-client.ts +32 -1
  398. package/src/ipc/gateway-client.ts +37 -3
  399. package/src/live-voice/live-voice-archive.ts +4 -4
  400. package/src/live-voice/live-voice-metrics.ts +10 -10
  401. package/src/live-voice/protocol.ts +5 -7
  402. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  403. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  404. package/src/mcp/mcp-auth-state.ts +133 -0
  405. package/src/mcp/mcp-oauth-provider.ts +19 -0
  406. package/src/media/image-service.ts +1 -7
  407. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  408. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  409. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  412. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  413. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  414. package/src/memory/admin.ts +5 -9
  415. package/src/memory/anisotropy.test.ts +247 -0
  416. package/src/memory/anisotropy.ts +443 -0
  417. package/src/memory/auto-analysis-constants.ts +17 -0
  418. package/src/memory/auto-analysis-guard.ts +5 -15
  419. package/src/memory/canonical-guardian-store.ts +7 -7
  420. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  421. package/src/memory/context-search/agent-protocol.ts +6 -6
  422. package/src/memory/context-search/agent-runner.ts +51 -9
  423. package/src/memory/context-search/sources/conversations.ts +2 -11
  424. package/src/memory/context-search/sources/memory-v2.ts +22 -9
  425. package/src/memory/context-search/sources/memory.ts +0 -1
  426. package/src/memory/context-search/types.ts +0 -1
  427. package/src/memory/conversation-crud.ts +5 -13
  428. package/src/memory/conversation-key-store.ts +2 -15
  429. package/src/memory/db-init.ts +6 -0
  430. package/src/memory/embedding-backend.ts +9 -21
  431. package/src/memory/embedding-runtime-manager.ts +119 -5
  432. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
  433. package/src/memory/graph/conversation-graph-memory.ts +43 -78
  434. package/src/memory/graph/extraction.ts +1 -3
  435. package/src/memory/graph/graph-search.test.ts +10 -67
  436. package/src/memory/graph/graph-search.ts +9 -20
  437. package/src/memory/graph/retriever.test.ts +6 -0
  438. package/src/memory/graph/retriever.ts +34 -10
  439. package/src/memory/graph/tools.ts +1 -1
  440. package/src/memory/indexer.ts +54 -45
  441. package/src/memory/job-handlers/backfill.ts +2 -11
  442. package/src/memory/job-handlers/cleanup.ts +43 -0
  443. package/src/memory/job-handlers/embedding.ts +6 -8
  444. package/src/memory/job-handlers/summarization.ts +2 -7
  445. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  446. package/src/memory/jobs/embed-concept-page.ts +28 -2
  447. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  448. package/src/memory/jobs-store.ts +114 -22
  449. package/src/memory/jobs-worker.ts +193 -106
  450. package/src/memory/memory-v2-activation-log-store.ts +33 -15
  451. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  452. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  453. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  454. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  455. package/src/memory/migrations/index.ts +6 -0
  456. package/src/memory/migrations/registry.ts +8 -0
  457. package/src/memory/pkb/pkb-search.test.ts +6 -0
  458. package/src/memory/pkb/pkb-search.ts +7 -0
  459. package/src/memory/qdrant-client.ts +49 -32
  460. package/src/memory/rerank-local.ts +374 -0
  461. package/src/memory/schema/infrastructure.ts +15 -0
  462. package/src/memory/search/semantic.ts +13 -67
  463. package/src/memory/sparse-tokenize.ts +49 -0
  464. package/src/memory/trace-event-store.ts +1 -17
  465. package/src/memory/v2/__tests__/activation.test.ts +387 -344
  466. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  467. package/src/memory/v2/__tests__/injection.test.ts +181 -169
  468. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  469. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  470. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  471. package/src/memory/v2/__tests__/sim.test.ts +154 -188
  472. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  473. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  474. package/src/memory/v2/__tests__/static-context.test.ts +76 -2
  475. package/src/memory/v2/activation.ts +213 -239
  476. package/src/memory/v2/consolidation-job.ts +65 -17
  477. package/src/memory/v2/constants.ts +7 -0
  478. package/src/memory/v2/injection.ts +123 -103
  479. package/src/memory/v2/prompts/consolidation.ts +348 -92
  480. package/src/memory/v2/qdrant.ts +198 -1
  481. package/src/memory/v2/reranker.ts +177 -0
  482. package/src/memory/v2/sim.ts +113 -77
  483. package/src/memory/v2/skill-content.ts +4 -3
  484. package/src/memory/v2/skill-store.ts +91 -53
  485. package/src/memory/v2/sparse-bm25.ts +245 -0
  486. package/src/memory/v2/static-context.ts +28 -5
  487. package/src/memory/v2/types.ts +10 -10
  488. package/src/messaging/providers/gmail/types.ts +0 -49
  489. package/src/messaging/providers/slack/adapter.ts +1 -31
  490. package/src/messaging/providers/slack/types.ts +0 -32
  491. package/src/notifications/README.md +10 -10
  492. package/src/notifications/broadcaster.ts +1 -1
  493. package/src/notifications/copy-composer.ts +13 -0
  494. package/src/notifications/guardian-question-mode.ts +5 -5
  495. package/src/notifications/signal.ts +4 -0
  496. package/src/oauth/AGENTS.md +3 -1
  497. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  498. package/src/oauth/connect-orchestrator.ts +6 -0
  499. package/src/oauth/connection-resolver.test.ts +66 -1
  500. package/src/oauth/connection-resolver.ts +55 -1
  501. package/src/oauth/credential-token-resolver.ts +1 -3
  502. package/src/oauth/manual-token-connection.ts +0 -4
  503. package/src/oauth/oauth-connect-state.ts +77 -0
  504. package/src/oauth/seed-providers.ts +58 -1
  505. package/src/outbound-proxy/index.ts +1 -37
  506. package/src/outbound-proxy/logging.ts +1 -1
  507. package/src/outbound-proxy/policy.ts +6 -5
  508. package/src/outbound-proxy/router.ts +2 -1
  509. package/src/permissions/approval-policy.test.ts +6 -275
  510. package/src/permissions/approval-policy.ts +0 -51
  511. package/src/permissions/checker.test.ts +0 -1
  512. package/src/permissions/checker.ts +3 -17
  513. package/src/permissions/gateway-threshold-reader.ts +2 -0
  514. package/src/permissions/prompter.ts +34 -1
  515. package/src/permissions/secret-prompter.ts +6 -2
  516. package/src/plugins/defaults/injectors.ts +35 -2
  517. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  518. package/src/plugins/types.ts +7 -0
  519. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  520. package/src/proactive-artifact/decision.test.ts +226 -0
  521. package/src/proactive-artifact/decision.ts +165 -0
  522. package/src/proactive-artifact/index.ts +7 -0
  523. package/src/proactive-artifact/job.test.ts +867 -0
  524. package/src/proactive-artifact/job.ts +352 -0
  525. package/src/proactive-artifact/message-copy.ts +41 -0
  526. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  527. package/src/proactive-artifact/trigger-state.ts +119 -0
  528. package/src/prompts/bootstrap-cleanup.ts +27 -0
  529. package/src/prompts/normalize-onboarding.ts +80 -0
  530. package/src/prompts/persona-resolver.ts +101 -9
  531. package/src/prompts/system-prompt.ts +23 -24
  532. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  533. package/src/prompts/templates/SOUL.md +13 -1
  534. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  535. package/src/providers/model-intents.ts +7 -0
  536. package/src/providers/openrouter/client.ts +8 -0
  537. package/src/providers/retry.ts +50 -0
  538. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  539. package/src/providers/types.ts +1 -0
  540. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  541. package/src/runtime/agent-wake.ts +238 -100
  542. package/src/runtime/assistant-event-hub.ts +151 -99
  543. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  544. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  545. package/src/runtime/auth/middleware.ts +0 -96
  546. package/src/runtime/auth/route-policy.ts +32 -0
  547. package/src/runtime/auth/same-actor.ts +216 -0
  548. package/src/runtime/btw-sidechain.ts +2 -3
  549. package/src/runtime/channel-invite-transport.ts +2 -48
  550. package/src/runtime/channel-invite-transports/email.ts +1 -1
  551. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  552. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  553. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  554. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  555. package/src/runtime/channel-invite-types.ts +54 -0
  556. package/src/runtime/channel-readiness-service.ts +32 -13
  557. package/src/runtime/channel-retry-sweep.ts +65 -1
  558. package/src/runtime/guardian-reply-router.ts +10 -0
  559. package/src/runtime/http-server.ts +3 -329
  560. package/src/runtime/http-types.ts +0 -5
  561. package/src/runtime/local-actor-identity.ts +52 -11
  562. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  563. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  564. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  565. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  566. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  567. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  568. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  569. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  570. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  571. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  572. package/src/runtime/migrations/migration-transport.ts +7 -7
  573. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  574. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  575. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  576. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  577. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  578. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  579. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  580. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  581. package/src/runtime/pending-interactions.ts +43 -9
  582. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  583. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  584. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
  585. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  586. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  587. package/src/runtime/routes/approval-interception-types.ts +13 -0
  588. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  589. package/src/runtime/routes/backup-routes.ts +15 -38
  590. package/src/runtime/routes/btw-routes.ts +14 -37
  591. package/src/runtime/routes/client-routes.ts +21 -2
  592. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  593. package/src/runtime/routes/contact-routes.ts +0 -25
  594. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  595. package/src/runtime/routes/conversation-routes.ts +65 -39
  596. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  597. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  598. package/src/runtime/routes/document-pdf-renderer.ts +169 -0
  599. package/src/runtime/routes/documents-routes.ts +32 -75
  600. package/src/runtime/routes/errors.ts +19 -4
  601. package/src/runtime/routes/events-routes.ts +38 -0
  602. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  603. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  604. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  605. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  606. package/src/runtime/routes/host-bash-routes.ts +56 -6
  607. package/src/runtime/routes/host-browser-routes.ts +108 -13
  608. package/src/runtime/routes/host-cu-routes.ts +66 -9
  609. package/src/runtime/routes/host-file-routes.ts +54 -5
  610. package/src/runtime/routes/host-transfer-routes.ts +122 -19
  611. package/src/runtime/routes/http-adapter.ts +1 -0
  612. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  613. package/src/runtime/routes/identity-routes.ts +21 -180
  614. package/src/runtime/routes/inbound-message-handler.ts +78 -21
  615. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  616. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  617. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  618. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  619. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  620. package/src/runtime/routes/index.ts +14 -0
  621. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  622. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  623. package/src/runtime/routes/memory-item-routes.ts +10 -12
  624. package/src/runtime/routes/memory-v2-routes.ts +474 -1
  625. package/src/runtime/routes/migration-routes.ts +96 -0
  626. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  627. package/src/runtime/routes/schedule-routes.ts +7 -0
  628. package/src/runtime/verification-outbound-actions.ts +4 -4
  629. package/src/runtime/verification-templates.ts +4 -7
  630. package/src/schedule/integration-status.ts +66 -2
  631. package/src/schedule/recurrence-engine.ts +4 -1
  632. package/src/schedule/retry-backoff.ts +18 -0
  633. package/src/schedule/retry-policy.ts +82 -0
  634. package/src/schedule/run-script.ts +37 -5
  635. package/src/schedule/schedule-recovery.ts +64 -0
  636. package/src/schedule/schedule-store.ts +106 -2
  637. package/src/schedule/scheduler-types.ts +25 -0
  638. package/src/schedule/scheduler.ts +83 -39
  639. package/src/security/encrypted-store.ts +2 -0
  640. package/src/security/oauth-callback-registry.ts +8 -0
  641. package/src/security/secure-keys.ts +55 -0
  642. package/src/sequence/analytics.ts +5 -5
  643. package/src/sequence/engine.ts +1 -1
  644. package/src/skills/catalog-files.ts +2 -8
  645. package/src/skills/include-graph.ts +5 -5
  646. package/src/skills/remote-skill-policy.ts +10 -16
  647. package/src/skills/skill-file-provider.ts +1 -1
  648. package/src/skills/skill-file-types.ts +13 -0
  649. package/src/skills/skillssh-audit-types.ts +28 -0
  650. package/src/skills/skillssh-registry.ts +8 -21
  651. package/src/subagent/index.ts +1 -7
  652. package/src/subagent/manager.ts +1 -15
  653. package/src/tasks/task-runner.ts +0 -1
  654. package/src/tasks/task-store.ts +0 -3
  655. package/src/telemetry/types.ts +2 -0
  656. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  657. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  658. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  659. package/src/tools/apps/executors.ts +56 -69
  660. package/src/tools/background-tool-registry.ts +17 -3
  661. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  662. package/src/tools/browser/browser-execution.ts +2 -2
  663. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  664. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  665. package/src/tools/browser/cdp-client/factory.ts +23 -24
  666. package/src/tools/browser/cdp-client/index.ts +1 -14
  667. package/src/tools/computer-use/definitions.ts +42 -20
  668. package/src/tools/executor.ts +2 -0
  669. package/src/tools/host-filesystem/edit.test.ts +151 -0
  670. package/src/tools/host-filesystem/edit.ts +68 -0
  671. package/src/tools/host-filesystem/read.test.ts +129 -0
  672. package/src/tools/host-filesystem/read.ts +68 -0
  673. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  674. package/src/tools/host-filesystem/transfer.ts +78 -3
  675. package/src/tools/host-filesystem/write.test.ts +134 -0
  676. package/src/tools/host-filesystem/write.ts +68 -0
  677. package/src/tools/host-terminal/host-shell.ts +66 -1
  678. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  679. package/src/tools/memory/register.test.ts +12 -9
  680. package/src/tools/memory/register.ts +1 -2
  681. package/src/tools/provider-tool-name.ts +28 -0
  682. package/src/tools/registry.ts +30 -9
  683. package/src/tools/schedule/create.ts +6 -0
  684. package/src/tools/schedule/list.ts +2 -0
  685. package/src/tools/schedule/update.ts +10 -0
  686. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  687. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  688. package/src/tools/skills/load.ts +0 -32
  689. package/src/tools/terminal/shell.ts +9 -1
  690. package/src/tools/tool-approval-handler.ts +32 -11
  691. package/src/tools/types.ts +28 -2
  692. package/src/tts/provider-catalog.ts +3 -5
  693. package/src/usage/pricing.ts +1 -1
  694. package/src/util/disk-usage.ts +138 -0
  695. package/src/util/platform.ts +21 -11
  696. package/src/util/process-liveness.ts +26 -0
  697. package/src/workspace/hatched-date.ts +86 -0
  698. package/src/workspace/heartbeat-service.ts +19 -0
  699. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  700. package/src/workspace/migrations/006-services-config.ts +8 -5
  701. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  702. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  703. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  704. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  705. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  706. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  707. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  708. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  709. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  710. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  711. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  712. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  713. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  714. package/src/workspace/migrations/AGENTS.md +1 -1
  715. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  716. package/src/workspace/migrations/registry.ts +8 -0
  717. package/src/workspace/migrations/utils.ts +21 -0
  718. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  719. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  720. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  721. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  722. package/src/__tests__/twilio-rest.test.ts +0 -34
  723. package/src/backup/__tests__/backup-key.test.ts +0 -152
  724. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  725. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  726. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  727. package/src/backup/backup-key.ts +0 -137
  728. package/src/backup/backup-worker.ts +0 -472
  729. package/src/backup/offsite-writer.ts +0 -222
  730. package/src/backup/stream-crypt.ts +0 -263
  731. package/src/daemon/message-types/pairing.ts +0 -58
  732. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  733. package/src/memory/v2/skill-qdrant.ts +0 -395
  734. package/src/outbound-proxy/config.ts +0 -20
  735. package/src/outbound-proxy/health.ts +0 -18
  736. package/src/outbound-proxy/types.ts +0 -150
  737. package/src/runtime/capability-tokens.ts +0 -190
  738. package/src/signals/bash.ts +0 -198
  739. package/src/signals/mcp-reload.ts +0 -18
@@ -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
+ }
@@ -19,6 +19,8 @@ export const cronJobs = sqliteTable("cron_jobs", {
19
19
  lastRunAt: integer("last_run_at"),
20
20
  lastStatus: text("last_status"), // 'ok' | 'error'
21
21
  retryCount: integer("retry_count").notNull().default(0),
22
+ maxRetries: integer("max_retries").notNull().default(3),
23
+ retryBackoffMs: integer("retry_backoff_ms").notNull().default(60000),
22
24
  createdBy: text("created_by").notNull(), // 'agent' | 'user'
23
25
  mode: text("mode").notNull().default("execute"), // 'notify' | 'execute'
24
26
  routingIntent: text("routing_intent").notNull().default("all_channels"), // 'single_channel' | 'multi_channel' | 'all_channels'
@@ -54,6 +56,19 @@ export const cronRuns = sqliteTable("cron_runs", {
54
56
  export const scheduleJobs = cronJobs;
55
57
  export const scheduleRuns = cronRuns;
56
58
 
59
+ export const heartbeatRuns = sqliteTable("heartbeat_runs", {
60
+ id: text("id").primaryKey(),
61
+ scheduledFor: integer("scheduled_for").notNull(),
62
+ startedAt: integer("started_at"),
63
+ finishedAt: integer("finished_at"),
64
+ durationMs: integer("duration_ms"),
65
+ status: text("status").notNull(), // 'pending' | 'running' | 'ok' | 'error' | 'timeout' | 'skipped' | 'missed' | 'superseded'
66
+ skipReason: text("skip_reason"), // 'disabled' | 'outside_active_hours' | 'overlap'
67
+ error: text("error"),
68
+ conversationId: text("conversation_id"),
69
+ createdAt: integer("created_at").notNull(),
70
+ });
71
+
57
72
  export const sharedAppLinks = sqliteTable("shared_app_links", {
58
73
  id: text("id").primaryKey(),
59
74
  shareToken: text("share_token").notNull().unique(),
@@ -1,5 +1,7 @@
1
1
  import { inArray } from "drizzle-orm";
2
2
 
3
+ import { getConfig } from "../../config/loader.js";
4
+ import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
3
5
  import { getDb } from "../db-connection.js";
4
6
  import { withQdrantBreaker } from "../qdrant-circuit-breaker.js";
5
7
  import type {
@@ -7,7 +9,7 @@ import type {
7
9
  QdrantSparseVector,
8
10
  } from "../qdrant-client.js";
9
11
  import { getQdrantClient } from "../qdrant-client.js";
10
- import { conversations, memorySegments, memorySummaries } from "../schema.js";
12
+ import { memorySegments, memorySummaries } from "../schema.js";
11
13
  // ── Types (inlined from deleted types.ts) ──────────────────────────
12
14
 
13
15
  type CandidateType = "segment" | "item" | "summary" | "media";
@@ -50,11 +52,15 @@ export async function semanticSearch(
50
52
  _model: string,
51
53
  limit: number,
52
54
  excludedMessageIds: string[] = [],
53
- scopeIds?: string[],
54
55
  sparseVector?: QdrantSparseVector,
55
56
  ): Promise<Candidate[]> {
56
57
  if (limit <= 0) return [];
57
58
 
59
+ // v2 owns the read path when both gates are on; the v1 `memory` collection
60
+ // is in active retirement, and routing semantic recall there would re-enter
61
+ // the same corrupted sparse segments that can OOM-crash Qdrant.
62
+ if (isMemoryV2ReadActive(getConfig())) return [];
63
+
58
64
  const qdrant = getQdrantClient();
59
65
 
60
66
  // Overfetch to account for items filtered out post-query (invalidated, excluded, etc.)
@@ -68,7 +74,7 @@ export async function semanticSearch(
68
74
  let isHybrid = false;
69
75
  if (sparseVector && sparseVector.indices.length > 0) {
70
76
  isHybrid = true;
71
- const filter = buildHybridFilter(excludedMessageIds, scopeIds);
77
+ const filter = buildHybridFilter(excludedMessageIds);
72
78
  results = await withQdrantBreaker(() =>
73
79
  qdrant.hybridSearch({
74
80
  denseVector: queryVector,
@@ -85,7 +91,6 @@ export async function semanticSearch(
85
91
  fetchLimit,
86
92
  ["summary", "segment", "media"],
87
93
  excludedMessageIds,
88
- scopeIds,
89
94
  ),
90
95
  );
91
96
  }
@@ -95,18 +100,15 @@ export async function semanticSearch(
95
100
  // Batch-fetch all backing records upfront to avoid N+1 queries per result
96
101
  const summaryTargetIds: string[] = [];
97
102
  const segmentTargetIds: string[] = [];
98
- const mediaConversationIds: string[] = [];
99
103
  for (const r of results) {
100
104
  if (r.payload.target_type === "summary")
101
105
  summaryTargetIds.push(r.payload.target_id);
102
106
  else if (r.payload.target_type === "segment")
103
107
  segmentTargetIds.push(r.payload.target_id);
104
- else if (r.payload.target_type === "media" && r.payload.conversation_id)
105
- mediaConversationIds.push(r.payload.conversation_id);
106
108
  }
107
109
 
108
110
  const summariesMap = new Map<string, typeof memorySummaries.$inferSelect>();
109
- if (scopeIds && summaryTargetIds.length > 0) {
111
+ if (summaryTargetIds.length > 0) {
110
112
  const allSummaries = db
111
113
  .select()
112
114
  .from(memorySummaries)
@@ -116,7 +118,7 @@ export async function semanticSearch(
116
118
  }
117
119
 
118
120
  const segmentsMap = new Map<string, typeof memorySegments.$inferSelect>();
119
- if (scopeIds && segmentTargetIds.length > 0) {
121
+ if (segmentTargetIds.length > 0) {
120
122
  const allSegments = db
121
123
  .select()
122
124
  .from(memorySegments)
@@ -125,23 +127,6 @@ export async function semanticSearch(
125
127
  for (const seg of allSegments) segmentsMap.set(seg.id, seg);
126
128
  }
127
129
 
128
- // Batch-fetch conversation scope IDs for media results to avoid N+1 queries.
129
- // When a conversation is not found (deleted), its media is excluded rather than
130
- // falling back to "default" scope, which would leak private media.
131
- const mediaScopeMap = new Map<string, string>();
132
- if (scopeIds && mediaConversationIds.length > 0) {
133
- const unique = [...new Set(mediaConversationIds)];
134
- const rows = db
135
- .select({
136
- id: conversations.id,
137
- memoryScopeId: conversations.memoryScopeId,
138
- })
139
- .from(conversations)
140
- .where(inArray(conversations.id, unique))
141
- .all();
142
- for (const row of rows) mediaScopeMap.set(row.id, row.memoryScopeId);
143
- }
144
-
145
130
  const candidates: Candidate[] = [];
146
131
  for (const result of results) {
147
132
  const { payload, score } = result;
@@ -153,10 +138,7 @@ export async function semanticSearch(
153
138
  // Legacy item vectors — skip (table dropped, Qdrant cleanup pending)
154
139
  continue;
155
140
  } else if (payload.target_type === "summary") {
156
- if (scopeIds) {
157
- const summary = summariesMap.get(payload.target_id);
158
- if (!summary || !scopeIds.includes(summary.scopeId)) continue;
159
- }
141
+ if (!summariesMap.has(payload.target_id)) continue;
160
142
  candidates.push({
161
143
  key: `summary:${payload.target_id}`,
162
144
  type: "summary",
@@ -173,22 +155,6 @@ export async function semanticSearch(
173
155
  finalScore: 0,
174
156
  });
175
157
  } else if (payload.target_type === "media") {
176
- // Use stored memory_scope_id when available; fall back to deriving
177
- // scope from conversation_id for legacy media points.
178
- // If the conversation was deleted, skip the media to avoid leaking
179
- // private media into the default scope.
180
- if (scopeIds) {
181
- let mediaScopeId: string | undefined;
182
- if (payload.memory_scope_id) {
183
- mediaScopeId = payload.memory_scope_id;
184
- } else if (payload.conversation_id) {
185
- mediaScopeId = mediaScopeMap.get(payload.conversation_id);
186
- if (!mediaScopeId) continue; // conversation deleted — skip
187
- } else {
188
- mediaScopeId = "default";
189
- }
190
- if (!scopeIds.includes(mediaScopeId)) continue;
191
- }
192
158
  candidates.push({
193
159
  key: `media:${payload.target_id}`,
194
160
  type: "media",
@@ -205,10 +171,7 @@ export async function semanticSearch(
205
171
  finalScore: 0,
206
172
  });
207
173
  } else {
208
- if (scopeIds) {
209
- const segment = segmentsMap.get(payload.target_id);
210
- if (!segment || !scopeIds.includes(segment.scopeId)) continue;
211
- }
174
+ if (!segmentsMap.has(payload.target_id)) continue;
212
175
  candidates.push({
213
176
  key: `segment:${payload.target_id}`,
214
177
  type: "segment",
@@ -247,14 +210,9 @@ export async function semanticSearch(
247
210
  /**
248
211
  * Build a Qdrant filter for hybrid search. Mirrors the logic in
249
212
  * `searchWithFilter` but as a standalone object for the query API.
250
- *
251
- * Scope filtering: points with a `memory_scope_id` payload field are
252
- * filtered at the Qdrant level. Legacy points without the field pass
253
- * through and are caught by post-query DB filtering.
254
213
  */
255
214
  function buildHybridFilter(
256
215
  excludeMessageIds: string[],
257
- scopeIds?: string[],
258
216
  ): Record<string, unknown> {
259
217
  const mustConditions: Array<Record<string, unknown>> = [
260
218
  {
@@ -263,18 +221,6 @@ function buildHybridFilter(
263
221
  },
264
222
  ];
265
223
 
266
- // Scope filtering: accept points whose memory_scope_id matches one of the
267
- // allowed scopes, OR points that lack the field entirely (legacy data).
268
- // Post-query DB filtering remains as defense-in-depth for legacy points.
269
- if (scopeIds && scopeIds.length > 0) {
270
- mustConditions.push({
271
- should: [
272
- { key: "memory_scope_id", match: { any: scopeIds } },
273
- { is_empty: { key: "memory_scope_id" } },
274
- ],
275
- });
276
- }
277
-
278
224
  const mustNotConditions: Array<Record<string, unknown>> = [
279
225
  { key: "_meta", match: { value: true } },
280
226
  ];
@@ -0,0 +1,49 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Sparse-vector tokenization primitives
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // Shared by both the legacy TF-only encoder in `embedding-backend.ts`
6
+ // (`generateSparseEmbedding`) and the BM25 encoder in `v2/sparse-bm25.ts`.
7
+ //
8
+ // Lives in its own module so consumers of the BM25 encoder don't transitively
9
+ // depend on `embedding-backend.ts` for these primitives — that matters
10
+ // because many tests mock `embedding-backend.js` wholesale via
11
+ // `mock.module(...)`, and a missing export from the mock would break any
12
+ // transitive importer of these helpers.
13
+
14
+ import { stemmer } from "stemmer";
15
+
16
+ /** Hashed-vocabulary size for sparse encoders. */
17
+ export const SPARSE_VOCAB_SIZE = 30_000;
18
+
19
+ /** Tokenize text into lowercase alphanumeric tokens (Unicode-aware). */
20
+ export function tokenize(text: string): string[] {
21
+ return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
22
+ }
23
+
24
+ /**
25
+ * Tokenize and apply Porter stemming so morphological variants collapse to a
26
+ * shared bucket (e.g. `running`/`runs`/`ran` → `run`, `supplements` →
27
+ * `supplement`). Used only by the BM25 sparse channel in
28
+ * `v2/sparse-bm25.ts`; both the document-side and query-side encoders call
29
+ * this so doc and query tokens land in the same hash buckets.
30
+ *
31
+ * Other callers (workspace context-search, the legacy TF-only
32
+ * `generateSparseEmbedding`) intentionally keep the non-stemmed `tokenize()`
33
+ * because they predate this and rebuilding their on-disk indexes is out of
34
+ * scope here.
35
+ */
36
+ export function tokenizeStemmed(text: string): string[] {
37
+ return tokenize(text).map((token) => stemmer(token));
38
+ }
39
+
40
+ /** Hash a token to a stable index in [0, vocabSize). */
41
+ export function tokenHash(token: string, vocabSize: number): number {
42
+ // FNV-1a 32-bit hash for speed
43
+ let hash = 0x811c9dc5;
44
+ for (let i = 0; i < token.length; i++) {
45
+ hash ^= token.charCodeAt(i);
46
+ hash = Math.imul(hash, 0x01000193) >>> 0;
47
+ }
48
+ return hash % vocabSize;
49
+ }
@@ -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
  // ---------------------------------------------------------------------------