@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,26 @@
1
1
  /**
2
2
  * v2 read-side cutover behavior for the PKB-derived default injectors.
3
3
  *
4
- * When `isMemoryV2ReadActive(getConfig())` is true:
4
+ * When `getConfig().memory.v2.enabled` is true:
5
5
  * - `pkb-context` silences itself (concept pages own retrieval).
6
6
  * - `pkb-reminder` still fires (its body is generic recall/remember
7
7
  * guidance) but skips the PKB-search hints — those name PKB paths.
8
8
  * - `now-md` fires unchanged (workspace state, independent of PKB).
9
9
  *
10
- * Mocks `isMemoryV2ReadActive` at the module level so each test can flip the
11
- * effective gate state without standing up a full feature-flag + config
12
- * stack. Mocks the PKB hybrid search so the reminder-with-hints branch can
13
- * resolve deterministically when called.
10
+ * Mocks `getConfig` at the module level so each test can flip the effective
11
+ * gate state without standing up a full config stack. Mocks the PKB hybrid
12
+ * search so the reminder-with-hints branch can resolve deterministically
13
+ * when called.
14
14
  */
15
15
  import { beforeEach, describe, expect, mock, test } from "bun:test";
16
16
 
17
17
  let v2Active = false;
18
18
 
19
- mock.module("../memory/context-search/sources/memory-v2.js", () => ({
20
- isMemoryV2ReadActive: () => v2Active,
19
+ const realLoader = await import("../config/loader.js");
20
+
21
+ mock.module("../config/loader.js", () => ({
22
+ ...realLoader,
23
+ getConfig: () => ({ memory: { v2: { enabled: v2Active } } }),
21
24
  }));
22
25
 
23
26
  mock.module("../memory/pkb/pkb-search.js", () => ({
@@ -14,7 +14,7 @@
14
14
 
15
15
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
- import { beforeEach, describe, expect, mock, test } from "bun:test";
17
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
18
18
 
19
19
  // ── Mock setup (must be before any imports from the project) ──────────────
20
20
 
@@ -115,6 +115,7 @@ describe("inline-command skill_load permissions", () => {
115
115
  beforeEach(() => {
116
116
  clearRiskCache();
117
117
  _clearGlobalCacheForTesting();
118
+ _setOverridesForTesting({});
118
119
  mockIpcResponse("get_global_thresholds", {
119
120
  interactive: "low",
120
121
  autonomous: "medium",
@@ -133,6 +134,10 @@ describe("inline-command skill_load permissions", () => {
133
134
  }
134
135
  });
135
136
 
137
+ afterEach(() => {
138
+ _setOverridesForTesting({});
139
+ });
140
+
136
141
  // ── Default behavior ─────────────────────────────────────────────────
137
142
 
138
143
  describe("default behavior", () => {
@@ -180,7 +180,7 @@ describe("installSkill routing", () => {
180
180
  "vercel-labs",
181
181
  "agent-skills",
182
182
  "react-best-practices",
183
- true, // overwrite
183
+ true, // overwrite — handler default is true for HTTP API back-compat; CLI passes explicit false
184
184
  undefined, // ref
185
185
  undefined, // contactId
186
186
  );
@@ -221,7 +221,7 @@ describe("installSkill routing", () => {
221
221
  "owner",
222
222
  "repo",
223
223
  "my-skill",
224
- true,
224
+ true, // overwrite — handler default is true for HTTP API back-compat; CLI passes explicit false
225
225
  undefined, // ref
226
226
  undefined, // contactId
227
227
  );
@@ -1,17 +1,17 @@
1
1
  /**
2
- * Tests for the memory-v2 skill seed gate invoked from the daemon startup
3
- * path (`assistant/src/daemon/memory-v2-startup.ts`).
2
+ * Tests for the memory-v2 skill seed gate and the v2 concept-page schema
3
+ * rebuild gate, both invoked from the daemon startup path
4
+ * (`assistant/src/daemon/memory-v2-startup.ts`).
4
5
  *
5
- * The gate is exercised in isolation rather than mounting the full lifecycle
6
- * import graph. Coverage matrix from PR 8 acceptance criteria:
7
- * - Case 1: feature flag on + `config.memory.v2.enabled` on seed runs.
8
- * - Case 2: feature flag off → seed does not run.
9
- * - Case 3: `config.memory.v2.enabled` off (flag on) seed does not run.
10
- * - Case 4: `seedV2SkillEntries` rejects → gate does not throw and the
11
- * warning is logged.
6
+ * The gates are exercised in isolation rather than mounting the full
7
+ * lifecycle import graph. Coverage matrix:
8
+ * - Skill seed (`maybeSeedMemoryV2Skills`): config gating, rejection
9
+ * swallowing.
10
+ * - Schema rebuild (`maybeRebuildMemoryV2Concepts`): config gating,
11
+ * drift-triggered reembed enqueue, empty-after-create reembed enqueue,
12
+ * no enqueue when collection is healthy, error swallowing.
12
13
  *
13
- * The seed call itself is fire-and-forget (`void` + `.catch`); the gate must
14
- * never block startup or surface an exception.
14
+ * Both gates must never block startup or surface an exception.
15
15
  */
16
16
  import { beforeEach, describe, expect, mock, test } from "bun:test";
17
17
 
@@ -22,31 +22,38 @@ import type { AssistantConfig } from "../config/schema.js";
22
22
  // ---------------------------------------------------------------------------
23
23
 
24
24
  interface TestState {
25
- flagOverrides: Record<string, boolean>;
26
25
  seedCallCount: number;
27
26
  seedShouldReject: Error | null;
28
27
  warnCalls: Array<{ obj: unknown; msg: unknown }>;
28
+ infoCalls: Array<{ obj: unknown; msg: unknown }>;
29
+ // Rebuild-gate mocks (drive maybeRebuildMemoryV2Concepts).
30
+ ensureCollectionCallCount: number;
31
+ ensureCollectionResult: { migrated: boolean };
32
+ ensureCollectionThrows: Error | null;
33
+ countResult: number;
34
+ listPagesResult: string[];
35
+ enqueueCalls: Array<{ type: string; payload: Record<string, unknown> }>;
36
+ clearSentinelCallCount: number;
29
37
  }
30
38
 
31
39
  const state: TestState = {
32
- flagOverrides: {},
33
40
  seedCallCount: 0,
34
41
  seedShouldReject: null,
35
42
  warnCalls: [],
43
+ infoCalls: [],
44
+ ensureCollectionCallCount: 0,
45
+ ensureCollectionResult: { migrated: false },
46
+ ensureCollectionThrows: null,
47
+ countResult: 0,
48
+ listPagesResult: [],
49
+ enqueueCalls: [],
50
+ clearSentinelCallCount: 0,
36
51
  };
37
52
 
38
53
  // ---------------------------------------------------------------------------
39
54
  // Mocks — installed before the module under test is loaded.
40
55
  // ---------------------------------------------------------------------------
41
56
 
42
- mock.module("../config/assistant-feature-flags.js", () => ({
43
- isAssistantFeatureFlagEnabled: (key: string, _config: unknown): boolean => {
44
- const explicit = state.flagOverrides[key];
45
- if (typeof explicit === "boolean") return explicit;
46
- return true; // undeclared flags default to enabled
47
- },
48
- }));
49
-
50
57
  mock.module("../memory/v2/skill-store.js", () => ({
51
58
  seedV2SkillEntries: async (): Promise<void> => {
52
59
  state.seedCallCount += 1;
@@ -54,18 +61,59 @@ mock.module("../memory/v2/skill-store.js", () => ({
54
61
  },
55
62
  }));
56
63
 
64
+ mock.module("../memory/v2/qdrant.js", () => ({
65
+ ensureConceptPageCollection: async (): Promise<{ migrated: boolean }> => {
66
+ state.ensureCollectionCallCount += 1;
67
+ if (state.ensureCollectionThrows) throw state.ensureCollectionThrows;
68
+ return state.ensureCollectionResult;
69
+ },
70
+ countConceptPagePoints: async (): Promise<number> => state.countResult,
71
+ clearReembedSentinel: async (): Promise<void> => {
72
+ state.clearSentinelCallCount += 1;
73
+ },
74
+ // The rebuild gate does not call this, but the seed gate's fire-and-forget
75
+ // chain imports it; provide a no-op so the dynamic import resolves.
76
+ dropLegacySkillsCollection: async (): Promise<void> => {},
77
+ }));
78
+
79
+ mock.module("../memory/v2/page-store.js", () => ({
80
+ hasConceptPages: async (): Promise<boolean> =>
81
+ state.listPagesResult.length > 0,
82
+ }));
83
+
84
+ mock.module("../memory/jobs-store.js", () => ({
85
+ enqueueMemoryJob: (
86
+ type: string,
87
+ payload: Record<string, unknown>,
88
+ ): string => {
89
+ state.enqueueCalls.push({ type, payload });
90
+ return "test-job-id";
91
+ },
92
+ }));
93
+
94
+ mock.module("../util/platform.js", () => ({
95
+ getWorkspaceDir: () => "/tmp/test-workspace",
96
+ // qdrant.ts (mocked away in this file) reads `getDataDir` for the reembed
97
+ // sentinel path; bun mocks share the same module record across files, so
98
+ // include it here too so a peer test importing `getDataDir` doesn't see
99
+ // `undefined` after this mock evaluates.
100
+ getDataDir: () => "/tmp/test-workspace/data",
101
+ }));
102
+
57
103
  mock.module("../util/logger.js", () => ({
58
104
  getLogger: () => ({
59
105
  warn: (obj: unknown, msg: unknown) => {
60
106
  state.warnCalls.push({ obj, msg });
61
107
  },
62
- info: () => {},
108
+ info: (obj: unknown, msg: unknown) => {
109
+ state.infoCalls.push({ obj, msg });
110
+ },
63
111
  error: () => {},
64
112
  debug: () => {},
65
113
  }),
66
114
  }));
67
115
 
68
- const { maybeSeedMemoryV2Skills } =
116
+ const { maybeSeedMemoryV2Skills, maybeRebuildMemoryV2Concepts } =
69
117
  await import("../daemon/memory-v2-startup.js");
70
118
 
71
119
  // ---------------------------------------------------------------------------
@@ -99,65 +147,38 @@ async function flushMicrotasks(): Promise<void> {
99
147
  // Tests
100
148
  // ---------------------------------------------------------------------------
101
149
 
150
+ function resetState(): void {
151
+ state.seedCallCount = 0;
152
+ state.seedShouldReject = null;
153
+ state.warnCalls = [];
154
+ state.infoCalls = [];
155
+ state.ensureCollectionCallCount = 0;
156
+ state.ensureCollectionResult = { migrated: false };
157
+ state.ensureCollectionThrows = null;
158
+ state.countResult = 0;
159
+ state.listPagesResult = [];
160
+ state.enqueueCalls = [];
161
+ state.clearSentinelCallCount = 0;
162
+ }
163
+
102
164
  describe("maybeSeedMemoryV2Skills (daemon startup gate)", () => {
103
- beforeEach(() => {
104
- state.flagOverrides = {};
105
- state.seedCallCount = 0;
106
- state.seedShouldReject = null;
107
- state.warnCalls = [];
108
- });
165
+ beforeEach(resetState);
109
166
 
110
- test("invokes seedV2SkillEntries when flag and config are both enabled", async () => {
111
- state.flagOverrides = { "memory-v2-enabled": true };
167
+ test("invokes seedV2SkillEntries when memory.v2.enabled is true", async () => {
112
168
  maybeSeedMemoryV2Skills(makeConfig(true));
113
169
  await flushMicrotasks();
114
170
  expect(state.seedCallCount).toBe(1);
115
171
  expect(state.warnCalls).toHaveLength(0);
116
172
  });
117
173
 
118
- test("does not invoke seedV2SkillEntries when feature flag is off", async () => {
119
- state.flagOverrides = { "memory-v2-enabled": false };
120
- maybeSeedMemoryV2Skills(makeConfig(true));
121
- await flushMicrotasks();
122
- expect(state.seedCallCount).toBe(0);
123
- expect(state.warnCalls).toHaveLength(0);
124
- });
125
-
126
- test("does not invoke seedV2SkillEntries when config.memory.v2.enabled is off", async () => {
127
- state.flagOverrides = { "memory-v2-enabled": true };
174
+ test("does not invoke seedV2SkillEntries when memory.v2.enabled is false", async () => {
128
175
  maybeSeedMemoryV2Skills(makeConfig(false));
129
176
  await flushMicrotasks();
130
177
  expect(state.seedCallCount).toBe(0);
131
178
  expect(state.warnCalls).toHaveLength(0);
132
179
  });
133
180
 
134
- test("does not invoke seedV2SkillEntries when both gates are off", async () => {
135
- state.flagOverrides = { "memory-v2-enabled": false };
136
- maybeSeedMemoryV2Skills(makeConfig(false));
137
- await flushMicrotasks();
138
- expect(state.seedCallCount).toBe(0);
139
- expect(state.warnCalls).toHaveLength(0);
140
- });
141
-
142
- test("re-invocation seeds after flag flips on (deferred-init race recovery)", async () => {
143
- // Models the lifecycle-startup race: the synchronous seed call evaluates
144
- // the flag while the gateway IPC override fetch is still in flight, falls
145
- // through to the registry default (`false`), and skips. Once
146
- // `initFeatureFlagOverrides()` resolves, the chained `.then` re-invokes
147
- // the seed with the now-populated cache and the flag flips to `true`.
148
- state.flagOverrides = { "memory-v2-enabled": false };
149
- maybeSeedMemoryV2Skills(makeConfig(true));
150
- await flushMicrotasks();
151
- expect(state.seedCallCount).toBe(0);
152
-
153
- state.flagOverrides = { "memory-v2-enabled": true };
154
- maybeSeedMemoryV2Skills(makeConfig(true));
155
- await flushMicrotasks();
156
- expect(state.seedCallCount).toBe(1);
157
- });
158
-
159
181
  test("swallows seedV2SkillEntries rejections and logs a warning", async () => {
160
- state.flagOverrides = { "memory-v2-enabled": true };
161
182
  state.seedShouldReject = new Error("seed failed");
162
183
 
163
184
  // The gate must not throw — startup must not block on this.
@@ -172,3 +193,84 @@ describe("maybeSeedMemoryV2Skills (daemon startup gate)", () => {
172
193
  expect(msg).toBe("Failed to seed v2 skill entries");
173
194
  });
174
195
  });
196
+
197
+ describe("maybeRebuildMemoryV2Concepts (daemon startup gate)", () => {
198
+ beforeEach(resetState);
199
+
200
+ test("does nothing when memory.v2.enabled is false", async () => {
201
+ await maybeRebuildMemoryV2Concepts(makeConfig(false));
202
+
203
+ expect(state.ensureCollectionCallCount).toBe(0);
204
+ expect(state.enqueueCalls).toEqual([]);
205
+ });
206
+
207
+ test("enqueues memory_v2_reembed when the collection was migrated", async () => {
208
+ state.ensureCollectionResult = { migrated: true };
209
+
210
+ await maybeRebuildMemoryV2Concepts(makeConfig(true));
211
+
212
+ expect(state.ensureCollectionCallCount).toBe(1);
213
+ expect(state.enqueueCalls).toEqual([
214
+ { type: "memory_v2_reembed", payload: {} },
215
+ ]);
216
+ // After the reembed is queued, the on-disk sentinel that the qdrant
217
+ // ensure-path may have written is cleared so it does not re-trigger on
218
+ // the next startup.
219
+ expect(state.clearSentinelCallCount).toBe(1);
220
+ // Migrated path skips the count probe — drift detection is the trigger.
221
+ // (The mock's countConceptPagePoints would silently return 0 either way,
222
+ // but keeping the path conditional keeps the lifecycle hook predictable.)
223
+ });
224
+
225
+ test("enqueues reembed when the collection is empty but pages exist on disk (crash-mid-rebuild recovery)", async () => {
226
+ state.ensureCollectionResult = { migrated: false };
227
+ state.countResult = 0;
228
+ state.listPagesResult = ["people/alice", "topics/zsh"];
229
+
230
+ await maybeRebuildMemoryV2Concepts(makeConfig(true));
231
+
232
+ expect(state.enqueueCalls).toEqual([
233
+ { type: "memory_v2_reembed", payload: {} },
234
+ ]);
235
+ });
236
+
237
+ test("does not enqueue when the collection is healthy and populated", async () => {
238
+ state.ensureCollectionResult = { migrated: false };
239
+ state.countResult = 1185;
240
+ state.listPagesResult = ["people/alice"];
241
+
242
+ await maybeRebuildMemoryV2Concepts(makeConfig(true));
243
+
244
+ expect(state.enqueueCalls).toEqual([]);
245
+ });
246
+
247
+ test("does not enqueue when the collection is empty AND no pages exist on disk (fresh workspace)", async () => {
248
+ state.ensureCollectionResult = { migrated: false };
249
+ state.countResult = 0;
250
+ state.listPagesResult = [];
251
+
252
+ await maybeRebuildMemoryV2Concepts(makeConfig(true));
253
+
254
+ expect(state.enqueueCalls).toEqual([]);
255
+ });
256
+
257
+ test("swallows ensureConceptPageCollection failures and logs a warning", async () => {
258
+ state.ensureCollectionThrows = new Error("Qdrant unreachable");
259
+
260
+ // Must not throw — startup never blocks on this gate.
261
+ let thrown: unknown = null;
262
+ try {
263
+ await maybeRebuildMemoryV2Concepts(makeConfig(true));
264
+ } catch (err) {
265
+ thrown = err;
266
+ }
267
+ expect(thrown).toBeNull();
268
+
269
+ expect(state.enqueueCalls).toEqual([]);
270
+ expect(state.warnCalls.length).toBeGreaterThan(0);
271
+ const lastWarn = state.warnCalls[state.warnCalls.length - 1];
272
+ expect((lastWarn.obj as { err: Error }).err.message).toBe(
273
+ "Qdrant unreachable",
274
+ );
275
+ });
276
+ });
@@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import { getLLMCallSiteLabel } from "../config/llm-callsite-catalog.js";
4
4
  import { CALL_SITE_CATALOG } from "../config/schemas/call-site-catalog.js";
5
- import { LLMCallSiteEnum } from "../config/schemas/llm.js";
5
+ import { LLMCallSiteEnum, LLMSchema } from "../config/schemas/llm.js";
6
6
 
7
7
  describe("LLM call-site catalog", () => {
8
8
  test("resolves every backend call-site enum value from the catalog", () => {
@@ -31,4 +31,23 @@ describe("LLM call-site catalog", () => {
31
31
  test("returns the raw ID for unknown call sites", () => {
32
32
  expect(getLLMCallSiteLabel("unknownCallSite")).toBe("unknownCallSite");
33
33
  });
34
+
35
+ test("registers the memoryRouter call site under the memory domain", () => {
36
+ expect(LLMCallSiteEnum.options).toContain("memoryRouter");
37
+
38
+ const entry = CALL_SITE_CATALOG.find(({ id }) => id === "memoryRouter");
39
+ expect(entry).toBeDefined();
40
+ expect(entry?.domain).toBe("memory");
41
+ expect(entry?.displayName).toBe("Memory Router");
42
+ expect(entry?.description).toBe(
43
+ "Selects which concept pages to inject for the next agent turn by routing over a cached page index.",
44
+ );
45
+ });
46
+
47
+ test("memoryRouter is addressable as a call-site override key in LLMSchema", () => {
48
+ const parsed = LLMSchema.parse({
49
+ callSites: { memoryRouter: { model: "claude-sonnet-4-6" } },
50
+ });
51
+ expect(parsed.callSites.memoryRouter?.model).toBe("claude-sonnet-4-6");
52
+ });
34
53
  });
@@ -2,7 +2,9 @@ import { readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { describe, expect, test } from "bun:test";
4
4
 
5
+ import { MANAGED_PROVIDER_META } from "../providers/managed-proxy/constants.js";
5
6
  import { PROVIDER_CATALOG } from "../providers/model-catalog.js";
7
+ import { resolvePricing, resolvePricingForUsage } from "../util/pricing.js";
6
8
 
7
9
  /**
8
10
  * Parity guard: daemon LLM provider catalog vs client LLM catalog JSON.
@@ -50,6 +52,13 @@ interface ClientCatalogModel {
50
52
  outputPer1mTokens: number;
51
53
  cacheWritePer1mTokens?: number;
52
54
  cacheReadPer1mTokens?: number;
55
+ tiers?: Array<{
56
+ inputTokenThreshold: number;
57
+ inputPer1mTokens: number;
58
+ outputPer1mTokens: number;
59
+ cacheReadPer1mTokens?: number;
60
+ cacheWritePer1mTokens?: number;
61
+ }>;
53
62
  };
54
63
  }
55
64
 
@@ -62,6 +71,7 @@ interface ClientCatalogEntry {
62
71
  envVar?: string;
63
72
  apiKeyPlaceholder?: string;
64
73
  credentialsGuide?: ClientCatalogCredentialsGuide;
74
+ supportsManagedAuth?: boolean;
65
75
  defaultModel: string;
66
76
  models: ClientCatalogModel[];
67
77
  }
@@ -114,6 +124,9 @@ describe("LLM catalog parity: daemon vs client", () => {
114
124
  expect(clientEntry.setupHint).toBe(daemonEntry.setupHint);
115
125
  expect(clientEntry.envVar).toBe(daemonEntry.envVar);
116
126
  expect(clientEntry.apiKeyPlaceholder).toBe(daemonEntry.apiKeyPlaceholder);
127
+ expect(clientEntry.supportsManagedAuth).toBe(
128
+ daemonEntry.supportsManagedAuth,
129
+ );
117
130
  expect(clientEntry.credentialsGuide).toEqual(
118
131
  daemonEntry.credentialsGuide,
119
132
  );
@@ -121,6 +134,19 @@ describe("LLM catalog parity: daemon vs client", () => {
121
134
  }
122
135
  });
123
136
 
137
+ test("supportsManagedAuth mirrors MANAGED_PROVIDER_META", () => {
138
+ // The catalog field is derived from MANAGED_PROVIDER_META at build
139
+ // time. This test guards against future hand-edits to model-catalog.ts
140
+ // that would let the two drift. Adding a provider to MANAGED_PROVIDER_META
141
+ // must auto-propagate; flipping `managed: true` to `false` (or vice
142
+ // versa) must propagate too.
143
+ for (const entry of PROVIDER_CATALOG) {
144
+ const expectedSupportsManagedAuth =
145
+ MANAGED_PROVIDER_META[entry.id]?.managed === true;
146
+ expect(entry.supportsManagedAuth).toBe(expectedSupportsManagedAuth);
147
+ }
148
+ });
149
+
124
150
  test("each provider's model count matches the daemon catalog", () => {
125
151
  const json = loadClientCatalog();
126
152
 
@@ -248,6 +274,126 @@ describe("LLM catalog parity: daemon vs client", () => {
248
274
  });
249
275
  });
250
276
 
277
+ // -----------------------------------------------------------------------
278
+ // pricing.ts ↔ model-catalog.ts parity
279
+ //
280
+ // `assistant/src/util/pricing.ts` reads pricing from `PROVIDER_CATALOG`
281
+ // (catalog-first) with a legacy fallback table for models we still bill
282
+ // for but no longer advertise. These tests probe `resolvePricing` /
283
+ // `resolvePricingForUsage` for every priced catalog model so any drift
284
+ // between the catalog row and the resolver's output (including cache
285
+ // discounts and long-context tier rates) fails CI.
286
+ // -----------------------------------------------------------------------
287
+
288
+ test("each priced catalog model has matching base rates in pricing.ts", () => {
289
+ // 100k tokens stays below every long-context tier threshold in the
290
+ // catalog (smallest threshold is 200k), so resolvePricing returns the
291
+ // base rate uncontaminated by tier selection.
292
+ const PROBE_TOKENS = 100_000;
293
+ const TOKENS_PER_MILLION = 1_000_000;
294
+
295
+ for (const provider of PROVIDER_CATALOG) {
296
+ for (const model of provider.models) {
297
+ if (!model.pricing) continue;
298
+
299
+ const inputResult = resolvePricing(
300
+ provider.id,
301
+ model.id,
302
+ PROBE_TOKENS,
303
+ 0,
304
+ );
305
+ expect(
306
+ inputResult.pricingStatus,
307
+ `${provider.id}/${model.id} unpriced in pricing.ts`,
308
+ ).toBe("priced");
309
+ const inputRate =
310
+ (inputResult.estimatedCostUsd ?? 0) *
311
+ (TOKENS_PER_MILLION / PROBE_TOKENS);
312
+ expect(
313
+ inputRate,
314
+ `${provider.id}/${model.id} input rate drift`,
315
+ ).toBeCloseTo(model.pricing.inputPer1mTokens, 6);
316
+
317
+ const outputResult = resolvePricing(
318
+ provider.id,
319
+ model.id,
320
+ 0,
321
+ PROBE_TOKENS,
322
+ );
323
+ const outputRate =
324
+ (outputResult.estimatedCostUsd ?? 0) *
325
+ (TOKENS_PER_MILLION / PROBE_TOKENS);
326
+ expect(
327
+ outputRate,
328
+ `${provider.id}/${model.id} output rate drift`,
329
+ ).toBeCloseTo(model.pricing.outputPer1mTokens, 6);
330
+ }
331
+ }
332
+ });
333
+
334
+ test("each priced catalog model has matching cache-read rate in pricing.ts", () => {
335
+ const PROBE_TOKENS = 100_000;
336
+ const TOKENS_PER_MILLION = 1_000_000;
337
+
338
+ for (const provider of PROVIDER_CATALOG) {
339
+ for (const model of provider.models) {
340
+ const cacheReadCatalogRate = model.pricing?.cacheReadPer1mTokens;
341
+ if (cacheReadCatalogRate === undefined) continue;
342
+
343
+ const result = resolvePricingForUsage(provider.id, model.id, {
344
+ directInputTokens: 0,
345
+ outputTokens: 0,
346
+ cacheCreationInputTokens: 0,
347
+ cacheReadInputTokens: PROBE_TOKENS,
348
+ anthropicCacheCreation: null,
349
+ });
350
+ expect(
351
+ result.pricingStatus,
352
+ `${provider.id}/${model.id} unpriced in pricing.ts`,
353
+ ).toBe("priced");
354
+ const cacheReadResolvedRate =
355
+ (result.estimatedCostUsd ?? 0) * (TOKENS_PER_MILLION / PROBE_TOKENS);
356
+ expect(
357
+ cacheReadResolvedRate,
358
+ `${provider.id}/${model.id} cache-read rate drift`,
359
+ ).toBeCloseTo(cacheReadCatalogRate, 6);
360
+ }
361
+ }
362
+ });
363
+
364
+ test("each priced catalog tier resolves at its tier rate", () => {
365
+ const TOKENS_PER_MILLION = 1_000_000;
366
+
367
+ for (const provider of PROVIDER_CATALOG) {
368
+ for (const model of provider.models) {
369
+ const tiers = model.pricing?.tiers;
370
+ if (!tiers || tiers.length === 0) continue;
371
+
372
+ for (const tier of tiers) {
373
+ const probeTokens = tier.inputTokenThreshold + 1_000;
374
+ const result = resolvePricingForUsage(provider.id, model.id, {
375
+ directInputTokens: probeTokens,
376
+ outputTokens: 0,
377
+ cacheCreationInputTokens: 0,
378
+ cacheReadInputTokens: 0,
379
+ anthropicCacheCreation: null,
380
+ });
381
+ expect(
382
+ result.pricingStatus,
383
+ `${provider.id}/${model.id} unpriced at tier ${tier.inputTokenThreshold}`,
384
+ ).toBe("priced");
385
+ const resolvedRate =
386
+ (result.estimatedCostUsd ?? 0) *
387
+ (TOKENS_PER_MILLION / probeTokens);
388
+ expect(
389
+ resolvedRate,
390
+ `${provider.id}/${model.id} input rate drift at tier ${tier.inputTokenThreshold}`,
391
+ ).toBeCloseTo(tier.inputPer1mTokens, 6);
392
+ }
393
+ }
394
+ }
395
+ });
396
+
251
397
  test("Gemini 2.5 Pro catalog context matches provider limits", () => {
252
398
  const gemini = PROVIDER_CATALOG.find((entry) => entry.id === "gemini");
253
399
  expect(