@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,5 +1,6 @@
1
1
  import type { TranslatorBudget } from "../../lib/translator-budget";
2
2
  import { finalizeTranslatorBudgetResponse } from "../../lib/translator-budget";
3
+ import { isNonReplayableResponse, markResponseNonReplayable } from "../../lib/upstream-retry";
3
4
  import {
4
5
  isNativePassthroughSseResponse,
5
6
  markNativePassthroughSseResponse,
@@ -47,11 +48,13 @@ export function finalizeOwnedTranslatorBudget(response: Response, budget: Transl
47
48
  markEagerRelaySseResponse(finalizedResponse);
48
49
  }
49
50
  if (isPreinspectedJsonResponse(response)) markPreinspectedJsonResponse(finalizedResponse);
51
+ if (isNonReplayableResponse(response)) markResponseNonReplayable(finalizedResponse);
52
+ if (runTurnAdapterSseResponses.has(response)) runTurnAdapterSseResponses.add(finalizedResponse);
50
53
  return finalizedResponse;
51
54
  }
52
55
 
53
56
  /** Release a serving-account slot when the client body ends, errors or is cancelled. */
54
- export function finalizeAccountLease(response: Response, release: () => void): Response {
57
+ export function finalizeAccountLease(response: Response, release: () => void, onCancel?: () => void): Response {
55
58
  if (!response.body) { release(); return response; }
56
59
  const reader = response.body.getReader();
57
60
  let done = false;
@@ -64,12 +67,14 @@ export function finalizeAccountLease(response: Response, release: () => void): R
64
67
  else controller.enqueue(next.value);
65
68
  } catch (error) { finish(); controller.error(error); }
66
69
  },
67
- async cancel(reason) { try { await reader.cancel(reason); } finally { finish(); } },
70
+ async cancel(reason) { onCancel?.(); try { await reader.cancel(reason); } finally { finish(); } },
68
71
  });
69
72
  const wrapped = new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
73
+ if (isNonReplayableResponse(response)) markResponseNonReplayable(wrapped);
70
74
  if (isNativePassthroughSseResponse(response)) markNativePassthroughSseResponse(wrapped);
71
75
  if (isEagerRelaySseResponse(response)) markEagerRelaySseResponse(wrapped);
72
76
  if (isPreinspectedJsonResponse(response)) markPreinspectedJsonResponse(wrapped);
77
+ if (runTurnAdapterSseResponses.has(response)) runTurnAdapterSseResponses.add(wrapped);
73
78
  return wrapped;
74
79
  }
75
80
 
@@ -1,3 +1,4 @@
1
+ import { effectiveAzureOutputBudget } from "../../adapters/azure";
1
2
  import { sanitizeLogMetadataString } from "../../lib/redact";
2
3
  import type { RouteResult } from "../../router";
3
4
  import type { InboundWire } from "../../providers/registry";
