@vellumai/assistant 0.7.3 → 0.8.1

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 (778) hide show
  1. package/AGENTS.md +11 -0
  2. package/ARCHITECTURE.md +29 -28
  3. package/Dockerfile +6 -4
  4. package/README.md +2 -2
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  6. package/bun.lock +3 -0
  7. package/docker-entrypoint.sh +16 -0
  8. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  9. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  10. package/eslint.config.mjs +12 -0
  11. package/knip.json +3 -1
  12. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  13. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  14. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  15. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  16. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  17. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  19. package/openapi.yaml +4126 -959
  20. package/package.json +5 -1
  21. package/scripts/generate-openapi.ts +52 -4
  22. package/scripts/sync-llm-catalog.ts +165 -0
  23. package/scripts/sync-web-search-catalog.ts +107 -0
  24. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  25. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  26. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  27. package/src/__tests__/anthropic-provider.test.ts +92 -2
  28. package/src/__tests__/app-control-flow.test.ts +7 -0
  29. package/src/__tests__/approval-cascade.test.ts +8 -16
  30. package/src/__tests__/approval-routes-http.test.ts +6 -0
  31. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  32. package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
  33. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  34. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  35. package/src/__tests__/btw-routes.test.ts +1 -0
  36. package/src/__tests__/call-constants.test.ts +10 -1
  37. package/src/__tests__/call-controller.test.ts +127 -0
  38. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  39. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  40. package/src/__tests__/channel-policy.test.ts +12 -0
  41. package/src/__tests__/checker.test.ts +89 -0
  42. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
  43. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  44. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  45. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  46. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
  48. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  49. package/src/__tests__/config-schema.test.ts +14 -3
  50. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  51. package/src/__tests__/config-set-route.test.ts +198 -0
  52. package/src/__tests__/config-watcher.test.ts +6 -0
  53. package/src/__tests__/contacts-tools.test.ts +51 -199
  54. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  55. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  56. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  57. package/src/__tests__/context-search-fanout.test.ts +20 -157
  58. package/src/__tests__/context-search-memory-source.test.ts +3 -26
  59. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  60. package/src/__tests__/context-search-types.test.ts +7 -2
  61. package/src/__tests__/context-window-manager.test.ts +389 -1
  62. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
  63. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  64. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  65. package/src/__tests__/conversation-agent-loop.test.ts +3 -3
  66. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  67. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  68. package/src/__tests__/conversation-error.test.ts +38 -0
  69. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  70. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  71. package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
  72. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  74. package/src/__tests__/conversation-process-callsite.test.ts +22 -7
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
  76. package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
  77. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  78. package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
  79. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  81. package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
  82. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
  83. package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
  84. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
  85. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  86. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  87. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  88. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  89. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  90. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  91. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  92. package/src/__tests__/filing-service.test.ts +25 -22
  93. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  94. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  95. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  96. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
  97. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  98. package/src/__tests__/heartbeat-service.test.ts +50 -233
  99. package/src/__tests__/history-repair.test.ts +89 -0
  100. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  101. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  102. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  103. package/src/__tests__/host-browser-routes.test.ts +325 -33
  104. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  105. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  106. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  107. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  108. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  109. package/src/__tests__/injector-chain.test.ts +24 -16
  110. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  111. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  112. package/src/__tests__/install-skill-routing.test.ts +2 -2
  113. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
  114. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  115. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  116. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  117. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  118. package/src/__tests__/llm-resolver.test.ts +46 -0
  119. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  120. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  121. package/src/__tests__/mcp-cli.test.ts +182 -220
  122. package/src/__tests__/mcp-health-check.test.ts +56 -27
  123. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  124. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  125. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  126. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  127. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  128. package/src/__tests__/oauth-cli.test.ts +38 -1888
  129. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  130. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  131. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  132. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  133. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  134. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  135. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  136. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  137. package/src/__tests__/plugin-types.test.ts +13 -11
  138. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  139. package/src/__tests__/profile-entry-status.test.ts +43 -0
  140. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  141. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  142. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  143. package/src/__tests__/relay-server.test.ts +164 -2
  144. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  145. package/src/__tests__/schedule-retry.test.ts +56 -4
  146. package/src/__tests__/schedule-routes.test.ts +104 -0
  147. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  148. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  149. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  150. package/src/__tests__/scheduler-wake.test.ts +0 -63
  151. package/src/__tests__/secret-allowlist.test.ts +1 -0
  152. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  153. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  154. package/src/__tests__/secret-response-routing.test.ts +7 -5
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  156. package/src/__tests__/server-history-render.test.ts +82 -0
  157. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  158. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  159. package/src/__tests__/skill-include-graph.test.ts +31 -0
  160. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  161. package/src/__tests__/skill-load-tool.test.ts +42 -16
  162. package/src/__tests__/skills.test.ts +39 -0
  163. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  164. package/src/__tests__/suggestion-routes.test.ts +3 -3
  165. package/src/__tests__/sync-message-contract.test.ts +63 -0
  166. package/src/__tests__/task-scheduler.test.ts +88 -23
  167. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  168. package/src/__tests__/tool-executor.test.ts +155 -0
  169. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  170. package/src/__tests__/usage-cli.test.ts +11 -73
  171. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  172. package/src/__tests__/vercel-config.test.ts +168 -0
  173. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  174. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  175. package/src/__tests__/web-search.test.ts +303 -2
  176. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  177. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  178. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
  179. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  180. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  181. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  182. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  183. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  184. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  185. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  186. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  187. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
  188. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  189. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  190. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  191. package/src/acp/resolve-agent.test.ts +25 -0
  192. package/src/acp/resolve-agent.ts +13 -2
  193. package/src/acp/session-manager.ts +14 -0
  194. package/src/agent/loop.ts +11 -0
  195. package/src/approvals/guardian-decision-primitive.ts +0 -13
  196. package/src/approvals/guardian-request-resolvers.ts +19 -102
  197. package/src/calls/call-constants.ts +5 -8
  198. package/src/calls/call-controller.ts +130 -67
  199. package/src/calls/relay-server.ts +42 -1
  200. package/src/calls/relay-setup-router.ts +36 -0
  201. package/src/calls/types.ts +1 -0
  202. package/src/calls/voice-session-bridge.ts +24 -5
  203. package/src/channels/config.ts +14 -1
  204. package/src/channels/types.ts +1 -0
  205. package/src/cli/AGENTS.md +164 -4
  206. package/src/cli/__tests__/notifications.test.ts +54 -0
  207. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  208. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  209. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  210. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  211. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  212. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  213. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  214. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  215. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  216. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  217. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  218. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  219. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  220. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  221. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  222. package/src/cli/commands/__tests__/status.test.ts +249 -0
  223. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  224. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  225. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  226. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  227. package/src/cli/commands/attachment.ts +8 -3
  228. package/src/cli/commands/audit.ts +95 -64
  229. package/src/cli/commands/auth.ts +61 -58
  230. package/src/cli/commands/avatar.ts +276 -390
  231. package/src/cli/commands/backup.ts +409 -505
  232. package/src/cli/commands/bash.ts +9 -5
  233. package/src/cli/commands/browser.ts +28 -9
  234. package/src/cli/commands/cache.ts +9 -4
  235. package/src/cli/commands/changelog.ts +414 -0
  236. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  237. package/src/cli/commands/clients.ts +8 -3
  238. package/src/cli/commands/completions.ts +9 -9
  239. package/src/cli/commands/config.ts +102 -72
  240. package/src/cli/commands/contacts.ts +575 -696
  241. package/src/cli/commands/conversations-defer.ts +17 -69
  242. package/src/cli/commands/conversations-import.ts +90 -253
  243. package/src/cli/commands/conversations.ts +346 -436
  244. package/src/cli/commands/credential-execution.ts +9 -6
  245. package/src/cli/commands/credentials.ts +456 -736
  246. package/src/cli/commands/domain.ts +128 -206
  247. package/src/cli/commands/email.ts +606 -794
  248. package/src/cli/commands/gateway.ts +8 -1
  249. package/src/cli/commands/image-generation.ts +157 -205
  250. package/src/cli/commands/inference-providers.ts +352 -0
  251. package/src/cli/commands/inference-session.ts +415 -0
  252. package/src/cli/commands/inference.ts +87 -65
  253. package/src/cli/commands/keys.ts +8 -3
  254. package/src/cli/commands/mcp.ts +103 -287
  255. package/src/cli/commands/memory-v2.ts +163 -517
  256. package/src/cli/commands/notifications.ts +33 -7
  257. package/src/cli/commands/oauth/apps.ts +292 -261
  258. package/src/cli/commands/oauth/connect.ts +182 -345
  259. package/src/cli/commands/oauth/disconnect.ts +16 -215
  260. package/src/cli/commands/oauth/index.ts +49 -45
  261. package/src/cli/commands/oauth/mode.ts +43 -199
  262. package/src/cli/commands/oauth/ping.ts +17 -125
  263. package/src/cli/commands/oauth/providers.ts +732 -921
  264. package/src/cli/commands/oauth/request.ts +60 -350
  265. package/src/cli/commands/oauth/shared.ts +11 -121
  266. package/src/cli/commands/oauth/status.ts +31 -121
  267. package/src/cli/commands/oauth/token.ts +13 -55
  268. package/src/cli/commands/pending.ts +19 -10
  269. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  270. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  271. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  272. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  273. package/src/cli/commands/platform/connect.ts +16 -80
  274. package/src/cli/commands/platform/disconnect.ts +14 -112
  275. package/src/cli/commands/platform/index.ts +177 -246
  276. package/src/cli/commands/routes.ts +153 -336
  277. package/src/cli/commands/sequence.ts +316 -360
  278. package/src/cli/commands/skills.ts +449 -671
  279. package/src/cli/commands/status.ts +58 -37
  280. package/src/cli/commands/stt.ts +94 -262
  281. package/src/cli/commands/task.ts +14 -40
  282. package/src/cli/commands/trust.ts +8 -3
  283. package/src/cli/commands/tts.ts +162 -167
  284. package/src/cli/commands/ui.ts +35 -42
  285. package/src/cli/commands/usage.ts +188 -126
  286. package/src/cli/commands/watchers.ts +8 -3
  287. package/src/cli/commands/webhooks.ts +99 -193
  288. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  289. package/src/cli/lib/daemon-credential-client.ts +4 -5
  290. package/src/cli/lib/nested-value.ts +44 -0
  291. package/src/cli/lib/open-browser.ts +36 -0
  292. package/src/cli/lib/register-command.ts +19 -0
  293. package/src/cli/lib/time-ago.ts +34 -0
  294. package/src/cli/program.ts +2 -4
  295. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  296. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  297. package/src/cli/utils/conversation-id.ts +30 -0
  298. package/src/cli/utils/parse-duration.ts +41 -0
  299. package/src/config/acp-defaults.test.ts +5 -1
  300. package/src/config/acp-defaults.ts +11 -4
  301. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  302. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  303. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  304. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  305. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  306. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  308. package/src/config/bundled-tool-registry.ts +0 -2
  309. package/src/config/feature-flag-registry.json +17 -17
  310. package/src/config/llm-resolver.ts +16 -1
  311. package/src/config/loader.ts +148 -33
  312. package/src/config/raw-config-utils.ts +2 -30
  313. package/src/config/schema.ts +4 -0
  314. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  315. package/src/config/schemas/call-site-catalog.ts +29 -7
  316. package/src/config/schemas/llm-request-logs.ts +57 -0
  317. package/src/config/schemas/llm.ts +52 -2
  318. package/src/config/schemas/memory-retrospective.ts +48 -0
  319. package/src/config/schemas/memory-v2.ts +33 -2
  320. package/src/config/schemas/memory.ts +4 -0
  321. package/src/config/schemas/services.ts +15 -12
  322. package/src/config/seed-inference-profiles.ts +195 -134
  323. package/src/contacts/contact-store.ts +0 -61
  324. package/src/context/window-manager.ts +191 -5
  325. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
  326. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  327. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  328. package/src/daemon/approval-generators.ts +23 -29
  329. package/src/daemon/config-watcher.ts +2 -0
  330. package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
  331. package/src/daemon/conversation-agent-loop.ts +140 -107
  332. package/src/daemon/conversation-error.ts +21 -0
  333. package/src/daemon/conversation-lifecycle.ts +68 -13
  334. package/src/daemon/conversation-process.ts +36 -19
  335. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  336. package/src/daemon/conversation-slash.ts +175 -23
  337. package/src/daemon/conversation-store.ts +17 -10
  338. package/src/daemon/conversation-surfaces.ts +92 -26
  339. package/src/daemon/conversation-tool-setup.ts +33 -19
  340. package/src/daemon/conversation.ts +49 -10
  341. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  342. package/src/daemon/guardian-action-generators.ts +7 -22
  343. package/src/daemon/handlers/config-model.ts +8 -126
  344. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  345. package/src/daemon/handlers/config-vercel.ts +3 -1
  346. package/src/daemon/handlers/shared.ts +26 -0
  347. package/src/daemon/handlers/skills.ts +84 -5
  348. package/src/daemon/history-repair.ts +33 -6
  349. package/src/daemon/host-app-control-proxy.ts +44 -19
  350. package/src/daemon/host-bash-proxy.ts +85 -158
  351. package/src/daemon/host-browser-proxy.ts +97 -36
  352. package/src/daemon/host-cu-proxy.ts +1 -1
  353. package/src/daemon/host-file-proxy.ts +1 -1
  354. package/src/daemon/host-proxy-base.ts +13 -1
  355. package/src/daemon/host-proxy-preactivation.ts +25 -1
  356. package/src/daemon/host-transfer-proxy.ts +2 -2
  357. package/src/daemon/identity-helpers.ts +19 -0
  358. package/src/daemon/lifecycle.ts +128 -114
  359. package/src/daemon/meet-host-supervisor.ts +15 -15
  360. package/src/daemon/memory-v2-startup.ts +62 -14
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/bookmarks.ts +18 -0
  363. package/src/daemon/message-types/conversations.ts +12 -9
  364. package/src/daemon/message-types/messages.ts +28 -2
  365. package/src/daemon/message-types/sync.ts +60 -0
  366. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  367. package/src/daemon/pkb-reminder-builder.ts +21 -7
  368. package/src/daemon/process-message.ts +56 -23
  369. package/src/daemon/server.ts +23 -18
  370. package/src/daemon/shutdown-handlers.ts +0 -2
  371. package/src/daemon/tool-setup-types.ts +9 -0
  372. package/src/daemon/tool-side-effects.ts +6 -4
  373. package/src/daemon/wake-target-adapter.ts +11 -0
  374. package/src/documents/document-store.ts +35 -1
  375. package/src/export/transcript-formatter.ts +61 -2
  376. package/src/filing/filing-service.ts +42 -56
  377. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  378. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  379. package/src/heartbeat/heartbeat-service.ts +149 -128
  380. package/src/home/__tests__/feed-types.test.ts +63 -131
  381. package/src/home/__tests__/feed-writer.test.ts +77 -278
  382. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  383. package/src/home/feed-types.ts +19 -73
  384. package/src/home/feed-writer.ts +25 -156
  385. package/src/home/post-connect-feed.ts +1 -3
  386. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  387. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  388. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  389. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  390. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  391. package/src/ipc/assistant-server.ts +148 -42
  392. package/src/ipc/cli-client.ts +370 -50
  393. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  394. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  395. package/src/ipc/skill-routes/events.ts +30 -3
  396. package/src/ipc/skill-server.ts +99 -42
  397. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  398. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  399. package/src/live-voice/live-voice-session-manager.ts +11 -4
  400. package/src/live-voice/live-voice-session.ts +14 -6
  401. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  402. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  403. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  404. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  405. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
  406. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  407. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  408. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  409. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  412. package/src/memory/bookmark-crud.ts +179 -0
  413. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  414. package/src/memory/context-search/agent-protocol.ts +5 -1
  415. package/src/memory/context-search/agent-runner.ts +60 -85
  416. package/src/memory/context-search/limits.ts +1 -4
  417. package/src/memory/context-search/search.ts +23 -113
  418. package/src/memory/context-search/sources/conversations.ts +18 -6
  419. package/src/memory/context-search/sources/memory-v2.ts +40 -31
  420. package/src/memory/context-search/sources/memory.ts +9 -2
  421. package/src/memory/context-search/sources/workspace.ts +13 -10
  422. package/src/memory/context-search/types.ts +1 -1
  423. package/src/memory/conversation-bootstrap.ts +11 -0
  424. package/src/memory/conversation-crud.ts +312 -10
  425. package/src/memory/conversation-queries.ts +9 -5
  426. package/src/memory/conversation-title-service.ts +1 -0
  427. package/src/memory/conversation-types.ts +16 -0
  428. package/src/memory/db-init.ts +14 -0
  429. package/src/memory/embedding-backend.ts +2 -1
  430. package/src/memory/embedding-runtime-manager.ts +1 -2
  431. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
  432. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  433. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  434. package/src/memory/graph/conversation-graph-memory.ts +108 -14
  435. package/src/memory/graph/extraction.ts +4 -0
  436. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  437. package/src/memory/graph/graph-search.test.ts +6 -5
  438. package/src/memory/graph/graph-search.ts +3 -4
  439. package/src/memory/graph/retriever.test.ts +12 -7
  440. package/src/memory/graph/retriever.ts +4 -5
  441. package/src/memory/graph/tool-handlers.ts +20 -11
  442. package/src/memory/graph/tools.ts +48 -9
  443. package/src/memory/indexer.ts +18 -2
  444. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
  445. package/src/memory/jobs/embed-concept-page.ts +261 -89
  446. package/src/memory/jobs-store.ts +51 -1
  447. package/src/memory/jobs-worker.ts +60 -7
  448. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  449. package/src/memory/llm-request-log-source-local.ts +26 -0
  450. package/src/memory/llm-request-log-source.ts +97 -0
  451. package/src/memory/llm-request-log-store.ts +1 -1
  452. package/src/memory/memory-retrospective-constants.ts +13 -0
  453. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  454. package/src/memory/memory-retrospective-job.ts +351 -0
  455. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  456. package/src/memory/memory-retrospective-state.ts +162 -0
  457. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  458. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  459. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  460. package/src/memory/message-content.ts +38 -1
  461. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  462. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  463. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  464. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  465. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  466. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  467. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  468. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  469. package/src/memory/migrations/243-provider-connections.ts +68 -0
  470. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  471. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  472. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  473. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  474. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  475. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  476. package/src/memory/migrations/index.ts +7 -0
  477. package/src/memory/pkb/pkb-search.test.ts +6 -5
  478. package/src/memory/pkb/pkb-search.ts +4 -5
  479. package/src/memory/published-pages-store.ts +16 -0
  480. package/src/memory/qdrant-client.ts +3 -0
  481. package/src/memory/schema/bookmarks.ts +38 -0
  482. package/src/memory/schema/conversations.ts +2 -0
  483. package/src/memory/schema/index.ts +2 -0
  484. package/src/memory/schema/inference.ts +29 -0
  485. package/src/memory/schema/memory-core.ts +9 -0
  486. package/src/memory/search/semantic.ts +5 -9
  487. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  488. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  489. package/src/memory/v2/__tests__/activation.test.ts +46 -9
  490. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  491. package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
  492. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  493. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  494. package/src/memory/v2/__tests__/injection.test.ts +768 -33
  495. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  496. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  497. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  498. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  499. package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
  500. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  501. package/src/memory/v2/__tests__/router.test.ts +516 -0
  502. package/src/memory/v2/__tests__/sim.test.ts +163 -8
  503. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  504. package/src/memory/v2/__tests__/static-context.test.ts +8 -35
  505. package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
  506. package/src/memory/v2/activation-store.ts +34 -5
  507. package/src/memory/v2/activation.ts +40 -27
  508. package/src/memory/v2/backfill-jobs.ts +17 -84
  509. package/src/memory/v2/consolidation-job.ts +92 -86
  510. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  511. package/src/memory/v2/injection.ts +466 -115
  512. package/src/memory/v2/migration.ts +117 -20
  513. package/src/memory/v2/page-index.ts +191 -0
  514. package/src/memory/v2/page-store.ts +42 -0
  515. package/src/memory/v2/prompts/consolidation.ts +14 -7
  516. package/src/memory/v2/prompts/router.ts +192 -0
  517. package/src/memory/v2/qdrant.ts +307 -133
  518. package/src/memory/v2/reranker.ts +14 -7
  519. package/src/memory/v2/router.ts +322 -0
  520. package/src/memory/v2/sim.ts +88 -34
  521. package/src/memory/v2/skill-store.ts +118 -29
  522. package/src/memory/v2/static-context.ts +20 -17
  523. package/src/memory/v2/sweep-job.ts +127 -102
  524. package/src/memory/v2/types.ts +16 -5
  525. package/src/memory/validation.ts +13 -0
  526. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  527. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  528. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  529. package/src/notifications/adapters/platform.ts +171 -0
  530. package/src/notifications/conversation-pairing.ts +2 -2
  531. package/src/notifications/copy-composer.ts +61 -12
  532. package/src/notifications/decision-engine.ts +46 -0
  533. package/src/notifications/destination-resolver.ts +21 -0
  534. package/src/notifications/emit-signal.ts +28 -1
  535. package/src/notifications/home-feed-side-effect.ts +111 -0
  536. package/src/notifications/signal.ts +5 -0
  537. package/src/permissions/checker.ts +12 -0
  538. package/src/permissions/gateway-threshold-reader.ts +116 -8
  539. package/src/permissions/ipc-risk-types.ts +2 -0
  540. package/src/permissions/prompter.ts +86 -96
  541. package/src/permissions/secret-prompter.ts +31 -31
  542. package/src/plugin-api/index.ts +13 -0
  543. package/src/plugin-api/package.json +12 -0
  544. package/src/plugin-api/types.ts +62 -0
  545. package/src/plugins/defaults/injectors.ts +20 -5
  546. package/src/plugins/external-plugin-loader.ts +294 -0
  547. package/src/plugins/types.ts +46 -30
  548. package/src/plugins/user-loader.ts +64 -41
  549. package/src/proactive-artifact/job.test.ts +63 -8
  550. package/src/proactive-artifact/job.ts +20 -2
  551. package/src/proactive-artifact/message-copy.ts +18 -1
  552. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  553. package/src/proactive-artifact/trigger-state.ts +4 -0
  554. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  555. package/src/prompts/system-prompt.ts +22 -1
  556. package/src/prompts/templates/SOUL.md +13 -28
  557. package/src/prompts/update-bulletin-job.ts +61 -73
  558. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  559. package/src/providers/__tests__/inference.test.ts +288 -0
  560. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  561. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  562. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  563. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  564. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  565. package/src/providers/anthropic/client.ts +95 -26
  566. package/src/providers/call-site-routing.ts +94 -16
  567. package/src/providers/connection-resolution.ts +163 -0
  568. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  569. package/src/providers/inference/adapter-factory.ts +173 -0
  570. package/src/providers/inference/auth.ts +112 -0
  571. package/src/providers/inference/backfill.ts +196 -0
  572. package/src/providers/inference/connections.ts +356 -0
  573. package/src/providers/inference/resolve-auth.ts +65 -0
  574. package/src/providers/model-catalog.ts +104 -6
  575. package/src/providers/openai/responses-provider.ts +4 -2
  576. package/src/providers/provider-env-vars.ts +17 -7
  577. package/src/providers/provider-secret-catalog.ts +49 -30
  578. package/src/providers/provider-send-message.ts +41 -20
  579. package/src/providers/registry.ts +143 -159
  580. package/src/providers/retry.ts +18 -10
  581. package/src/providers/search-provider-catalog.ts +121 -0
  582. package/src/runtime/AGENTS.md +18 -5
  583. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  584. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  585. package/src/runtime/actor-trust-resolver.ts +32 -10
  586. package/src/runtime/agent-wake.ts +35 -6
  587. package/src/runtime/assistant-event-hub.ts +3 -85
  588. package/src/runtime/auth/route-policy.ts +304 -8
  589. package/src/runtime/auth/same-actor.ts +2 -0
  590. package/src/runtime/background-job-runner.ts +339 -0
  591. package/src/runtime/btw-sidechain.ts +1 -0
  592. package/src/runtime/channel-approvals.ts +3 -2
  593. package/src/runtime/guardian-reply-router.ts +0 -10
  594. package/src/runtime/http-router.ts +36 -1
  595. package/src/runtime/http-server.ts +31 -5
  596. package/src/runtime/http-types.ts +2 -0
  597. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  598. package/src/runtime/middleware/request-logger.ts +62 -1
  599. package/src/runtime/pending-interactions.ts +19 -15
  600. package/src/runtime/pre-first-message-gate.ts +83 -0
  601. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  602. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  603. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  604. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  605. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  606. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  607. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  608. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  609. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  610. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  611. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  612. package/src/runtime/routes/acp-routes.ts +10 -8
  613. package/src/runtime/routes/app-management-routes.ts +228 -3
  614. package/src/runtime/routes/approval-routes.ts +7 -21
  615. package/src/runtime/routes/audit-routes.ts +43 -0
  616. package/src/runtime/routes/auth-routes.ts +72 -0
  617. package/src/runtime/routes/avatar-routes.ts +273 -20
  618. package/src/runtime/routes/backup-routes.ts +406 -2
  619. package/src/runtime/routes/bookmark-routes.ts +154 -0
  620. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  621. package/src/runtime/routes/consolidation-routes.ts +8 -9
  622. package/src/runtime/routes/contact-routes.ts +0 -160
  623. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  624. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  625. package/src/runtime/routes/conversation-query-routes.ts +373 -82
  626. package/src/runtime/routes/conversation-routes.ts +31 -10
  627. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  628. package/src/runtime/routes/credential-routes.ts +540 -0
  629. package/src/runtime/routes/debug-bash-routes.ts +2 -0
  630. package/src/runtime/routes/debug-routes.ts +2 -2
  631. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  632. package/src/runtime/routes/domain-routes.ts +167 -0
  633. package/src/runtime/routes/email-routes.ts +603 -0
  634. package/src/runtime/routes/errors.ts +2 -2
  635. package/src/runtime/routes/events-routes.ts +192 -0
  636. package/src/runtime/routes/filing-routes.ts +2 -3
  637. package/src/runtime/routes/home-feed-routes.ts +6 -78
  638. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  639. package/src/runtime/routes/host-browser-routes.ts +103 -22
  640. package/src/runtime/routes/http-adapter.ts +2 -0
  641. package/src/runtime/routes/identity-routes.ts +5 -0
  642. package/src/runtime/routes/image-generation-routes.ts +99 -0
  643. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  644. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  645. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  646. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
  647. package/src/runtime/routes/index.ts +36 -0
  648. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  649. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  650. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  651. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  652. package/src/runtime/routes/inference-send-routes.ts +115 -0
  653. package/src/runtime/routes/integrations/twilio.ts +1 -0
  654. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  655. package/src/runtime/routes/memory-item-routes.test.ts +3 -9
  656. package/src/runtime/routes/memory-item-routes.ts +5 -6
  657. package/src/runtime/routes/memory-v2-routes.ts +105 -404
  658. package/src/runtime/routes/notification-routes.ts +2 -0
  659. package/src/runtime/routes/oauth-apps.ts +112 -7
  660. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  661. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  662. package/src/runtime/routes/oauth-providers.ts +298 -8
  663. package/src/runtime/routes/platform-routes.ts +336 -0
  664. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  665. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  666. package/src/runtime/routes/playground/state.ts +2 -1
  667. package/src/runtime/routes/publish-routes.ts +221 -0
  668. package/src/runtime/routes/schedule-routes.ts +82 -0
  669. package/src/runtime/routes/sequence-routes.ts +291 -0
  670. package/src/runtime/routes/settings-routes.ts +2 -10
  671. package/src/runtime/routes/skills-routes.ts +31 -1
  672. package/src/runtime/routes/stt-routes.ts +240 -3
  673. package/src/runtime/routes/surface-action-routes.ts +43 -7
  674. package/src/runtime/routes/tts-routes.ts +67 -0
  675. package/src/runtime/routes/types.ts +32 -0
  676. package/src/runtime/routes/user-routes-cli.ts +243 -0
  677. package/src/runtime/routes/webhook-routes.ts +165 -0
  678. package/src/runtime/sync/resource-sync-events.ts +25 -0
  679. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  680. package/src/runtime/sync/sync-publisher.ts +21 -0
  681. package/src/schedule/scheduler.ts +200 -123
  682. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  683. package/src/security/secret-patterns.ts +3 -0
  684. package/src/sequence/engine.ts +38 -40
  685. package/src/skills/include-graph.ts +35 -13
  686. package/src/subagent/manager.ts +20 -15
  687. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  688. package/src/tools/browser/browser-execution.ts +15 -4
  689. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  690. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  691. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  692. package/src/tools/browser/cdp-client/factory.ts +66 -5
  693. package/src/tools/browser/runtime-check.ts +77 -0
  694. package/src/tools/document/document-tool.ts +20 -0
  695. package/src/tools/executor.ts +18 -2
  696. package/src/tools/memory/register.test.ts +10 -8
  697. package/src/tools/memory/register.ts +9 -1
  698. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  699. package/src/tools/network/web-search.ts +280 -37
  700. package/src/tools/permission-checker.ts +28 -5
  701. package/src/tools/skills/load.ts +24 -20
  702. package/src/tools/subagent/spawn.ts +3 -3
  703. package/src/tools/terminal/shell.ts +44 -0
  704. package/src/tools/tool-name-aliases.ts +19 -0
  705. package/src/tools/types.ts +19 -1
  706. package/src/usage/attribution.ts +3 -2
  707. package/src/util/pricing.ts +86 -160
  708. package/src/watcher/__tests__/engine.test.ts +301 -0
  709. package/src/watcher/constants.ts +7 -0
  710. package/src/watcher/engine.ts +90 -90
  711. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  712. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  713. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  714. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
  715. package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
  716. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  717. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  718. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  719. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  720. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  721. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  722. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  723. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  724. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  725. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  726. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  727. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  728. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  729. package/src/workspace/migrations/registry.ts +28 -0
  730. package/src/workspace/migrations/runner.ts +13 -2
  731. package/src/workspace/migrations/types.ts +13 -3
  732. package/src/workspace/provider-commit-message-generator.ts +3 -2
  733. package/src/__tests__/context-search-pkb-source.test.ts +0 -492
  734. package/src/__tests__/credentials-cli.test.ts +0 -1225
  735. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  736. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  737. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  738. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  739. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  740. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  741. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  742. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  743. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  744. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  745. package/src/cli/commands/autonomy.ts +0 -365
  746. package/src/cli/commands/memory.ts +0 -424
  747. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
  748. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  749. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  750. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  751. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  752. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  753. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  754. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  755. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  756. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  757. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  758. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  759. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  760. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  761. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  762. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  763. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  764. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  765. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  766. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  767. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  768. package/src/home/assistant-feed-authoring.ts +0 -135
  769. package/src/home/emit-feed-event.ts +0 -169
  770. package/src/home/feed-scheduler.ts +0 -281
  771. package/src/home/platform-gmail-digest.ts +0 -163
  772. package/src/home/rewrite-command-preview.ts +0 -66
  773. package/src/home/rewrite-feed-title.ts +0 -58
  774. package/src/home/rollup-producer.ts +0 -426
  775. package/src/memory/admin.ts +0 -326
  776. package/src/memory/context-search/sources/pkb.ts +0 -477
  777. package/src/memory/graph/compaction.ts +0 -299
  778. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -1,23 +1,13 @@
