@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
@@ -12,18 +12,35 @@ export interface MemoryV2ConceptRowRecord {
12
12
  simUser: number;
13
13
  simAssistant: number;
14
14
  simNow: number;
15
+ /**
16
+ * Cross-encoder rerank delta in raw rerank space (`alpha · r_norm_u`)
17
+ * for the user channel. Zero when rerank is disabled or the slug fell
18
+ * outside the unified top-K-by-pre-rerank-A_o window. Applied
19
+ * additively to A_o weighted by `c_user` — `simUser` itself is the
20
+ * raw fused score and never carries the boost. Stored as a JSON field,
21
+ * so older log rows pre-date this addition and decode with `undefined`;
22
+ * readers should fall back to 0.
23
+ */
24
+ simUserRerankBoost: number;
25
+ /**
26
+ * Cross-encoder rerank delta for the assistant channel. Same semantics
27
+ * as `simUserRerankBoost`, weighted by `c_assistant` when applied to
28
+ * A_o. The NOW channel intentionally bypasses rerank, so there is no
29
+ * `simNowRerankBoost`.
30
+ */
31
+ simAssistantRerankBoost: number;
32
+ /**
33
+ * True when rerank ran and this slug landed in the unified
34
+ * top-K-by-pre-rerank-A_o pool. Distinguishes "cross-encoder evaluated
35
+ * this and chose 0" from "rerank skipped this slug" so the inspector
36
+ * can keep the rerank rows visible at `+0.000` instead of silently
37
+ * dropping them. Older log rows pre-date this field and decode with
38
+ * `undefined`; readers should fall back to `false`.
39
+ */
40
+ inRerankPool: boolean;
15
41
  spreadContribution: number;
16
42
  source: "prior_state" | "ann_top50" | "both";
17
- status: "in_context" | "injected" | "not_injected";
18
- }
19
-
20
- export interface MemoryV2SkillRowRecord {
21
- id: string;
22
- activation: number;
23
- simUser: number;
24
- simAssistant: number;
25
- simNow: number;
26
- status: "injected" | "not_injected";
43
+ status: "in_context" | "injected" | "not_injected" | "page_missing";
27
44
  }
28
45
 