@@ -211,6 +212,16 @@ export async function applyFinalRouteRequestNormalization(args: {
211
212
  logCtx.model = virtualModel?.selectedModelId ?? route.modelId;
212
213
  logCtx.provider = route.providerName;
213
214
  logCtx.spendPoolId = route.providerName;
215
+ // Admission precedes adapter serialization. Reserve the same explicit output cap
216
+ // the final destination will send, and recompute from the caller on every fallback.
217
+ const rawBudget = parsed._rawBody && typeof parsed._rawBody === "object"
218
+ ? (parsed._rawBody as { max_output_tokens?: unknown }).max_output_tokens : undefined;
219
+ const outputBudget = effectiveAzureOutputBudget(route.provider,
220
+ route.provider.adapter === "azure" || route.provider.adapter === "azure-openai"
221
+ ? rawBudget : parsed.options.maxOutputTokens);
222
+ if (typeof outputBudget === "number" && outputBudget > 0) {
223
+ logCtx.spendOutputCeilingTokens = Math.trunc(outputBudget);
224
+ }
214
225
  logCtx.providerAdapter = route.provider.adapter;
215
226
  logCtx.routeDecision = route.routeDecision;
216
227
  logCtx.policyEligibility = route.policyEligibility;
@@ -276,6 +276,39 @@ export function isSelfIdentifiedOpaqueBlobRejection(bodyText: string): boolean {
276
276
  }
277
277
 
278
278
 
279
+ /**
280
+ * Opted-in native reasoning retention forwards ciphertext another model or account minted. ChatGPT
281
+ * can refuse it inside a 200 stream -- a Codex WebSocket `error` frame or `response.failed` --
282
+ * rather than as an HTTP 4xx, so the passthrough inspects the zero-output prelude of exactly these
283
+ * requests. Ordinary turns keep the function-output-only inspection.
284
+ */
285
+ export function retainedReasoningStreamCandidate(parsed: OcxParsedRequest, outboundBody: string | undefined): boolean {
286
+ return parsed._nativeReasoningRetainedAcrossRoute === true
287
+ && parsed._stripReasoningEncryptedContent !== true
288
+ && outboundResponsesBodyCarriesOpaqueBlob(outboundBody);
289
+ }
290
+
291
+ /**
292
+ * Whether a stream-prelude payload is a self-identified refusal of retained ciphertext. A match marks
293
+ * the projected failure as the 4xx it is, so the shared single-shot trigger accepts it.
294
+ */
295
+ export function retainedReasoningStreamRejection(
296
+ payload: unknown,
297
+ parsed: OcxParsedRequest,
298
+ outboundBody: string | undefined,
299
+ preflightLog: RequestLogContext,
300
+ ): boolean {
301
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) return false;
302
+ if (!retainedReasoningStreamCandidate(parsed, outboundBody)) return false;
303
+ const { type, response } = payload as { type?: unknown; response?: { error?: unknown } };
304
+ if (type !== "error" && type !== "response.failed") return false;
305
+ const envelope = type === "error" ? payload : { error: response?.error };
306
+ if (!isSelfIdentifiedOpaqueBlobRejection(JSON.stringify(envelope))) return false;
307
+ preflightLog.terminalHttpStatus = 400;
308
+ return true;
309
+ }
310
+
311
+
279
312
  /**
280
313
  * Whether an upstream Responses 4xx authoritatively rejected opaque replay state.
281
314
  *
@@ -411,6 +444,8 @@ export async function consoleGoUploadRejectionBody(
411
444
 
412
445
  export function prepareOpaqueBlobRecovery(parsed: OcxParsedRequest): void {
413
446
  parsed._stripReasoningEncryptedContent = true;
447
+ delete parsed._nativeReasoningRetainedAcrossRoute;
448
+ parsed._stripNativeCompactionEncryptedContent = true;
414
449
  // The destination rejected state another serving identity minted. A reasoning item's id names
415
450
  // an item in that identity's store, so it goes with the blob.
416
451
  parsed._dropForeignReasoningItemIds = true;
@@ -15,6 +15,7 @@ import type { InboundWire } from "../../providers/registry";
15
15
  import type { ExplicitOpenAiCallerAuth } from "../../providers/openai-sidecar";
16
16
  import type { CallerDirectAuth } from "../../providers/caller-authorization";
17
17
  import type { CompactionRoutingOverride } from "./compaction-routing";
18
+ import type { MainHardLockFallbackOverride } from "./main-hard-lock-routing";
18
19
  import type { TranslatorBudget } from "../../lib/translator-budget";
19
20
  import type { NativeReasoningOwner } from "../../responses/reasoning-replay-cache";
20
21
  import type { TransientSendBudget } from "../../lib/upstream-retry";
@@ -22,6 +23,8 @@ import type { RequestLogContext } from "../request-log";
22
23
  import type { UpstreamHostAdmissionLease } from "../../codex/upstream-host-health";
23
24
  import type { AccountLease } from "../../oauth/kiro-account-load";
24
25
  import type { PolicyRequestScope } from "./policy-request-scope";
26
+ import type { OcxParsedRequest } from "../../types";
27
+ import type { PolicyRequestEvidence } from "../../routing/evaluator";
25
28
 
26
29
  export interface ConsumedComboFailure {
27
30
  response: Response;
@@ -61,6 +64,32 @@ export interface ClientEncoderOption {
61
64
  stream: boolean;
62
65
  model: string;
63
66
  inputTokenFloor?: number;
67
+ /**
68
+ * `direct` when the request side also skipped the internal Responses body (the Antigravity
69
+ * direct lane), so the attempt's request path is traced as `[inbound, ir, upstream]`.
70
+ */
71
+ requestLane?: "bridge" | "direct";
72
+ }
73
+
74
+ /**
75
+ * The Antigravity direct lane (`protocols.rollout.antigravityDirect`). The ingress sends the core
76
+ * a Responses body that carries only the request settings; the conversation is decoded straight
77
+ * from the client body. Request preparation applies `decode` at the parse seam, reads routing
78
+ * evidence from `evidence`, and calls `restoreBridgeConversation` if the final route is not the
79
+ * one the lane was decided for, so every `_rawBody` reader of another adapter sees the full
80
+ * bridge body.
81
+ */
82
+ export interface DirectRequestOption {
83
+ protocol: "chat" | "messages";
84
+ /** The concrete route the ingress decided the lane for. */
85
+ providerName: string;
86
+ modelId: string;
87
+ /** Policy-routing evidence from the client body; the settings-only body has no `input`. */
88
+ evidence: PolicyRequestEvidence;
89
+ /** The settings-only parse with the directly decoded conversation in place of its empty one. */
90
+ decode(base: OcxParsedRequest): OcxParsedRequest;
91
+ /** The bridge projection's conversation fields (`input`, `instructions`, `tools`). */
92
+ bridgeConversation(): Record<string, unknown>;
64
93
  }
