@bitkyc08/opencodex 2.84.0 → 2.87.0

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 (518) hide show
  1. package/README.md +0 -4
  2. package/bin/ocx.mjs +61 -3
  3. package/gui/dist/assets/App-ZfYbLHkB.js +58 -0
  4. package/gui/dist/assets/App-wT3mXqFz.css +1 -0
  5. package/gui/dist/assets/{Tray-C9TGtwad.js → Tray-DCd-A1az.js} +1 -1
  6. package/gui/dist/assets/index-CfYDMj34.js +94 -0
  7. package/gui/dist/assets/index-DPeB9HpV.css +1 -0
  8. package/gui/dist/assets/quota-summary-ChvmKGOk.js +1 -0
  9. package/gui/dist/index.html +2 -2
  10. package/package.json +1 -2
  11. package/src/adapters/anthropic/beta-allowlist.ts +91 -11
  12. package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
  13. package/src/adapters/anthropic/client-identity.ts +1 -1
  14. package/src/adapters/anthropic/passthrough.ts +16 -3
  15. package/src/adapters/anthropic-progress.ts +84 -0
  16. package/src/adapters/anthropic.ts +108 -21
  17. package/src/adapters/azure.ts +19 -1
  18. package/src/adapters/base.ts +2 -0
  19. package/src/adapters/claude-cli/adapter.ts +111 -23
  20. package/src/adapters/claude-cli/profiles.ts +2 -1
  21. package/src/adapters/claude-cli/stable-replay.ts +108 -0
  22. package/src/adapters/claude-cli/usage-admission.ts +230 -0
  23. package/src/adapters/client-fingerprint.ts +24 -0
  24. package/src/adapters/coding-agent/protocol.ts +1 -1
  25. package/src/adapters/coding-agent/turn.ts +40 -11
  26. package/src/adapters/cursor/arg-codec.ts +17 -5
  27. package/src/adapters/cursor/catalog.ts +8 -0
  28. package/src/adapters/cursor/effort-map.ts +3 -0
  29. package/src/adapters/cursor/freeform-args.ts +75 -0
  30. package/src/adapters/cursor/protobuf-events.ts +36 -23
  31. package/src/adapters/dsh-account.ts +97 -0
  32. package/src/adapters/google-antigravity-wire.ts +22 -1
  33. package/src/adapters/google.ts +37 -10
  34. package/src/adapters/openai-chat/messages.ts +4 -3
  35. package/src/adapters/openai-chat/passthrough.ts +8 -2
  36. package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
  37. package/src/adapters/openai-chat/response-events.ts +59 -1
  38. package/src/adapters/openai-chat.ts +8 -5
  39. package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
  40. package/src/adapters/openai-responses/passthrough.ts +57 -125
  41. package/src/adapters/openai-responses/request-strips.ts +25 -3
  42. package/src/adapters/openai-responses/transport.ts +81 -0
  43. package/src/adapters/qoder/adapter.ts +44 -3
  44. package/src/adapters/registry.ts +5 -0
  45. package/src/adapters/zed.ts +26 -1
  46. package/src/advisor/activity.ts +55 -0
  47. package/src/advisor/budget.ts +62 -0
  48. package/src/advisor/consult.ts +223 -0
  49. package/src/advisor/context.ts +238 -0
  50. package/src/advisor/disclosure.ts +20 -0
  51. package/src/advisor/evidence-tool.ts +21 -0
  52. package/src/advisor/evidence.ts +117 -0
  53. package/src/advisor/runtime.ts +353 -0
  54. package/src/advisor/settings.ts +144 -0
  55. package/src/advisor/state.ts +369 -0
  56. package/src/advisor/synthetic-tool.ts +33 -0
  57. package/src/bridge/errors.ts +24 -1
  58. package/src/bridge/internal.ts +3 -1
  59. package/src/bridge/response-json.ts +18 -3
  60. package/src/bridge/sse.ts +58 -8
  61. package/src/bridge/terminal-refusal.ts +59 -0
  62. package/src/chat/inbound.ts +30 -6
  63. package/src/chat/outbound.ts +5 -0
  64. package/src/claude/desktop-3p-library.ts +72 -7
  65. package/src/claude/desktop-3p.ts +75 -19
  66. package/src/claude/desktop-first-party.ts +1 -1
  67. package/src/claude/desktop-picker-platform.ts +4 -0
  68. package/src/claude/desktop-picker-profile.ts +11 -4
  69. package/src/claude/desktop-picker.ts +15 -8
  70. package/src/claude/desktop-profile.ts +10 -1
  71. package/src/claude/desktop-remote-store-io.ts +5 -3
  72. package/src/claude/desktop-system-proxy.ts +50 -4
  73. package/src/claude/inbound-content-options.ts +11 -0
  74. package/src/claude/inbound.ts +154 -50
  75. package/src/claude/intercept/local-ca.ts +8 -1
  76. package/src/claude/intercept/picker-ca-startup.ts +2 -1
  77. package/src/claude/intercept/picker-runtime.ts +6 -5
  78. package/src/claude/intercept/picker-trust-windows.ts +338 -0
  79. package/src/claude/intercept/picker-trust.ts +19 -0
  80. package/src/claude/intercept/port-policy.ts +30 -0
  81. package/src/claude/intercept/runtime.ts +97 -94
  82. package/src/claude/model-default-settings.ts +154 -0
  83. package/src/claude/model-info.ts +7 -7
  84. package/src/claude/outbound.ts +51 -19
  85. package/src/cli/account-api.ts +1 -0
  86. package/src/cli/account-policy-dto.ts +6 -0
  87. package/src/cli/account-policy.ts +34 -5
  88. package/src/cli/account-preservation.ts +44 -0
  89. package/src/cli/account.ts +8 -2
  90. package/src/cli/advisor.ts +165 -0
  91. package/src/cli/auxiliary-listener-preflight.ts +37 -0
  92. package/src/cli/capabilities-accounts.ts +20 -1
  93. package/src/cli/capabilities-agents-routing.ts +23 -2
  94. package/src/cli/capabilities-base.ts +39 -11
  95. package/src/cli/capabilities-observe-system.ts +63 -3
  96. package/src/cli/capabilities-provider-models.ts +11 -0
  97. package/src/cli/chatgpt-command.ts +35 -14
  98. package/src/cli/claude.ts +46 -6
  99. package/src/cli/codex-cli-update.ts +151 -41
  100. package/src/cli/codex-provider.ts +44 -0
  101. package/src/cli/combo-input.ts +10 -1
  102. package/src/cli/combo-result.ts +1 -1
  103. package/src/cli/combo.ts +2 -1
  104. package/src/cli/cross-home-owner.ts +17 -14
  105. package/src/cli/dispatch.ts +30 -5
  106. package/src/cli/doctor.ts +15 -1
  107. package/src/cli/ensure-desktop-cold-start.ts +382 -0
  108. package/src/cli/export-command.ts +1 -1
  109. package/src/cli/help.ts +4 -2
  110. package/src/cli/index.ts +14 -5
  111. package/src/cli/integration-plan-dto.ts +3 -0
  112. package/src/cli/log-history.ts +172 -0
  113. package/src/cli/models-runtime-subcommands.ts +1 -0
  114. package/src/cli/models-runtime.ts +72 -8
  115. package/src/cli/observe-stream.ts +2 -0
  116. package/src/cli/observe.ts +16 -4
  117. package/src/cli/provider.ts +27 -5
  118. package/src/cli/registry.ts +41 -9
  119. package/src/cli/restart-scope.ts +3 -1
  120. package/src/cli/runtime-api.ts +5 -3
  121. package/src/cli/system-command.ts +40 -8
  122. package/src/cli/uninstall-client-state.ts +32 -0
  123. package/src/cli/usage-compare.ts +309 -0
  124. package/src/cli/usage-model-search.ts +4 -4
  125. package/src/cli/usage-report.ts +2 -2
  126. package/src/cli/v2.ts +1 -1
  127. package/src/client/machine-listener.ts +1 -3
  128. package/src/client/runtime.ts +1 -0
  129. package/src/clients/client-path.ts +51 -0
  130. package/src/clients/config-export/contracts.ts +3 -1
  131. package/src/clients/config-export/model-metadata.ts +3 -2
  132. package/src/clients/config-export/qoder.ts +93 -0
  133. package/src/clients/config-export.ts +35 -48
  134. package/src/clients/gentle-shell-path.ts +87 -0
  135. package/src/codex/account-auto-switch.ts +2 -0
  136. package/src/codex/account-identity.ts +29 -0
  137. package/src/codex/account-label.ts +1 -1
  138. package/src/codex/account-lifecycle.ts +21 -5
  139. package/src/codex/account-preservation.ts +28 -0
  140. package/src/codex/account-use-remaining.ts +23 -0
  141. package/src/codex/app-server-processes.ts +97 -7
  142. package/src/codex/app-server-restart-service.ts +55 -4
  143. package/src/codex/auth-api/account-list.ts +4 -0
  144. package/src/codex/auth-api/account-pause-group.ts +6 -50
  145. package/src/codex/auth-api/account-preservation.ts +57 -0
  146. package/src/codex/auth-api/pool-mode-gate.ts +5 -2
  147. package/src/codex/auth-api/routes.ts +8 -0
  148. package/src/codex/auth-api/use-remaining-route.ts +36 -0
  149. package/src/codex/auth-api.ts +0 -1
  150. package/src/codex/auth-context.ts +81 -7
  151. package/src/codex/autostart-health.ts +4 -0
  152. package/src/codex/catalog/auto-review.ts +20 -3
  153. package/src/codex/catalog/build-entries.ts +19 -2
  154. package/src/codex/catalog/combo-member.ts +14 -5
  155. package/src/codex/catalog/configured-tiers.ts +50 -0
  156. package/src/codex/catalog/effort.ts +4 -1
  157. package/src/codex/catalog/gather-capture.ts +2 -0
  158. package/src/codex/catalog/metadata.ts +11 -9
  159. package/src/codex/catalog/model-hints.ts +42 -19
  160. package/src/codex/catalog/model-visibility.ts +3 -1
  161. package/src/codex/catalog/native-ultrafast.ts +106 -0
  162. package/src/codex/catalog/parsing.ts +35 -86
  163. package/src/codex/catalog/provider-models.ts +40 -34
  164. package/src/codex/catalog/retained-sync.ts +2 -0
  165. package/src/codex/catalog/routed-gather.ts +33 -16
  166. package/src/codex/catalog/vendor-context.ts +82 -0
  167. package/src/codex/cli-install-provenance.ts +105 -17
  168. package/src/codex/cli-update-plan.ts +545 -0
  169. package/src/codex/config-write-lock.ts +63 -4
  170. package/src/codex/convergence.ts +2 -0
  171. package/src/codex/desktop-app/picker-freshness.ts +96 -0
  172. package/src/codex/desktop-app/types.ts +2 -0
  173. package/src/codex/desktop-app/windows.ts +29 -16
  174. package/src/codex/desktop-app-restart.ts +25 -2
  175. package/src/codex/desktop-compatibility/certificate-service.ts +99 -0
  176. package/src/codex/desktop-compatibility/certificate-store.ts +193 -0
  177. package/src/codex/desktop-compatibility/connection-store.ts +87 -0
  178. package/src/codex/desktop-compatibility/installed-build.ts +73 -0
  179. package/src/codex/desktop-compatibility/json-body.ts +29 -0
  180. package/src/codex/desktop-compatibility/native-identity.ts +62 -0
  181. package/src/codex/desktop-compatibility/relay-listener.ts +93 -0
  182. package/src/codex/desktop-compatibility/routing-binding.ts +10 -0
  183. package/src/codex/desktop-compatibility/routing-preflight.ts +69 -0
  184. package/src/codex/desktop-compatibility/runtime-ownership.ts +28 -0
  185. package/src/codex/desktop-compatibility/runtime.ts +182 -0
  186. package/src/codex/desktop-compatibility/service.ts +30 -0
  187. package/src/codex/desktop-compatibility/startup-settings.ts +50 -0
  188. package/src/codex/desktop-compatibility/usage-activation.ts +86 -0
  189. package/src/codex/desktop-compatibility/usage-controlled-fetch.ts +59 -0
  190. package/src/codex/desktop-compatibility/usage-controller.ts +107 -0
  191. package/src/codex/desktop-compatibility/usage-policy.ts +59 -0
  192. package/src/codex/desktop-compatibility/usage-refresh.ts +33 -0
  193. package/src/codex/desktop-compatibility/usage-sse-controller.ts +86 -0
  194. package/src/codex/desktop-compatibility/windows-activation-source.ts +44 -0
  195. package/src/codex/desktop-compatibility/windows-certificate-trust.ts +81 -0
  196. package/src/codex/desktop-compatibility/windows-key-protection.ts +165 -0
  197. package/src/codex/desktop-compatibility/windows-package-command.ts +86 -0
  198. package/src/codex/desktop-compatibility/windows-package-launch.ts +28 -0
  199. package/src/codex/features.ts +85 -45
  200. package/src/codex/history-provider.ts +1 -1
  201. package/src/codex/inject/config-write-section.ts +4 -1
  202. package/src/codex/inject/history-failure.ts +27 -0
  203. package/src/codex/inject/remove.ts +18 -6
  204. package/src/codex/inject/restore.ts +24 -2
  205. package/src/codex/inject/routing-classify.ts +4 -3
  206. package/src/codex/inject.ts +18 -27
  207. package/src/codex/journal.ts +16 -1
  208. package/src/codex/main-account-hard-lock.ts +30 -1
  209. package/src/codex/main-account.ts +99 -15
  210. package/src/codex/native-main-refresh-mode.ts +217 -0
  211. package/src/codex/native-profile-startup.ts +1 -1
  212. package/src/codex/ocx-compaction-history.ts +12 -10
  213. package/src/codex/paths.ts +86 -1
  214. package/src/codex/provider-routing.ts +174 -0
  215. package/src/codex/refresh.ts +2 -2
  216. package/src/codex/routing/health-store.ts +2 -2
  217. package/src/codex/routing/pool-recovery.ts +79 -0
  218. package/src/codex/routing/selection.ts +4 -3
  219. package/src/codex/routing/thread-affinity.ts +1 -1
  220. package/src/codex/shim-diagnostics.ts +6 -0
  221. package/src/codex/shim-overlay.ts +7 -2
  222. package/src/codex/signed-in-identity.ts +43 -0
  223. package/src/codex/subagent-model-fallback.ts +1 -1
  224. package/src/codex/sync.ts +6 -1
  225. package/src/codex/user-identity.ts +16 -5
  226. package/src/codex/windows-local-appdata.ts +84 -0
  227. package/src/combos/failover.ts +6 -1
  228. package/src/combos/index.ts +1 -0
  229. package/src/combos/resolve.ts +46 -10
  230. package/src/combos/types.ts +15 -0
  231. package/src/config/diagnostics.ts +35 -7
  232. package/src/config/live-reconcile.ts +51 -2
  233. package/src/config/load-degrade.ts +23 -1
  234. package/src/config/opencode-wire-upgrade.ts +54 -0
  235. package/src/config/opencode-zen-upgrade.ts +52 -0
  236. package/src/config/owner-registry.ts +22 -17
  237. package/src/config/paths.ts +10 -3
  238. package/src/config/provider-validation.ts +45 -2
  239. package/src/config/schema/config-schema.ts +39 -0
  240. package/src/config/schema/desktop-compatibility.ts +9 -0
  241. package/src/config/schema/leaf-validators.ts +39 -9
  242. package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
  243. package/src/config/schema/native-reasoning-retention.ts +26 -0
  244. package/src/config.ts +2 -0
  245. package/src/generated/compatibility-version.json +962 -350
  246. package/src/generated/model-metadata.ts +1 -1
  247. package/src/grok/sync.ts +1 -1
  248. package/src/images/loop.ts +46 -8
  249. package/src/integrations/catalog-refresh.ts +1 -1
  250. package/src/integrations/config-io.ts +20 -2
  251. package/src/integrations/journal.ts +15 -1
  252. package/src/integrations/mutation-plan.ts +2 -0
  253. package/src/integrations/registry.ts +15 -0
  254. package/src/integrations/store.ts +3 -0
  255. package/src/integrations/writer.ts +10 -1
  256. package/src/lib/advisor-activation.ts +16 -0
  257. package/src/lib/background-work.ts +65 -0
  258. package/src/lib/bounded-file-read.ts +58 -0
  259. package/src/lib/bun-path-runtime.d.mts +10 -1
  260. package/src/lib/bun-path-runtime.mjs +62 -3
  261. package/src/lib/codex-restart-contract.ts +15 -0
  262. package/src/lib/desktop-proxy-route.ts +30 -0
  263. package/src/lib/desktop-upstream-tunnel.ts +72 -0
  264. package/src/lib/empty-tool-catalog.ts +62 -0
  265. package/src/lib/errors.ts +26 -3
  266. package/src/lib/gcp-adc.ts +96 -9
  267. package/src/lib/gcp-credential-input.ts +12 -0
  268. package/src/lib/lab-live-route-production.ts +5 -0
  269. package/src/lib/local-internal-call-capability.ts +55 -0
  270. package/src/lib/opaque-proxy-tunnel.ts +217 -0
  271. package/src/lib/package-tree-integrity.ts +2 -2
  272. package/src/lib/redact.ts +2 -2
  273. package/src/lib/socks5-fetch.ts +48 -71
  274. package/src/lib/socks5-handshake.ts +112 -0
  275. package/src/lib/translator-budget.ts +7 -1
  276. package/src/oauth/account-quota-rank.ts +69 -2
  277. package/src/oauth/anthropic-account-refusal.ts +20 -2
  278. package/src/oauth/anthropic-oauth-definitions.ts +3 -1
  279. package/src/oauth/anthropic-routing.ts +1 -21
  280. package/src/oauth/anthropic.ts +38 -7
  281. package/src/oauth/callback-server.ts +27 -1
  282. package/src/oauth/chatgpt-device.ts +1 -1
  283. package/src/oauth/chatgpt-shared.ts +83 -0
  284. package/src/oauth/chatgpt.ts +8 -72
  285. package/src/oauth/dsh.ts +203 -0
  286. package/src/oauth/generic-account-failover.ts +62 -12
  287. package/src/oauth/generic-session-affinity.ts +125 -0
  288. package/src/oauth/index.ts +188 -111
  289. package/src/oauth/kiro-device-login.ts +2 -1
  290. package/src/oauth/kiro.ts +7 -1
  291. package/src/oauth/local-token-detect.ts +21 -1
  292. package/src/oauth/login-cli-errors.ts +44 -0
  293. package/src/oauth/login-cli.ts +69 -7
  294. package/src/oauth/login-flow-state.ts +371 -23
  295. package/src/oauth/meta-muse-errors.ts +41 -0
  296. package/src/oauth/meta-muse-keychain.ts +52 -0
  297. package/src/oauth/meta-muse.ts +51 -84
  298. package/src/oauth/model-discovery-auth.ts +3 -0
  299. package/src/oauth/pool-settings-capability.ts +4 -2
  300. package/src/oauth/refresh-flight-retirement.ts +48 -0
  301. package/src/oauth/session-affinity-key.ts +23 -0
  302. package/src/oauth/store-anthropic-instance.ts +9 -2
  303. package/src/oauth/store.ts +12 -5
  304. package/src/protocols/codecs/chat-ir.ts +467 -0
  305. package/src/protocols/codecs/chat.ts +10 -1
  306. package/src/protocols/codecs/messages-ir.ts +500 -0
  307. package/src/protocols/encoders/adapter-events.ts +5 -4
  308. package/src/protocols/encoders/messages.ts +9 -6
  309. package/src/protocols/features.ts +10 -2
  310. package/src/protocols/path.ts +11 -1
  311. package/src/protocols/plan-snapshot.ts +39 -16
  312. package/src/protocols/plan.ts +9 -1
  313. package/src/protocols/provider-summary.ts +2 -1
  314. package/src/protocols/settings.ts +8 -0
  315. package/src/providers/antigravity-account-roster.ts +102 -0
  316. package/src/providers/antigravity-models.ts +85 -7
  317. package/src/providers/api-key-cooldowns.ts +49 -0
  318. package/src/providers/api-key-resolve.ts +11 -6
  319. package/src/providers/api-key-response-ownership.ts +57 -0
  320. package/src/providers/api-key-selection.ts +31 -6
  321. package/src/providers/api-keys.ts +214 -3
  322. package/src/providers/claude-cli-usage.ts +96 -0
  323. package/src/providers/dsh-account-destination.ts +31 -0
  324. package/src/providers/dsh-account-models.ts +41 -0
  325. package/src/providers/gcp-credential-cleanup.ts +59 -0
  326. package/src/providers/key-failover.ts +54 -50
  327. package/src/providers/key-store.ts +7 -2
  328. package/src/providers/model-rename-fields.ts +5 -0
  329. package/src/providers/model-rename-migration.ts +7 -5
  330. package/src/providers/openai-tiers-destination.ts +11 -2
  331. package/src/providers/openai-tiers.ts +5 -12
  332. package/src/providers/opencode-go-transport.ts +3 -1
  333. package/src/providers/quota/account-cache.ts +6 -5
  334. package/src/providers/quota/account-row.ts +34 -0
  335. package/src/providers/quota/antigravity.ts +28 -7
  336. package/src/providers/quota/dsh-account.ts +70 -0
  337. package/src/providers/quota/vendor-probes-oauth.ts +1 -93
  338. package/src/providers/quota-types.ts +2 -0
  339. package/src/providers/quota.ts +14 -20
  340. package/src/providers/registry/entries-core.ts +44 -14
  341. package/src/providers/registry/entries-extended.ts +19 -0
  342. package/src/providers/registry/types.ts +1 -1
  343. package/src/providers/request-pacing.ts +77 -19
  344. package/src/providers/routed-config.ts +339 -0
  345. package/src/providers/service-tier.ts +2 -1
  346. package/src/quota/window-mapping.ts +5 -2
  347. package/src/responses/anthropic-progress.ts +34 -0
  348. package/src/responses/assistant-replay.ts +35 -0
  349. package/src/responses/compaction-history-framing.ts +65 -0
  350. package/src/responses/compaction.ts +6 -1
  351. package/src/responses/incomplete-reason.ts +31 -0
  352. package/src/responses/parser.ts +78 -22
  353. package/src/responses/reasoning-envelope.ts +4 -0
  354. package/src/responses/reasoning-replay-cache.ts +24 -2
  355. package/src/responses/reasoning-retention.ts +173 -0
  356. package/src/responses/retained-compaction.ts +46 -0
  357. package/src/responses/schema.ts +23 -0
  358. package/src/responses/state.ts +32 -29
  359. package/src/router.ts +8 -321
  360. package/src/routing/health.ts +37 -22
  361. package/src/routing/history/build-file.ts +92 -0
  362. package/src/routing/history/indexer.ts +254 -221
  363. package/src/routing/history/ingest.ts +242 -0
  364. package/src/routing/history/rebuild-job.ts +111 -0
  365. package/src/routing/history/rebuild-protocol.ts +15 -0
  366. package/src/routing/history/rebuild-worker.ts +34 -0
  367. package/src/routing/profile.ts +1 -1
  368. package/src/server/admission-model-scope.ts +21 -1
  369. package/src/server/antigravity-direct-eligibility.ts +208 -0
  370. package/src/server/auth-cors.ts +15 -0
  371. package/src/server/chat-completions.ts +82 -10
  372. package/src/server/chat-native-reasoning.ts +123 -0
  373. package/src/server/chat-native-sse.ts +110 -7
  374. package/src/server/chat-native.ts +76 -17
  375. package/src/server/claude-messages.ts +164 -433
  376. package/src/server/effort-policy.ts +1 -1
  377. package/src/server/images.ts +15 -2
  378. package/src/server/index/desktop-compatibility-startup.ts +56 -0
  379. package/src/server/index/model-alias-id.ts +36 -0
  380. package/src/server/index/optional-listeners.ts +2 -0
  381. package/src/server/index/serve-options.ts +11 -3
  382. package/src/server/index/startup-warnings.ts +11 -0
  383. package/src/server/index/websocket-handler.ts +9 -0
  384. package/src/server/index.ts +14 -11
  385. package/src/server/inference/advisor-diagnostics.ts +31 -0
  386. package/src/server/inference/client-encoder-delivery.ts +6 -5
  387. package/src/server/login-shell-path.ts +146 -0
  388. package/src/server/management/advisor-routes.ts +202 -0
  389. package/src/server/management/agent-settings-routes.ts +22 -4
  390. package/src/server/management/claude-desktop-picker-routes.ts +1 -1
  391. package/src/server/management/combo-routes.ts +176 -50
  392. package/src/server/management/companion-routes.ts +4 -0
  393. package/src/server/management/config-routes.ts +77 -6
  394. package/src/server/management/context.ts +4 -0
  395. package/src/server/management/cursor-integration-routes.ts +1 -1
  396. package/src/server/management/desktop-compatibility-routes.ts +46 -0
  397. package/src/server/management/desktop-compatibility-runtime-routes.ts +46 -0
  398. package/src/server/management/desktop-compatibility-settings-routes.ts +27 -0
  399. package/src/server/management/model-routes.ts +13 -8
  400. package/src/server/management/model-rows.ts +14 -0
  401. package/src/server/management/native-integration-routes.ts +2 -7
  402. package/src/server/management/native-reasoning-retention-routes.ts +41 -0
  403. package/src/server/management/oauth-account-routes.ts +87 -14
  404. package/src/server/management/protocol-settings-patch.ts +1 -0
  405. package/src/server/management/provider-gcp-credential-routes.ts +29 -0
  406. package/src/server/management/provider-key-pacing-routes.ts +31 -0
  407. package/src/server/management/provider-overwrite-carry.ts +7 -0
  408. package/src/server/management/provider-routes.ts +25 -30
  409. package/src/server/management/route-registry.ts +21 -1
  410. package/src/server/management/sibling-guard.ts +1 -0
  411. package/src/server/management-api.ts +9 -1
  412. package/src/server/messages-antigravity-direct.ts +195 -0
  413. package/src/server/messages-native-tool-guard.ts +185 -0
  414. package/src/server/messages-native.ts +106 -22
  415. package/src/server/messages-shared.ts +431 -0
  416. package/src/server/relay.ts +1 -1
  417. package/src/server/request-log-terminal-status.ts +1 -1
  418. package/src/server/request-log.ts +13 -1
  419. package/src/server/responses/account-change-state.ts +8 -2
  420. package/src/server/responses/adapter-continuation.ts +48 -19
  421. package/src/server/responses/adapter-delivery.ts +43 -8
  422. package/src/server/responses/adapter-dispatch.ts +48 -4
  423. package/src/server/responses/advisor-plan-slot.ts +27 -0
  424. package/src/server/responses/advisor-retention.ts +117 -0
  425. package/src/server/responses/advisor-slot.ts +368 -0
  426. package/src/server/responses/code-mode-collab-surface.ts +116 -8
  427. package/src/server/responses/codex-ws-wire.ts +15 -8
  428. package/src/server/responses/compact.ts +303 -125
  429. package/src/server/responses/compaction-recovery.ts +18 -10
  430. package/src/server/responses/compaction-retention.ts +61 -0
  431. package/src/server/responses/context-overflow.ts +11 -6
  432. package/src/server/responses/core-auth.ts +6 -0
  433. package/src/server/responses/core-codex-account.ts +11 -1
  434. package/src/server/responses/core-combo-failure.ts +12 -1
  435. package/src/server/responses/core-combo.ts +141 -36
  436. package/src/server/responses/core-errors.ts +3 -3
  437. package/src/server/responses/core-lifetime.ts +7 -2
  438. package/src/server/responses/core-normalize.ts +11 -0
  439. package/src/server/responses/core-opaque-recovery.ts +35 -0
  440. package/src/server/responses/core-options.ts +51 -0
  441. package/src/server/responses/core-pipeline.ts +141 -0
  442. package/src/server/responses/core-replay.ts +25 -6
  443. package/src/server/responses/core.ts +3 -116
  444. package/src/server/responses/fetch-helpers.ts +73 -19
  445. package/src/server/responses/main-hard-lock-routing.ts +109 -0
  446. package/src/server/responses/native-response-control.ts +4 -2
  447. package/src/server/responses/passthrough-delivery.ts +19 -11
  448. package/src/server/responses/passthrough-dispatch.ts +29 -16
  449. package/src/server/responses/request-prepare.ts +144 -17
  450. package/src/server/responses/request-sidecar-auth.ts +2 -2
  451. package/src/server/responses/request-transport.ts +120 -27
  452. package/src/server/responses/response-effects.ts +1 -0
  453. package/src/server/responses/run-turn-execution.ts +166 -38
  454. package/src/server/responses/sidecar-execution.ts +98 -5
  455. package/src/server/responses/terminal-guard.ts +4 -17
  456. package/src/server/responses-undeclared-tool-guard.ts +30 -9
  457. package/src/server/startup-action-control.ts +16 -2
  458. package/src/server/startup-health-cache.ts +1 -0
  459. package/src/service/auth-preflight.ts +71 -0
  460. package/src/service/cli.ts +4 -2
  461. package/src/service/definition.ts +97 -0
  462. package/src/service/desktop-startup.ts +14 -0
  463. package/src/service/guards.ts +1 -61
  464. package/src/service/health-sentinel-linux.ts +112 -0
  465. package/src/service/health-sentinel-main.ts +99 -61
  466. package/src/service/health-sentinel-probe.ts +24 -7
  467. package/src/service/health.ts +5 -89
  468. package/src/service/launchd.ts +27 -7
  469. package/src/service/logging.ts +135 -0
  470. package/src/service/repair.ts +2 -1
  471. package/src/service/state.ts +7 -8
  472. package/src/service/systemd.ts +1 -1
  473. package/src/service/windows-guarded-manager.ts +2 -1
  474. package/src/service/windows-ops.ts +1 -1
  475. package/src/service/windows-scheduler.ts +2 -7
  476. package/src/service/windows-taskxml.ts +2 -2
  477. package/src/service/windows-wscript.ts +14 -0
  478. package/src/service.ts +4 -2
  479. package/src/sidecar/auth.ts +2 -0
  480. package/src/tray/windows-tray.ps1 +43 -24
  481. package/src/types/config.ts +124 -6
  482. package/src/types/opencode-go.ts +61 -0
  483. package/src/types/opencode-zen.ts +29 -0
  484. package/src/types/provider.ts +39 -6
  485. package/src/types/request.ts +38 -2
  486. package/src/types/tools.ts +2 -0
  487. package/src/types/wire.ts +29 -37
  488. package/src/types.ts +1 -0
  489. package/src/update/async-check.ts +1 -1
  490. package/src/update/badge.ts +2 -2
  491. package/src/update/index.ts +88 -15
  492. package/src/update/job-supervised-restart.ts +107 -0
  493. package/src/update/job.ts +32 -32
  494. package/src/update/notify.ts +1 -1
  495. package/src/update/npm-invocation.mjs +12 -2
  496. package/src/update/refresh-scheduler.ts +2 -2
  497. package/src/update/supervised-recovery.d.mts +27 -0
  498. package/src/update/supervised-recovery.mjs +157 -0
  499. package/src/usage/cache-diagnostic.ts +2 -0
  500. package/src/usage/cost.ts +48 -12
  501. package/src/usage/expected-prices.ts +15 -0
  502. package/src/usage/ledger-retention.ts +2 -1
  503. package/src/usage/ledger-scanner.ts +6 -5
  504. package/src/usage/log.ts +17 -8
  505. package/src/usage/summary.ts +22 -9
  506. package/src/usage/user-cost-overlays.ts +14 -19
  507. package/src/usage/user-cost-validation.ts +38 -0
  508. package/src/vision/eligibility.ts +13 -0
  509. package/src/web-search/gemini-executor.ts +2 -2
  510. package/src/web-search/loop.ts +55 -5
  511. package/src/web-search/progress-stream.ts +4 -1
  512. package/src/web-search/run-turn-loop.ts +9 -1
  513. package/assets/sponsors/packycode.png +0 -0
  514. package/gui/dist/assets/App-CSJvmjNs.css +0 -1
  515. package/gui/dist/assets/App-CZtqiGcw.js +0 -56
  516. package/gui/dist/assets/index-BB6uK6tU.css +0 -1
  517. package/gui/dist/assets/index-CTm4l-HQ.js +0 -94
  518. package/gui/dist/assets/quota-summary-BbEeRfPY.js +0 -1
