@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
@@ -2,18 +2,22 @@
2
2
  // Memory v2 — Skill catalog → embedded skill entries
3
3
  // ---------------------------------------------------------------------------
4
4
  //
5
- // Mirrors v1's `seedSkillGraphNodes` + `seedUninstalledCatalogSkillMemories`
6
- // (capability-seed.ts) for the v2 pipeline: enumerate the enabled-skill
7
- // catalog AND uninstalled catalog skills, render each skill's prose statement
8
- // via `buildSkillContent`, embed dense + sparse, upsert into the dedicated
9
- // `memory_v2_skills` Qdrant collection, and prune stale points from prior
10
- // catalog state. Including uninstalled catalog skills ensures their activation
11
- // hints are discoverable by intent so the model can auto-install them.
5
+ // Enumerate the enabled-skill catalog AND uninstalled catalog skills, render
6
+ // each skill's prose statement via `buildSkillContent`, embed dense + sparse,
7
+ // and upsert into `memory_v2_concept_pages` under the slug `skills/<id>`.
8
+ // Including uninstalled catalog skills ensures their activation hints are
9
+ // discoverable by intent so the model can auto-install them.
12
10
  //
13
- // Unlike v1, skill entries are kept in a small in-process cache so the render
14
- // path can fetch a `SkillEntry` synchronously by id without round-tripping to
15
- // Qdrant. The cache is replaced atomically at the end of a successful seed
16
- // run; on error the prior cache stays intact (skills are best-effort).
11
+ // Skills share the concept-page collection rather than living in a dedicated
12
+ // one so the per-turn activation pipeline scores them against the same
13
+ // candidate ANN as concept pages, with the same decay and spread machinery.
14
+ // The render path branches on the `skills/` slug prefix to surface them as
15
+ // the `### Skills You Can Use` subsection.
16
+ //
17
+ // Skill entries are kept in a small in-process cache so the render path can
18
+ // fetch a `SkillEntry` synchronously by id without round-tripping to Qdrant.
19
+ // The cache is replaced atomically at the end of a successful seed run; on
20
+ // error the prior cache stays intact (skills are best-effort).
17
21
 
18
22
  import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
19
23
  import { getConfig } from "../../config/loader.js";
@@ -25,19 +29,36 @@ import {
25
29
  fromSkillSummary,
26
30
  } from "../../skills/skill-memory.js";
27
31
  import { getLogger } from "../../util/logger.js";
32
+ import { applyCorrectionIfCalibrated } from "../anisotropy.js";
28
33
  import {
29
34
  embedWithBackend,
30
35
  generateSparseEmbedding,
31
36
  } from "../embedding-backend.js";
37
+ import {
38
+ pruneSlugsWithPrefixExcept,
39
+ upsertConceptPageEmbedding,
40
+ } from "./qdrant.js";
32
41
  import {
33
42
  augmentMcpSetupDescription,
34
43
  buildSkillContent,
35
44
  } from "./skill-content.js";
36
- import { pruneSkillsExcept, upsertSkillEmbedding } from "./skill-qdrant.js";
37
45
  import type { SkillEntry } from "./types.js";
38
46
 
39
47
  const log = getLogger("memory-v2-skill-store");
40
48
 
