@vellumai/assistant 0.8.4 → 0.8.6

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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -425,7 +425,7 @@ describe("RetryProvider — callSite resolution", () => {
425
425
  expect(config.temperature).toBe(0.5);
426
426
  });
427
427
 
428
- test("strips effort/speed/thinking for providers that don't support them", async () => {
428
+ test("strips effort/speed for providers that don't support them (e.g. fireworks)", async () => {
429
429
  setLlmConfig({
430
430
  default: {
431
431
  provider: "anthropic",
@@ -434,14 +434,14 @@ describe("RetryProvider — callSite resolution", () => {
434
434
  speed: "fast",
435
435
  },
436
436
  callSites: {
437
- memoryRetrieval: { thinking: { enabled: true } },
437
+ memoryRetrieval: { thinking: { enabled: false } },
438
438
  },
439
439
  });
440
440
 
441
441
  let seen: SendMessageOptions | undefined;
442
- // gemini does not support effort/speed/thinking — they must be stripped.
442
+ // fireworks does not support speed or thinking — they must be stripped.
443
443
  const wrapped = new RetryProvider(
444
- makeProvider("gemini", (options) => {
444
+ makeProvider("fireworks", (options) => {
445
445
  seen = options;
446
446
  }),
447
447
  );
@@ -451,13 +451,93 @@ describe("RetryProvider — callSite resolution", () => {
451
451
  });
452
452
 
453
453
  const config = seen?.config as Record<string, unknown>;
454
- expect(config.effort).toBeUndefined();
455
454
  expect(config.speed).toBeUndefined();
456
455
  expect(config.thinking).toBeUndefined();
457
456
  // Model still comes through.
458
457
  expect(config.model).toBe("claude-opus-4-7");
459
458
  });
460
459
 
460
+ test("preserves thinking + level for Gemini provider", async () => {
461
+ setLlmConfig({
462
+ default: {
463
+ provider: "gemini",
464
+ model: "gemini-3.5-flash",
465
+ thinking: { enabled: true, streamThinking: true, level: "high" },
466
+ },
467
+ callSites: { mainAgent: {} },
468
+ });
469
+
470
+ let seen: SendMessageOptions | undefined;
471
+ const wrapped = new RetryProvider(
472
+ makeProvider("gemini", (options) => {
473
+ seen = options;
474
+ }),
475
+ );
476
+
477
+ await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
478
+ config: { callSite: "mainAgent" },
479
+ });
480
+
481
+ const config = seen?.config as Record<string, unknown>;
482
+ expect(config.thinking).toEqual({
483
+ type: "adaptive",
484
+ level: "high",
485
+ streamThinking: true,
486
+ });
487
+ });
488
+
489
+ test("Gemini disabled thinking carries the wire `disabled` discriminator", async () => {
490
+ setLlmConfig({
491
+ default: {
492
+ provider: "gemini",
493
+ model: "gemini-3.5-flash",
494
+ thinking: { enabled: false, streamThinking: false },
495
+ },
496
+ callSites: { mainAgent: {} },
497
+ });
498
+
499
+ let seen: SendMessageOptions | undefined;
500
+ const wrapped = new RetryProvider(
501
+ makeProvider("gemini", (options) => {
502
+ seen = options;
503
+ }),
504
+ );
505
+
506
+ await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
507
+ config: { callSite: "mainAgent" },
508
+ });
509
+
510
+ const config = seen?.config as Record<string, unknown>;
511
+ expect(config.thinking).toEqual({ type: "disabled" });
512
+ });
513
+
514
+ test("scrubs Gemini-only thinking extras (level, streamThinking) for Anthropic", async () => {
515
+ setLlmConfig({
516
+ default: {
517
+ provider: "anthropic",
518
+ model: "claude-opus-4-7",
519
+ thinking: { enabled: true, streamThinking: true, level: "high" },
520
+ },
521
+ callSites: { mainAgent: {} },
522
+ });
523
+
524
+ let seen: SendMessageOptions | undefined;
525
+ const wrapped = new RetryProvider(
526
+ makeProvider("anthropic", (options) => {
527
+ seen = options;
528
+ }),
529
+ );
530
+
531
+ await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
532
+ config: { callSite: "mainAgent" },
533
+ });
534
+
535
+ const config = seen?.config as Record<string, unknown>;
536
+ // Anthropic's SDK rejects unknown keys inside the `thinking` object with
537
+ // "Extra inputs are not permitted" — must be exactly `{ type }`.
538
+ expect(config.thinking).toEqual({ type: "adaptive" });
539
+ });
540
+
461
541
  test("explicit per-call config.model wins over resolved callSite model", async () => {
462
542
  setLlmConfig({
463
543
  default: { provider: "anthropic", model: "resolved-model" },
@@ -1,6 +1,5 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
2
 
3
- import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/system-prompt.js";
4
3
  import { isAbortReason } from "../../util/abort-reasons.js";
5
4
  import { ProviderError } from "../../util/errors.js";
6
5
  import { getLogger } from "../../util/logger.js";
@@ -819,6 +818,15 @@ export class AnthropicProvider implements Provider {
819
818
  ((config as Record<string, unknown> | undefined)?.cacheTtl as
820
819
  | "5m"
821
820
  | "1h") ?? "1h";
821
+ // Opt-out for callers (e.g. the memory router) that send a single
822
+ // user message per call with content that changes every time. The
823
+ // turn-start cache breakpoint below is only useful when the same
824
+ // prefix is re-sent on a subsequent call (typical for the main agent
825
+ // loop's tool-use iterations); one-shot callers pay cache_creation
826
+ // cost without a future hit.
827
+ const disableTurnStartCache =
828
+ (config as Record<string, unknown> | undefined)?.disableTurnStartCache ===
829
+ true;
822
830
  let sentMessages: Anthropic.MessageParam[] | undefined;
823
831
  const startedAt = Date.now();
824
832
  // Hoisted so the catch block can distinguish our inner stream timeout
@@ -980,14 +988,11 @@ export class AnthropicProvider implements Provider {
980
988
  // followed by user tool_result). Replaying stale thinking blocks from
981
989
  // earlier turns causes 400 errors when the signature is no longer
982
990
  // valid (e.g. after a provider/model/profile switch).
983
- const activeToolUseStart =
984
- findActiveToolUseContinuationStart(formatted);
991
+ const activeToolUseStart = findActiveToolUseContinuationStart(formatted);
985
992
  for (let i = 0; i < activeToolUseStart; i++) {
986
993
  const msg = formatted[i];
987
994
  if (msg.role !== "assistant" || !Array.isArray(msg.content)) continue;
988
- const stripped = (
989
- msg.content as Anthropic.ContentBlockParam[]
990
- ).filter(
995
+ const stripped = (msg.content as Anthropic.ContentBlockParam[]).filter(
991
996
  (b) =>
992
997
  typeof b === "string" ||
993
998
  (b.type !== "thinking" && b.type !== "redacted_thinking"),
@@ -1009,6 +1014,7 @@ export class AnthropicProvider implements Provider {
1009
1014
  speed,
1010
1015
  output_config,
1011
1016
  cacheTtl: _cacheTtl,
1017
+ disableTurnStartCache: _disableTurnStartCache,
1012
1018
  max_tokens: callerMaxTokens,
1013
1019
  usageAttributionHeaders,
1014
1020
  ...restConfig
@@ -1065,38 +1071,17 @@ export class AnthropicProvider implements Provider {
1065
1071
  };
1066
1072
 
1067
1073
  if (systemPrompt) {
1068
- const boundaryIdx = systemPrompt.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
1069
- if (boundaryIdx >= 0) {
1070
- // Split into two cache blocks: static instructions (stable across
1071
- // turns) and dynamic workspace content (changes when files are
1072
- // edited). The static prefix stays cached even when workspace
1073
- // files change, saving ~8-10K tokens of cache creation per turn.
1074
- // Both blocks use 1-hour cache TTL to avoid repeated cache misses
1075
- // for conversations with turn gaps exceeding the default 5-minute
1076
- // window.
1077
- const staticBlock = systemPrompt.slice(0, boundaryIdx);
1078
- const dynamicBlock = systemPrompt.slice(
1079
- boundaryIdx + SYSTEM_PROMPT_CACHE_BOUNDARY.length,
1080
- );
1081
- const systemBlocks = [staticBlock, dynamicBlock]
1082
- .filter((text) => text.length > 0)
1083
- .map((text) => ({
1084
- type: "text" as const,
1085
- text,
1086
- cache_control: cacheControl,
1087
- }));
1088
- if (systemBlocks.length > 0) {
1089
- params.system = systemBlocks;
1090
- }
1091
- } else {
1092
- params.system = [
1093
- {
1094
- type: "text" as const,
1095
- text: systemPrompt,
1096
- cache_control: cacheControl,
1097
- },
1098
- ];
1099
- }
1074
+ // The whole system prompt is rendered as a single cached
1075
+ // block. A 1-hour cache TTL is used (when supported by the
1076
+ // model) so the breakpoint survives turn gaps that exceed the
1077
+ // default 5-minute window.
1078
+ params.system = [
1079
+ {
1080
+ type: "text" as const,
1081
+ text: systemPrompt,
1082
+ cache_control: cacheControl,
1083
+ },
1084
+ ];
1100
1085
  }
1101
1086
 
1102
1087
  if (tools && tools.length > 0) {
@@ -1160,7 +1145,9 @@ export class AnthropicProvider implements Provider {
1160
1145
  }
1161
1146
  };
1162
1147
  const turnStartIdx = findUserTextMsgIdx(msgs.length - 1);
1163
- if (turnStartIdx >= 0) applyCacheControlToLastBlock(turnStartIdx);
1148
+ if (turnStartIdx >= 0 && !disableTurnStartCache) {
1149
+ applyCacheControlToLastBlock(turnStartIdx);
1150
+ }
1164
1151
 
1165
1152
  // Previous-turn anchor: when this request is the first of a new turn
1166
1153
  // (turn-start is the very last message — no tool-use loop yet), also
@@ -1172,9 +1159,8 @@ export class AnthropicProvider implements Provider {
1172
1159
  // cache_creation tokens per new turn). Skipped during tool-use loops
1173
1160
  // where the current turn-start already covers the same prefix and a
1174
1161
  // second anchor would blow the 4-breakpoint budget.
1175
- let prevTurnAnchorIdx = -1;
1176
1162
  if (turnStartIdx === msgs.length - 1 && turnStartIdx > 0) {
1177
- prevTurnAnchorIdx = findUserTextMsgIdx(turnStartIdx - 1);
1163
+ const prevTurnAnchorIdx = findUserTextMsgIdx(turnStartIdx - 1);
1178
1164
  if (prevTurnAnchorIdx >= 0)
1179
1165
  applyCacheControlToLastBlock(prevTurnAnchorIdx);
1180
1166
  }
@@ -1185,7 +1171,6 @@ export class AnthropicProvider implements Provider {
1185
1171
  // cheaply without conflicting with the 1h breakpoints above.
1186
1172
  // Skip thinking/redacted_thinking blocks — Anthropic doesn't allow
1187
1173
  // cache_control on those types.
1188
- let tailBreakpointApplied = false;
1189
1174
  if (turnStartIdx >= 0 && turnStartIdx < sentMessages.length - 1) {
1190
1175
  const lastMsg = sentMessages[sentMessages.length - 1];
1191
1176
  if (Array.isArray(lastMsg.content) && lastMsg.content.length > 0) {
@@ -1207,34 +1192,15 @@ export class AnthropicProvider implements Provider {
1207
1192
  if (tailBlock && typeof tailBlock !== "string") {
1208
1193
  (tailBlock as unknown as Record<string, unknown>).cache_control =
1209
1194
  tailCacheControl;
1210
- tailBreakpointApplied = true;
1211
1195
  }
1212
1196
  }
1213
1197
  }
1214
1198
 
1215
- // Enforce Anthropic API maximum of 4 cache_control blocks.
1216
- // With the system prompt boundary split into 2 cached blocks AND
1217
- // tools + turn-start + (tail OR prev-turn-anchor), we'd have 5.
1218
- // Drop the static system block's breakpoint it's small (<1K
1219
- // tokens) so the re-read cost is negligible, while the dynamic
1220
- // block (workspace context) rarely changes mid-session and
1221
- // benefits more from caching. Tail and prev-turn-anchor are
1222
- // mutually exclusive (prev-turn-anchor only fires when turn-start
1223
- // is the last message, which is the exact condition that suppresses
1224
- // the tail), so we never exceed 5.
1225
- const hasToolCacheBreakpoint =
1226
- params.tools?.some(
1227
- (t) => "cache_control" in t && t.cache_control != null,
1228
- ) ?? false;
1229
- if (
1230
- (tailBreakpointApplied || prevTurnAnchorIdx >= 0) &&
1231
- Array.isArray(params.system) &&
1232
- params.system.length === 2 &&
1233
- hasToolCacheBreakpoint
1234
- ) {
1235
- delete (params.system[0] as unknown as Record<string, unknown>)
1236
- .cache_control;
1237
- }
1199
+ // Cache-breakpoint accounting: system(1) + tools(1) + turn-start(1) +
1200
+ // (tail OR prev-turn-anchor)(1) = 4 exactly Anthropic's per-request
1201
+ // cap. Tail and prev-turn-anchor are mutually exclusive (the latter
1202
+ // only fires when turn-start is the last message, which suppresses
1203
+ // the tail), so the total can't drift past 4.
1238
1204
 
1239
1205
  // Strip orphaned UTF-16 surrogates so the Anthropic JSON parser never
1240
1206
  // sees invalid strings produced by upstream surrogate-splitting `.slice()` calls.
@@ -24,6 +24,10 @@ import { AsyncLocalStorage } from "node:async_hooks";
24
24
  import { resolveCallSiteConfig } from "../config/llm-resolver.js";
25
25
  import { getConfig } from "../config/loader.js";
26
26
  import { getDb } from "../memory/db-connection.js";
27
+ import {
28
+ describeSubscriptionModelIncompatibility,
29
+ isConnectionCompatibleWithModel,
30
+ } from "./connection-model-compat.js";
27
31
  import {
28
32
  ConnectionResolutionError,
29
33
  tryResolveProviderForConnectionName,
@@ -73,10 +77,15 @@ export class CallSiteRoutingProvider implements Provider {
73
77
  * `expectedProvider` is the provider name the resolved profile
74
78
  * declared. The hook verifies the connection's provider matches
75
79
  * and throws on mismatch.
80
+ *
81
+ * `model` is the resolved call-site model, threaded through so the
82
+ * connection lookup can gate `oauth_subscription` (Codex) connections
83
+ * by model compatibility.
76
84
  */
77
85
  private readonly resolveByConnection: (
78
86
  connectionName: string,
79
87
  expectedProvider: string,
88
+ model: string | undefined,
80
89
  ) => Promise<Provider | null>,
81
90
  ) {
82
91
  this.tokenEstimationProvider = defaultProvider.tokenEstimationProvider;
@@ -140,22 +149,33 @@ export class CallSiteRoutingProvider implements Provider {
140
149
  if (!callSite) return this.defaultProvider;
141
150
 
142
151
  const overrideProfile = options?.config?.overrideProfile;
152
+ // Forward the per-conversation mix seed so transport selection picks the
153
+ // same mix arm as wire-param normalization in `retry.ts` — otherwise a mix
154
+ // spanning providers could route the transport to a different arm than the
155
+ // request params.
156
+ const selectionSeed = options?.config?.selectionSeed;
143
157
  const resolved = resolveCallSiteConfig(callSite, getConfig().llm, {
144
158
  overrideProfile,
159
+ selectionSeed,
145
160
  });
146
161
 
147
162
  let connectionName = resolved.provider_connection;
148
163
 
149
164
  // When no connection is set and the provider differs from the default,
150
- // auto-resolve to an active connection for the provider (handles the
151
- // "Any active X connection" case where the profile set provider but
152
- // not provider_connection, and the merge didn't inherit one).
165
+ // auto-resolve a connection for the provider (handles the case where the
166
+ // profile set provider but not provider_connection, and the merge didn't
167
+ // inherit one).
168
+ let autoResolveCandidates:
169
+ | import("./inference/auth.js").ProviderConnection[]
170
+ | undefined;
153
171
  if (!connectionName && resolved.provider !== this.defaultProvider.name) {
154
172
  try {
155
- const candidates = listConnections(getDb(), {
173
+ autoResolveCandidates = listConnections(getDb(), {
156
174
  provider: resolved.provider,
157
175
  });
158
- const active = candidates.find((c) => c.status === "active");
176
+ const active = autoResolveCandidates.find((c) =>
177
+ isConnectionCompatibleWithModel(c, resolved.model),
178
+ );
159
179
  if (active) {
160
180
  connectionName = active.name;
161
181
  }
@@ -168,6 +188,7 @@ export class CallSiteRoutingProvider implements Provider {
168
188
  const connectionProvider = await this.resolveByConnection(
169
189
  connectionName,
170
190
  resolved.provider,
191
+ resolved.model,
171
192
  );
172
193
  if (connectionProvider) return connectionProvider;
173
194
  return this.defaultProvider;
@@ -177,6 +198,20 @@ export class CallSiteRoutingProvider implements Provider {
177
198
  return this.defaultProvider;
178
199
  }
179
200
 
201
+ if (autoResolveCandidates) {
202
+ const incompatMsg = describeSubscriptionModelIncompatibility(
203
+ autoResolveCandidates,
204
+ resolved.model,
205
+ );
206
+ if (incompatMsg) {
207
+ throw new ConnectionResolutionError(
208
+ "<resolved-callsite>",
209
+ "model_incompatible",
210
+ incompatMsg,
211
+ );
212
+ }
213
+ }
214
+
180
215
  throw new ConnectionResolutionError(
181
216
  "<resolved-callsite>",
182
217
  "missing_connection",
@@ -200,11 +235,12 @@ export function wrapWithCallSiteRouting(
200
235
  ): Provider {
201
236
  return new CallSiteRoutingProvider(
202
237
  base,
203
- (connectionName, expectedProvider) =>
238
+ (connectionName, expectedProvider, model) =>
204
239
  tryResolveProviderForConnectionName(
205
240
  connectionName,
206
241
  config,
207
242
  expectedProvider,
243
+ model,
208
244
  ),
209
245
  );
210
246
  }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Model-compatibility gate for auto-resolved provider connections.
3
+ *
4
+ * When a profile uses "Any active <provider> connection" (no
5
+ * `provider_connection` pinned), the daemon auto-picks an active connection
6
+ * for the provider. `oauth_subscription` connections (ChatGPT Codex) hard-
7
+ * route every request to the Codex endpoint, which rejects non-Codex models
8
+ * with HTTP 400. This helper lets the auto-resolution sites skip such a
9
+ * connection when the requested model is not Codex-compatible.
10
+ */
11
+
12
+ import type { ProviderConnection } from "./inference/auth.js";
13
+ import { isCodexSubscriptionModel } from "./openai/codex-models.js";
14
+
15
+ /**
16
+ * Whether `connection` can serve a request for `model` during
17
+ * auto-resolution.
18
+ *
19
+ * `oauth_subscription` connections route through the ChatGPT Codex endpoint,
20
+ * so they are only compatible with Codex models. Every other auth type
21
+ * imposes no model restriction and is always compatible.
22
+ *
23
+ * `model` may be undefined when the call site has no resolved model; in that
24
+ * case no model gating is applied (returns true) so resolution behaviour is
25
+ * unchanged.
26
+ *
27
+ * This gate applies to auto-resolution only — an explicitly pinned
28
+ * `provider_connection` bypasses connection selection entirely and is used
29
+ * regardless of model.
30
+ */
31
+ export function isConnectionCompatibleWithModel(
32
+ connection: Pick<ProviderConnection, "auth">,
33
+ model: string | undefined,
34
+ ): boolean {
35
+ if (connection.auth.type !== "oauth_subscription") return true;
36
+ if (!model) return true;
37
+ return isCodexSubscriptionModel(model);
38
+ }
39
+
40
+ /**
41
+ * When auto-resolution found candidates but none were model-compatible,
42
+ * return a user-facing explanation if the incompatibility is specifically
43
+ * due to all candidates being `oauth_subscription` (ChatGPT) connections.
44
+ *
45
+ * Returns `null` when the incompatibility has a different cause (callers
46
+ * should fall through to their existing generic error).
47
+ */
48
+ export function describeSubscriptionModelIncompatibility(
49
+ candidates: Pick<ProviderConnection, "auth">[],
50
+ model: string | undefined,
51
+ ): string | null {
52
+ if (!model || candidates.length === 0) return null;
53
+ if (candidates.some((c) => isConnectionCompatibleWithModel(c, model))) {
54
+ return null;
55
+ }
56
+ const allSubscription = candidates.every(
57
+ (c) => c.auth.type === "oauth_subscription",
58
+ );
59
+ if (!allSubscription) return null;
60
+ return `Model "${model}" isn't available through your ChatGPT subscription. Select a supported model or add an OpenAI API key connection.`;
61
+ }
@@ -30,6 +30,10 @@
30
30
  import { resolveCallSiteConfig } from "../config/llm-resolver.js";
31
31
  import { getDb } from "../memory/db-connection.js";
32
32
  import { getLogger } from "../util/logger.js";
33
+ import {
34
+ describeSubscriptionModelIncompatibility,
35
+ isConnectionCompatibleWithModel,
36
+ } from "./connection-model-compat.js";
33
37
  import { getConnection, listConnections } from "./inference/connections.js";
34
38
  import type { ProvidersConfig } from "./registry.js";
35
39
  import { resolveProviderFromConnection } from "./registry.js";
@@ -51,7 +55,8 @@ export class ConnectionResolutionError extends Error {
51
55
  | "lookup_failed"
52
56
  | "not_found"
53
57
  | "provider_mismatch"
54
- | "missing_connection",
58
+ | "missing_connection"
59
+ | "model_incompatible",
55
60
  message: string,
56
61
  public readonly cause?: unknown,
57
62
  ) {
@@ -79,11 +84,16 @@ export class ConnectionResolutionError extends Error {
79
84
  * `expectedProvider` is the provider name the resolving profile declared.
80
85
  * Pass `undefined` to skip the mismatch check (callers that don't yet
81
86
  * know the expected provider).
87
+ *
88
+ * `model` is the resolved call-site model. It gates the `provider_mismatch`
89
+ * auto-recovery below so a non-Codex model is never rerouted onto an
90
+ * `oauth_subscription` (ChatGPT Codex) connection.
82
91
  */
83
92
  export async function tryResolveProviderForConnectionName(
84
93
  connectionName: string,
85
94
  config: ProvidersConfig,
86
95
  expectedProvider?: string,
96
+ model?: string,
87
97
  ): Promise<Provider | null> {
88
98
  let connection;
89
99
  try {
@@ -110,10 +120,13 @@ export async function tryResolveProviderForConnectionName(
110
120
  // "anthropic-managed" leaked through). Try to find an active connection
111
121
  // for the expected provider before giving up.
112
122
  let resolved = false;
123
+ let mismatchCandidates: import("./inference/auth.js").ProviderConnection[] | undefined;
113
124
  try {
114
125
  const db = getDb();
115
- const candidates = listConnections(db, { provider: expectedProvider });
116
- const active = candidates.find((c) => c.status === "active");
126
+ mismatchCandidates = listConnections(db, { provider: expectedProvider });
127
+ const active = mismatchCandidates.find((c) =>
128
+ isConnectionCompatibleWithModel(c, model),
129
+ );
117
130
  if (active) {
118
131
  log.info(
119
132
  {
@@ -121,7 +134,7 @@ export async function tryResolveProviderForConnectionName(
121
134
  resolvedConnection: active.name,
122
135
  expectedProvider,
123
136
  },
124
- "Auto-resolved stale provider_connection to matching active connection",
137
+ "Auto-resolved stale provider_connection to matching connection",
125
138
  );
126
139
  connection = active;
127
140
  resolved = true;
@@ -130,6 +143,16 @@ export async function tryResolveProviderForConnectionName(
130
143
  // DB not available — fall through to the original error.
131
144
  }
132
145
  if (!resolved) {
146
+ const incompatMsg = mismatchCandidates
147
+ ? describeSubscriptionModelIncompatibility(mismatchCandidates, model)
148
+ : null;
149
+ if (incompatMsg) {
150
+ throw new ConnectionResolutionError(
151
+ connectionName,
152
+ "model_incompatible",
153
+ incompatMsg,
154
+ );
155
+ }
133
156
  throw new ConnectionResolutionError(
134
157
  connectionName,
135
158
  "provider_mismatch",
@@ -137,13 +160,6 @@ export async function tryResolveProviderForConnectionName(
137
160
  );
138
161
  }
139
162
  }
140
- if (connection.status === "disabled") {
141
- log.debug(
142
- { connectionName, provider: connection.provider },
143
- "provider_connection is disabled — returning null",
144
- );
145
- return null;
146
- }
147
163
  // `resolveProviderFromConnection` reaches into auth resolution (credential
148
164
  // reads, managed-proxy context). A transient failure there is a soft
149
165
  // miss — log and return null so the caller can treat it the same as
@@ -151,7 +167,7 @@ export async function tryResolveProviderForConnectionName(
151
167
  // catch is specifically for in-flight failures that should not take
152
168
  // dispatch offline.
153
169
  try {
154
- return await resolveProviderFromConnection(connection, config);
170
+ return await resolveProviderFromConnection(connection, config, { model });
155
171
  } catch (err) {
156
172
  log.warn(
157
173
  { err, connectionName },
@@ -187,12 +203,15 @@ export async function resolveDefaultProvider(
187
203
  // provider without a connection ("Any active" selection), and the merge
188
204
  // cleared or failed to inherit one. Try to find an active connection
189
205
  // for the provider before giving up.
206
+ let autoResolveCandidates: import("./inference/auth.js").ProviderConnection[] | undefined;
190
207
  if (resolved.provider) {
191
208
  try {
192
- const candidates = listConnections(getDb(), {
209
+ autoResolveCandidates = listConnections(getDb(), {
193
210
  provider: resolved.provider,
194
211
  });
195
- const active = candidates.find((c) => c.status === "active");
212
+ const active = autoResolveCandidates.find((c) =>
213
+ isConnectionCompatibleWithModel(c, resolved.model),
214
+ );
196
215
  if (active) {
197
216
  log.info(
198
217
  { provider: resolved.provider, resolvedConnection: active.name },
@@ -205,6 +224,19 @@ export async function resolveDefaultProvider(
205
224
  }
206
225
  }
207
226
  if (!connectionName) {
227
+ const incompatMsg = autoResolveCandidates
228
+ ? describeSubscriptionModelIncompatibility(
229
+ autoResolveCandidates,
230
+ resolved.model,
231
+ )
232
+ : null;
233
+ if (incompatMsg) {
234
+ throw new ConnectionResolutionError(
235
+ "<llm.default>",
236
+ "model_incompatible",
237
+ incompatMsg,
238
+ );
239
+ }
208
240
  throw new ConnectionResolutionError(
209
241
  "<llm.default>",
210
242
  "missing_connection",
@@ -216,5 +248,6 @@ export async function resolveDefaultProvider(
216
248
  connectionName,
217
249
  config,
218
250
  resolved.provider,
251
+ resolved.model,
219
252
  );
220
253
  }
@@ -34,6 +34,7 @@ export class FireworksProvider extends OpenAIChatCompletionsProvider {
34
34
  // overrides (e.g. DeepSeek V4 → "max") come from
35
35
  // {@link resolveMaxReasoningEffort}.
36
36
  maxReasoningEffort: "high",
37
+ assistantReasoningField: "reasoning_content",
37
38
  });
38
39
  }
39
40