@@ -1,4 +1,8 @@
1
- import type { ResponsesRequestContext, ResponsesAdmissionState, ResponsesDispatchers } from "./core-options";
1
+ import type { HandleResponsesOptions, ResponsesRequestContext, ResponsesAdmissionState, ResponsesDispatchers } from "./core-options";
2
+ import type { PolicyRequestEvidence } from "../../routing/evaluator";
3
+ import type { RequestLogContext } from "../request-log";
4
+ import { markProtocolEntry, protocolMarkFeatures } from "../../protocols/trace";
5
+ import { isAntigravityRoute } from "../antigravity-direct-eligibility";
2
6
  import { capturePolicyRequestRoute, assertPolicyNormalizedRoute, recordPolicyPreparedDestination, policyCandidateRefusalResponse } from "./policy-request-scope";
3
7
  import {
4
8
  agentTaskRecoveryConfig,
@@ -13,7 +17,7 @@ import {
13
17
  unreadableEncryptedAgentTaskResponse,
14
18
  } from "./core-errors";
15
19
  import { parseSyntheticRowId } from "../fast-row";
16
- import { resolveComboId, comboIdFromRawBody, NoAvailableComboTargetsError } from "../../combos";
20
+ import { resolveComboId, comboIdFromRawBody, comboExclusionReasons, NoAvailableComboTargetsError, pickComboTarget } from "../../combos";
17
21
  import { INTERCEPT_TARGET_UNAVAILABLE_CODE, interceptTargetUnavailableResponse, resolveChosenTarget, resolveShadowCallTarget } from "./shadow-target-availability";
18
22
  import {
19
23
  MEMORY_MODEL_TARGET_UNAVAILABLE_CODE,
@@ -80,6 +84,7 @@ import {
80
84
  } from "../../router";
81
85
  import { evidenceFromBody } from "../../routing/request-evidence";
82
86
  import { OPENAI_CODEX_PROVIDER_ID, isCanonicalOpenAiForwardProvider } from "../../providers/openai-tiers";
87
+ import { resolveNativeReasoningRetention } from "../../config/schema/native-reasoning-retention";
83
88
  import { isThreadSpawnRequest } from "../effort-policy";
84
89
  import {
85
90
  resolveSubagentFallbackChain,
@@ -129,6 +134,7 @@ import {
129
134
  } from "../../codex/loopback-target";
130
135
  import { checkComboTargetInputAdmission, checkInputAdmission } from "./input-admission";
131
136
  import {
137
+ admissionMayUseMeteredComboTargets,
132
138
  admissionModelDeniedResponse,
133
139
  AdmissionModelDeniedError,
134
140
  assertRouteAllowedByScope,
@@ -136,6 +142,13 @@ import {
136
142
  routeAllowedByScope,
137
143
  } from "../admission-model-scope";
138
144
  import { nativeContextLimits } from "../../codex/catalog";
145
+ import type { ClientToolCatalogRestriction } from "../../lib/empty-tool-catalog";
146
+ import {
147
+ currentTurnWireToolCatalogBody,
148
+ hasExplicitEmptyToolCatalog,
149
+ collectDeclaredWireToolNames,
150
+ collectDeclaredBareCustomWireToolNames,
151
+ } from "../responses-undeclared-tool-guard";
139
152
  import { streamingContextOverflowResponse } from "./context-overflow";
140
153
  import {
141
154
  preAuthUpstreamHostCircuitKey,
@@ -145,6 +158,7 @@ import {
145
158
  } from "./core-codex-account";
146
159
  import { acquireUpstreamHostAdmission } from "../../codex/upstream-host-health";
147
160
  import { applyCompactionRoutingOverride, compactionRoutingKeepsProviderIdentity } from "./compaction-routing";
161
+ import { applyMainHardLockFallbackOverride } from "./main-hard-lock-routing";
148
162
  import { codexAuthContextLogLabel } from "../../codex/account-label";
149
163
  import {
150
164
  conversationStateBindingFromAuth,
@@ -155,6 +169,48 @@ import {
155
169
 
156
170
  import { redactHostedImageDisplayPaths } from "../responses-hosted-image-display";
157
171
 
172
+ /** Policy-routing evidence. The direct lane's settings-only body has no conversation to scan. */
173
+ function routeEvidence(options: Pick<HandleResponsesOptions, "directRequest">, parsed: OcxParsedRequest): PolicyRequestEvidence {
174
+ return options.directRequest?.evidence ?? evidenceFromBody(parsed._rawBody);
175
+ }
176
+
177
+ /**
178
+ * Leave the Antigravity direct lane for this request: put the bridge conversation back on the
179
+ * Responses body so every `_rawBody` reader sees what the bridge would have sent, and trace the
180
+ * request as the bridge. The IR conversation already decoded stays: it equals what
181
+ * `parseRequest` builds from the restored body (`tests/protocols/chat-ir-parity.test.ts`).
182
+ */
183
+ function restoreDirectRequestConversation(options: HandleResponsesOptions, body: unknown, logCtx: RequestLogContext): void {
184
+ const direct = options.directRequest;
185
+ if (!direct) return;
186
+ options.directRequest = undefined;
187
+ if (body && typeof body === "object" && !Array.isArray(body)) Object.assign(body, direct.bridgeConversation());
188
+ if (options.clientEncoder) options.clientEncoder = { ...options.clientEncoder, requestLane: "bridge" };
189
+ markProtocolEntry(logCtx, {
190
+ inbound: direct.protocol,
191
+ lane: "bridge",
192
+ reasonCodes: ["not-migrated"],
193
+ features: protocolMarkFeatures(logCtx) ?? [],
194
+ });
195
+ }
196
+
197
+ /**
198
+ * Leave the direct lane as soon as the route stops being the Antigravity route it was decided
199
+ * for. Called after every route assignment, so readers that run between a reroute and dispatch
200
+ * (canonical sanitization, ciphertext stripping, final normalization) see the bridge body.
201
+ */
202
+ function leaveDirectLaneIfRerouted(
203
+ options: HandleResponsesOptions,
204
+ route: Pick<RouteResult, "providerName" | "modelId" | "provider">,
205
+ parsed: OcxParsedRequest,
206
+ logCtx: RequestLogContext,
207
+ ): void {
208
+ const direct = options.directRequest;
209
+ if (!direct) return;
210
+ if (route.providerName === direct.providerName && route.modelId === direct.modelId && isAntigravityRoute(route)) return;
211
+ restoreDirectRequestConversation(options, parsed._rawBody, logCtx);
212
+ }
213
+
158
214
  /** Parses, selects, and admits one request without changing the dispatch policy. */
159
215
  export async function prepareResponsesRequest(
160
216
  requestContext: Pick<ResponsesRequestContext, "options" | "config" | "req" | "logCtx">,
@@ -240,14 +296,14 @@ export async function prepareResponsesRequest(
240
296
  effort: comboEffortRow.effort,
241
297
  };
242
298
  }
299
+ const isCompactionTrigger = body !== null && typeof body === "object" && !Array.isArray(body)
300
+ && Array.isArray((body as { input?: unknown }).input)
301
+ && ((body as { input: unknown[] }).input).some((item: unknown) =>
302
+ typeof item === "object" && item !== null && (item as { type?: string }).type === "compaction_trigger");
243
303
  // Compaction may send the last client-visible bare model after a combo switch.
244
304
  // Configured selectors take precedence; otherwise recall before combo dispatch (#3891).
245
305
  if (!concreteSelection && !options.compactionRoutingOverride && body && typeof body === "object" && !Array.isArray(body)) {
246
306
  const rawModel = (body as { model?: unknown }).model;
247
- const rawInput = (body as { input?: unknown }).input;
248
- const isCompactionTrigger = Array.isArray(rawInput)
249
- && rawInput.some((item: unknown) =>
250
- typeof item === "object" && item !== null && (item as { type?: string }).type === "compaction_trigger");
251
307
  if (typeof rawModel === "string" && !rawModel.includes("/") && isCompactionTrigger
252
308
  && !comboRows.fastRow && !comboEffortRow
253
309
  && !resolveComboId(config, rawModel)) {
@@ -276,6 +332,7 @@ export async function prepareResponsesRequest(
276
332
  }
277
333
  }
278
334
  let shadowCallIntercepted = false;
335
+ let shadowCallMatches = false;
279
336
  // Luna is also selectable by users/children. Both intercept sites use the same
280
337
  // per-turn provenance; WS frames must not inherit the handshake's classification.
281
338
  const threadSpawn = isThreadSpawnRequest(req.headers);
@@ -285,6 +342,7 @@ export async function prepareResponsesRequest(
285
342
  const rawShadowModel = (body as { model?: unknown }).model;
286
343
  if (shadowIntercept?.enabled && shadowIntercept.model && typeof rawShadowModel === "string"
287
344
  && isShadowSourceModel(rawShadowModel, shadowIntercept.sourceModels)) {
345
+ shadowCallMatches = true;
288
346
  const shadowComboId = resolveComboId(config, shadowIntercept.model);
289
347
  if (shadowComboId && Object.hasOwn(config.combos ?? {}, shadowComboId)) {
290
348
  shadowCallIntercepted = true;
@@ -298,6 +356,16 @@ export async function prepareResponsesRequest(
298
356
  }
299
357
  }
300
358
  }
359
+ // The hard-lock fallback owns ordinary turns only, and only after every more specific
360
+ // routing setting had its chance above: a shadow-intercepted, memory-phased, compaction
361
+ // or decision turn keeps its own destination, and an intercepted combo selector is
362
+ // already owned by the intercept. A spawned sub-agent turn names its model on purpose,
363
+ // the same reason the shadow intercept leaves it alone. Like the sites above it, this
364
+ // must run before comboIdFromRawBody reads `model`.
365
+ if (!concreteSelection && !options.compactionRoutingOverride && !isCompactionTrigger && !options.internalDecisionCall
366
+ && !shadowCallIntercepted && !shadowCallMatches && !memoryModelApplies && !threadSpawn && inboundWire === "responses") {
367
+ options.mainHardLockFallbackOverride = applyMainHardLockFallbackOverride(body, config);
368
+ }
301
369
  const comboId = !concreteSelection ? comboIdFromRawBody(body, config) : null;
302
370
  // A decision model may be a plain model or a non-JEV combo. A JEV combo here would recurse
303
371
  // into another decision, so the call is refused and the parent decision fails open.
@@ -306,6 +374,9 @@ export async function prepareResponsesRequest(
306
374
  }
307
375
  if (comboId && Object.hasOwn(config.combos ?? {}, comboId)) {
308
376
  options.onRequestBodyRead?.();
377
+ // The Antigravity direct lane is decided for one concrete route; a body that reached a combo
378
+ // goes through the combo's own child loop with the full bridge conversation.
379
+ restoreDirectRequestConversation(options, body, logCtx);
309
380
  return requestDispatchers.handleComboResponses(req, body, comboId, config, logCtx, {
310
381
  ...options,
311
382
  // Concrete combo child selectors no longer match the shadow source model. Carry the
@@ -381,11 +452,30 @@ export async function prepareResponsesRequest(
381
452
 
382
453
  let parsed: OcxParsedRequest;
383
454
  let toolBridgeMaps: ReturnType<typeof buildToolBridgeMaps>;
455
+ let clientToolCatalogRestriction: ClientToolCatalogRestriction | undefined;
384
456
  try {
385
457
  parsed = parseRequest(body);
458
+ // Antigravity direct lane: the body carried only the request settings, so the parse above
459
+ // produced them with an empty conversation; the conversation itself comes straight from the
460
+ // client body. Inside this try so a decode error answers exactly like a parse error.
461
+ if (options.directRequest) parsed = options.directRequest.decode(parsed);
462
+ parsed._nativeReasoningRetention = resolveNativeReasoningRetention(config);
463
+ // Capture before route rewrites or hosted sidecars can add tools; replayed catalogs are history.
464
+ // The direct settings body omits tools, including current legacy Chat functions. Recover
465
+ // their wire names only when this restriction needs a non-empty decoded catalog.
466
+ const catalogBody = options.directRequest && options.clientDeclaredEmptyToolCatalog === true && parsed.context.tools?.length
467
+ ? options.directRequest.bridgeConversation() : parsed._rawBody;
468
+ const currentCatalog = currentTurnWireToolCatalogBody(catalogBody, parsed._replayPrefixLen);
469
+ if (options.clientDeclaredEmptyToolCatalog === true || hasExplicitEmptyToolCatalog(currentCatalog)) {
470
+ clientToolCatalogRestriction = {
471
+ declaredToolNames: collectDeclaredWireToolNames(currentCatalog),
472
+ bareCustomToolNames: collectDeclaredBareCustomWireToolNames(currentCatalog),
473
+ };
474
+ }
386
475
  if (options.inboundWire === "anthropic") {
387
476
  parsed._nativeReasoningReplay = options.nativeReasoningReplay;
388
477
  parsed._nativeReasoningMint = options.nativeReasoningMint;
478
+ parsed._anthropicServerTools = options.anthropicServerTools;
389
479
  }
390
480
  parsed._promptCacheKeyIsSharedCohort = options.promptCacheKeyIsSharedCohort;
391
481
  // The body may have been rebuilt since the inbound observation (previous-response
@@ -508,7 +598,10 @@ export async function prepareResponsesRequest(
508
598
  if (!logCtx.conversationId) {
509
599
  logCtx.conversationId = resolvedConversationId;
510
600
  }
511
- logCtx.requestedModel = options.compactionRoutingOverride?.sourceModel ?? parsed.modelId;
601
+ // A rewritten turn logs the selector the client asked for, so the usage log never
602
+ // claims the operator typed the fallback model themselves.
603
+ logCtx.requestedModel = options.mainHardLockFallbackOverride?.sourceModel
604
+ ?? options.compactionRoutingOverride?.sourceModel ?? parsed.modelId;
512
605
  logCtx.requestedEffort = parsed.options.reasoning;
513
606
  // What this request may spend beyond its input, for the durable spend reservation (#4707).
514
607
  // Read from the caller rather than from the adapter's serialized body, because the
@@ -529,7 +622,7 @@ export async function prepareResponsesRequest(
529
622
  // The selector the caller actually sent, captured before shadow interception
530
623
  // or a subagent fallback rewrites it, so a refusal names the client's own
531
624
  // request rather than a destination it never asked for.
532
- const inboundSelector = parsed.modelId;
625
+ const inboundSelector = options.mainHardLockFallbackOverride?.sourceModel ?? parsed.modelId;
533
626
  const selectorTargetsSecondary = (selector: string): boolean => {
534
627
  const slash = selector.indexOf("/");
535
628
  if (slash <= 0) return false;
@@ -549,6 +642,19 @@ export async function prepareResponsesRequest(
549
642
  }
550
643
  const admissionScope = resolveAdmissionModelScope(config, options.admission);
551
644
  const captureInboundRoutePolicy = (candidate: RouteResult, captureRequestPolicy = true): RouteResult => {
645
+ // Router-collapsed aliases bypass the combo loop. Re-pick before capturing destination
646
+ // policy so random/RR cannot refuse while an unmetered target is still usable.
647
+ if (candidate.combo?.target.metered && !admissionMayUseMeteredComboTargets(
648
+ config, options.admission, config.combos?.[candidate.combo.comboId],
649
+ )) {
650
+ const pick = pickComboTarget(config, candidate.combo.comboId, { eligible: target => !target.metered });
651
+ if (!pick) {
652
+ throw new NoAvailableComboTargetsError(candidate.combo.comboId,
653
+ comboExclusionReasons(config, candidate.combo.comboId, target => !target.metered));
654
+ }
655
+ const routed = routeConcreteModel(config, `${pick.target.provider}/${pick.target.model}`);
656
+ candidate = { ...routed, combo: pick, routeKind: "combo", routeReason: routed.routeReason === "blocked-model-redirect" ? "blocked-model-redirect" : "combo-pick" };
657
+ }
552
658
  // Every route this request path produces passes through here: the direct
553
659
  // name, an alias, a policy or combo selection, a compaction override, a
554
660
  // shadow-intercept target and both subagent-fallback re-routes. Checking
@@ -582,8 +688,8 @@ export async function prepareResponsesRequest(
582
688
  const resolved = concreteSelection
583
689
  ? routeConcreteModel(config, modelId)
584
690
  : parsed._compactionRequest === true
585
- ? routeCompactionModel(config, modelId, evidenceFromBody(parsed._rawBody))
586
- : routeModel(config, modelId, evidenceFromBody(parsed._rawBody));
691
+ ? routeCompactionModel(config, modelId, routeEvidence(options, parsed))
692
+ : routeModel(config, modelId, routeEvidence(options, parsed));
587
693
  // A Pool 2 selector may leave Pool 2 only through an operator-configured cross-provider
588
694
  // blocked-model redirect, which the router marks as a credential-domain rewrite. Any other
589
695
  // destination means the selector fell through to default resolution, which stays refused.
@@ -615,7 +721,7 @@ export async function prepareResponsesRequest(
615
721
  }
616
722
  const _sci = config.shadowCallIntercept;
617
723
  let shadowRoute: RouteResult | undefined;
618
- if (!concreteSelection && !memoryRoute && !options.memoryModelPhase && !options.compactionRoutingOverride && !options.internalDecisionCall && !preserveShadowModel && _sci?.enabled && _sci.model && isShadowSourceModel(parsed.modelId, _sci.sourceModels)) {
724
+ if (!concreteSelection && !memoryRoute && !options.memoryModelPhase && !options.compactionRoutingOverride && !options.mainHardLockFallbackOverride && !options.internalDecisionCall && !preserveShadowModel && _sci?.enabled && _sci.model && isShadowSourceModel(parsed.modelId, _sci.sourceModels)) {
619
725
  const sourcePrefix = shadowSourceModelPrefix(parsed.modelId, _sci.sourceModels)!;
620
726
  let sourceIdentity = { providerName: OPENAI_CODEX_PROVIDER_ID, modelId: sourcePrefix };
621
727
  try {
@@ -654,6 +760,7 @@ export async function prepareResponsesRequest(
654
760
  if (parsed._compactionRequest === true || options.compactionRoutingOverride) parsed._cursorIsolateConversation = true;
655
761
  route = memoryRoute ?? shadowRoute ?? resolveRoute(options.policyFallbackCandidate
656
762
  ? `${options.policyFallbackCandidate.provider}/${options.policyFallbackCandidate.model}` : parsed.modelId);
763
+ leaveDirectLaneIfRerouted(options, route, parsed, logCtx);
657
764
  // Name the phase in the persisted route decision, so the request log says why this turn went to
658
765
  // the memory destination instead of leaving it looking like a plain user selection. Set here, on
659
766
  // the resolved route, so a combo child's own route carries it too.
@@ -667,15 +774,22 @@ export async function prepareResponsesRequest(
667
774
  };
668
775
  }
669
776
  }
670
- if (options.compactionRoutingOverride && !compactionRoutingKeepsProviderIdentity(config, options.compactionRoutingOverride, route)) {
777
+ if ((options.compactionRoutingOverride && !compactionRoutingKeepsProviderIdentity(config, options.compactionRoutingOverride, route))
778
+ || options.mainHardLockFallbackOverride) {
671
779
  credentialDomainWasRewritten = true;
672
780
  // The destination does not share the conversation's credential domain, so it can neither
673
781
  // verify the source backend's reasoning ciphertext nor decode its native compaction blob.
674
782
  // This is the same condition an account change already reports (account-change-state.ts),
675
783
  // and the serializer turns a stored summary into readable text instead of dropping it.
676
784
  parsed._stripReasoningEncryptedContent = true;
785
+ parsed._stripNativeCompactionEncryptedContent = true;
677
786
  if (parsed._compactionRequest === true) parsed._portableCompaction = true;
678
787
  }
788
+ // A v1 fallback needs an ocx1 summary for replacement-history decoding, even when this
789
+ // custom destination separately accepts native v2 triggers. Legacy defaults stay intact.
790
+ if (options.compactionRecoveryKind === "compaction-v1" && parsed._compactionRequest === true
791
+ && route.provider.adapter === "openai-responses" && route.provider.supportsNativeCompactionTrigger === true
792
+ && !isCanonicalOpenAiForwardProvider(route.provider)) parsed._portableCompaction = true;
679
793
  logCtx.routeDecision = route.routeDecision;
680
794
  logCtx.policyEligibility = route.policyEligibility;
681
795
  } catch (err) {
@@ -686,7 +800,7 @@ export async function prepareResponsesRequest(
686
800
  if (policyRefusal) return policyRefusal;
687
801
  if (err instanceof AdmissionModelDeniedError) return admissionModelDeniedResponse(err);
688
802
  if (err instanceof NoAvailableComboTargetsError) {
689
- return comboUnavailable(err.comboId);
803
+ return comboUnavailable(err.comboId, undefined, err.reasons);
690
804
  }
691
805
  if (err instanceof NoEligiblePolicyCandidateError) {
692
806
  // Persist the evaluation trace (per-candidate exclusions + the
@@ -893,8 +1007,9 @@ export async function prepareResponsesRequest(
893
1007
  if (fallback?.to && !slugsEquivalent(fallback.to, route.modelId)) {
894
1008
  try {
895
1009
  route = captureInboundRoutePolicy(
896
- routeModel(config, fallback.to, evidenceFromBody(parsed._rawBody)),
1010
+ routeModel(config, fallback.to, routeEvidence(options, parsed)),
897
1011
  );
1012
+ leaveDirectLaneIfRerouted(options, route, parsed, logCtx);
898
1013
  credentialDomainWasRewritten = true;
899
1014
  logCtx.routeDecision = route.routeDecision;
900
1015
  logCtx.policyEligibility = route.policyEligibility;
@@ -903,7 +1018,7 @@ export async function prepareResponsesRequest(
903
1018
  if (policyRefusal) return policyRefusal;
904
1019
  if (err instanceof AdmissionModelDeniedError) return admissionModelDeniedResponse(err);
905
1020
  if (err instanceof NoAvailableComboTargetsError) {
906
- return comboUnavailable(err.comboId);
1021
+ return comboUnavailable(err.comboId, undefined, err.reasons);
907
1022
  }
908
1023
  if (err instanceof NoEligiblePolicyCandidateError) {
909
1024
  logCtx.routeDecision = err.trace;
@@ -975,6 +1090,7 @@ export async function prepareResponsesRequest(
975
1090
  "_promptCacheKeyIsSharedCohort",
976
1091
  "_cursorClientThreadId",
977
1092
  "_reasoningReplayScope",
1093
+ "_nativeReasoningRetention",
978
1094
  "_cursorIsolateConversation",
979
1095
  ];
980
1096
  for (const key of kept) {
@@ -1109,8 +1225,9 @@ export async function prepareResponsesRequest(
1109
1225
  if (fallback?.to && !slugsEquivalent(fallback.to, route.modelId)) {
1110
1226
  try {
1111
1227
  route = captureInboundRoutePolicy(
1112
- routeModel(config, fallback.to, evidenceFromBody(parsed._rawBody)),
1228
+ routeModel(config, fallback.to, routeEvidence(options, parsed)),
1113
1229
  );
1230
+ leaveDirectLaneIfRerouted(options, route, parsed, logCtx);
1114
1231
  credentialDomainWasRewritten = true;
1115
1232
  logCtx.routeDecision = route.routeDecision;
1116
1233
  logCtx.policyEligibility = route.policyEligibility;
@@ -1119,7 +1236,7 @@ export async function prepareResponsesRequest(
1119
1236
  if (policyRefusal) return policyRefusal;
1120
1237
  if (err instanceof AdmissionModelDeniedError) return admissionModelDeniedResponse(err);
1121
1238
  if (err instanceof NoAvailableComboTargetsError) {
1122
- return comboUnavailable(err.comboId);
1239
+ return comboUnavailable(err.comboId, undefined, err.reasons);
1123
1240
  }
1124
1241
  if (err instanceof NoEligiblePolicyCandidateError) {
1125
1242
  logCtx.routeDecision = err.trace;
@@ -1257,6 +1374,8 @@ export async function prepareResponsesRequest(
1257
1374
  // for streaming clients.
1258
1375
  const clientRequestedStream = parsed.stream;
1259
1376
  const admittedPolicyRoute = { providerName: route.providerName, modelId: route.modelId };
1377
+ // Final guard before normalization may inject guidance into the raw body.
1378
+ leaveDirectLaneIfRerouted(options, route, parsed, logCtx);
1260
1379
  await applyFinalRouteRequestNormalization({
1261
1380
  parsed,
1262
1381
  route,
@@ -1434,6 +1553,8 @@ export async function prepareResponsesRequest(
1434
1553
  applyAccountChangeConversationStateScrub({
1435
1554
  body: parsed._rawBody,
1436
1555
  parsed,
1556
+ preserveReasoningEncryptedContent: isCanonicalOpenAiForwardProvider(route.provider)
1557
+ && parsed._nativeReasoningRetention?.accountSwitch === true,
1437
1558
  bindingKey: binding.bindingKey,
1438
1559
  servingAccountId: binding.accountId,
1439
1560
  logCtx,
@@ -1452,6 +1573,12 @@ export async function prepareResponsesRequest(
1452
1573
  commitSkillsSnapshot?.();
1453
1574
  return {
1454
1575
  inboundWire,
1576
+ clientDeclaredEmptyToolCatalog: options.clientDeclaredEmptyToolCatalog === true,
1577
+ clientToolCatalogRestriction,
1578
+ // Admission facts later route rewrites must not re-derive: the selector the caller sent and
1579
+ // the key scope as it stood when this request was admitted.
1580
+ inboundSelector,
1581
+ admissionScope,
1455
1582
  translatorBudget,
1456
1583
  parsed,
1457
1584
  toolBridgeMaps,
@@ -2,7 +2,7 @@ import type { ResponsesRequestContext } from "./core-options";
2
2
  import type { PreparedResponsesRequest } from "./request-prepare";
3
3
  import type { ResponsesTransport } from "./request-transport";
4
4
  import type { ResolvedOpenAiForwardSidecar } from "../../providers/openai-sidecar";
5
- import { isCanonicalOpenAiForwardProvider } from "../../providers/openai-tiers";
5
+ import { isCanonicalOpenAiForwardProvider, supportsNativeResponsesCompactionTrigger } from "../../providers/openai-tiers";
6
6
  import { omitEarlierCompactionImages } from "../../responses/compaction-images";
7
7
  import {
8
8
  shouldResolveOpenAiVisionSidecar,
@@ -51,7 +51,7 @@ export async function prepareResponsesSidecarAuth(
51
51
  let openAiSidecar: ResolvedOpenAiForwardSidecar | undefined;
52
52
  const visionDescribeTerminal = options.visionDescribeTerminal === true;
53
53
  const routedCompaction = parsed._compactionRequest === true
54
- && (!isCanonicalOpenAiForwardProvider(route.provider) || parsed._portableCompaction === true);
54
+ && (!supportsNativeResponsesCompactionTrigger(route.provider) || parsed._portableCompaction === true);
55
55
  if (routedCompaction) parsed.context.messages = omitEarlierCompactionImages(parsed.context.messages);
56
56
  const needsOpenAiVision = !visionDescribeTerminal
57
57
  && shouldResolveOpenAiVisionSidecar(config, route.provider, route.modelId, parsed, route.providerName);