29
46
  export interface MemoryV2ConfigSnapshot {
@@ -34,7 +51,6 @@ export interface MemoryV2ConfigSnapshot {
34
51
  k: number;
35
52
  hops: number;
36
53
  top_k: number;
37
- top_k_skills: number;
38
54
  epsilon: number;
39
55
  }
40
56
 
@@ -43,7 +59,6 @@ export interface RecordMemoryV2ActivationLogParams {
43
59
  turn: number;
44
60
  mode: "context-load" | "per-turn";
45
61
  concepts: MemoryV2ConceptRowRecord[];
46
- skills: MemoryV2SkillRowRecord[];
47
62
  config: MemoryV2ConfigSnapshot;
48
63
  }
49
64
 
@@ -51,6 +66,11 @@ export function recordMemoryV2ActivationLog(
51
66
  params: RecordMemoryV2ActivationLogParams,
52
67
  ): void {
53
68
  const db = getDb();
69
+ // Skills now live as concept rows under `slug: "skills/<id>"`, so the
70
+ // separate `skills_json` column is always written empty. The column itself
71
+ // remains in the schema for backwards-compat with prior log rows; the
72
+ // reader drops it. A future migration can DROP the column once those rows
73
+ // age out of relevance.
54
74
  db.insert(memoryV2ActivationLogs)
55
75
  .values({
56
76
  id: uuid(),
@@ -59,7 +79,7 @@ export function recordMemoryV2ActivationLog(
59
79
  turn: params.turn,
60
80
  mode: params.mode,
61
81
  conceptsJson: JSON.stringify(params.concepts),
62
- skillsJson: JSON.stringify(params.skills),
82
+ skillsJson: "[]",
63
83
  configJson: JSON.stringify(params.config),
64
84
  createdAt: Date.now(),
65
85
  })
@@ -87,7 +107,6 @@ export interface MemoryV2ActivationLog {
87
107
  turn: number;
88
108
  mode: "context-load" | "per-turn";
89
109
  concepts: MemoryV2ConceptRowRecord[];
90
- skills: MemoryV2SkillRowRecord[];
91
110
  config: MemoryV2ConfigSnapshot;
92
111
  }
93
112
 
@@ -109,7 +128,6 @@ export function getMemoryV2ActivationLogByMessageIds(
109
128
  turn: row.turn,
110
129
  mode: row.mode as "context-load" | "per-turn",
111
130
  concepts: JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[],
112
- skills: JSON.parse(row.skillsJson) as MemoryV2SkillRowRecord[],
113
131
  config: JSON.parse(row.configJson) as MemoryV2ConfigSnapshot,
114
132
  };
115
133
  }
@@ -0,0 +1,169 @@
1
+ import type { MemoryV2ConceptRowRecord } from "./memory-v2-activation-log-store.js";
2
+ import { rawAll, rawGet } from "./raw-query.js";
3
+ import { listPages } from "./v2/page-store.js";
4
+
5
+ type ConceptStatus = MemoryV2ConceptRowRecord["status"];
6
+
7
+ export type ConceptFrequencyCounts = Record<ConceptStatus, number>;
8
+
9
+ export interface ConceptFrequencyRow {
10
+ slug: string;
11
+ counts: ConceptFrequencyCounts;
12
+ totalEvaluations: number;
13
+ lastInjectedAt: number | null;
14
+ /** Whether the slug currently has a markdown page on disk. */
15
+ onDisk: boolean;
16
+ }
17
+
18
+ export interface ConceptFrequencyResponse {
19
+ filters: {
20
+ conversationId: string | null;
21
+ sinceMs: number | null;
22
+ };
23
+ totals: {
24
+ /** Activation log rows scanned (turns of evaluation in the window). */
25
+ logCount: number;
26
+ /** Sum of per-row concept evaluations across all log rows in the window. */
27
+ conceptOccurrences: number;
28
+ };
29
+ /** Per-slug aggregates, sorted by `totalEvaluations` desc, then slug asc. */
30
+ concepts: ConceptFrequencyRow[];
31
+ /**
32
+ * Slugs present on disk that never appeared in any activation log row in
33
+ * the window — i.e. retrieval never even scored them as a candidate.
34
+ */
35
+ neverEvaluatedSlugs: string[];
36
+ }
37
+
38
+ export interface GetConceptFrequencyFilters {
39
+ conversationId?: string;
40
+ sinceMs?: number;
41
+ }
42
+
43
+ interface AggRow {
44
+ slug: string | null;
45
+ status: ConceptStatus | string | null;
46
+ count: number;
47
+ last_seen: number;
48
+ }
49
+
50
+ const ZERO_COUNTS: ConceptFrequencyCounts = {
51
+ injected: 0,
52
+ in_context: 0,
53
+ not_injected: 0,
54
+ page_missing: 0,
55
+ };
56
+
57
+ interface CountRow {
58
+ count: number;
59
+ }
60
+
61
+ export async function getConceptFrequencySummary(
62
+ workspaceDir: string,
63
+ filters: GetConceptFrequencyFilters = {},
64
+ ): Promise<ConceptFrequencyResponse> {
65
+ const conversationId = filters.conversationId ?? null;
66
+ const sinceMs = filters.sinceMs ?? null;
67
+
68
+ // Kick off the on-disk page walk in parallel with the (synchronous) SQL
69
+ // queries below — listPages does fs.readdir, rawAll/rawGet are sync.
70
+ const onDiskSlugsPromise = listPages(workspaceDir);
71
+
72
+ const aggRows = rawAll<AggRow>(
73
+ `SELECT
74
+ json_extract(c.value, '$.slug') AS slug,
75
+ json_extract(c.value, '$.status') AS status,
76
+ COUNT(*) AS count,
77
+ MAX(l.created_at) AS last_seen
78
+ FROM memory_v2_activation_logs l, json_each(l.concepts_json) c
79
+ WHERE (? IS NULL OR l.conversation_id = ?)
80
+ AND (? IS NULL OR l.created_at >= ?)
81
+ GROUP BY slug, status`,
82
+ conversationId,
83
+ conversationId,
84
+ sinceMs,
85
+ sinceMs,
86
+ );
87
+
88
+ const logCountRow = rawGet<CountRow>(
89
+ `SELECT COUNT(*) AS count
90
+ FROM memory_v2_activation_logs
91
+ WHERE (? IS NULL OR conversation_id = ?)
92
+ AND (? IS NULL OR created_at >= ?)`,
93
+ conversationId,
94
+ conversationId,
95
+ sinceMs,
96
+ sinceMs,
97
+ );
98
+
99
+ const bySlug = new Map<string, ConceptFrequencyRow>();
100
+ let conceptOccurrences = 0;
101
+
102
+ for (const row of aggRows) {
103
+ if (!row.slug) continue;
104
+ let entry = bySlug.get(row.slug);
105
+ if (!entry) {
106
+ entry = {
107
+ slug: row.slug,
108
+ counts: { ...ZERO_COUNTS },
109
+ totalEvaluations: 0,
110
+ lastInjectedAt: null,
111
+ onDisk: false,
112
+ };
113
+ bySlug.set(row.slug, entry);
114
+ }
115
+
116
+ switch (row.status) {
117
+ case "injected":
118
+ entry.counts.injected += row.count;
119
+ entry.lastInjectedAt =
120
+ entry.lastInjectedAt === null
121
+ ? row.last_seen
122
+ : Math.max(entry.lastInjectedAt, row.last_seen);
123
+ break;
124
+ case "in_context":
125
+ entry.counts.in_context += row.count;
126
+ break;
127
+ case "not_injected":
128
+ entry.counts.not_injected += row.count;
129
+ break;
130
+ case "page_missing":
131
+ entry.counts.page_missing += row.count;
132
+ break;
133
+ default:
134
+ // Forward-compat: unknown status values are ignored, not summed into
135
+ // totalEvaluations. The activation pipeline produces a closed enum.
136
+ continue;
137
+ }
138
+ entry.totalEvaluations += row.count;
139
+ conceptOccurrences += row.count;
140
+ }
141
+
142
+ const onDiskSlugs = new Set(await onDiskSlugsPromise);
143
+ for (const entry of bySlug.values()) {
144
+ entry.onDisk = onDiskSlugs.has(entry.slug);
145
+ }
146
+
147
+ const neverEvaluatedSlugs: string[] = [];
148
+ for (const slug of onDiskSlugs) {
149
+ if (!bySlug.has(slug)) neverEvaluatedSlugs.push(slug);
150
+ }
151
+ neverEvaluatedSlugs.sort();
152
+
153
+ const concepts = [...bySlug.values()].sort((a, b) => {
154
+ if (b.totalEvaluations !== a.totalEvaluations) {
155
+ return b.totalEvaluations - a.totalEvaluations;
156
+ }
157
+ return a.slug.localeCompare(b.slug);
158
+ });
159
+
160
+ return {
161
+ filters: { conversationId, sinceMs },
162
+ totals: {
163
+ logCount: logCountRow?.count ?? 0,
164
+ conceptOccurrences,
165
+ },
166
+ concepts,
167
+ neverEvaluatedSlugs,
168
+ };
169
+ }
@@ -0,0 +1,45 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { tableHasColumn } from "./schema-introspection.js";
4
+ import { withCrashRecovery } from "./validate-migration-state.js";
5
+
6
+ const CHECKPOINT_KEY = "migration_heartbeat_runs_v1";
7
+
8
+ /**
9
+ * Create the heartbeat_runs table for tracking heartbeat execution lifecycle.
10
+ *
11
+ * Each row represents one scheduled heartbeat tick, tracking its progression
12
+ * through the status lifecycle: pending -> running -> ok/error/timeout, or
13
+ * pending -> skipped/missed/superseded.
14
+ */
15
+ export function migrateHeartbeatRuns(database: DrizzleDb): void {
16
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
17
+ if (tableHasColumn(database, "heartbeat_runs", "id")) {
18
+ return;
19
+ }
20
+ const raw = getSqliteFrom(database);
21
+ raw.exec(/*sql*/ `
22
+ CREATE TABLE IF NOT EXISTS heartbeat_runs (
23
+ id TEXT PRIMARY KEY,
24
+ scheduled_for INTEGER NOT NULL,
25
+ started_at INTEGER,
26
+ finished_at INTEGER,
27
+ duration_ms INTEGER,
28
+ status TEXT NOT NULL,
29
+ skip_reason TEXT,
30
+ error TEXT,
31
+ conversation_id TEXT,
32
+ created_at INTEGER NOT NULL
33
+ )
34
+ `);
35
+ raw.exec(/*sql*/ `
36
+ CREATE INDEX IF NOT EXISTS idx_heartbeat_runs_scheduled_for
37
+ ON heartbeat_runs (scheduled_for)
38
+ `);
39
+ });
40
+ }
41
+
42
+ export function downHeartbeatRuns(database: DrizzleDb): void {
43
+ const raw = getSqliteFrom(database);
44
+ raw.exec(/*sql*/ `DROP TABLE IF EXISTS heartbeat_runs`);
45
+ }
@@ -0,0 +1,20 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+
4
+ export function migrateScheduleRetryPolicy(database: DrizzleDb): void {
5
+ const raw = getSqliteFrom(database);
6
+ try {
7
+ raw.exec(
8
+ `ALTER TABLE cron_jobs ADD COLUMN max_retries INTEGER NOT NULL DEFAULT 3`,
9
+ );
10
+ } catch {
11
+ /* Column already exists */
12
+ }
13
+ try {
14
+ raw.exec(
15
+ `ALTER TABLE cron_jobs ADD COLUMN retry_backoff_ms INTEGER NOT NULL DEFAULT 60000`,
16
+ );
17
+ } catch {
18
+ /* Column already exists */
19
+ }
20
+ }
@@ -0,0 +1,18 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ const CHECKPOINT_KEY = "migration_trace_events_created_at_index_v1";
6
+
7
+ /**
8
+ * Add an index on `trace_events.created_at` so the periodic prune job
9
+ * can locate expired rows without a full table scan.
10
+ */
11
+ export function migrateTraceEventsCreatedAtIndex(database: DrizzleDb): void {
12
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
13
+ const raw = getSqliteFrom(database);
14
+ raw.exec(
15
+ `CREATE INDEX IF NOT EXISTS idx_trace_events_created_at ON trace_events(created_at)`,
16
+ );
17
+ });
18
+ }
@@ -195,6 +195,12 @@ export {
195
195
  downToolInvocationsMatchedRuleId,
196
196
  migrateToolInvocationsMatchedRuleId,
197
197
  } from "./236-tool-invocations-matched-rule-id.js";