49
+ /**
50
+ * Slug prefix under which skill embeddings are indexed in
51
+ * `memory_v2_concept_pages`. Concept-page slugs must match
52
+ * `[a-z0-9][a-z0-9-]*(/...)*`, and `skills` matches that pattern, so the
53
+ * prefix coexists with hand-authored concept pages without escape work.
54
+ */
55
+ export const SKILL_SLUG_PREFIX = "skills/";
56
+
57
+ /** Compose the unified-collection slug for a skill id. */
58
+ export function skillSlugFor(id: string): string {
59
+ return `${SKILL_SLUG_PREFIX}${id}`;
60
+ }
61
+
41
62
  /**
42
63
  * Module-level cache of rendered skill entries keyed by skill id. `null` until
43
64
  * the first successful seed run completes; replaced atomically on each
@@ -46,30 +67,27 @@ const log = getLogger("memory-v2-skill-store");
46
67
  let entries: Map<string, SkillEntry> | null = null;
47
68
 
48
69
  /**
49
- * Seed (or re-seed) the v2 skill embedding collection from the live skill
50
- * catalog. Idempotent: safe to call repeatedly. Best-effort: never throws —
51
- * any failure leaves the prior `entries` cache in place and logs a warning.
70
+ * Seed (or re-seed) skill embeddings into the unified concept-page collection.
71
+ * Idempotent: safe to call repeatedly. Best-effort: never throws — any
72
+ * failure leaves the prior `entries` cache in place and logs a warning.
52
73
  *
53
74
  * Steps:
54
- * 1. Enumerate the local skill catalog and resolve each skill's enabled state
55
- * (`resolveSkillStates`).
56
- * 2. Build a `SkillCapabilityInput` per enabled skill, applying the
57
- * mcp-setup augmentation (mirrors v1) and the prose-style content render
58
- * (`buildSkillContent`, capped at 500 chars).
75
+ * 1. Enumerate the local skill catalog and resolve each skill's enabled
76
+ * state (`resolveSkillStates`).
77
+ * 2. Build a `SkillEntry` per enabled skill, applying the mcp-setup
78
+ * augmentation and the prose-style content render (`buildSkillContent`,
79
+ * capped at 500 chars).
59
80
  * 3. Defense-in-depth feature-flag filter: drop any skill whose declared
60
- * `metadata.vellum.feature-flag` is currently disabled. `resolveSkillStates`
61
- * already enforces this, but we mirror v1's enforcement point so the v2
62
- * collection never holds an embedding for a flag-gated skill if the two
63
- * ever drift.
64
- * 3b. Fetch the full remote catalog and seed any uninstalled skills so their
65
- * activation hints are discoverable by semantic search. Best-effort: if
66
- * the catalog fetch fails, only installed skills are seeded.
81
+ * `metadata.vellum.feature-flag` is currently disabled.
82
+ * 3b. Fetch the full remote catalog and seed any uninstalled skills so
83
+ * their activation hints are discoverable by semantic search. Best-effort:
84
+ * if the catalog fetch fails, only installed skills are seeded.
67
85
  * 4. Embed all `content` strings in a single dense `embedWithBackend` call,
68
86
  * and a per-skill synchronous `generateSparseEmbedding`.
69
- * 5. Upsert one Qdrant point per skill via `upsertSkillEmbedding` (keyed
70
- * deterministically on id so re-runs replace in place).
71
- * 6. Call `pruneSkillsExcept` with the active id list to drop any stale
72
- * points from prior catalog state (e.g. uninstalled skills).
87
+ * 5. Upsert one Qdrant point per skill via `upsertConceptPageEmbedding`
88
+ * keyed deterministically on slug `skills/<id>`.
89
+ * 6. Call `pruneSlugsWithPrefixExcept(SKILL_SLUG_PREFIX, ...)` to drop any
90
+ * stale points from prior catalog state (e.g. uninstalled skills).
73
91
  * 7. Replace the module-level `entries` cache with the freshly built map.
74
92
  */