1
1
  /**
2
- * Memory v2 route definitions — backfill + validate + reembed-skills.
3
- *
4
- * Migrated from `ipc/routes/memory-v2-backfill.ts` and
5
- * `ipc/routes/memory-v2-validate.ts` into the shared ROUTES array.
2
+ * Memory v2 route definitions — backfill, validate, concept-page reads,
3
+ * reembed-skills, and the activation-log concept-frequency aggregator.
6
4
  */
5
+ import { stat } from "node:fs/promises";
6
+ import { join } from "node:path";
7
+
7
8
  import { z } from "zod";
8
9
 
9
- import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
10
10
  import { loadConfig } from "../../config/loader.js";
11
- import {
12
- applyCorrectionIfCalibrated,
13
- explainedVarianceRatio,
14
- fitAnisotropyCalibration,
15
- saveCalibration,
16
- } from "../../memory/anisotropy.js";
17
- import {
18
- embedWithBackend,
19
- selectEmbeddingBackend,
20
- } from "../../memory/embedding-backend.js";
21
11
  import {
22
12
  enqueueMemoryJob,
23
13
  type MemoryJobType,
@@ -32,26 +22,43 @@ import {
32
22
  validateEdgeTargets,
33
23
  } from "../../memory/v2/edge-index.js";
34
24
  import {
25
+ getConceptsDir,
35
26
  listPages,
36
27
  readPage,
37
28
  renderPageContent,
38
29
  } from "../../memory/v2/page-store.js";
39
- import {
40
- hybridQueryConceptPages,
41
- sampleConceptPageDenseVectors,
42
- } from "../../memory/v2/qdrant.js";
43
- import { effectiveWeights } from "../../memory/v2/sim.js";
44
30
  import { seedV2SkillEntries } from "../../memory/v2/skill-store.js";
45
- import {
46
- generateBm25QueryEmbedding,
47
- getConceptPageCorpusStats,
48
- rebuildConceptPageCorpusStats,
49
- } from "../../memory/v2/sparse-bm25.js";
31
+ import { getLogger } from "../../util/logger.js";
50
32
  import { getWorkspaceDir } from "../../util/platform.js";
51
33
  import { RouteError } from "./errors.js";
52
34
  import type { RouteDefinition } from "./types.js";
53
35
  import type { RouteHandlerArgs } from "./types.js";
54
36
 
37
+ const log = getLogger("memory-v2-routes");
38
+
39
+ /**
40
+ * Wire-format error code emitted when v2 routes reject a request because
41
+ * `memory.v2.enabled` is false. Exported so tests and the macOS client can
42
+ * reference the same string without drift.
43
+ */
44
+ export const MEMORY_V2_DISABLED_CODE = "MEMORY_V2_DISABLED";
45
+
46
+ /**
47
+ * Reject the request when memory v2 is not active. Returning 409 (rather
48
+ * than serving a partial response) keeps clients honest — the desktop
49
+ * Memories panel reads this code to render an explicit "disabled in
50
+ * config" empty state.
51
+ */
52
+ function requireMemoryV2Enabled(): void {
53
+ if (!loadConfig().memory.v2.enabled) {
54
+ throw new RouteError(
55
+ "Memory v2 is not enabled — set memory.v2.enabled to true to use this command.",
56
+ MEMORY_V2_DISABLED_CODE,
57
+ 409,
58
+ );
59
+ }
60
+ }
61
+
55
62
  // ── Backfill ────────────────────────────────────────────────────────────
56
63
 
57
64
  const MemoryV2BackfillParams = z
@@ -76,6 +83,7 @@ const OP_TO_JOB_TYPE: Record<MemoryV2BackfillOp, MemoryJobType> = {
76
83
  async function handleBackfill({
77
84
  body = {},
78
85
  }: RouteHandlerArgs): Promise<MemoryV2BackfillResult> {
86
+ requireMemoryV2Enabled();
79
87
  const { op, force } = MemoryV2BackfillParams.parse(body);
80
88
  const payload: Record<string, unknown> =
81
89
  op === "migrate" && force === true ? { force: true } : {};
@@ -102,6 +110,11 @@ export type MemoryV2ValidateResult = {
102
110
  async function handleValidate({
103
111
  body = {},
104
112
  }: RouteHandlerArgs): Promise<MemoryV2ValidateResult> {
113
+ // Intentionally NOT gated on `memory.v2.enabled`. Validate is a read-only
114
+ // diagnostic walk over the on-disk concept-page workspace and must be
115
+ // runnable before flipping the flag — operators (and the
116
+ // vellum-memory-v2-migration skill) use it as the final dry-run check
117
+ // immediately before enabling v2.
105
118
  MemoryV2ValidateParams.parse(body);
106
119
 
107
120
  const workspaceDir = getWorkspaceDir();
@@ -117,7 +130,7 @@ async function handleValidate({
117
130
  const page = await readPage(workspaceDir, slug);
118
131
  if (!page) continue;
119
132
  knownSlugs.add(slug);
120
- const chars = Buffer.byteLength(page.body, "utf8");
133
+ const chars = page.body.length;
121
134
  if (chars > maxPageChars) {
122
135
  oversizedPages.push({ slug, chars });
123
136
  }
@@ -158,6 +171,7 @@ export type MemoryV2GetConceptPageResult = {
158
171
  async function handleGetConceptPage({
159
172
  body = {},
160
173
  }: RouteHandlerArgs): Promise<MemoryV2GetConceptPageResult> {
174
+ requireMemoryV2Enabled();
161
175
  const { slug } = MemoryV2GetConceptPageParams.parse(body);
162
176
  const workspaceDir = getWorkspaceDir();
163
177
  let page;
@@ -180,38 +194,57 @@ async function handleGetConceptPage({
180
194
  return { slug, rendered: renderPageContent(page) };
181
195
  }
182
196
 
183
- // ── Rebuild BM25 corpus stats ───────────────────────────────────────────
197
+ // ── List concept pages ──────────────────────────────────────────────────
184
198
 
185
- const MemoryV2RebuildCorpusStatsParams = z.object({}).strict();
199
+ const MemoryV2ListConceptPagesParams = z.object({}).strict();
186
200
 
187
- export interface MemoryV2RebuildCorpusStatsResult {
188
- totalDocs: number;
189
- avgDl: number;
190
- /** Number of distinct hashed-token buckets that received any DF count. */
191
- vocabularyBuckets: number;
192
- }
201
+ export type MemoryV2ListConceptPagesResult = {
202
+ pages: Array<{
203
+ slug: string;
204
+ bodyBytes: number;
205
+ edgeCount: number;
206
+ updatedAtMs: number;
207
+ }>;
208
+ };
193
209
 
194
- async function handleRebuildCorpusStats({
210
+ async function handleListConceptPages({
195
211
  body = {},
196
- }: RouteHandlerArgs): Promise<MemoryV2RebuildCorpusStatsResult> {
197
- MemoryV2RebuildCorpusStatsParams.parse(body);
212
+ }: RouteHandlerArgs): Promise<MemoryV2ListConceptPagesResult> {
213
+ requireMemoryV2Enabled();
214
+ MemoryV2ListConceptPagesParams.parse(body);
215
+
198
216
  const workspaceDir = getWorkspaceDir();
199
- await rebuildConceptPageCorpusStats(workspaceDir);
200
- const stats = getConceptPageCorpusStats();
201
- if (!stats) {
202
- // The rebuild always swaps in a non-null table on success, so a missing
203
- // value here means an unexpected reset between rebuild and read.
204
- throw new RouteError(
205
- "Corpus stats rebuild completed but no table is loaded",
206
- "MEMORY_V2_CORPUS_STATS_MISSING",
207
- 500,
208
- );
209
- }
210
- return {
211
- totalDocs: stats.totalDocs,
212
- avgDl: stats.avgDl,
213
- vocabularyBuckets: stats.df.size,
214
- };
217
+ const conceptsDir = getConceptsDir(workspaceDir);
218
+ const slugs = await listPages(workspaceDir);
219
+
220
+ const settled = await Promise.all(
221
+ slugs.map(async (slug) => {
222
+ try {
223
+ const page = await readPage(workspaceDir, slug);
224
+ if (!page) return null;
225
+ const stats = await stat(join(conceptsDir, `${slug}.md`));
226
+ return {
227
+ slug,
228
+ bodyBytes: Buffer.byteLength(page.body, "utf8"),
229
+ edgeCount: page.frontmatter.edges.length,
230
+ updatedAtMs: Math.floor(stats.mtimeMs),
231
+ };
232
+ } catch (err) {
233
+ // A single corrupt page (bad YAML, schema mismatch, etc.) shouldn't
234
+ // poison the whole listing — the validate route is the place to
235
+ // surface those; this one is read-only and best-effort.
236
+ log.warn(
237
+ `Skipping concept page '${slug}' in list-concept-pages: ${err instanceof Error ? err.message : String(err)}`,
238
+ );
239
+ return null;
240
+ }
241
+ }),
242
+ );
243
+ const pages = settled.filter(
244
+ (p): p is MemoryV2ListConceptPagesResult["pages"][number] => p !== null,
245
+ );
246
+
247
+ return { pages };
215
248
  }
216
249
 
217
250
  // ── Reembed skills ──────────────────────────────────────────────────────
@@ -225,244 +258,19 @@ export type MemoryV2ReembedSkillsResult = {
225
258
  async function handleReembedSkills({
226
259
  body = {},
227
260
  }: RouteHandlerArgs): Promise<MemoryV2ReembedSkillsResult> {
261
+ requireMemoryV2Enabled();
228
262
  MemoryV2ReembedSkillsParams.parse(body);
229
263
 
230
- // Gate the route on both the feature flag and the per-workspace config
231
- // toggle so the v2 skill collection never gets re-seeded against a
232
- // workspace whose v2 subsystem is intentionally off.
233
- const config = loadConfig();
234
- if (
235
- !isAssistantFeatureFlagEnabled("memory-v2-enabled", config) ||
236
- !config.memory.v2.enabled
237
- ) {
238
- throw new RouteError(
239
- "Memory v2 is not enabled — flip both the memory-v2-enabled feature flag and memory.v2.enabled to use this command.",
240
- "MEMORY_V2_DISABLED",
241
- 409,
242
- );
243
- }
244
-
245
264
  // Unlike the queued backfill jobs above, this is a CLI-driven sync
246
265
  // request: the operator wants the cache replaced before the next prompt
247
- // assembly, so we await the seed inline rather than enqueueing it.
248
- await seedV2SkillEntries();
266
+ // assembly, so we await the seed inline rather than enqueueing it. Pass
267
+ // `throwOnError` so embedding/Qdrant failures surface to the CLI instead
268
+ // of being swallowed by the default best-effort behavior.
269
+ await seedV2SkillEntries({ throwOnError: true });
249
270
 
250
271
  return { success: true };
251
272
  }
252
273
 
253
- // ── Explain similarity ──────────────────────────────────────────────────
254
-
255
- const MemoryV2ExplainSimilarityParams = z
256
- .object({
257
- userText: z.string().min(1),
258
- assistantText: z.string().optional(),
259
- nowText: z.string().optional(),
260
- top: z.number().int().min(1).default(25),
261
- })
262
- .strict();
263
-
264
- export interface MemoryV2ExplainSimilarityRow {
265
- slug: string;
266
- /** Raw dense cosine score, or null when the slug missed the dense channel. */
267
- denseScore: number | null;
268
- /** Raw sparse score (Qdrant scale), or null when the slug missed sparse. */
269
- sparseRaw: number | null;
270
- /** Sparse score divided by the per-batch max, in [0, 1]. */
271
- sparseNorm: number | null;
272
- /** `clamp01(dense_weight·dense + sparse_weight·sparseNorm)` — the simBatch fused value. */
273
- fused: number;
274
- }
275
-
276
- export interface MemoryV2ExplainSimilarityStats {
277
- count: number;
278
- min: number;
279
- max: number;
280
- mean: number;
281
- stddev: number;
282
- }
283
-
284
- export interface MemoryV2ExplainSimilarityChannel {
285
- channel: "user" | "assistant" | "now";
286
- textPreview: string;
287
- maxSparse: number;
288
- /**
289
- * Spread (max - min) of normalized sparse scores across this channel's
290
- * hits. Drives adaptive sparse weighting — low spread means the sparse
291
- * channel can't discriminate, so its weight collapses for this query.
292
- */
293
- sparseSpread: number;
294
- /** Sparse weight after adaptive collapse (≤ the configured base). */
295
- effectiveSparseWeight: number;
296
- /** Dense weight after adaptive compensation (≥ the configured base). */
297
- effectiveDenseWeight: number;
298
- rows: MemoryV2ExplainSimilarityRow[];
299
- stats: {
300
- dense: MemoryV2ExplainSimilarityStats;
301
- sparseRaw: MemoryV2ExplainSimilarityStats;
302
- sparseNorm: MemoryV2ExplainSimilarityStats;
303
- fused: MemoryV2ExplainSimilarityStats;
304
- };
305
- }
306
-
307
- export interface MemoryV2ExplainSimilarityResult {
308
- config: {
309
- dense_weight: number;
310
- sparse_weight: number;
311
- };
312
- channels: MemoryV2ExplainSimilarityChannel[];
313
- }
314
-
315
- function summarizeStats(values: number[]): MemoryV2ExplainSimilarityStats {
316
- if (values.length === 0) {
317
- return { count: 0, min: 0, max: 0, mean: 0, stddev: 0 };
318
- }
319
- let min = Infinity;
320
- let max = -Infinity;
321
- let sum = 0;
322
- for (const v of values) {
323
- if (v < min) min = v;
324
- if (v > max) max = v;
325
- sum += v;
326
- }
327
- const mean = sum / values.length;
328
- let sqDiff = 0;
329
- for (const v of values) sqDiff += (v - mean) * (v - mean);
330
- const stddev = Math.sqrt(sqDiff / values.length);
331
- return { count: values.length, min, max, mean, stddev };
332
- }
333
-
334
- async function scoreChannel(
335
- channel: "user" | "assistant" | "now",
336
- text: string,
337
- top: number,
338
- denseWeight: number,
339
- sparseWeight: number,
340
- config: ReturnType<typeof loadConfig>,
341
- ): Promise<MemoryV2ExplainSimilarityChannel> {
342
- const denseResult = await embedWithBackend(config, [text]);
343
- const denseVec = await applyCorrectionIfCalibrated(
344
- denseResult.vectors[0],
345
- denseResult.provider,
346
- denseResult.model,
347
- );
348
- const sparseVec = generateBm25QueryEmbedding(text);
349
-
350
- const hits = await hybridQueryConceptPages(denseVec, sparseVec, top);
351
-
352
- let maxSparse = 0;
353
- for (const hit of hits) {
354
- if (hit.sparseScore !== undefined && hit.sparseScore > maxSparse) {
355
- maxSparse = hit.sparseScore;
356
- }
357
- }
358
-
359
- // Mirror simBatch's adaptive weighting so the printed `fused` matches what
360
- // production retrieval would actually score for this query — otherwise
361
- // operators staring at the diagnostic would see different numbers than
362
- // the activation pipeline saw.
363
- const {
364
- dense: effDense,
365
- sparse: effSparse,
366
- spread: sparseSpread,
367
- } = effectiveWeights(hits, maxSparse, denseWeight, sparseWeight, config);
368
-
369
- const rows: MemoryV2ExplainSimilarityRow[] = hits.map((hit) => {
370
- const dense = hit.denseScore ?? 0;
371
- const sparseNorm =
372
- hit.sparseScore !== undefined && maxSparse > 0
373
- ? hit.sparseScore / maxSparse
374
- : 0;
375
- const fusedRaw = effDense * dense + effSparse * sparseNorm;
376
- const fused = Math.max(0, Math.min(1, fusedRaw));
377
- return {
378
- slug: hit.slug,
379
- denseScore: hit.denseScore ?? null,
380
- sparseRaw: hit.sparseScore ?? null,
381
- sparseNorm: hit.sparseScore !== undefined ? sparseNorm : null,
382
- fused,
383
- };
384
- });
385
-
386
- rows.sort((a, b) => b.fused - a.fused);
387
-
388
- const denseValues: number[] = [];
389
- const sparseRawValues: number[] = [];
390
- const sparseNormValues: number[] = [];
391
- const fusedValues: number[] = [];
392
- for (const row of rows) {
393
- if (row.denseScore !== null) denseValues.push(row.denseScore);
394
- if (row.sparseRaw !== null) sparseRawValues.push(row.sparseRaw);
395
- if (row.sparseNorm !== null) sparseNormValues.push(row.sparseNorm);
396
- fusedValues.push(row.fused);
397
- }
398
-
399
- return {
400
- channel,
401
- textPreview: text.length > 120 ? `${text.slice(0, 120)}…` : text,
402
- maxSparse,
403
- sparseSpread,
404
- effectiveSparseWeight: effSparse,
405
- effectiveDenseWeight: effDense,
406
- rows,
407
- stats: {
408
- dense: summarizeStats(denseValues),
409
- sparseRaw: summarizeStats(sparseRawValues),
410
- sparseNorm: summarizeStats(sparseNormValues),
411
- fused: summarizeStats(fusedValues),
412
- },
413
- };
414
- }
415
-
416
- async function handleExplainSimilarity({
417
- body = {},
418
- }: RouteHandlerArgs): Promise<MemoryV2ExplainSimilarityResult> {
419
- const params = MemoryV2ExplainSimilarityParams.parse(body);
420
- const config = loadConfig();
421
- const { dense_weight: denseWeight, sparse_weight: sparseWeight } =
422
- config.memory.v2;
423
-
424
- const channels: MemoryV2ExplainSimilarityChannel[] = [];
425
- channels.push(
426
- await scoreChannel(
427
- "user",
428
- params.userText,
429
- params.top,
430
- denseWeight,
431
- sparseWeight,
432
- config,
433
- ),
434
- );
435
- if (params.assistantText && params.assistantText.length > 0) {
436
- channels.push(
437
- await scoreChannel(
438
- "assistant",
439
- params.assistantText,
440
- params.top,
441
- denseWeight,
442
- sparseWeight,
443
- config,
444
- ),
445
- );
446
- }
447
- if (params.nowText && params.nowText.length > 0) {
448
- channels.push(
449
- await scoreChannel(
450
- "now",
451
- params.nowText,
452
- params.top,
453
- denseWeight,
454
- sparseWeight,
455
- config,
456
- ),
457
- );
458
- }
459
-
460
- return {
461
- config: { dense_weight: denseWeight, sparse_weight: sparseWeight },
462
- channels,
463
- };
464
- }
465
-
466
274
  // ── Concept injection frequency (debug-only) ────────────────────────────
467
275
 
468
276
  const MemoryV2ConceptFrequencyParams = z
@@ -475,98 +283,13 @@ const MemoryV2ConceptFrequencyParams = z
475
283
  async function handleConceptFrequency({
476
284
  body = {},
477
285
  }: RouteHandlerArgs): Promise<ConceptFrequencyResponse> {
286
+ requireMemoryV2Enabled();
478
287
  const { conversationId, sinceMs } =
479
288
  MemoryV2ConceptFrequencyParams.parse(body);
480
289
  const workspaceDir = getWorkspaceDir();
481
290
  return getConceptFrequencySummary(workspaceDir, { conversationId, sinceMs });
482
291
  }
483
292
 
484
- // ── Fit anisotropy calibration ──────────────────────────────────────────
485
-
486
- const MemoryV2FitAnisotropyParams = z
487
- .object({
488
- /**
489
- * Number of leading principal components to project out at apply time.
490
- * `1` is the canonical default for transformer embeddings; raise to 2-3
491
- * only when the variance spectrum shows multiple dominant directions.
492
- */
493
- k: z.number().int().min(1).max(16).default(1),
494
- /**
495
- * Maximum number of stored vectors to pull from Qdrant for the fit.
496
- * 5_000 is plenty for 3072-dim Gemini — power iteration converges fast
497
- * and pulling the full corpus would just cost wall-clock time.
498
- */
499
- sample: z.number().int().min(1).max(100_000).default(5_000),
500
- })
501
- .strict();
502
-
503
- export interface MemoryV2FitAnisotropyResult {
504
- provider: string;
505
- model: string;
506
- dim: number;
507
- k: number;
508
- sampleCount: number;
509
- totalVariance: number;
510
- componentVariance: number[];
511
- /** `componentVariance[i] / totalVariance` for each component. */
512
- explainedVarianceRatio: number[];
513
- /** Absolute path the calibration was written to. */
514
- path: string;
515
- }
516
-
517
- async function handleFitAnisotropy({
518
- body = {},
519
- }: RouteHandlerArgs): Promise<MemoryV2FitAnisotropyResult> {
520
- const { k, sample } = MemoryV2FitAnisotropyParams.parse(body);
521
- const config = loadConfig();
522
-
523
- const selection = await selectEmbeddingBackend(config);
524
- if (!selection.backend) {
525
- throw new RouteError(
526
- `Cannot fit anisotropy calibration: ${selection.reason ?? "no embedding backend configured"}`,
527
- "MEMORY_V2_NO_EMBEDDING_BACKEND",
528
- 409,
529
- );
530
- }
531
-
532
- const vectors = await sampleConceptPageDenseVectors(sample);
533
- if (vectors.length === 0) {
534
- throw new RouteError(
535
- "Cannot fit anisotropy calibration: the v2 concept-page collection is empty. " +
536
- "Embed some concept pages first (run `assistant memory v2 reembed`), then retry.",
537
- "MEMORY_V2_NO_VECTORS",
538
- 409,
539
- );
540
- }
541
- if (vectors.length < k * 4) {
542
- // PCA on too-few samples is unstable — refuse rather than hand back
543
- // overfit components. The 4× heuristic is conservative; in practice
544
- // anisotropy fits stabilise at a few hundred samples per component.
545
- throw new RouteError(
546
- `Cannot fit k=${k} components from only ${vectors.length} vectors — need at least ${k * 4}. ` +
547
- "Embed more concept pages or fit a smaller k.",
548
- "MEMORY_V2_INSUFFICIENT_VECTORS",
549
- 409,
550
- );
551
- }
552
-
553
- const { provider, model } = selection.backend;
554
- const calib = fitAnisotropyCalibration(vectors, k, { provider, model });
555
- const path = await saveCalibration(calib);
556
-
557
- return {
558
- provider,
559
- model,
560
- dim: calib.dim,
561
- k,
562
- sampleCount: calib.sampleCount,
563
- totalVariance: calib.totalVariance,
564
- componentVariance: calib.componentVariance,
565
- explainedVarianceRatio: explainedVarianceRatio(calib),
566
- path,
567
- };
568
- }
569
-
570
293
  // ── Route definitions ───────────────────────────────────────────────────
571
294
 
572
295
  export const ROUTES: RouteDefinition[] = [
@@ -588,7 +311,7 @@ export const ROUTES: RouteDefinition[] = [
588
311
  handler: handleValidate,
589
312
  summary: "Validate memory v2 workspace state",
590
313
  description:
591
- "Read-only structural validation of the v2 workspace — reports orphan edges, oversized pages, and parse failures.",
314
+ "Read-only structural validation of the v2 workspace — reports orphan edges, oversized pages, and parse failures. Runnable regardless of memory.v2.enabled so operators can dry-run validation before flipping the flag.",
592
315
  tags: ["memory"],
593
316
  requestBody: MemoryV2ValidateParams,
594
317
  },
@@ -604,37 +327,26 @@ export const ROUTES: RouteDefinition[] = [
604
327
  requestBody: MemoryV2GetConceptPageParams,
605
328
  },
606
329
  {
607
- operationId: "memory_v2_reembed_skills",
330
+ operationId: "memory_v2_list_concept_pages",
608
331
  method: "POST",
609
- endpoint: "memory/v2/reembed-skills",
610
- handler: handleReembedSkills,
611
- summary: "Re-seed v2 skill entries from the current skill catalog",
332
+ endpoint: "memory/v2/list-concept-pages",
333
+ handler: handleListConceptPages,
334
+ summary: "List all memory v2 concept pages with metadata",
612
335
  description:
613
- "Synchronously re-runs seedV2SkillEntries against the current skill catalog. Gated on memory-v2-enabled flag and config.memory.v2.enabled.",
336
+ "Returns slugs, body sizes, edge counts, and last-modified timestamps for every concept page on disk. Read-only; used by the desktop About → Memories surface to render a browse-able list.",
614
337
  tags: ["memory"],
615
- requestBody: MemoryV2ReembedSkillsParams,
338
+ requestBody: MemoryV2ListConceptPagesParams,
616
339
  },
617
340
  {
618
- operationId: "memory_v2_explain_similarity",
619
- method: "POST",
620
- endpoint: "memory/v2/explain-similarity",
621
- handler: handleExplainSimilarity,
622
- summary: "Diagnose dense vs sparse similarity score distributions",
623
- description:
624
- "Read-only diagnostic. Embeds the supplied text(s), runs hybrid dense + sparse queries against the concept-page collection, and returns per-slug raw dense, raw sparse, normalized sparse, and fused scores plus per-channel summary stats. Used to investigate score-compression at the head of the activation distribution.",
625
- tags: ["memory"],
626
- requestBody: MemoryV2ExplainSimilarityParams,
627
- },
628
- {
629
- operationId: "memory_v2_rebuild_corpus_stats",
341
+ operationId: "memory_v2_reembed_skills",
630
342
  method: "POST",
631
- endpoint: "memory/v2/rebuild-corpus-stats",
632
- handler: handleRebuildCorpusStats,
633
- summary: "Rebuild the BM25 corpus statistics for memory v2",
343
+ endpoint: "memory/v2/reembed-skills",
344
+ handler: handleReembedSkills,
345
+ summary: "Re-seed v2 skill entries from the current skill catalog",
634
346
  description:
635
- "Walks every concept page on disk, recomputes the document-frequency table and average document length used by the BM25 sparse channel, and atomically swaps the in-memory stats. Run after bulk content imports or to recover from a rebuild that errored at startup. Does not reembed individual page sparse vectors — pair with `assistant memory v2 reembed` when document-side weights need refreshing.",
347
+ "Synchronously re-runs seedV2SkillEntries against the current skill catalog. Gated on config.memory.v2.enabled.",
636
348
  tags: ["memory"],
637
- requestBody: MemoryV2RebuildCorpusStatsParams,
349
+ requestBody: MemoryV2ReembedSkillsParams,
638
350
  },
639
351
  {
640
352
  operationId: "memory_v2_concept_frequency",
@@ -647,15 +359,4 @@ export const ROUTES: RouteDefinition[] = [
647
359
  tags: ["memory"],
648
360
  requestBody: MemoryV2ConceptFrequencyParams,
649
361
  },
650
- {
651
- operationId: "memory_v2_fit_anisotropy",
652
- method: "POST",
653
- endpoint: "memory/v2/fit-anisotropy",
654
- handler: handleFitAnisotropy,
655
- summary: "Fit the embedding anisotropy correction for memory v2",
656
- description:
657
- "Samples stored dense vectors from the concept-page Qdrant collection, fits a corpus mean + top-k principal components (Mu & Viswanath 'all-but-the-top'), and persists the calibration so subsequent embeds and queries apply the correction. Run `assistant memory v2 reembed` after fitting so stored vectors are written under the new calibration — until then, queries (corrected) and stored vectors (uncorrected) live in different spaces.",
658
- tags: ["memory"],
659
- requestBody: MemoryV2FitAnisotropyParams,
660
- },
661
362
  ];
@@ -75,6 +75,7 @@ const EmitSignalParams = z.object({
75
75
  routingIntent: z
76
76
  .enum(["single_channel", "multi_channel", "all_channels"])
77
77
  .optional(),
78
+ conversationAffinityHint: z.record(z.string(), z.string()).optional(),
78
79
  dedupeKey: z.string().optional(),
79
80
  throwOnError: z.boolean().optional(),
80
81
  });
@@ -95,6 +96,7 @@ async function handleEmitSignal({ body = {} }: RouteHandlerArgs) {
95
96
  attentionHints: validated.attentionHints as AttentionHints,
96
97
  contextPayload: validated.contextPayload as Record<string, unknown>,
97
98
  routingIntent: validated.routingIntent,
99
+ conversationAffinityHint: validated.conversationAffinityHint,
98
100
  dedupeKey: validated.dedupeKey,
99
101
  throwOnError: validated.throwOnError,
100
102
  });