198
+ export {
199
+ downHeartbeatRuns,
200
+ migrateHeartbeatRuns,
201
+ } from "./237-heartbeat-runs.js";
202
+ export { migrateScheduleRetryPolicy } from "./238-schedule-retry-policy.js";
203
+ export { migrateTraceEventsCreatedAtIndex } from "./239-trace-events-created-at-index.js";
198
204
  export {
199
205
  MIGRATION_REGISTRY,
200
206
  type MigrationRegistryEntry,
@@ -47,6 +47,7 @@ import { downActivationState } from "./232-activation-state.js";
47
47
  import { downMemoryV2ActivationLogs } from "./234-memory-v2-activation-logs.js";
48
48
  import { downSlackCompactionWatermark } from "./235-slack-compaction-watermark.js";
49
49
  import { downToolInvocationsMatchedRuleId } from "./236-tool-invocations-matched-rule-id.js";
50
+ import { downHeartbeatRuns } from "./237-heartbeat-runs.js";
50
51
 
51
52
  export interface MigrationRegistryEntry {
52
53
  /** The checkpoint key written to memory_checkpoints on completion. */
@@ -404,6 +405,13 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
404
405
  "Add matched_trust_rule_id column to tool_invocations for trust rule audit and rule editor UI",
405
406
  down: downToolInvocationsMatchedRuleId,
406
407
  },
408
+ {
409
+ key: "migration_heartbeat_runs_v1",
410
+ version: 47,
411
+ description:
412
+ "Create heartbeat_runs table for tracking heartbeat execution lifecycle with CAS state transitions",
413
+ down: downHeartbeatRuns,
414
+ },
407
415
  ];