75
93
  export async function seedV2SkillEntries(): Promise<void> {
@@ -82,8 +100,7 @@ export async function seedV2SkillEntries(): Promise<void> {
82
100
  // Track every locally-installed skill id (regardless of enabled/disabled
83
101
  // state) so the catalog-seeding loop below treats them all as "installed"
84
102
  // and never re-seeds a disabled skill from `getCatalog()` as if it were
85
- // uninstalled. Mirrors v1's `seedUninstalledCatalogSkillMemories`, which
86
- // keys off `loadSkillCatalog()` (the installed set) for the same reason.
103
+ // uninstalled.
87
104
  const installedIds = new Set<string>(catalog.map((s) => s.id));
88
105
 
89
106
  // Build the input list, applying the mcp-setup description augmentation
@@ -99,8 +116,8 @@ export async function seedV2SkillEntries(): Promise<void> {
99
116
  }
100
117
 
101
118
  // Seed uninstalled catalog skills so their activation hints are
102
- // discoverable by intent (mirrors v1's seedUninstalledCatalogSkillMemories).
103
- // Track whether the catalog was available so we can guard pruning below.
119
+ // discoverable by intent. Track whether the catalog was available so we
120
+ // can guard pruning below.
104
121
  let catalogAvailable = false;
105
122
  try {
106
123
  const fullCatalog = await getCatalog();
@@ -122,31 +139,41 @@ export async function seedV2SkillEntries(): Promise<void> {
122
139
 
123
140
  // Embed all content strings in one batched call. Sparse vectors are
124
141
  // computed in-process (no network).
125
- const { vectors: denseVectors } = await embedWithBackend(
142
+ const embedded = await embedWithBackend(
126
143
  config,
127
144
  seeds.map((s) => s.content),
128
145
  );
146
+ const denseVectors = await Promise.all(
147
+ embedded.vectors.map((v) =>
148
+ applyCorrectionIfCalibrated(v, embedded.provider, embedded.model),
149
+ ),
150
+ );
129
151
 
130
152
  const now = Date.now();
131
153
  const nextEntries = new Map<string, SkillEntry>();
132
- for (let i = 0; i < seeds.length; i++) {
133
- const seed = seeds[i];
134
- await upsertSkillEmbedding({
135
- ...seed,
136
- dense: denseVectors[i],
137
- sparse: generateSparseEmbedding(seed.content),
138
- updatedAt: now,
139
- });
154
+ await Promise.all(
155
+ seeds.map((seed, i) =>
156
+ upsertConceptPageEmbedding({
157
+ slug: skillSlugFor(seed.id),
158
+ dense: denseVectors[i],
159
+ sparse: generateSparseEmbedding(seed.content),
160
+ updatedAt: now,
161
+ }),
162
+ ),
163
+ );
164
+ for (const seed of seeds) {
140
165
  nextEntries.set(seed.id, seed);
141
166
  }
142
167
 
143
- // Prune stale points. When the catalog is unavailable (empty array from
144
- // network failure or cold cache), we cannot enumerate which uninstalled
145
- // catalog skills should exist, so skip pruning entirely to avoid
146
- // aggressively removing previously-seeded catalog skill embeddings.
147
- // Mirrors v1's safeguard in capability-seed.ts (lines 124–143).
168
+ // Prune stale skill slugs. When the catalog is unavailable (empty array
169
+ // from network failure or cold cache), we cannot enumerate which
170
+ // uninstalled catalog skills should exist, so skip pruning entirely to
171
+ // avoid aggressively removing previously-seeded catalog skill embeddings.
148
172
  if (catalogAvailable) {
149
- await pruneSkillsExcept(seeds.map((s) => s.id));
173
+ await pruneSlugsWithPrefixExcept(
174
+ SKILL_SLUG_PREFIX,
175
+ seeds.map((s) => s.id),
176
+ );
150
177
  } else {
151
178
  log.info(
152
179
  "Catalog unavailable — skipping skill pruning to preserve prior catalog embeddings",
@@ -163,13 +190,24 @@ export async function seedV2SkillEntries(): Promise<void> {
163
190
  /**
164
191
  * Synchronous lookup of a previously-seeded `SkillEntry` by skill id. Returns
165
192
  * `null` when the cache has not yet been populated, when the id is unknown,
166
- * or when a prior seed run dropped the id (e.g. the skill was disabled). Used
167
- * by the render path to attach skill-related content to outgoing prompts.
193
+ * or when a prior seed run dropped the id (e.g. the skill was disabled).
194
+ *
195
+ * Accepts either a bare skill id (`example-skill`) or its unified-collection
196
+ * slug (`skills/example-skill`) so render-side callers can pass through what
197
+ * they have without a manual prefix strip.
168
198
  */
169
- export function getSkillCapability(id: string): SkillEntry | null {
199
+ export function getSkillCapability(idOrSlug: string): SkillEntry | null {
200
+ const id = idOrSlug.startsWith(SKILL_SLUG_PREFIX)
201
+ ? idOrSlug.slice(SKILL_SLUG_PREFIX.length)
202
+ : idOrSlug;
170
203
  return entries?.get(id) ?? null;
171
204
  }
172
205
 
206
+ /** True iff the slug refers to a skill entry in the unified collection. */
207
+ export function isSkillSlug(slug: string): boolean {
208
+ return slug.startsWith(SKILL_SLUG_PREFIX);
209
+ }
210
+
173
211
  /** @internal Test-only: clear the module-level cache. */
174
212
  export function _resetSkillStoreForTests(): void {
175
213
  entries = null;
@@ -0,0 +1,245 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory v2 — BM25 sparse channel
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // Replaces the legacy TF-only sparse embedding (`generateSparseEmbedding` in
6
+ // `../embedding-backend.ts`) with a real Okapi BM25 implementation. Common
7
+ // words like "i", "am", "the" no longer dominate sparse matching the way they
8
+ // did when every token was weighted equally.
9
+ //
10
+ // BM25 score for document `d` and query `q`:
11
+ //
12
+ // score(d, q) = Σ_t∈q IDF(t) · TF_sat(d, t)
13
+ // TF_sat(d, t) = tf(d, t) · (k1 + 1)
14
+ // / (tf(d, t) + k1 · (1 - b + b · |d| / avg_dl))
15
+ // IDF(t) = log( (N - df(t) + 0.5) / (df(t) + 0.5) + 1 )
16
+ //
17
+ // `+1` inside the IDF log keeps the result non-negative even when df(t) > N/2,
18
+ // matching the variant Lucene uses for `BM25Similarity`.
19
+ //
20
+ // **Asymmetric encoding**: documents carry the full BM25 weight per token
21
+ // (IDF · TF_sat baked into the stored vector), and queries carry binary
22
+ // occurrence per token. Qdrant's sparse dot product then reduces to the BM25
23
+ // score directly. Putting BM25 on the doc side means the weights need
24
+ // recomputing whenever the corpus DF or avg_dl changes — operators trigger
25
+ // that with `assistant memory v2 reembed` after major content shifts.
26
+
27
+ import { readFile } from "node:fs/promises";
28
+
29
+ import type { SparseEmbedding } from "../embedding-types.js";
30
+ import {
31
+ SPARSE_VOCAB_SIZE,
32
+ tokenHash,
33
+ tokenizeStemmed,
34
+ } from "../sparse-tokenize.js";
35
+ import { listPages } from "./page-store.js";
36
+
37
+ /**
38
+ * Aggregate corpus statistics used to weight a BM25 document vector. Held in
39
+ * memory after a startup walk over `memory/concepts/`.
40
+ */
41
+ export interface CorpusStats {
42
+ /** Total document count over which DF was accumulated. */
43
+ totalDocs: number;
44
+ /** hashedTokenIndex (in `[0, SPARSE_VOCAB_SIZE)`) → distinct-doc count. */
45
+ df: Map<number, number>;
46
+ /** Average document length in tokens, post-tokenize. */
47
+ avgDl: number;
48
+ /** Wall-clock millis at build time — used by diagnostics, not the formula. */
49
+ builtAt: number;
50
+ }
51
+
52
+ /** BM25 hyperparameters. Standard Lucene/Elasticsearch defaults. */
53
+ export interface Bm25Params {
54
+ /** TF saturation curve. ~1.2 is standard. */
55
+ k1: number;
56
+ /** Length normalization. 0 = none, 1 = full. ~0.75 is standard. */
57
+ b: number;
58
+ }
59
+
60
+ let _conceptPageStats: CorpusStats | null = null;
61
+
62
+ /**
63
+ * Latest in-memory corpus stats for `memory/concepts/`, or `null` if a build
64
+ * has not yet completed. Callers must handle `null` and fall back to legacy
65
+ * TF-only behavior so the daemon remains usable during the brief startup
66
+ * window before {@link rebuildConceptPageCorpusStats} finishes.
67
+ */
68
+ export function getConceptPageCorpusStats(): CorpusStats | null {
69
+ return _conceptPageStats;
70
+ }
71
+
72
+ /**
73
+ * Walk every concept page on disk, accumulate document frequency per hashed
74
+ * token bucket, and average document length. Atomically swaps the result into
75
+ * the module-level cache when the walk succeeds. On error the previous stats
76
+ * stay live.
77
+ *
78
+ * Reads bodies via `readPage`-equivalent direct file reads to avoid paying for
79
+ * frontmatter parsing on every page (we only need the body for sparse).
80
+ */
81
+ export async function rebuildConceptPageCorpusStats(
82
+ workspaceDir: string,
83
+ ): Promise<void> {
84
+ const slugs = await listPages(workspaceDir);
85
+ if (slugs.length === 0) {
86
+ _conceptPageStats = {
87
+ totalDocs: 0,
88
+ df: new Map(),
89
+ avgDl: 0,
90
+ builtAt: Date.now(),
91
+ };
92
+ return;
93
+ }
94
+
95
+ const df = new Map<number, number>();
96
+ let totalTokens = 0;
97
+ let docsCounted = 0;
98
+
99
+ for (const slug of slugs) {
100
+ const body = await readPageBodyForStats(workspaceDir, slug);
101
+ if (body === null) continue;
102
+ const tokens = tokenizeStemmed(body);
103
+ if (tokens.length === 0) continue;
104
+ totalTokens += tokens.length;
105
+ docsCounted += 1;
106
+ const seen = new Set<number>();
107
+ for (const token of tokens) {
108
+ const idx = tokenHash(token, SPARSE_VOCAB_SIZE);
109
+ if (seen.has(idx)) continue;
110
+ seen.add(idx);
111
+ df.set(idx, (df.get(idx) ?? 0) + 1);
112
+ }
113
+ }
114
+
115
+ _conceptPageStats = {
116
+ totalDocs: docsCounted,
117
+ df,
118
+ avgDl: docsCounted > 0 ? totalTokens / docsCounted : 0,
119
+ builtAt: Date.now(),
120
+ };
121
+ }
122
+
123
+ /**
124
+ * Read just the body of a page for stats accumulation. Skips the YAML
125
+ * frontmatter without invoking the schema-validating `readPage` parser, since
126
+ * any parse failure surfaced there would abort the whole rebuild — and we
127
+ * only need the prose half for tokenization.
128
+ */
129
+ async function readPageBodyForStats(
130
+ workspaceDir: string,
131
+ slug: string,
132
+ ): Promise<string | null> {
133
+ const path = `${workspaceDir}/memory/concepts/${slug}.md`;
134
+ let raw: string;
135
+ try {
136
+ raw = await readFile(path, "utf-8");
137
+ } catch {
138
+ return null;
139
+ }
140
+ // Strip a leading `---\n...\n---\n` block if present; otherwise return raw.
141
+ if (raw.startsWith("---")) {
142
+ const closing = raw.indexOf("\n---", 3);
143
+ if (closing !== -1) {
144
+ const after = raw.indexOf("\n", closing + 4);
145
+ if (after !== -1) return raw.slice(after + 1);
146
+ }
147
+ }
148
+ return raw;
149
+ }
150
+
151
+ /**
152
+ * Compute the BM25 IDF weight for a hashed token bucket. Returns `0` when the
153
+ * token's df equals the corpus size (a token in every document carries no
154
+ * discriminating power).
155
+ */
156
+ function computeIdf(stats: CorpusStats, hashIdx: number): number {
157
+ const df = stats.df.get(hashIdx) ?? 0;
158
+ const numerator = stats.totalDocs - df + 0.5;
159
+ const denominator = df + 0.5;
160
+ return Math.log(numerator / denominator + 1);
161
+ }
162
+
163
+ /**
164
+ * Document-side BM25-weighted sparse vector. Each emitted value is
165
+ * `IDF(t) · TF_sat(d, t)` so the dot product against a binary query vector
166
+ * (see {@link generateBm25QueryEmbedding}) yields the BM25 score.
167
+ *
168
+ * Returns an empty embedding for empty input or when the corpus is empty
169
+ * (every IDF would be zero anyway).
170
+ */
171
+ export function generateBm25DocEmbedding(
172
+ text: string,
173
+ stats: CorpusStats,
174
+ params: Bm25Params,
175
+ ): SparseEmbedding {
176
+ const tokens = tokenizeStemmed(text);
177
+ if (tokens.length === 0 || stats.totalDocs === 0) {
178
+ return { indices: [], values: [] };
179
+ }
180
+
181
+ // Per-document term frequencies, keyed by hashed bucket.
182
+ const tf = new Map<number, number>();
183
+ for (const token of tokens) {
184
+ const idx = tokenHash(token, SPARSE_VOCAB_SIZE);
185
+ tf.set(idx, (tf.get(idx) ?? 0) + 1);
186
+ }
187
+
188
+ const docLen = tokens.length;
189
+ // avg_dl can be 0 only when totalDocs is 0, which we already short-circuited.
190
+ const lengthFactor = 1 - params.b + (params.b * docLen) / stats.avgDl;
191
+ const indices: number[] = [];
192
+ const values: number[] = [];
193
+
194
+ for (const [idx, freq] of tf) {
195
+ const idf = computeIdf(stats, idx);
196
+ if (idf === 0) continue; // Skip tokens that contribute nothing to scores.
197
+ const saturated =
198
+ (freq * (params.k1 + 1)) / (freq + params.k1 * lengthFactor);
199
+ const weight = idf * saturated;
200
+ if (weight === 0) continue;
201
+ indices.push(idx);
202
+ values.push(weight);
203
+ }
204
+
205
+ return { indices, values };
206
+ }
207
+
208
+ /**
209
+ * Query-side sparse vector — binary occurrence per distinct query token. The
210
+ * dot product `Σ_t v_q(t) · v_d(t)` against a BM25-weighted document vector
211
+ * is exactly the BM25 score, since `v_q(t) = 1` for tokens in the query and
212
+ * `0` otherwise.
213
+ *
214
+ * Stateless — does not need corpus stats, so callers can use this on every
215
+ * turn without coordinating with {@link rebuildConceptPageCorpusStats}.
216
+ */
217
+ export function generateBm25QueryEmbedding(text: string): SparseEmbedding {
218
+ const tokens = tokenizeStemmed(text);
219
+ if (tokens.length === 0) {
220
+ return { indices: [], values: [] };
221
+ }
222
+
223
+ const seen = new Set<number>();
224
+ const indices: number[] = [];
225
+ const values: number[] = [];
226
+ for (const token of tokens) {
227
+ const idx = tokenHash(token, SPARSE_VOCAB_SIZE);
228
+ if (seen.has(idx)) continue;
229
+ seen.add(idx);
230
+ indices.push(idx);
231
+ values.push(1);
232
+ }
233
+
234
+ return { indices, values };
235
+ }
236
+
237
+ /** @internal Test-only: reset module-level singletons. */
238
+ export function _resetCorpusStatsForTests(): void {
239
+ _conceptPageStats = null;
240
+ }
241
+
242
+ /** @internal Test-only: install a fixture stats table without disk I/O. */
243
+ export function _setCorpusStatsForTests(stats: CorpusStats | null): void {
244
+ _conceptPageStats = stats;
245
+ }
@@ -6,16 +6,18 @@
6
6
  // and returns a concatenated, header-wrapped block ready to splice into the
7
7
  // current user message via the injector chain.
8
8
  //
9
- // Pairs with the v2 per-turn activation block (`prependMemoryV2Block` in
10
- // `conversation-graph-memory.ts`) that block carries activated concept
11
- // pages selected by the activation pipeline; this static block carries the
12
- // always-relevant aggregate views written by consolidation and the user.
13
- // Both land on the user message so the system prompt stays cache-stable.
9
+ // Pairs with the v2 per-turn activation block (`maybeRouteV2Injection` in
10
+ // `conversation-graph-memory.ts`, which threads through `injectTextBlock`)
11
+ // that block carries activated concept pages selected by the activation
12
+ // pipeline; this static block carries the always-relevant aggregate views
13
+ // written by consolidation and the user. Both land on the user message so
14
+ // the system prompt stays cache-stable.
14
15
  //
15
16
  // Refresh cadence is owned by the caller: the agent loop only passes the
16
17
  // content through when `mode === "full"` (first turn / post-compaction),
17
18
  // matching the existing PKB auto-inject pattern.
18
19
 
20
+ import type { ChannelId } from "../../channels/types.js";
19
21
  import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
20
22
  import { loadConfig } from "../../config/loader.js";
21
23
  import { readPromptFile } from "../../prompts/system-prompt.js";
@@ -60,3 +62,24 @@ export function readMemoryV2StaticContent(): string | null {
60
62
  }
61
63
  return sections.length > 0 ? sections.join("\n\n") : null;
62
64
  }
65
+
66
+ /**
67
+ * Static memory holds the user's aggregate personal pages
68
+ * (essentials/threads/recent/buffer). Block injection when a non-guardian
69
+ * actor reaches the assistant over a remote channel — otherwise the model
70
+ * can be prompt-injected into reciting private memory. Internal flows
71
+ * (`sourceChannel: "vellum"`) and turns with no trust context pass through
72
+ * unchanged; this gate exists only to keep remote untrusted actors out.
73
+ */
74
+ export function shouldLoadMemoryV2Static(args: {
75
+ shouldInjectNowAndPkb: boolean;
76
+ sourceChannel: ChannelId | undefined;
77
+ isTrustedActor: boolean;
78
+ }): boolean {
79
+ if (!args.shouldInjectNowAndPkb) return false;
80
+ const isRemoteUntrustedActor =
81
+ args.sourceChannel !== undefined &&
82
+ args.sourceChannel !== "vellum" &&
83
+ !args.isTrustedActor;
84
+ return !isRemoteUntrustedActor;
85
+ }
@@ -85,20 +85,20 @@ export const ActivationStateSchema = z.object({
85
85
  export type ActivationState = z.infer<typeof ActivationStateSchema>;
86
86
 
87
87
  // ---------------------------------------------------------------------------
88
- // Skill autoinjection (synthetic in-memory entries, not on-disk pages)
88
+ // Skill entries (synthetic concept-collection rows, not on-disk pages)
89
89
  // ---------------------------------------------------------------------------
90
90
 
91
91
  /**
92
- * Per-skill capability snapshot held in-process and embedded into the
93
- * `memory_v2_skills` Qdrant collection. `content` is the rendered
94
- * `buildSkillContent` string — already capped at 500 chars upstream and
95
- * already containing the skill's display name — and is what we embed and
96
- * what we render verbatim in `### Skills You Can Use`.
92
+ * Per-skill capability snapshot held in-process and embedded into the unified
93
+ * `memory_v2_concept_pages` Qdrant collection under the slug `skills/<id>`.
94
+ * `content` is the rendered `buildSkillContent` string — already capped at
95
+ * 500 chars upstream and already containing the skill's display name — and
96
+ * is what we embed and what we render verbatim in `### Skills You Can Use`.
97
97
  *
98
- * Plain interface (no Zod) because skill data does not cross a
99
- * serialization boundary: it is built in-process by `seedV2SkillEntries`
100
- * and read in-process by `renderInjectionBlock`. The Qdrant payload is
101
- * not parsed back through this type.
98
+ * Plain interface (no Zod) because skill data does not cross a serialization
99
+ * boundary: it is built in-process by `seedV2SkillEntries` and read in-process
100
+ * by `renderInjectionBlock`. The Qdrant payload is not parsed back through
101
+ * this type.
102
102
  */
103
103
  export interface SkillEntry {
104
104
  id: string;
@@ -95,52 +95,3 @@ export interface GmailModifyRequest {
95
95
 
96
96
  /** Message format for GET requests */
97
97
  export type GmailMessageFormat = "minimal" | "full" | "raw" | "metadata";
98
-
99
- /** Attachment data from the Gmail API */
100
- export interface GmailAttachment {
101
- size: number;
102
- data: string; // base64url-encoded
103
- }
104
-
105
- /** Gmail filter criteria */
106
- export interface GmailFilterCriteria {
107
- from?: string;
108
- to?: string;
109
- subject?: string;
110
- query?: string;
111
- hasAttachment?: boolean;
112
- excludeChats?: boolean;
113
- size?: number;
114
- sizeComparison?: "larger" | "smaller";
115
- }
116
-
117
- /** Gmail filter action */
118
- export interface GmailFilterAction {
119
- addLabelIds?: string[];
120
- removeLabelIds?: string[];
121
- forward?: string;
122
- }
123
-
124
- /** Gmail filter */
125
- export interface GmailFilter {
126
- id: string;
127
- criteria: GmailFilterCriteria;
128
- action: GmailFilterAction;
129
- }
130
-
131
- /** Gmail filters list response */
132
- export interface GmailFiltersListResponse {
133
- filter?: GmailFilter[];
134
- }
135
-
136
- /** Gmail vacation auto-reply settings */
137
- export interface GmailVacationSettings {
138
- enableAutoReply: boolean;
139
- responseSubject?: string;
140
- responseBodyPlainText?: string;
141
- responseBodyHtml?: string;
142
- restrictToContacts?: boolean;
143
- restrictToDomain?: boolean;
144
- startTime?: string; // epoch ms as string
145
- endTime?: string; // epoch ms as string
146
- }
@@ -11,7 +11,6 @@ import {
11
11
  } from "@vellumai/slack-text";
12
12
 
13
13
  import { findContactChannel } from "../../../contacts/contact-store.js";
14
- import { upsertContactChannel } from "../../../contacts/contacts-write.js";
15
14
  import type { OAuthConnection } from "../../../oauth/connection.js";
16
15
  import { resolveOAuthConnection } from "../../../oauth/connection-resolver.js";
17
16
  import { isProviderConnected } from "../../../oauth/oauth-store.js";
@@ -163,18 +162,6 @@ async function resolveUserName(
163
162
  resp.user.real_name ||
164
163
  resp.user.name;
165
164
  userNameCache.set(userId, name);
166
-
167
- // Persist to contacts for future sessions
168
- try {
169
- upsertContactChannel({
170
- sourceChannel: "slack",
171
- externalUserId: userId,
172
- displayName: name,
173
- });
174
- } catch {
175
- // Non-fatal — caching failure shouldn't break messaging
176
- }
177
-
178
165
  return name;
179
166
  } catch {
180
167
  return userId;
@@ -433,24 +420,7 @@ export const slackProvider: MessagingProvider = {
433
420
  const dmUserId = conv.metadata.dmUserId as string;
434
421
  conv.name = await resolveUserName(auth, dmUserId);
435
422
 
436
- // Persist the DM channel ID so future sends skip conversations.open
437
- try {
438
- const existing = findContactChannel({
439
- channelType: "slack",
440
- externalUserId: dmUserId,
441
- });
442
- if (existing && !existing.channel.externalChatId) {
443
- upsertContactChannel({
444
- contactId: existing.contact.id,
445
- sourceChannel: "slack",
446
- externalUserId: dmUserId,
447
- externalChatId: conv.id,
448
- displayName: conv.name,
449
- });
450
- }
451
- } catch {
452
- // Non-fatal
453
- }
423
+
454
424
  }
455
425
  }
456
426