@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
@@ -1,6 +1,5 @@
1
1
  import OpenAI from "openai";
2
2
 
3
- import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/cache-boundary.js";
4
3
  import { isAbortReason } from "../../util/abort-reasons.js";
5
4
  import { ProviderError } from "../../util/errors.js";
6
5
  import { extractRetryAfterMs } from "../../util/retry.js";
@@ -55,6 +54,81 @@ export function detectOpenAICompatibleContextOverflow(
55
54
  return extractOverflowTokensFromMessage(message);
56
55
  }
57
56
 
57
+ /**
58
+ * Build the human-readable error string surfaced from an
59
+ * `OpenAI.APIError`. The SDK's `error.message` is typically a one-line
60
+ * summary like `"400 Provider returned error"` — useless when the
61
+ * upstream is OpenRouter (which wraps the real downstream error on
62
+ * `error.error.metadata.raw`) or any provider that returns nested
63
+ * structured details.
64
+ *
65
+ * Returns `{ detail, requestId }` where `detail` includes the JSON body
66
+ * (truncated) and `requestId` is the upstream correlation header when
67
+ * present. Callers fold these into the thrown `ProviderError` so log
68
+ * lines actually identify the failure without re-running the request.
69
+ *
70
+ * Exported for tests.
71
+ */
72
+ export function extractApiErrorDetail(
73
+ error: InstanceType<typeof OpenAI.APIError>,
74
+ ): { detail: string; requestId: string | undefined } {
75
+ const body = (error as { error?: unknown }).error;
76
+ let detail = "";
77
+ if (body !== undefined && body !== null) {
78
+ try {
79
+ const serialized = typeof body === "string" ? body : JSON.stringify(body);
80
+ if (serialized && serialized !== "{}") {
81
+ detail =
82
+ serialized.length > MAX_API_ERROR_DETAIL_CHARS
83
+ ? `${serialized.slice(0, MAX_API_ERROR_DETAIL_CHARS)}…`
84
+ : serialized;
85
+ }
86
+ } catch {
87
+ // Body had a cycle or threw on toJSON — fall through with empty detail.
88
+ }
89
+ }
90
+ const requestId = readHeader(error.headers, [
91
+ "x-request-id",
92
+ "x-openrouter-request-id",
93
+ "openai-request-id",
94
+ "x-amzn-requestid",
95
+ ]);
96
+ return { detail, requestId };
97
+ }
98
+
99
+ /** Cap on the inline-rendered body to keep log lines readable while still
100
+ * surfacing the meaningful upstream payload. Tuned to comfortably hold
101
+ * OpenRouter's `error.metadata.raw` strings, which are typically <1KB. */
102
+ const MAX_API_ERROR_DETAIL_CHARS = 2000;
103
+
104
+ /**
105
+ * Read the first matching header from an SDK error's headers object,
106
+ * tolerating both Map-like (`Headers.get()`) and plain-object shapes.
107
+ * Mirrors the shape-tolerance already in `extractRetryAfterMs`.
108
+ */
109
+ function readHeader(
110
+ headers: unknown,
111
+ names: readonly string[],
112
+ ): string | undefined {
113
+ if (!headers) return undefined;
114
+ const getter =
115
+ typeof (headers as { get?: unknown }).get === "function"
116
+ ? (headers as { get(name: string): string | null }).get.bind(headers)
117
+ : undefined;
118
+ for (const name of names) {
119
+ let value: string | null | undefined;
120
+ if (getter) {
121
+ value = getter(name);
122
+ } else if (typeof headers === "object") {
123
+ const record = headers as Record<string, unknown>;
124
+ const raw = record[name] ?? record[name.toLowerCase()];
125
+ value = typeof raw === "string" ? raw : undefined;
126
+ }
127
+ if (typeof value === "string" && value.length > 0) return value;
128
+ }
129
+ return undefined;
130
+ }
131
+
58
132
  export interface OpenAIChatCompletionsProviderOptions {
59
133
  baseURL?: string;
60
134
  providerName?: string;
@@ -76,6 +150,10 @@ export interface OpenAIChatCompletionsProviderOptions {
76
150
  * blocks. MiniMax and similar providers embed reasoning inside XML-style
77
151
  * tags in the regular content field rather than using `reasoning_content`. */
78
152
  parseThinkTags?: boolean;
153
+ /** Wire field used to replay prior assistant thinking on multi-turn requests.
154
+ * DeepSeek/Fireworks use `"reasoning_content"`; OpenRouter uses `"reasoning"`.
155
+ * When unset, thinking blocks are dropped from outbound assistant messages. */
156
+ assistantReasoningField?: "reasoning" | "reasoning_content";
79
157
  }
80
158
 
81
159
  /** Wire-level reasoning_effort values. The OpenAI SDK type doesn't include
@@ -147,6 +225,10 @@ export class OpenAIChatCompletionsProvider implements Provider {
147
225
  private maxReasoningEffort: "high" | "xhigh" | "max";
148
226
  private requestHeaders: Record<string, string>;
149
227
  private parseThinkTags: boolean;
228
+ private assistantReasoningField:
229
+ | "reasoning"
230
+ | "reasoning_content"
231
+ | undefined;
150
232
 
151
233
  constructor(
152
234
  apiKey: string,
@@ -155,16 +237,21 @@ export class OpenAIChatCompletionsProvider implements Provider {
155
237
  ) {
156
238
  this.name = options.providerName ?? "openai";
157
239
  this.providerLabel = options.providerLabel ?? "OpenAI";
240
+ this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
241
+ // Keep the SDK deadline behind our provider stream timeout so
242
+ // createStreamTimeout owns the user-facing timeout error.
243
+ const sdkTimeoutMs = this.streamTimeoutMs + 60_000;
158
244
  this.client = new OpenAI({
159
245
  apiKey,
160
246
  baseURL: options.baseURL,
247
+ timeout: sdkTimeoutMs,
161
248
  });
162
249
  this.model = model;
163
- this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
164
250
  this.extraCreateParams = options.extraCreateParams ?? {};
165
251
  this.maxReasoningEffort = options.maxReasoningEffort ?? "xhigh";
166
252
  this.requestHeaders = options.requestHeaders ?? {};
167
253
  this.parseThinkTags = options.parseThinkTags ?? false;
254
+ this.assistantReasoningField = options.assistantReasoningField;
168
255
  }
169
256
 
170
257
  async sendMessage(
@@ -521,18 +608,18 @@ export class OpenAIChatCompletionsProvider implements Provider {
521
608
  ? signal.reason
522
609
  : undefined;
523
610
  if (error instanceof OpenAI.APIError) {
611
+ const { detail, requestId } = extractApiErrorDetail(error);
612
+ const detailSuffix = detail ? ` ${detail}` : "";
613
+ const requestIdSuffix = requestId ? ` [request_id=${requestId}]` : "";
614
+ const formattedMessage = `${this.providerLabel} API error (${error.status}): ${error.message}${detailSuffix}${requestIdSuffix}`;
524
615
  const overflow = detectOpenAICompatibleContextOverflow(error);
525
616
  if (overflow) {
526
- throw new ContextOverflowError(
527
- `${this.providerLabel} API error (${error.status}): ${error.message}`,
528
- this.name,
529
- {
530
- actualTokens: overflow.actualTokens,
531
- maxTokens: overflow.maxTokens,
532
- statusCode: error.status,
533
- cause: error,
534
- },
535
- );
617
+ throw new ContextOverflowError(formattedMessage, this.name, {
618
+ actualTokens: overflow.actualTokens,
619
+ maxTokens: overflow.maxTokens,
620
+ statusCode: error.status,
621
+ cause: error,
622
+ });
536
623
  }
537
624
  const retryAfterMs = extractRetryAfterMs(error.headers);
538
625
  const errorOptions: {
@@ -543,7 +630,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
543
630
  errorOptions.retryAfterMs = retryAfterMs;
544
631
  if (abortReason) errorOptions.abortReason = abortReason;
545
632
  throw new ProviderError(
546
- `${this.providerLabel} API error (${error.status}): ${error.message}`,
633
+ formattedMessage,
547
634
  this.name,
548
635
  error.status,
549
636
  Object.keys(errorOptions).length > 0 ? errorOptions : undefined,
@@ -593,7 +680,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
593
680
  if (systemPrompt) {
594
681
  result.push({
595
682
  role: "system",
596
- content: systemPrompt.replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY, "\n"),
683
+ content: systemPrompt,
597
684
  });
598
685
  }
599
686
 
@@ -658,6 +745,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
658
745
  msg: Message,
659
746
  ): OpenAI.Chat.Completions.ChatCompletionAssistantMessageParam {
660
747
  const textParts: string[] = [];
748
+ const reasoningParts: string[] = [];
661
749
  const toolCalls: OpenAI.Chat.Completions.ChatCompletionMessageToolCall[] =
662
750
  [];
663
751
 
@@ -666,6 +754,10 @@ export class OpenAIChatCompletionsProvider implements Provider {
666
754
  case "text":
667
755
  textParts.push(block.text);
668
756
  break;
757
+ case "thinking":
758
+ // Anthropic thinking blocks carry signatures — skip those.
759
+ if (!block.signature) reasoningParts.push(block.thinking);
760
+ break;
669
761
  case "tool_use":
670
762
  toolCalls.push({
671
763
  id: block.id,
@@ -682,7 +774,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
682
774
  case "web_search_tool_result":
683
775
  textParts.push("[Web search results]");
684
776
  break;
685
- // thinking, redacted_thinking, image — not applicable for OpenAI assistant messages
777
+ // redacted_thinking, image — not applicable for OpenAI assistant messages
686
778
  }
687
779
  }
688
780
 
@@ -692,6 +784,15 @@ export class OpenAIChatCompletionsProvider implements Provider {
692
784
  content: textParts.length > 0 ? textParts.join("") : null,
693
785
  };
694
786
 
787
+ if (reasoningParts.length > 0 && this.assistantReasoningField) {
788
+ (
789
+ result as OpenAI.Chat.Completions.ChatCompletionAssistantMessageParam & {
790
+ reasoning?: string;
791
+ reasoning_content?: string;
792
+ }
793
+ )[this.assistantReasoningField] = reasoningParts.join("");
794
+ }
795
+
695
796
  if (toolCalls.length > 0) {
696
797
  result.tool_calls = toolCalls;
697
798
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Model IDs accepted by the ChatGPT Codex subscription endpoint
3
+ * (`https://chatgpt.com/backend-api/codex`).
4
+ *
5
+ * `oauth_subscription` OpenAI connections hard-route every request to that
6
+ * endpoint, which rejects any model outside this set with HTTP 400. The set
7
+ * gates whether such a connection may serve a given model during auto-
8
+ * resolution of an "Any active OpenAI connection" profile.
9
+ */
10
+ export const CODEX_SUBSCRIPTION_MODEL_IDS: ReadonlySet<string> = new Set([
11
+ "gpt-5.5",
12
+ "gpt-5.4",
13
+ "gpt-5.4-mini",
14
+ "gpt-5.3-codex",
15
+ ]);
16
+
17
+ /** True when `model` is accepted by the Codex subscription endpoint. */
18
+ export function isCodexSubscriptionModel(model: string): boolean {
19
+ return CODEX_SUBSCRIPTION_MODEL_IDS.has(model);
20
+ }
@@ -1,8 +1,8 @@
1
1
  import OpenAI from "openai";
2
2
 
3
- import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../../prompts/cache-boundary.js";
4
3
  import { isAbortReason } from "../../util/abort-reasons.js";
5
4
  import { ProviderError } from "../../util/errors.js";
5
+ import { getLogger } from "../../util/logger.js";
6
6
  import { extractRetryAfterMs } from "../../util/retry.js";
7
7
  import { escapeXmlAttr } from "../../util/xml.js";
8
8
  import { createStreamTimeout } from "../stream-timeout.js";
@@ -17,6 +17,8 @@ import type {
17
17
  import { ContextOverflowError } from "../types.js";
18
18
  import { detectOpenAICompatibleContextOverflow } from "./chat-completions-provider.js";
19
19
 
20
+ const log = getLogger("openai-responses");
21
+
20
22
  export interface OpenAIResponsesProviderOptions {
21
23
  baseURL?: string;
22
24
  providerName?: string;
@@ -24,7 +26,7 @@ export interface OpenAIResponsesProviderOptions {
24
26
  streamTimeoutMs?: number;
25
27
  useNativeWebSearch?: boolean;
26
28
  /** When true, target the Codex subscription endpoint and strip fields it
27
- * rejects (`max_output_tokens`, `metadata`). */
29
+ * rejects (`max_output_tokens`). */
28
30
  codexSubscription?: boolean;
29
31
  }
30
32
 
@@ -72,6 +74,9 @@ interface ResponsesStreamEvent {
72
74
  response?: {
73
75
  model?: string;
74
76
  status?: string;
77
+ incomplete_details?: {
78
+ reason?: "max_output_tokens" | "content_filter";
79
+ } | null;
75
80
  /** Full output items array — preserved as part of rawResponse for the
76
81
  * LLM context normalizer, which uses its presence to detect Responses
77
82
  * API payloads in stored diagnostics. */
@@ -107,6 +112,7 @@ export class OpenAIResponsesProvider implements Provider {
107
112
  private streamTimeoutMs: number;
108
113
  private useNativeWebSearch: boolean;
109
114
  private codexSubscription: boolean;
115
+ private lastCodexErrorBody: string | undefined;
110
116
 
111
117
  constructor(
112
118
  apiKey: string,
@@ -116,14 +122,39 @@ export class OpenAIResponsesProvider implements Provider {
116
122
  this.name = options.providerName ?? "openai";
117
123
  this.providerLabel = options.providerLabel ?? "OpenAI";
118
124
  this.codexSubscription = options.codexSubscription ?? false;
125
+ this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
126
+ // Keep the SDK deadline behind our provider stream timeout so
127
+ // createStreamTimeout owns the user-facing timeout error.
128
+ const sdkTimeoutMs = this.streamTimeoutMs + 60_000;
119
129
  this.client = new OpenAI({
120
130
  apiKey,
121
131
  baseURL: this.codexSubscription
122
132
  ? "https://chatgpt.com/backend-api/codex"
123
133
  : options.baseURL,
134
+ timeout: sdkTimeoutMs,
135
+ ...(this.codexSubscription
136
+ ? {
137
+ fetch: async (url: RequestInfo | URL, init?: RequestInit) => {
138
+ const res = await globalThis.fetch(url, init);
139
+ if (!res.ok) {
140
+ const body = await res.text();
141
+ this.lastCodexErrorBody = body;
142
+ log.warn(
143
+ { status: res.status, body, url: String(url) },
144
+ "Codex endpoint raw error response",
145
+ );
146
+ return new Response(body, {
147
+ status: res.status,
148
+ statusText: res.statusText,
149
+ headers: res.headers,
150
+ });
151
+ }
152
+ return res;
153
+ },
154
+ }
155
+ : {}),
124
156
  });
125
157
  this.model = model;
126
- this.streamTimeoutMs = options.streamTimeoutMs ?? 1_800_000;
127
158
  this.useNativeWebSearch = options.useNativeWebSearch ?? false;
128
159
  }
129
160
 
@@ -149,13 +180,11 @@ export class OpenAIResponsesProvider implements Provider {
149
180
  const params: Record<string, unknown> = {
150
181
  model: modelOverride ?? this.model,
151
182
  input,
183
+ ...(this.codexSubscription ? { store: false } : {}),
152
184
  };
153
185
 
154
186
  if (systemPrompt) {
155
- params.instructions = systemPrompt.replaceAll(
156
- SYSTEM_PROMPT_CACHE_BOUNDARY,
157
- "\n",
158
- );
187
+ params.instructions = systemPrompt;
159
188
  }
160
189
 
161
190
  if (maxTokens && !this.codexSubscription) {
@@ -190,9 +219,9 @@ export class OpenAIResponsesProvider implements Provider {
190
219
  parameters: t.input_schema,
191
220
  strict: null,
192
221
  }));
193
- const webSearchTool = {
194
- type: "web_search_preview" as const,
195
- };
222
+ const webSearchTool = this.codexSubscription
223
+ ? { type: "web_search" as const, external_web_access: false }
224
+ : { type: "web_search_preview" as const };
196
225
  params.tools = [...mappedOther, webSearchTool];
197
226
  } else {
198
227
  params.tools = tools.map((t) => ({
@@ -228,20 +257,26 @@ export class OpenAIResponsesProvider implements Provider {
228
257
  let rawFinalResponse: unknown = undefined;
229
258
 
230
259
  try {
231
- // The SDK exposes `client.responses.stream()` cast through
232
- // `unknown` to avoid `any` while the SDK's exported types stabilise.
260
+ // Use `create()` with `stream: true` instead of the higher-level
261
+ // `stream()` helper. The `stream()` helper wraps the response in a
262
+ // `ResponseStream` that runs `maybeParseResponse()` after iteration,
263
+ // which crashes when the Codex subscription endpoint omits `output`
264
+ // from the `response.completed` event payload.
233
265
  const responsesApi = this.client.responses as unknown as {
234
- stream(
266
+ create(
235
267
  p: Record<string, unknown>,
236
- o: { signal: AbortSignal; headers?: Record<string, string> },
237
- ): AsyncIterable<ResponsesStreamEvent>;
268
+ o?: { signal?: AbortSignal; headers?: Record<string, string> },
269
+ ): Promise<AsyncIterable<ResponsesStreamEvent>>;
238
270
  };
239
- const stream = responsesApi.stream(params, {
240
- signal: timeoutSignal,
241
- ...(usageAttributionHeaders
242
- ? { headers: usageAttributionHeaders }
243
- : {}),
244
- });
271
+ const stream = await responsesApi.create(
272
+ { ...params, stream: true },
273
+ {
274
+ signal: timeoutSignal,
275
+ ...(usageAttributionHeaders
276
+ ? { headers: usageAttributionHeaders }
277
+ : {}),
278
+ },
279
+ );
245
280
 
246
281
  for await (const event of stream) {
247
282
  switch (event.type) {
@@ -313,7 +348,8 @@ export class OpenAIResponsesProvider implements Provider {
313
348
  break;
314
349
  }
315
350
 
316
- case "response.completed": {
351
+ case "response.completed":
352
+ case "response.incomplete": {
317
353
  const response = event.response;
318
354
  if (response) {
319
355
  rawFinalResponse = response;
@@ -328,15 +364,22 @@ export class OpenAIResponsesProvider implements Provider {
328
364
  cachedInputTokens =
329
365
  response.usage.input_tokens_details?.cached_tokens ?? 0;
330
366
  }
331
- finishReason = response.status ?? "completed";
367
+ finishReason =
368
+ response.incomplete_details?.reason ??
369
+ response.status ??
370
+ (event.type === "response.incomplete"
371
+ ? "incomplete"
372
+ : "completed");
332
373
  }
333
374
  // Emit server_tool_complete for any web search calls that were started.
334
- for (const toolUseId of webSearchCallIds) {
335
- onEvent?.({
336
- type: "server_tool_complete",
337
- toolUseId,
338
- isError: false,
339
- });
375
+ if (event.type === "response.completed") {
376
+ for (const toolUseId of webSearchCallIds) {
377
+ onEvent?.({
378
+ type: "server_tool_complete",
379
+ toolUseId,
380
+ isError: false,
381
+ });
382
+ }
340
383
  }
341
384
  break;
342
385
  }
@@ -431,8 +474,22 @@ export class OpenAIResponsesProvider implements Provider {
431
474
  if (retryAfterMs !== undefined)
432
475
  errorOptions.retryAfterMs = retryAfterMs;
433
476
  if (abortReason) errorOptions.abortReason = abortReason;
477
+ let errorDetail = error.message;
478
+ if (this.lastCodexErrorBody) {
479
+ try {
480
+ const parsed = JSON.parse(this.lastCodexErrorBody);
481
+ if (parsed.detail) errorDetail = parsed.detail;
482
+ } catch {
483
+ errorDetail = this.lastCodexErrorBody.slice(0, 200);
484
+ }
485
+ this.lastCodexErrorBody = undefined;
486
+ }
487
+ const extras = [error.code, error.type, error.param]
488
+ .filter(Boolean)
489
+ .join(", ");
490
+ const extraSuffix = extras ? ` [${extras}]` : "";
434
491
  throw new ProviderError(
435
- `${this.providerLabel} API error (${error.status}): ${error.message}`,
492
+ `${this.providerLabel} API error (${error.status}): ${errorDetail}${extraSuffix}`,
436
493
  this.name,
437
494
  error.status,
438
495
  Object.keys(errorOptions).length > 0 ? errorOptions : undefined,
@@ -122,6 +122,7 @@ export class OpenRouterProvider extends OpenAIChatCompletionsProvider {
122
122
  providerLabel: "OpenRouter",
123
123
  streamTimeoutMs: options.streamTimeoutMs,
124
124
  requestHeaders: OPENROUTER_APP_ATTRIBUTION_HEADERS,
125
+ assistantReasoningField: "reasoning",
125
126
  });
126
127
  this.openRouterApiKey = apiKey;
127
128
  this.defaultModel = model;
@@ -199,17 +200,21 @@ export class OpenRouterProvider extends OpenAIChatCompletionsProvider {
199
200
  ? EFFORT_TO_REASONING_EFFORT[effort]
200
201
  : undefined;
201
202
  const summaryOverride = extractReasoningSummaryOverride(config);
202
- const reasoning: Record<string, unknown> = { enabled: thinkingEnabled };
203
- if (mappedEffort) {
204
- reasoning.effort = clampReasoningEffort(
205
- mappedEffort,
206
- this.resolveMaxReasoningEffort(this.resolveEffectiveModel(options)),
207
- );
208
- }
203
+ // Only send `reasoning` when explicitly enabling thinking. Omitting the
204
+ // field lets OpenRouter use the model's natural default, which avoids 400s
205
+ // from reasoning-only models (e.g. DeepSeek R1) that reject `enabled: false`.
206
+ const extras: Record<string, unknown> = {};
209
207
  if (thinkingEnabled) {
208
+ const reasoning: Record<string, unknown> = { enabled: true };
209
+ if (mappedEffort) {
210
+ reasoning.effort = clampReasoningEffort(
211
+ mappedEffort,
212
+ this.resolveMaxReasoningEffort(this.resolveEffectiveModel(options)),
213
+ );
214
+ }
210
215
  reasoning.summary = summaryOverride ?? "detailed";
216
+ extras.reasoning = reasoning;
211
217
  }
212
- const extras: Record<string, unknown> = { reasoning };
213
218
  const only = extractOnlyList(config);
214
219
  if (only.length > 0) {
215
220
  const existingProvider = (config?.provider ?? {}) as Record<
@@ -9,6 +9,10 @@ import { getConfig } from "../config/loader.js";
9
9
  import type { LLMCallSite } from "../config/schemas/llm.js";
10
10
  import { getDb } from "../memory/db-connection.js";
11
11
  import { getLogger } from "../util/logger.js";
12
+ import {
13
+ describeSubscriptionModelIncompatibility,
14
+ isConnectionCompatibleWithModel,
15
+ } from "./connection-model-compat.js";
12
16
  import { tryResolveProviderForConnectionName } from "./connection-resolution.js";
13
17
  import { listConnections } from "./inference/connections.js";
14
18
  import { initializeProviders, listProviders } from "./registry.js";
@@ -116,19 +120,29 @@ export async function resolveConfiguredProvider(
116
120
 
117
121
  // Connection-aware path: every dispatch goes through `provider_connection`.
118
122
  // The boot-time backfill ensures every profile has one in production.
119
- // When unset (profile set provider with "Any active" connection, test envs
120
- // that skip backfill, freshly-installed configs not yet backfilled, or
121
- // users who manually cleared the field), try to auto-resolve from the
122
- // provider before falling back to null.
123
+ // When unset (profile set provider without a connection, test envs that
124
+ // skip backfill, freshly-installed configs not yet backfilled, or users
125
+ // who manually cleared the field), try to auto-resolve from the provider
126
+ // before falling back to null.
123
127
  if (!connectionName) {
124
128
  if (inferenceProvider) {
125
129
  try {
126
130
  const candidates = listConnections(getDb(), {
127
131
  provider: inferenceProvider,
128
132
  });
129
- const active = candidates.find((c) => c.status === "active");
133
+ const active = candidates.find((c) =>
134
+ isConnectionCompatibleWithModel(c, resolved.model),
135
+ );
130
136
  if (active) {
131
137
  connectionName = active.name;
138
+ } else {
139
+ const incompatMsg = describeSubscriptionModelIncompatibility(
140
+ candidates,
141
+ resolved.model,
142
+ );
143
+ if (incompatMsg) {
144
+ log.warn({ callSite, inferenceProvider, model: resolved.model }, incompatMsg);
145
+ }
132
146
  }
133
147
  } catch {
134
148
  // DB not available — fall through to the existing null-return path.
@@ -147,6 +161,7 @@ export async function resolveConfiguredProvider(
147
161
  connectionName,
148
162
  config,
149
163
  inferenceProvider,
164
+ resolved.model,
150
165
  );
151
166
  if (!connectionProvider) {
152
167
  // Soft credential failure — the connection resolved to no usable
@@ -29,10 +29,18 @@ const log = getLogger("provider-registry");
29
29
  const providers = new Map<string, Provider>();
30
30
  const routingSources = new Map<string, "user-key" | "managed-proxy">();
31
31
  const OPENAI_COMPATIBLE_ENDPOINTS_FLAG = "openai-compatible-endpoints";
32
+ const NATIVE_WEB_SEARCH_PROVIDER_IDS = new Set(["anthropic", "openai"]);
32
33
 
33
- /** Per-connection provider cache, keyed by connection name. */
34
+ /** Per-connection provider cache, keyed by connection name and model. */
34
35
  const connectionProviders = new Map<string, Provider>();
35
36
 
37
+ function getConnectionProviderCacheKey(
38
+ connection: ProviderConnection,
39
+ model: string,
40
+ ): string {
41
+ return `${connection.name}\u0000${model}`;
42
+ }
43
+
36
44
  function registerProvider(name: string, provider: Provider): void {
37
45
  providers.set(name, new UsageTrackingProvider(provider));
38
46
  }
@@ -98,6 +106,30 @@ function resolveModel(config: ProvidersConfig, providerName: string): string {
98
106
  return getProviderDefaultModel(providerName);
99
107
  }
100
108
 
109
+ export function isNativeWebSearchCapableProvider(
110
+ providerName: string,
111
+ model: string,
112
+ ): boolean {
113
+ if (NATIVE_WEB_SEARCH_PROVIDER_IDS.has(providerName)) {
114
+ return true;
115
+ }
116
+ if (providerName === "openrouter" && model.startsWith("anthropic/")) {
117
+ return true;
118
+ }
119
+ return false;
120
+ }
121
+
122
+ function shouldUseNativeWebSearch(
123
+ config: ProvidersConfig,
124
+ providerName: string,
125
+ model: string,
126
+ ): boolean {
127
+ return (
128
+ config.services["web-search"].provider === "inference-provider-native" &&
129
+ isNativeWebSearchCapableProvider(providerName, model)
130
+ );
131
+ }
132
+
101
133
  /**
102
134
  * Resolve provider credentials. User key takes precedence; managed proxy is
103
135
  * used as a fallback when platform prerequisites are available.
@@ -135,8 +167,6 @@ export async function initializeProviders(
135
167
 
136
168
  const streamTimeoutMs =
137
169
  (config.timeouts?.providerStreamTimeoutSec ?? 1800) * 1000;
138
- const useNativeWebSearch =
139
- config.services["web-search"].provider === "inference-provider-native";
140
170
  const mainAgentProvider = resolveCallSiteConfig(
141
171
  "mainAgent",
142
172
  config.llm,
@@ -174,6 +204,11 @@ export async function initializeProviders(
174
204
  }
175
205
 
176
206
  const model = resolveModel(config, entry.id);
207
+ const useNativeWebSearch = shouldUseNativeWebSearch(
208
+ config,
209
+ entry.id,
210
+ model,
211
+ );
177
212
  const adapter = buildProviderAdapter(entry.id, {
178
213
  apiKey,
179
214
  model,
@@ -221,6 +256,7 @@ export async function initializeProviders(
221
256
  export async function resolveProviderFromConnection(
222
257
  connection: ProviderConnection,
223
258
  config: ProvidersConfig,
259
+ opts: { model?: string } = {},
224
260
  ): Promise<Provider | null> {
225
261
  if (
226
262
  connection.provider === "openai-compatible" &&
@@ -229,7 +265,9 @@ export async function resolveProviderFromConnection(
229
265
  return null;
230
266
  }
231
267
 
232
- const cached = connectionProviders.get(connection.name);
268
+ const model = opts.model ?? resolveModel(config, connection.provider);
269
+ const cacheKey = getConnectionProviderCacheKey(connection, model);
270
+ const cached = connectionProviders.get(cacheKey);
233
271
  if (cached) return cached;
234
272
 
235
273
  const authResult = await resolveAuth(connection.auth, connection.provider, {
@@ -259,9 +297,11 @@ export async function resolveProviderFromConnection(
259
297
 
260
298
  const streamTimeoutMs =
261
299
  (config.timeouts?.providerStreamTimeoutSec ?? 1800) * 1000;
262
- const useNativeWebSearch =
263
- config.services["web-search"].provider === "inference-provider-native";
264
- const model = resolveModel(config, connection.provider);
300
+ const useNativeWebSearch = shouldUseNativeWebSearch(
301
+ config,
302
+ connection.provider,
303
+ model,
304
+ );
265
305
 
266
306
  const provider = createAdapterFromConnection(
267
307
  connection,
@@ -274,7 +314,7 @@ export async function resolveProviderFromConnection(
274
314
  );
275
315
 
276
316
  if (provider) {
277
- connectionProviders.set(connection.name, provider);
317
+ connectionProviders.set(cacheKey, provider);
278
318
  }
279
319
 
280
320
  return provider;