408
416
 
409
417
  export function getMaxMigrationVersion(): number {
@@ -1,6 +1,12 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import { makeMockLogger } from "../../__tests__/helpers/mock-logger.js";
4
+ import { _setOverridesForTesting } from "../../config/assistant-feature-flags.js";
5
+
6
+ // This test exercises the v1 PKB search path. The `memory-v2-enabled` flag
7
+ // (registry default `true`) makes pkb-search short-circuit to keep traffic
8
+ // off the legacy collection — disable it so the v1 path stays under test.
9
+ _setOverridesForTesting({ "memory-v2-enabled": false });
4
10
 
5
11
  mock.module("../../util/logger.js", () => ({
6
12
  getLogger: () => makeMockLogger(),
@@ -2,7 +2,9 @@
2
2
  // PKB — Qdrant hybrid search for indexed PKB markdown files
3
3
  // ---------------------------------------------------------------------------
4
4
 
5
+ import { getConfig } from "../../config/loader.js";
5
6
  import { getLogger } from "../../util/logger.js";
7
+ import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
6
8
  import {
7
9
  isQdrantBreakerOpen,
8
10
  withQdrantBreaker,
@@ -40,6 +42,11 @@ export async function searchPkbFiles(
40
42
  limit: number,
41
43
  scopeIds?: string[],
42
44
  ): Promise<PkbSearchResult[]> {
45
+ // v2 owns the read path when both gates are on; v2 absorbs PKB as a read
46
+ // source, so PKB hint search short-circuits to keep traffic off the v1
47
+ // collection (avoiding OOM-crash risk from a corrupted sparse segment).
48
+ if (isMemoryV2ReadActive(getConfig())) return [];
49
+
43
50
  if (isQdrantBreakerOpen()) {
44
51
  log.warn("Qdrant circuit breaker open, skipping PKB search");
45
52
  return [];
@@ -73,19 +73,31 @@ export interface QdrantSearchResult {
73
73
  payload: QdrantPointPayload;
74
74
  }
75
75
 
76
+ /**
77
+ * Strip a trailing `:sparse-v<digits>` segment from a sentinel string.
78
+ *
79
+ * Legacy v1 sentinels (pre-decouple) included the sparse encoder version in
80
+ * the embedding-model identity. The suffix is no longer written, but stored
81
+ * sentinels written by older daemons may still carry it — strip it before
82
+ * comparing identities so existing collections aren't unnecessarily rebuilt.
83
+ */
84
+ export function stripLegacySparseSuffix(sentinel: string): string {
85
+ return sentinel.replace(/:sparse-v\d+$/, "");
86
+ }
87
+
76
88
  let _instance: VellumQdrantClient | null = null;
77
89
 
78
90
  export function getQdrantClient(): VellumQdrantClient {
79
91
  if (!_instance) {
80
92
  throw new Error(
81
- "Qdrant client not initialized. Call initQdrantClient() first."
93
+ "Qdrant client not initialized. Call initQdrantClient() first.",
82
94
  );
83
95
  }
84
96
  return _instance;
85
97
  }
86
98
 
87
99
  export function initQdrantClient(
88
- config: QdrantClientConfig
100
+ config: QdrantClientConfig,
89
101
  ): VellumQdrantClient {
90
102
  _instance = new VellumQdrantClient(config);
91
103
  return _instance;
@@ -140,12 +152,28 @@ export class VellumQdrantClient {
140
152
  const dimMismatch =
141
153
  currentSize != null && currentSize !== this.vectorSize;
142
154
 
143
- // Check model identity via a sentinel point that stores the embedding model
155
+ // Check model identity via a sentinel point that stores the embedding model.
156
+ //
157
+ // Legacy sentinels included a ":sparse-v<N>" suffix that conflated the
158
+ // sparse encoder version with the dense model identity. Sparse vectors
159
+ // are upserted in place and never require collection recreation, so a
160
+ // stored value matching the current dense identity after stripping any
161
+ // legacy sparse suffix is treated as compatible. Compatible-but-legacy
162
+ // sentinels are rewritten to the new format below to clean up gradually.
144
163
  let modelMismatch = false;
164
+ let needsSentinelRewrite = false;
145
165
  if (this.embeddingModel) {
146
166
  const sentinel = await this.readSentinel();
147
- if (sentinel && sentinel !== this.embeddingModel) {
148
- modelMismatch = true;
167
+ if (sentinel) {
168
+ const normalizedStored = stripLegacySparseSuffix(sentinel);
169
+ const normalizedCurrent = stripLegacySparseSuffix(
170
+ this.embeddingModel,
171
+ );
172
+ if (normalizedStored !== normalizedCurrent) {
173
+ modelMismatch = true;
174
+ } else if (sentinel !== this.embeddingModel) {
175
+ needsSentinelRewrite = true;
176
+ }
149
177
  }
150
178
  }
151
179
 
@@ -156,7 +184,7 @@ export class VellumQdrantClient {
156
184
  currentSize,
157
185
  expectedSize: this.vectorSize,
158
186
  },
159
- "Qdrant collection uses unnamed vectors (legacy) — deleting and recreating with named vectors. Embeddings will be re-indexed."
187
+ "Qdrant collection uses unnamed vectors (legacy) — deleting and recreating with named vectors. Embeddings will be re-indexed.",
160
188
  );
161
189
  await this.client.deleteCollection(this.collection);
162
190
  migrated = true;
@@ -169,7 +197,7 @@ export class VellumQdrantClient {
169
197
  expectedSize: this.vectorSize,
170
198
  modelMismatch,
171
199
  },
172
- "Qdrant collection incompatible (dimension or model change) — deleting and recreating. Embeddings will be regenerated on demand."
200
+ "Qdrant collection incompatible (dimension or model change) — deleting and recreating. Embeddings will be regenerated on demand.",
173
201
  );
174
202
  await this.client.deleteCollection(this.collection);
175
203
  migrated = true;
@@ -178,12 +206,15 @@ export class VellumQdrantClient {
178
206
  if (await this.ensurePayloadIndexesSafe()) {
179
207
  this.collectionReady = true;
180
208
  }
209
+ if (needsSentinelRewrite && this.embeddingModel) {
210
+ await this.writeSentinel(this.embeddingModel);
211
+ }
181
212
  return { migrated: false };
182
213
  }
183
214
  } catch (err) {
184
215
  log.warn(
185
216
  { err },
186
- "Failed to verify collection compatibility, assuming compatible"
217
+ "Failed to verify collection compatibility, assuming compatible",
187
218
  );
188
219
  if (await this.ensurePayloadIndexesSafe()) {
189
220
  this.collectionReady = true;
@@ -197,7 +228,7 @@ export class VellumQdrantClient {
197
228
 
198
229
  log.info(
199
230
  { collection: this.collection, vectorSize: this.vectorSize },
200
- "Creating Qdrant collection with named vectors (dense + sparse)"
231
+ "Creating Qdrant collection with named vectors (dense + sparse)",
201
232
  );
202
233
 
203
234
  try {
@@ -253,7 +284,7 @@ export class VellumQdrantClient {
253
284
  this.collectionReady = true;
254
285
  log.info(
255
286
  { collection: this.collection },
256
- "Qdrant collection created with payload indexes"
287
+ "Qdrant collection created with payload indexes",
257
288
  );
258
289
  }
259
290
 
@@ -265,7 +296,7 @@ export class VellumQdrantClient {
265
296
  targetId: string,
266
297
  vector: number[],
267
298
  payload: Omit<QdrantPointPayload, "target_type" | "target_id">,
268
- sparseVector?: QdrantSparseVector
299
+ sparseVector?: QdrantSparseVector,
269
300
  ): Promise<string> {
270
301
  await this.ensureCollection();
271
302
 
@@ -320,7 +351,7 @@ export class VellumQdrantClient {
320
351
  async search(
321
352
  vector: number[],
322
353
  limit: number,
323
- filter?: Record<string, unknown>
354
+ filter?: Record<string, unknown>,
324
355
  ): Promise<QdrantSearchResult[]> {
325
356
  await this.ensureCollection();
326
357
 
@@ -348,7 +379,7 @@ export class VellumQdrantClient {
348
379
  return results.map((result) => ({
349
380
  id: typeof result.id === "string" ? result.id : String(result.id),
350
381
  score: result.score,
351
- payload: (result.payload as unknown) as QdrantPointPayload,
382
+ payload: result.payload as unknown as QdrantPointPayload,
352
383
  }));
353
384
  }
354
385
 
@@ -357,7 +388,6 @@ export class VellumQdrantClient {
357
388
  limit: number,
358
389
  targetTypes: Array<"segment" | "item" | "summary" | "media">,
359
390
  excludeMessageIds?: string[],
360
- scopeIds?: string[]
361
391
  ): Promise<QdrantSearchResult[]> {
362
392
  const mustConditions: Array<Record<string, unknown>> = [
363
393
  {
@@ -384,18 +414,6 @@ export class VellumQdrantClient {
384
414
  });
385
415
  }
386
416
 
387
- // Scope filtering: accept points whose memory_scope_id matches one of the
388
- // allowed scopes, OR points that lack the field entirely (legacy data).
389
- // Post-query DB filtering remains as defense-in-depth for legacy points.
390
- if (scopeIds && scopeIds.length > 0) {
391
- mustConditions.push({
392
- should: [
393
- { key: "memory_scope_id", match: { any: scopeIds } },
394
- { is_empty: { key: "memory_scope_id" } },
395
- ],
396
- });
397
- }
398
-
399
417
  const mustNotConditions: Array<Record<string, unknown>> = [
400
418
  { key: "_meta", match: { value: true } },
401
419
  ];
@@ -434,7 +452,7 @@ export class VellumQdrantClient {
434
452
  const queryParams = {
435
453
  prefetch: [
436
454
  {
437
- query: (denseVector as unknown) as number[],
455
+ query: denseVector as unknown as number[],
438
456
  using: "dense",
439
457
  limit: effectivePrefetchLimit,
440
458
  },
@@ -469,7 +487,7 @@ export class VellumQdrantClient {
469
487
  return (results.points ?? []).map((point) => ({
470
488
  id: typeof point.id === "string" ? point.id : String(point.id),
471
489
  score: point.score ?? 0,
472
- payload: (point.payload as unknown) as QdrantPointPayload,
490
+ payload: point.payload as unknown as QdrantPointPayload,
473
491
  }));
474
492
  }
475
493
 
@@ -594,7 +612,7 @@ export class VellumQdrantClient {
594
612
  } catch (err) {
595
613
  log.warn(
596
614
  { err, collection: this.collection },
597
- "Failed to delete Qdrant collection"
615
+ "Failed to delete Qdrant collection",
598
616
  );
599
617
  return false;
600
618
  }
@@ -762,8 +780,7 @@ export class VellumQdrantClient {
762
780
  ...(offset !== undefined ? { offset } : {}),
763
781
  });
764
782
  for (const point of result.points) {
765
- const id =
766
- typeof point.id === "string" ? point.id : String(point.id);
783
+ const id = typeof point.id === "string" ? point.id : String(point.id);
767
784
  const payload = (point.payload ?? {}) as Record<string, unknown>;
768
785
  out.push({ id, payload });
769
786
  }
@@ -788,7 +805,7 @@ export class VellumQdrantClient {
788
805
 
789
806
  private async findByTarget(
790
807
  targetType: string,
791
- targetId: string
808
+ targetId: string,
792
809
  ): Promise<string | null> {
793
810
  try {
794
811
  const results = await this.client.scroll(this.collection, {