65
94
 
66
95
  export interface HandleResponsesOptions {
@@ -137,8 +166,17 @@ export interface HandleResponsesOptions {
137
166
  * it. Omitted means a genuine Responses inbound.
138
167
  */
139
168
  inboundWire?: InboundWire;
169
+ /**
170
+ * Set by a translating ingress (Chat / Anthropic) when the client sent an explicit empty
171
+ * tool catalog. Those wires may defer tool delivery, so their translated body carries no
172
+ * readable catalog boundary; an explicit `[]` is still a deny-all declaration and the
173
+ * undeclared-tool guard enforces it. Absent catalogs and partial catalogs stay deferred.
174
+ */
175
+ clientDeclaredEmptyToolCatalog?: boolean;
140
176
  nativeReasoningReplay?: ReadonlyMap<string, string>;
141
177
  nativeReasoningMint?: { owner?: NativeReasoningOwner };
178
+ /** The Claude client's typed `web_search_*` / `web_fetch_*` declarations; kept only for `inboundWire: "anthropic"`. */
179
+ anthropicServerTools?: readonly Record<string, unknown>[];
142
180
  /** Droid's per-request effort default; each concrete combo or policy target applies it only if its ladder allows it. */
143
181
  droidDefaultEffort?: string;
144
182
  /** PF-07: the Chat source a combo child may send natively; set only by the Chat ingress. */
@@ -172,6 +210,8 @@ export interface HandleResponsesOptions {
172
210
  /** Internal handoff: the memory phase this turn belongs to, so combo children keep its routing. */
173
211
  memoryModelPhase?: "extract" | "consolidation";
174
212
  compactionRoutingOverride?: CompactionRoutingOverride | null;
213
+ /** Internal handoff: the hard-lock fallback rewrote this turn; the log shows `sourceModel`. */
214
+ mainHardLockFallbackOverride?: MainHardLockFallbackOverride | null;
175
215
  /** Internal combo handoff for one parent-validated continuation snapshot. */
176
216
  comboReplaySnapshot?: {
177
217
  sourceBody: unknown;
@@ -202,6 +242,15 @@ export interface HandleResponsesOptions {
202
242
  * rebuilds headers and carries the fact through this flag.
203
243
  */
204
244
  visionDescribeTerminal?: boolean;
245
+ /**
246
+ * Terminal advisor marker: true when the inbound request IS the advisor sidecar's own loopback
247
+ * consultation. The advisor planner then never plans a consultation — a depth cap of 1 that
248
+ * keeps Worker → Advisor → Advisor recursion impossible (same structure as
249
+ * {@linkcode visionDescribeTerminal}). The Chat surface detects the raw
250
+ * `x-opencodex-advisor-internal` header before its bridge rebuilds headers and carries the
251
+ * fact through this flag.
252
+ */
253
+ advisorInternal?: boolean;
205
254
  /**
206
255
  * Set only by the Chat and Messages ingresses when `protocols.rollout.directEncoders` is on and
207
256
  * the settled route is one non-Responses target. Adapter delivery then encodes the adapter
@@ -210,6 +259,8 @@ export interface HandleResponsesOptions {
210
259
  * returning a Responses body, which the ingress converts as before.
211
260
  */
212
261
  clientEncoder?: ClientEncoderOption;
262
+ /** Set only by the Chat or Messages ingress on an eligible Antigravity route; see {@link DirectRequestOption}. */
263
+ directRequest?: DirectRequestOption;
213
264
  }
214
265
 
215
266
  /** Values shared by the call, not a bag of mutable pipeline state. */
@@ -0,0 +1,141 @@
1
+ import { supportsNativeResponsesCompactionTrigger } from "../../providers/openai-tiers";
2
+ import type { OcxConfig } from "../../types";
3
+ import type { RequestLogContext } from "../request-log";
4
+ import type {
5
+ HandleResponsesOptions,
6
+ ResponsesRequestContext,
7
+ ResponsesAdmissionState,
8
+ ResponsesDispatchers,
9
+ } from "./core-options";
10
+ import type { TranslatorBudget } from "../../lib/translator-budget";
11
+ import { prepareResponsesRequest } from "./request-prepare";
12
+ import { prepareResponsesTransport } from "./request-transport";
13
+ import { prepareResponsesSidecarAuth } from "./request-sidecar-auth";
14
+ import { createResponsesEffects } from "./response-effects";
15
+ import { createResponsesSendBudget } from "./request-send-budget";
16
+ import { executePassthroughResponse } from "./passthrough-execution";
17
+ import { executeResponsesSidecars } from "./sidecar-execution";
18
+ import { createResponsesCompletionPolicy } from "./completion-policy";
19
+ import { executeResponsesRunTurn } from "./run-turn-execution";
20
+ import { prepareAdapterExchange } from "./adapter-dispatch";
21
+ import { createAdapterContinuations } from "./adapter-continuation";
22
+ import { deliverAdapterResponse } from "./adapter-delivery";
23
+ import { releaseUpstreamHostAdmission } from "../../codex/upstream-host-health";
24
+ import { releaseCodexAuthContextProbeLease } from "../../codex/auth-context";
25
+ import { formatErrorResponse } from "../../bridge";
26
+ import { InvalidRetainedCompactionSummary, prepareCompactionRetention } from "./compaction-retention";
27
+
28
+ /** Compose request phases while retaining the original admission-finally ownership. */
29
+ export async function handleResponsesInner(
30
+ req: Request,
31
+ config: OcxConfig,
32
+ logCtx: RequestLogContext,
33
+ options: HandleResponsesOptions & { translatorBudget: TranslatorBudget },
34
+ requestDispatchers: ResponsesDispatchers,
35
+ ): Promise<Response> {
36
+ const requestContext: ResponsesRequestContext = { req, config, logCtx, options };
37
+ const admissionState: ResponsesAdmissionState = {
38
+ pendingHostAdmissionLease: null,
39
+ authCtx: { kind: "main", accountId: null },
40
+ };
41
+ let retention: ReturnType<typeof prepareCompactionRetention>;
42
+ let releasePendingSend = () => {};
43
+ try {
44
+ const requestState = await prepareResponsesRequest(requestContext, admissionState, requestDispatchers);
45
+ if (requestState instanceof Response) return requestState;
46
+ const transportState = await prepareResponsesTransport(requestContext, admissionState, requestState);
47
+ if (transportState instanceof Response) return transportState;
48
+ options.onCompactionRecoveryRoute?.(requestState.route);
49
+ if (requestState.parsed._compactionRequest && options.compactionRecoveryKind !== "compaction-v1"
50
+ && (requestState.parsed._portableCompaction || !supportsNativeResponsesCompactionTrigger(requestState.route.provider))) {
51
+ retention = prepareCompactionRetention(requestState.parsed, config,
52
+ requestState.route.staticPolicy.model.contextWindow ?? requestState.route.staticPolicy.model.maxInputTokens,
53
+ options.translatorBudget, options.abortSignal ?? req.signal);
54
+ }
55
+ const execute = async (): Promise<Response> => {
56
+ const sidecarState = await prepareResponsesSidecarAuth(requestContext, requestState, transportState);
57
+ if (sidecarState instanceof Response) return sidecarState;
58
+ const responseEffects = createResponsesEffects(
59
+ requestContext,
60
+ admissionState,
61
+ requestState,
62
+ sidecarState,
63
+ );
64
+ const sendBudgetState = createResponsesSendBudget(requestContext);
65
+ if (sendBudgetState instanceof Response) return sendBudgetState;
66
+ if ("passthrough" in transportState.adapter && transportState.adapter.passthrough && !sidecarState.routedCompaction) {
67
+ const passthroughResult = await executePassthroughResponse(
68
+ requestContext,
69
+ admissionState,
70
+ requestState,
71
+ transportState,
72
+ sidecarState,
73
+ responseEffects,
74
+ sendBudgetState,
75
+ );
76
+ if (passthroughResult instanceof Response) return passthroughResult;
77
+ const unclaimedHop = sendBudgetState.pendingHopPermit;
78
+ releasePendingSend = () => { if (sendBudgetState.pendingHopPermit === unclaimedHop) { unclaimedHop?.release(); sendBudgetState.pendingHopPermit = undefined; } };
79
+ }
80
+ const sidecarPlans = await executeResponsesSidecars(
81
+ requestContext,
82
+ requestState,
83
+ transportState,
84
+ sidecarState,
85
+ responseEffects,
86
+ sendBudgetState,
87
+ );
88
+ if (sidecarPlans instanceof Response) return sidecarPlans;
89
+ const completionPolicy = createResponsesCompletionPolicy(requestContext, sidecarState);
90
+ if (transportState.adapter.runTurn) return await executeResponsesRunTurn(
91
+ requestContext,
92
+ admissionState,
93
+ requestState,
94
+ transportState,
95
+ sidecarState,
96
+ responseEffects,
97
+ sendBudgetState,
98
+ completionPolicy,
99
+ );
100
+ const adapterExchange = await prepareAdapterExchange(
101
+ requestContext,
102
+ admissionState,
103
+ requestState,
104
+ transportState,
105
+ responseEffects,
106
+ sendBudgetState,
107
+ );
108
+ if (adapterExchange instanceof Response) return adapterExchange;
109
+ const continuationState = createAdapterContinuations(
110
+ requestContext,
111
+ requestState,
112
+ transportState,
113
+ sidecarState,
114
+ sendBudgetState,
115
+ adapterExchange,
116
+ );
117
+ return await deliverAdapterResponse(
118
+ requestContext,
119
+ requestState,
120
+ transportState,
121
+ sidecarState,
122
+ responseEffects,
123
+ completionPolicy,
124
+ adapterExchange,
125
+ continuationState,
126
+ );
127
+ };
128
+ const response = await execute();
129
+ return retention ? retention.deliver(response) : response;
130
+ } catch (error) {
131
+ retention?.dispose();
132
+ if (error instanceof InvalidRetainedCompactionSummary) return formatErrorResponse(502, "invalid_compaction_summary", error.message);
133
+ throw error;
134
+ } finally {
135
+ releasePendingSend();
136
+ if (admissionState.pendingHostAdmissionLease) {
137
+ releaseUpstreamHostAdmission(admissionState.pendingHostAdmissionLease);
138
+ releaseCodexAuthContextProbeLease(admissionState.authCtx);
139
+ }
140
+ }
141
+ }
@@ -24,6 +24,7 @@ import {
24
24
  type NativeReasoningOwner,
25
25
  bindReasoningReplayScope,
26
26
  reasoningReplayServingIdentityChanged,
27
+ reasoningReplayServingIdentityChange,
27
28
  reasoningReplayItemStoreChanged,
28
29
  reasoningReplayOpaqueBlobRejectionMemoized,
29
30
  } from "../../responses/reasoning-replay-cache";
@@ -32,6 +33,7 @@ import type { CodexAuthContext } from "../../codex/auth-context";
32
33
  import { thoughtSignatureReplaySalt } from "../../responses/thought-signature-replay";
33
34
  import { randomUUID } from "node:crypto";
34
35
  import { requiresPlaintextReasoningReplay } from "../../adapters/openai-responses/passthrough";
36
+ import { isCanonicalOpenAiForwardProvider } from "../../providers/openai-tiers";
35
37
 
36
38
  /**
37
39
  * Adapters whose continuation state must survive Codex's store:false requests.
@@ -125,11 +127,13 @@ export function bindRouteReasoningReplayScope(args: {
125
127
  if (owner) parsed._nativeReasoningBoundOwner = owner;
126
128
  else delete parsed._nativeReasoningBoundOwner;
127
129
  if (parsed._nativeReasoningReplay?.size) {
130
+ const rejected = new Set<string>();
128
131
  for (const [blob, tag] of parsed._nativeReasoningReplay) {
129
132
  if (!nativeReasoningTagMatches(nativeReasoningTag(owner, blob), tag)) {
130
- stripNativeReasoningBlob(parsed, blob);
133
+ rejected.add(blob);
131
134
  }
132
135
  }
136
+ if (rejected.size) stripNativeReasoningBlobs(parsed, rejected);
133
137
  }
134
138
  const continuationDestinationIdentity = providerContinuationDestinationIdentity(parsed, provider);
135
139
  const continuationOwner = providerContinuationOwnerFromReplayIdentity(
@@ -154,8 +158,19 @@ export function bindRouteReasoningReplayScope(args: {
154
158
  );
155
159
  // Keep this sticky for the whole outbound request: a later auth/key rebind may compare equal
156
160
  // after the first mismatch, but it cannot make history minted by the prior route decodable.
157
- if (reasoningReplayServingIdentityChanged(parsed._reasoningReplayScope)) {
158
- parsed._stripReasoningEncryptedContent = true;
161
+ const identityChange = reasoningReplayServingIdentityChange(parsed._reasoningReplayScope);
162
+ if (identityChange) {
163
+ // Reasoning retention does not establish portability of native compacted history.
164
+ parsed._stripNativeCompactionEncryptedContent = true;
165
+ const retention = parsed._nativeReasoningRetention;
166
+ const mayRetainReasoning = isCanonicalOpenAiForwardProvider(provider)
167
+ && !identityChange.providerChanged
168
+ && !identityChange.destinationChanged
169
+ && !identityChange.adapterChanged
170
+ && (!identityChange.modelChanged || retention?.modelSwitch === true)
171
+ && (!identityChange.credentialChanged || retention?.accountSwitch === true);
172
+ if (!mayRetainReasoning) parsed._stripReasoningEncryptedContent = true;
173
+ else if (parsed._stripReasoningEncryptedContent !== true) parsed._nativeReasoningRetainedAcrossRoute = true;
159
174
  // Only a different destination or credential makes the replayed item ids unresolvable; a
160
175
  // model change on the same store keeps them.
161
176
  if (reasoningReplayItemStoreChanged(parsed._reasoningReplayScope)) {
@@ -164,16 +179,19 @@ export function bindRouteReasoningReplayScope(args: {
164
179
  }
165
180
  if (reasoningReplayOpaqueBlobRejectionMemoized(parsed._reasoningReplayScope)) {
166
181
  parsed._stripReasoningEncryptedContent = true;
182
+ parsed._stripNativeCompactionEncryptedContent = true;
167
183
  parsed._dropForeignReasoningItemIds = true;
168
184
  }
185
+ // Stripping is authoritative: nothing retained remains to be refused.
186
+ if (parsed._stripReasoningEncryptedContent === true) delete parsed._nativeReasoningRetainedAcrossRoute;
169
187
  bindProviderContinuationForRoute(parsed, continuationOwner);
170
188
  }
171
189
 
172
- function stripNativeReasoningBlob(parsed: OcxParsedRequest, blob: string): void {
190
+ function stripNativeReasoningBlobs(parsed: OcxParsedRequest, rejected: ReadonlySet<string>): void {
173
191
  const input = (parsed._rawBody as { input?: unknown } | undefined)?.input;
174
192
  if (Array.isArray(input)) {
175
193
  for (const item of input) {
176
- if (item && typeof item === "object" && item.type === "reasoning" && item.encrypted_content === blob) {
194
+ if (item && typeof item === "object" && item.type === "reasoning" && rejected.has(item.encrypted_content)) {
177
195
  delete item.encrypted_content;
178
196
  delete item.id;
179
197
  }
@@ -187,7 +205,8 @@ function stripNativeReasoningBlob(parsed: OcxParsedRequest, blob: string): void
187
205
  const item: unknown = JSON.parse(part.signature);
188
206
  if (!item || typeof item !== "object" || Array.isArray(item)) continue;
189
207
  const reasoning = item as Record<string, unknown>;
190
- if (reasoning.type !== "reasoning" || reasoning.encrypted_content !== blob) continue;
208
+ if (reasoning.type !== "reasoning" || typeof reasoning.encrypted_content !== "string"
209
+ || !rejected.has(reasoning.encrypted_content)) continue;
191
210
  delete reasoning.encrypted_content;
192
211
  delete reasoning.id;
193
212
  part.signature = JSON.stringify(reasoning);
@@ -1,9 +1,8 @@
1
+ import { handleResponsesInner } from "./core-pipeline";
1
2
  import type { OcxConfig } from "../../types";
2
3
  import type { RequestLogContext } from "../request-log";
3
4
  import type {
4
5
  HandleResponsesOptions,
5
- ResponsesRequestContext,
6
- ResponsesAdmissionState,
7
6
  ResponsesDispatchers,
8
7
  } from "./core-options";
9
8
  import { createTranslatorBudget } from "../../lib/translator-budget";
@@ -13,20 +12,6 @@ import { createInferenceSendBudget } from "../inference/context";
13
12
  import { finalizeOwnedTranslatorBudget, finalizeAccountLease } from "./core-lifetime";
14
13
  import type { TranslatorBudget } from "../../lib/translator-budget";
15
14
  import { executeComboResponses } from "./core-combo";
16
- import { prepareResponsesRequest } from "./request-prepare";
17
- import { prepareResponsesTransport } from "./request-transport";
18
- import { prepareResponsesSidecarAuth } from "./request-sidecar-auth";
19
- import { createResponsesEffects } from "./response-effects";
20
- import { createResponsesSendBudget } from "./request-send-budget";
21
- import { executePassthroughResponse } from "./passthrough-execution";
22
- import { executeResponsesSidecars } from "./sidecar-execution";
23
- import { createResponsesCompletionPolicy } from "./completion-policy";
24
- import { executeResponsesRunTurn } from "./run-turn-execution";
25
- import { prepareAdapterExchange } from "./adapter-dispatch";
26
- import { createAdapterContinuations } from "./adapter-continuation";
27
- import { deliverAdapterResponse } from "./adapter-delivery";
28
- import { releaseUpstreamHostAdmission } from "../../codex/upstream-host-health";
29
- import { releaseCodexAuthContextProbeLease } from "../../codex/auth-context";
30
15
  import { runWithCompactionRecovery } from "./compaction-recovery";
31
16
  /**
32
17
  * Route one `/v1/responses` request through the adapter pipeline: recovery loop, passthrough
@@ -48,7 +33,7 @@ export async function handleResponses(
48
33
  abortSignal.addEventListener("abort", cancel, { once: true });
49
34
  try {
50
35
  const response = await runWithCompactionRecovery(req, config, logCtx, {
51
- ...options,
36
+ ...options, abortSignal,
52
37
  openAiSidecarAuth: options.openAiSidecarAuth === undefined
53
38
  ? captureExplicitOpenAiCallerAuth(req.headers, config) : options.openAiSidecarAuth,
54
39
  nativeCallerAuth: options.nativeCallerAuth === undefined
@@ -62,7 +47,7 @@ export async function handleResponses(
62
47
  accountLoad,
63
48
  // Once at ingress, spend observer included: a combo child inherits the parent's holder.
64
49
  sendBudget: options.sendBudget ?? createInferenceSendBudget(req, logCtx),
65
- }, handleResponsesInner);
50
+ }, (req, config, logCtx, options) => handleResponsesInner(req, config, logCtx, options, requestDispatchers));
66
51
  const finalResponse = ownsBudget ? finalizeOwnedTranslatorBudget(response, translatorBudget, abortSignal) : response;
67
52
  if (!accountLoad.lease) { release(); return finalResponse; }
68
53
  return finalizeAccountLease(finalResponse, release);
@@ -92,104 +77,6 @@ export async function handleComboResponses(
92
77
  requestDispatchers,
93
78
  );
94
79
  }
95
- /** Compose request phases while retaining the original admission-finally ownership. */
96
- async function handleResponsesInner(
97
- req: Request,
98
- config: OcxConfig,
99
- logCtx: RequestLogContext,
100
- options: HandleResponsesOptions & { translatorBudget: TranslatorBudget },
101
- ): Promise<Response> {
102
- const requestContext: ResponsesRequestContext = { req, config, logCtx, options };
103
- const admissionState: ResponsesAdmissionState = {
104
- pendingHostAdmissionLease: null,
105
- authCtx: { kind: "main", accountId: null },
106
- };
107
- let releasePendingSend = () => {};
108
- try {
109
- const requestState = await prepareResponsesRequest(requestContext, admissionState, requestDispatchers);
110
- if (requestState instanceof Response) return requestState;
111
- const transportState = await prepareResponsesTransport(requestContext, admissionState, requestState);
112
- if (transportState instanceof Response) return transportState;
113
- options.onCompactionRecoveryRoute?.(requestState.route);
114
- const sidecarState = await prepareResponsesSidecarAuth(requestContext, requestState, transportState);
115
- if (sidecarState instanceof Response) return sidecarState;
116
- const responseEffects = createResponsesEffects(
117
- requestContext,
118
- admissionState,
119
- requestState,
120
- sidecarState,
121
- );
122
- const sendBudgetState = createResponsesSendBudget(requestContext);
123
- if (sendBudgetState instanceof Response) return sendBudgetState;
124
- if ("passthrough" in transportState.adapter && transportState.adapter.passthrough && !sidecarState.routedCompaction) {
125
- const passthroughResult = await executePassthroughResponse(
126
- requestContext,
127
- admissionState,
128
- requestState,
129
- transportState,
130
- sidecarState,
131
- responseEffects,
132
- sendBudgetState,
133
- );
134
- if (passthroughResult instanceof Response) return passthroughResult;
135
- const unclaimedHop = sendBudgetState.pendingHopPermit;
136
- releasePendingSend = () => { if (sendBudgetState.pendingHopPermit === unclaimedHop) { unclaimedHop?.release(); sendBudgetState.pendingHopPermit = undefined; } };
137
- }
138
- const sidecarPlans = await executeResponsesSidecars(
139
- requestContext,
140
- requestState,
141
- transportState,
142
- sidecarState,
143
- responseEffects,
144
- sendBudgetState,
145
- );
146
- if (sidecarPlans instanceof Response) return sidecarPlans;
147
- const completionPolicy = createResponsesCompletionPolicy(requestContext, sidecarState);
148
- if (transportState.adapter.runTurn) return await executeResponsesRunTurn(
149
- requestContext,
150
- admissionState,
151
- requestState,
152
- transportState,
153
- sidecarState,
154
- responseEffects,
155
- sendBudgetState,
156
- completionPolicy,
157
- );
158
- const adapterExchange = await prepareAdapterExchange(
159
- requestContext,
160
- admissionState,
161
- requestState,
162
- transportState,
163
- responseEffects,
164
- sendBudgetState,
165
- );
166
- if (adapterExchange instanceof Response) return adapterExchange;
167
- const continuationState = createAdapterContinuations(
168
- requestContext,
169
- requestState,
170
- transportState,
171
- sidecarState,
172
- sendBudgetState,
173
- adapterExchange,
174
- );
175
- return await deliverAdapterResponse(
176
- requestContext,
177
- requestState,
178
- transportState,
179
- sidecarState,
180
- responseEffects,
181
- completionPolicy,
182
- adapterExchange,
183
- continuationState,
184
- );
185
- } finally {
186
- releasePendingSend();
187
- if (admissionState.pendingHostAdmissionLease) {
188
- releaseUpstreamHostAdmission(admissionState.pendingHostAdmissionLease);
189
- releaseCodexAuthContextProbeLease(admissionState.authCtx);
190
- }
191
- }
192
- }
193
80
  const requestDispatchers: ResponsesDispatchers = { handleResponses, handleComboResponses };
194
81
  export { adapterNeedsForcedContinuation } from "./core-replay";
195
82
  export {