@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,12 +2,15 @@
2
2
  // Memory v2 — Per-turn activation update
3
3
  // ---------------------------------------------------------------------------
4
4
  //
5
- // Implements the activation formula from §4 of the design doc:
5
+ // Implements the activation formula from §4 of the design doc plus an
6
+ // additive cross-encoder rerank boost on the unified top-K-by-A_o pool:
6
7
  //
7
8
  // A_o(n, t+1) = d · A(n, t)
8
9
  // + c_user · sim(User_{t+1}, n)
9
10
  // + c_assistant · sim(Assistant_t, n)
10
11
  // + c_now · sim(NOW.md, n)
12
+ // + c_user · α · r_norm(User_{t+1}, n) [n ∈ topK]
13
+ // + c_assistant · α · r_norm(Assistant_t, n) [n ∈ topK]
11
14
  //
12
15
  // A(n, t+1) = [ A_o(n)
13
16
  // + k · Σ_{m∈in1(n)} A_o(m)
@@ -32,6 +35,7 @@
32
35
  // for the next turn and drop below `epsilon` if no longer relevant.
33
36
 
34
37
  import type { AssistantConfig } from "../../config/types.js";
38
+ import { applyCorrectionIfCalibrated } from "../anisotropy.js";
35
39
  import {
36
40
  embedWithBackend,
37
41
  generateSparseEmbedding,
@@ -39,23 +43,31 @@ import {
39
43
  import { clampUnitInterval } from "../validation.js";
40
44
  import type { EdgeIndex } from "./edge-index.js";
41
45
  import { hybridQueryConceptPages } from "./qdrant.js";
42
- import { simBatch, simSkillBatch } from "./sim.js";
43
- import { hybridQuerySkills } from "./skill-qdrant.js";
46
+ import { rerankCandidates } from "./reranker.js";
47
+ import { simBatch } from "./sim.js";
44
48
  import type { ActivationState, EverInjectedEntry } from "./types.js";
45
49
 
46
50
  /**
47
- * Top-K size for the un-restricted ANN candidate query against the v2
48
- * concept-page collection. The design doc fixes this at 50 — small enough to
49
- * keep the per-turn round-trip cheap, large enough to surface relevant pages
50
- * outside the prior active set.
51
+ * Sentinel passed to Qdrant when `config.memory.v2.ann_candidate_limit` is
52
+ * `null` (unlimited). Qdrant's query API requires an explicit numeric
53
+ * `limit`, so unlimited is represented as a number large enough that any
54
+ * realistic concept-page collection is returned in full.
55
+ *
56
+ * Why not `Number.MAX_SAFE_INTEGER`: Qdrant's sparse-vector `SearchContext`
57
+ * pre-allocates `limit * 16` bytes per query, so passing `MAX_SAFE_INTEGER`
58
+ * triggers a ~144 PB allocation and SIGABRTs the Qdrant process. 1_000_000
59
+ * is ~16 MB of pre-allocation in Qdrant — generous headroom over realistic
60
+ * concept-page counts (low thousands today) while staying well clear of
61
+ * the OOM cliff. Bump explicitly via `ann_candidate_limit` if you ever
62
+ * outgrow it.
51
63
  */
52
- const ANN_CANDIDATE_LIMIT = 50;
64
+ const UNLIMITED_ANN_CANDIDATE_LIMIT = 1_000_000;
53
65
 
54
66
  // ---------------------------------------------------------------------------
55
67
  // Candidate selection
56
68
  // ---------------------------------------------------------------------------
57
69
 
58
- export interface SelectCandidatesParams {
70
+ interface SelectCandidatesParams {
59
71
  /**
60
72
  * Prior-turn activation snapshot. Slugs with activation strictly greater
61
73
  * than `config.memory.v2.epsilon` are carried forward as candidates so the
@@ -69,9 +81,10 @@ export interface SelectCandidatesParams {
69
81
  /** NOW context string (essentials/threads/recent or NOW.md). */
70
82
  nowText: string;
71
83
  config: AssistantConfig;
84
+ signal?: AbortSignal;
72
85
  }
73
86
 
74
- export interface SelectCandidatesResult {
87
+ interface SelectCandidatesResult {
75
88
  /** Union of `fromPrior` and `fromAnn` — the per-turn candidate set. */
76
89
  candidates: Set<string>;
77
90
  /** Slugs carried forward from `priorState` because their activation > epsilon. */
@@ -96,7 +109,8 @@ export interface SelectCandidatesResult {
96
109
  export async function selectCandidates(
97
110
  params: SelectCandidatesParams,
98
111
  ): Promise<SelectCandidatesResult> {
99
- const { priorState, userText, assistantText, nowText, config } = params;
112
+ const { priorState, userText, assistantText, nowText, config, signal } =
113
+ params;
100
114
 
101
115
  const fromPrior = new Set<string>();
102
116
  const fromAnn = new Set<string>();
@@ -117,14 +131,20 @@ export async function selectCandidates(
117
131
  .join("\n");
118
132
 
119
133
  if (annQueryText.length > 0) {
120
- const denseResult = await embedWithBackend(config, [annQueryText]);
121
- const dense = denseResult.vectors[0];
122
- const sparse = generateSparseEmbedding(annQueryText);
123
- const hits = await hybridQueryConceptPages(
124
- dense,
125
- sparse,
126
- ANN_CANDIDATE_LIMIT,
134
+ throwIfAborted(signal);
135
+ const denseResult = await embedWithBackend(config, [annQueryText], {
136
+ signal,
137
+ });
138
+ const dense = await applyCorrectionIfCalibrated(
139
+ denseResult.vectors[0],
140
+ denseResult.provider,
141
+ denseResult.model,
127
142
  );
143
+ throwIfAborted(signal);
144
+ const sparse = generateSparseEmbedding(annQueryText);
145
+ const limit =
146
+ config.memory.v2.ann_candidate_limit ?? UNLIMITED_ANN_CANDIDATE_LIMIT;
147
+ const hits = await hybridQueryConceptPages(dense, sparse, limit);
128
148
  for (const hit of hits) fromAnn.add(hit.slug);
129
149
  }
130
150
 
@@ -137,13 +157,14 @@ export async function selectCandidates(
137
157
  // Own activation
138
158
  // ---------------------------------------------------------------------------
139
159
 
140
- export interface ComputeOwnActivationParams {
160
+ interface ComputeOwnActivationParams {
141
161
  candidates: ReadonlySet<string>;
142
162
  priorState: ActivationState | null;
143
163
  userText: string;
144
164
  assistantText: string;
145
165
  nowText: string;
146
166
  config: AssistantConfig;
167
+ signal?: AbortSignal;
147
168
  }
148
169
 
149
170
  /**
@@ -151,18 +172,24 @@ export interface ComputeOwnActivationParams {
151
172
  * coefficient weighting is applied. Surfaced for telemetry / inspector views
152
173
  * so the UI can show how each term contributed to the final value.
153
174
  */
154
- export interface OwnActivationBreakdown {
175
+ interface OwnActivationBreakdown {
155
176
  /** `d * prev(slug)` — the decayed prior-turn activation contribution. */
156
177
  priorContribution: number;
157
- /** Raw `sim(user, slug)` similarity, before `c_user` weighting. */
178
+ /** Raw fused `sim(user, slug)`, before `c_user` weighting. */
158
179
  simUser: number;
159
- /** Raw `sim(assistant, slug)` similarity, before `c_assistant` weighting. */
180
+ /** Raw fused `sim(assistant, slug)`, before `c_assistant` weighting. */
160
181
  simAssistant: number;
161
- /** Raw `sim(now, slug)` similarity, before `c_now` weighting. */
182
+ /** Raw fused `sim(now, slug)`, before `c_now` weighting. */
162
183
  simNow: number;
184
+ /** Rerank delta `α · r_norm_u`; 0 outside the top-K pool. Applied to `A_o` weighted by `c_user`. */
185
+ simUserRerankBoost: number;
186
+ /** Rerank delta `α · r_norm_a`; 0 outside the top-K pool. Applied to `A_o` weighted by `c_assistant`. NOW skips rerank. */
187
+ simAssistantRerankBoost: number;
188
+ /** True when this slug was in the unified top-K rerank pool. Lets the inspector distinguish "cross-encoder normalised to 0" from "rerank skipped this slug." */
189
+ inRerankPool: boolean;
163
190
  }
164
191
 
165
- export interface ComputeOwnActivationResult {
192
+ interface ComputeOwnActivationResult {
166
193
  /** Final clamped own-activation value per slug. */
167
194
  activation: Map<string, number>;
168
195
  /** Per-slug breakdown of the inputs that fed into `activation`. */
@@ -171,21 +198,34 @@ export interface ComputeOwnActivationResult {
171
198
 
172
199
  /**
173
200
  * Apply the own-activation formula
174
- * A_o(n) = d · prev(n) + c_user · sim_u + c_assistant · sim_a + c_now · sim_n
175
- * over the candidate set. Returns a sparse map keyed by slug; slugs whose
176
- * computed value rounds to 0 are still included so callers can see the
177
- * candidate set explicitly. Also returns a per-slug breakdown of the raw
178
- * inputs (decayed prior + raw sims) so callers can render contribution
179
- * diagnostics without re-running the math.
201
+ * A_o(n) = d · prev(n)
202
+ * + c_user · sim_u + c_assistant · sim_a + c_now · sim_n
203
+ * + c_user · α · r_norm_u + c_assistant · α · r_norm_a
204
+ * over the candidate set, where the rerank terms only fire for slugs that
205
+ * land in the unified top-K-by-pre-rerank-A_o window. Returns a sparse map
206
+ * keyed by slug; slugs whose computed value rounds to 0 are still included
207
+ * so callers can see the candidate set explicitly. Also returns a per-slug
208
+ * breakdown of the raw inputs (decayed prior + raw sims + rerank deltas) so
209
+ * callers can render contribution diagnostics without re-running the math.
180
210
  *
181
211
  * The three `simBatch` calls run concurrently — they hit independent named
182
- * vectors and embed independent query texts.
212
+ * vectors and embed independent query texts. Cross-encoder rerank then runs
213
+ * once on the unified top-K (selected by pre-rerank A_o, not per-channel
214
+ * fused sim) so an entry strong in both channels can't double-boost itself
215
+ * past entries that only land in one channel.
183
216
  */
184
217
  export async function computeOwnActivation(
185
218
  params: ComputeOwnActivationParams,
186
219
  ): Promise<ComputeOwnActivationResult> {
187
- const { candidates, priorState, userText, assistantText, nowText, config } =
188
- params;
220
+ const {
221
+ candidates,
222
+ priorState,
223
+ userText,
224
+ assistantText,
225
+ nowText,
226
+ config,
227
+ signal,
228
+ } = params;
189
229
 
190
230
  const activation = new Map<string, number>();
191
231
  const breakdown = new Map<string, OwnActivationBreakdown>();
@@ -194,35 +234,127 @@ export async function computeOwnActivation(
194
234
  const { d, c_user, c_assistant, c_now } = config.memory.v2;
195
235
  const slugList = [...candidates];
196
236
 
237
+ // NOW context is structured (timestamps, current focus) — outside the
238
+ // cross-encoder's training distribution, so it never participates in rerank.
197
239
  const [simUser, simAssistant, simNow] = await Promise.all([
198
- simBatch(userText, slugList, config),
199
- simBatch(assistantText, slugList, config),
200
- simBatch(nowText, slugList, config),
240
+ simBatch(userText, slugList, config, { signal }),
241
+ simBatch(assistantText, slugList, config, { signal }),
242
+ simBatch(nowText, slugList, config, { signal }),
201
243
  ]);
202
244
 
203
- for (const slug of slugList) {
245
+ interface SlugInputs {
246
+ slug: string;
247
+ priorContribution: number;
248
+ simU: number;
249
+ simA: number;
250
+ simN: number;
251
+ /** Pre-rerank A_o; ranking signal for the unified rerank pool. */
252
+ preRerank: number;
253
+ }
254
+ const inputs: SlugInputs[] = slugList.map((slug) => {
204
255
  const prev = priorState?.state[slug] ?? 0;
205
256
  const simU = simUser.get(slug) ?? 0;
206
257
  const simA = simAssistant.get(slug) ?? 0;
207
258
  const simN = simNow.get(slug) ?? 0;
208
- const value = d * prev + c_user * simU + c_assistant * simA + c_now * simN;
209
- activation.set(slug, clampUnitInterval(value));
210
- breakdown.set(slug, {
211
- priorContribution: d * prev,
212
- simUser: simU,
213
- simAssistant: simA,
214
- simNow: simN,
259
+ const priorContribution = d * prev;
260
+ return {
261
+ slug,
262
+ priorContribution,
263
+ simU,
264
+ simA,
265
+ simN,
266
+ preRerank:
267
+ priorContribution + c_user * simU + c_assistant * simA + c_now * simN,
268
+ };
269
+ });
270
+
271
+ // Unified top-K by pre-rerank A_o. Both channels rerank against the **same**
272
+ // slug set, so a slug strong on user can't crowd out one strong on assistant
273
+ // by virtue of appearing in both per-channel top-Ks. Both channel queries
274
+ // ride in a single `rerankCandidates` call so the worker tokenizes and
275
+ // forward-passes them together — half the per-call overhead of two
276
+ // serialised round-trips.
277
+ let userRerankBoost: ReadonlyMap<string, number> = new Map();
278
+ let assistantRerankBoost: ReadonlyMap<string, number> = new Map();
279
+ let inPoolSet: ReadonlySet<string> = new Set();
280
+ const rerankCfg = config.memory.v2.rerank;
281
+ if (rerankCfg?.enabled) {
282
+ throwIfAborted(signal);
283
+ const topSlugs = inputs
284
+ .slice()
285
+ .sort((a, b) => b.preRerank - a.preRerank)
286
+ .slice(0, rerankCfg.top_k)
287
+ .map((e) => e.slug);
288
+ if (topSlugs.length > 0) {
289
+ inPoolSet = new Set(topSlugs);
290
+ const [userScores, assistantScores] = await rerankCandidates(
291
+ [userText, assistantText],
292
+ topSlugs,
293
+ config,
294
+ );
295
+ throwIfAborted(signal);
296
+ userRerankBoost = normalizeRerankScores(userScores, rerankCfg.alpha);
297
+ assistantRerankBoost = normalizeRerankScores(
298
+ assistantScores,
299
+ rerankCfg.alpha,
300
+ );
301
+ }
302
+ }
303
+
304
+ for (const e of inputs) {
305
+ const boostU = userRerankBoost.get(e.slug) ?? 0;
306
+ const boostA = assistantRerankBoost.get(e.slug) ?? 0;
307
+ activation.set(
308
+ e.slug,
309
+ clampUnitInterval(e.preRerank + c_user * boostU + c_assistant * boostA),
310
+ );
311
+ breakdown.set(e.slug, {
312
+ priorContribution: e.priorContribution,
313
+ simUser: e.simU,
314
+ simAssistant: e.simA,
315
+ simNow: e.simN,
316
+ simUserRerankBoost: boostU,
317
+ simAssistantRerankBoost: boostA,
318
+ inRerankPool: inPoolSet.has(e.slug),
215
319
  });
216
320
  }
217
321
 
218
322
  return { activation, breakdown };
219
323
  }
220
324
 
325
+ /**
326
+ * Per-batch normalisation: divide raw cross-encoder scores by the channel's
327
+ * own max and return `alpha · r_norm` per slug. Empty input or all-zero
328
+ * scores yield an empty Map so the channel contributes 0 boost.
329
+ */
330
+ function normalizeRerankScores(
331
+ rawScores: ReadonlyMap<string, number>,
332
+ alpha: number,
333
+ ): Map<string, number> {
334
+ const out = new Map<string, number>();
335
+ if (rawScores.size === 0) return out;
336
+ let maxScore = 0;
337
+ for (const v of rawScores.values()) {
338
+ if (v > maxScore) maxScore = v;
339
+ }
340
+ if (maxScore === 0) return out;
341
+ for (const [slug, raw] of rawScores) {
342
+ out.set(slug, alpha * (raw / maxScore));
343
+ }
344
+ return out;
345
+ }
346
+
347
+ function throwIfAborted(signal: AbortSignal | undefined): void {
348
+ if (signal?.aborted) {
349
+ throw new DOMException("Aborted", "AbortError");
350
+ }
351
+ }
352
+
221
353
  // ---------------------------------------------------------------------------
222
354
  // Spreading activation
223
355
  // ---------------------------------------------------------------------------
224
356
 
225
- export interface SpreadActivationResult {
357
+ interface SpreadActivationResult {
226
358
  /** Final activation value per slug after spreading. */
227
359
  final: Map<string, number>;
228
360
  /**
@@ -239,20 +371,25 @@ export interface SpreadActivationResult {
239
371
  * Apply 2-hop spreading activation with neighborhood normalization. Edges are
240
372
  * directed: an edge A→B means A's activation contributes to B's final value.
241
373
  *
242
- * A(n) = [ A_o(n) + k · Σ_{m∈in1(n)} A_o(m) + k² · Σ_{m∈in2(n)} A_o(m) ]
243
- * / (1 + k · #in1(n) + k² · #in2(n))
374
+ * A(n) = [ A_o(n) + Σ_{r: |active_inR(n)| > 0} k^r · L2(active_inR(n)) ]
375
+ * / [ 1 + Σ_{r: |active_inR(n)| > 0} k^r ]
376
+ *
377
+ * `active_inR(n)` is the subset of structural predecessors at hop `r` that
378
+ * also appear in `ownActivation` (i.e. made the candidate set). `L2(.)` is
379
+ * the quadratic mean √(mean(A_o²)) — a mild bias toward strong outliers
380
+ * compared to the arithmetic mean, without letting a single high-cosine
381
+ * predecessor dominate the way `max` would.
244
382
  *
245
- * For each candidate slug `n`, BFS walks `incoming` adjacency to gather
246
- * predecessors at distance 1, 2 (i.e. nodes from which a directed path of
247
- * that length leads into `n`). The denominator counts those structural
248
- * predecessors at each hop (whether or not they appear in `ownActivation`)
249
- * so a pure source — no incoming edges — collapses to `A == A_o`. Missing
250
- * predecessors contribute 0 to the numerator.
383
+ * Hops with **no** active predecessors are dropped from BOTH numerator and
384
+ * denominator so a high-in-degree hub with mostly-inactive neighbors stays
385
+ * near `A_o` instead of being crushed by the structural count. A pure
386
+ * source (no incoming edges, or every edge points at a non-candidate)
387
+ * collapses to `A == A_o`.
251
388
  *
252
- * Bounded in [0, 1]: with `A_o [0, 1]` and `k [0, 1]`, the numerator is
253
- * at most `1 + k · #in1 + k² · #in2` — exactly the denominator — so the
254
- * ratio is at most 1. `clampUnitInterval` guards against numerical drift
255
- * and out-of-range inputs.
389
+ * Bounded in [0, 1]: every `L2` term max active A_o 1, so the numerator
390
+ * is at most `1 + Σ k^r` — exactly the denominator — so the ratio is at most
391
+ * 1. `clampUnitInterval` guards against numerical drift and out-of-range
392
+ * inputs.
256
393
  *
257
394
  * Pure function — no I/O. Reads the precomputed `incoming` map from
258
395
  * `edgeIndex` and runs a per-source BFS bounded by `hops`.
@@ -282,22 +419,28 @@ export function spreadActivation(
282
419
  // hop-0 only via `numerator = ownValue`.
283
420
  const distance = bfsPredecessorDistances(edgeIndex.incoming, slug, hops);
284
421
 
422
+ // Bucket only predecessors that are in `ownActivation` (the candidate
423
+ // set). Structural predecessors that didn't make the cut contribute
424
+ // nothing — neither to the numerator nor the denominator — so hub
425
+ // in-degree alone never penalizes a node.
426
+ const ringActiveCounts: number[] = new Array(hops + 1).fill(0);
427
+ const ringSquareSums: number[] = new Array(hops + 1).fill(0);
428
+ for (const [predecessor, hop] of distance) {
429
+ const predValue = ownActivation.get(predecessor);
430
+ if (predValue === undefined) continue;
431
+ ringActiveCounts[hop] += 1;
432
+ ringSquareSums[hop] += predValue * predValue;
433
+ }
434
+
285
435
  let numerator = ownValue;
286
436
  let denominator = 1;
287
437
  let kPow = 1;
288
- // Accumulate per-hop contributions in a single pass. We need per-hop
289
- // counts to weight by k^r, so bucket as we go.
290
- const ringCounts: number[] = new Array(hops + 1).fill(0);
291
- const ringSums: number[] = new Array(hops + 1).fill(0);
292
- for (const [predecessor, hop] of distance) {
293
- ringCounts[hop] += 1;
294
- ringSums[hop] += ownActivation.get(predecessor) ?? 0;
295
- }
296
438
  for (let r = 1; r <= hops; r++) {
297
439
  kPow *= k;
298
- if (ringCounts[r] === 0) continue;
299
- numerator += kPow * ringSums[r];
300
- denominator += kPow * ringCounts[r];
440
+ if (ringActiveCounts[r] === 0) continue;
441
+ const rms = Math.sqrt(ringSquareSums[r] / ringActiveCounts[r]);
442
+ numerator += kPow * rms;
443
+ denominator += kPow;
301
444
  }
302
445
 
303
446
  const finalValue = clampUnitInterval(numerator / denominator);
@@ -347,7 +490,7 @@ function bfsPredecessorDistances(
347
490
  // Injection selection
348
491
  // ---------------------------------------------------------------------------
349
492
 
350
- export interface SelectInjectionsParams {
493
+ interface SelectInjectionsParams {
351
494
  /** Final activation map after spread. */
352
495
  A: ReadonlyMap<string, number>;
353
496
  /** Slugs already attached to a prior user message (with their turn). */
@@ -356,7 +499,7 @@ export interface SelectInjectionsParams {
356
499
  topK: number;
357
500
  }
358
501
 
359
- export interface SelectInjectionsResult {
502
+ interface SelectInjectionsResult {
360
503
  /** Top-K slugs by activation (descending), used for the cached top-now view. */
361
504
  topNow: string[];
362
505
  /**
@@ -390,172 +533,3 @@ export function selectInjections(
390
533
 
391
534
  return { topNow, toInject };
392
535
  }
393
-
394
- // ---------------------------------------------------------------------------
395
- // Skill autoinjection — candidate / activation / injection selection
396
- // ---------------------------------------------------------------------------
397
- //
398
- // Skills are stateless: there is no decay carry-over (`d · prev`), no
399
- // spreading activation, and no `everInjected` dedup. The agent re-presents
400
- // the top-K active skills every turn so it can drop or pick them up freely.
401
- // The pipeline therefore reduces to:
402
- // 1. ANN candidate selection against the dedicated skills collection.
403
- // 2. Pure similarity-only activation: A_skill = c_user·sim_u +
404
- // c_assistant·sim_a + c_now·sim_n, clamped to [0, 1].
405
- // 3. Top-K by activation, lexicographic tie-break, no injection delta.
406
- //
407
- // The activation coefficients are reused from `config.memory.v2.{c_user,
408
- // c_assistant, c_now}` — the design doc (§9) deliberately shares them with
409
- // concept-page activation rather than introducing parallel knobs.
410
-
411
- export interface SelectSkillCandidatesParams {
412
- userText: string;
413
- assistantText: string;
414
- nowText: string;
415
- config: AssistantConfig;
416
- /** Top-K size for the ANN query against `memory_v2_skills`. */
417
- topK: number;
418
- }
419
-
420
- /**
421
- * ANN top-K against the skills collection using the concatenated turn text.
422
- * Runs a single embedding pass over `concat(user, assistant, now)` and a
423
- * single hybrid Qdrant query — there is no prior-state carry-forward (skills
424
- * are stateless).
425
- *
426
- * Returns a `Set<string>` of skill ids that hit either channel. Empty when
427
- * the joined text is empty or `topK <= 0`.
428
- */
429
- export async function selectSkillCandidates(
430
- params: SelectSkillCandidatesParams,
431
- ): Promise<Set<string>> {
432
- const { userText, assistantText, nowText, config, topK } = params;
433
-
434
- const candidates = new Set<string>();
435
- if (topK <= 0) return candidates;
436
-
437
- const annQueryText = [userText, assistantText, nowText]
438
- .filter((s) => s.length > 0)
439
- .join("\n");
440
- if (annQueryText.length === 0) return candidates;
441
-
442
- const denseResult = await embedWithBackend(config, [annQueryText]);
443
- const dense = denseResult.vectors[0];
444
- const sparse = generateSparseEmbedding(annQueryText);
445
- const hits = await hybridQuerySkills(dense, sparse, topK);
446
- for (const hit of hits) candidates.add(hit.id);
447
-
448
- return candidates;
449
- }
450
-
451
- export interface ComputeSkillActivationParams {
452
- candidates: ReadonlySet<string>;
453
- userText: string;
454
- assistantText: string;
455
- nowText: string;
456
- config: AssistantConfig;
457
- }
458
-
459
- /**
460
- * Per-skill breakdown of the raw similarity inputs, captured before any
461
- * coefficient weighting. Skills have no decay term, so the breakdown is just
462
- * the three raw sims. Surfaced for telemetry / inspector views.
463
- */
464
- export interface SkillActivationBreakdown {
465
- /** Raw `sim(user, skill)` similarity, before `c_user` weighting. */
466
- simUser: number;
467
- /** Raw `sim(assistant, skill)` similarity, before `c_assistant` weighting. */
468
- simAssistant: number;
469
- /** Raw `sim(now, skill)` similarity, before `c_now` weighting. */
470
- simNow: number;
471
- }
472
-
473
- export interface ComputeSkillActivationResult {
474
- /** Final clamped skill-activation value per id. */
475
- activation: Map<string, number>;
476
- /** Per-skill breakdown of the raw sim inputs that fed into `activation`. */
477
- breakdown: Map<string, SkillActivationBreakdown>;
478
- }
479
-
480
- /**
481
- * Apply the skill-side activation formula (no decay carry-over, no spread):
482
- * A_skill(s) = clamp01(c_user · sim_u + c_assistant · sim_a + c_now · sim_n)
483
- *
484
- * Reuses the activation coefficients from `config.memory.v2`. The three
485
- * `simSkillBatch` calls run concurrently — they hit independent named
486
- * vectors and embed independent query texts. Returns a per-skill breakdown
487
- * of the raw sims alongside the activation map so callers can render
488
- * contribution diagnostics without re-running the math.
489
- *
490
- * Empty candidates short-circuits to an empty map without touching the
491
- * embedding backend or Qdrant.
492
- */
493
- export async function computeSkillActivation(
494
- params: ComputeSkillActivationParams,
495
- ): Promise<ComputeSkillActivationResult> {
496
- const { candidates, userText, assistantText, nowText, config } = params;
497
-
498
- const activation = new Map<string, number>();
499
- const breakdown = new Map<string, SkillActivationBreakdown>();
500
- if (candidates.size === 0) return { activation, breakdown };
501
-
502
- const { c_user, c_assistant, c_now } = config.memory.v2;
503
- const idList = [...candidates];
504
-
505
- const [simUser, simAssistant, simNow] = await Promise.all([
506
- simSkillBatch(userText, idList, config),
507
- simSkillBatch(assistantText, idList, config),
508
- simSkillBatch(nowText, idList, config),
509
- ]);
510
-
511
- for (const id of idList) {
512
- const simU = simUser.get(id) ?? 0;
513
- const simA = simAssistant.get(id) ?? 0;
514
- const simN = simNow.get(id) ?? 0;
515
- const value = c_user * simU + c_assistant * simA + c_now * simN;
516
- activation.set(id, clampUnitInterval(value));
517
- breakdown.set(id, { simUser: simU, simAssistant: simA, simNow: simN });
518
- }
519
-
520
- return { activation, breakdown };
521
- }
522
-
523
- export interface SelectSkillInjectionsParams {
524
- /** Final skill activation map. */
525
- A: ReadonlyMap<string, number>;
526
- /** Cap on the per-turn skill slate, e.g. `config.memory.v2.skills_top_k`. */
527
- topK: number;
528
- }
529
-
530
- export interface SelectSkillInjectionsResult {
531
- /**
532
- * Top-K skill ids by activation (descending), tie-broken lexicographically.
533
- * Skills are re-presented every turn — no `toInject` delta — so the caller
534
- * uses this list verbatim to render the skill slate.
535
- */
536
- topNow: string[];
537
- }
538
-
539
- /**
540
- * Pick the top-K skill ids by activation (descending; stable on ties via id
541
- * lexicographic order). Skills are stateless — there is no `everInjected`
542
- * dedup, so the same id can appear on consecutive turns.
543
- *
544
- * Returns `{ topNow: [] }` for an empty activation map or `topK <= 0`.
545
- */
546
- export function selectSkillInjections(
547
- params: SelectSkillInjectionsParams,
548
- ): SelectSkillInjectionsResult {
549
- const { A, topK } = params;
550
- if (A.size === 0 || topK <= 0) {
551
- return { topNow: [] };
552
- }
553
-
554
- const ranked = [...A.entries()].sort(([idA, valA], [idB, valB]) => {
555
- if (valB !== valA) return valB - valA; // higher activation first
556
- return idA < idB ? -1 : idA > idB ? 1 : 0; // stable tie-break
557
- });
558
-
559
- const topNow = ranked.slice(0, topK).map(([id]) => id);
560
- return { topNow };
561
- }