@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.
- package/README.md +0 -4
- package/bin/ocx.mjs +61 -3
- package/gui/dist/assets/App-ZfYbLHkB.js +58 -0
- package/gui/dist/assets/App-wT3mXqFz.css +1 -0
- package/gui/dist/assets/{Tray-C9TGtwad.js → Tray-DCd-A1az.js} +1 -1
- package/gui/dist/assets/index-CfYDMj34.js +94 -0
- package/gui/dist/assets/index-DPeB9HpV.css +1 -0
- package/gui/dist/assets/quota-summary-ChvmKGOk.js +1 -0
- package/gui/dist/index.html +2 -2
- package/package.json +1 -2
- package/src/adapters/anthropic/beta-allowlist.ts +91 -11
- package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
- package/src/adapters/anthropic/client-identity.ts +1 -1
- package/src/adapters/anthropic/passthrough.ts +16 -3
- package/src/adapters/anthropic-progress.ts +84 -0
- package/src/adapters/anthropic.ts +108 -21
- package/src/adapters/azure.ts +19 -1
- package/src/adapters/base.ts +2 -0
- package/src/adapters/claude-cli/adapter.ts +111 -23
- package/src/adapters/claude-cli/profiles.ts +2 -1
- package/src/adapters/claude-cli/stable-replay.ts +108 -0
- package/src/adapters/claude-cli/usage-admission.ts +230 -0
- package/src/adapters/client-fingerprint.ts +24 -0
- package/src/adapters/coding-agent/protocol.ts +1 -1
- package/src/adapters/coding-agent/turn.ts +40 -11
- package/src/adapters/cursor/arg-codec.ts +17 -5
- package/src/adapters/cursor/catalog.ts +8 -0
- package/src/adapters/cursor/effort-map.ts +3 -0
- package/src/adapters/cursor/freeform-args.ts +75 -0
- package/src/adapters/cursor/protobuf-events.ts +36 -23
- package/src/adapters/dsh-account.ts +97 -0
- package/src/adapters/google-antigravity-wire.ts +22 -1
- package/src/adapters/google.ts +37 -10
- package/src/adapters/openai-chat/messages.ts +4 -3
- package/src/adapters/openai-chat/passthrough.ts +8 -2
- package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
- package/src/adapters/openai-chat/response-events.ts +59 -1
- package/src/adapters/openai-chat.ts +8 -5
- package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
- package/src/adapters/openai-responses/passthrough.ts +57 -125
- package/src/adapters/openai-responses/request-strips.ts +25 -3
- package/src/adapters/openai-responses/transport.ts +81 -0
- package/src/adapters/qoder/adapter.ts +44 -3
- package/src/adapters/registry.ts +5 -0
- package/src/adapters/zed.ts +26 -1
- package/src/advisor/activity.ts +55 -0
- package/src/advisor/budget.ts +62 -0
- package/src/advisor/consult.ts +223 -0
- package/src/advisor/context.ts +238 -0
- package/src/advisor/disclosure.ts +20 -0
- package/src/advisor/evidence-tool.ts +21 -0
- package/src/advisor/evidence.ts +117 -0
- package/src/advisor/runtime.ts +353 -0
- package/src/advisor/settings.ts +144 -0
- package/src/advisor/state.ts +369 -0
- package/src/advisor/synthetic-tool.ts +33 -0
- package/src/bridge/errors.ts +24 -1
- package/src/bridge/internal.ts +3 -1
- package/src/bridge/response-json.ts +18 -3
- package/src/bridge/sse.ts +58 -8
- package/src/bridge/terminal-refusal.ts +59 -0
- package/src/chat/inbound.ts +30 -6
- package/src/chat/outbound.ts +5 -0
- package/src/claude/desktop-3p-library.ts +72 -7
- package/src/claude/desktop-3p.ts +75 -19
- package/src/claude/desktop-first-party.ts +1 -1
- package/src/claude/desktop-picker-platform.ts +4 -0
- package/src/claude/desktop-picker-profile.ts +11 -4
- package/src/claude/desktop-picker.ts +15 -8
- package/src/claude/desktop-profile.ts +10 -1
- package/src/claude/desktop-remote-store-io.ts +5 -3
- package/src/claude/desktop-system-proxy.ts +50 -4
- package/src/claude/inbound-content-options.ts +11 -0
- package/src/claude/inbound.ts +154 -50
- package/src/claude/intercept/local-ca.ts +8 -1
- package/src/claude/intercept/picker-ca-startup.ts +2 -1
- package/src/claude/intercept/picker-runtime.ts +6 -5
- package/src/claude/intercept/picker-trust-windows.ts +338 -0
- package/src/claude/intercept/picker-trust.ts +19 -0
- package/src/claude/intercept/port-policy.ts +30 -0
- package/src/claude/intercept/runtime.ts +97 -94
- package/src/claude/model-default-settings.ts +154 -0
- package/src/claude/model-info.ts +7 -7
- package/src/claude/outbound.ts +51 -19
- package/src/cli/account-api.ts +1 -0
- package/src/cli/account-policy-dto.ts +6 -0
- package/src/cli/account-policy.ts +34 -5
- package/src/cli/account-preservation.ts +44 -0
- package/src/cli/account.ts +8 -2
- package/src/cli/advisor.ts +165 -0
- package/src/cli/auxiliary-listener-preflight.ts +37 -0
- package/src/cli/capabilities-accounts.ts +20 -1
- package/src/cli/capabilities-agents-routing.ts +23 -2
- package/src/cli/capabilities-base.ts +39 -11
- package/src/cli/capabilities-observe-system.ts +63 -3
- package/src/cli/capabilities-provider-models.ts +11 -0
- package/src/cli/chatgpt-command.ts +35 -14
- package/src/cli/claude.ts +46 -6
- package/src/cli/codex-cli-update.ts +151 -41
- package/src/cli/codex-provider.ts +44 -0
- package/src/cli/combo-input.ts +10 -1
- package/src/cli/combo-result.ts +1 -1
- package/src/cli/combo.ts +2 -1
- package/src/cli/cross-home-owner.ts +17 -14
- package/src/cli/dispatch.ts +30 -5
- package/src/cli/doctor.ts +15 -1
- package/src/cli/ensure-desktop-cold-start.ts +382 -0
- package/src/cli/export-command.ts +1 -1
- package/src/cli/help.ts +4 -2
- package/src/cli/index.ts +14 -5
- package/src/cli/integration-plan-dto.ts +3 -0
- package/src/cli/log-history.ts +172 -0
- package/src/cli/models-runtime-subcommands.ts +1 -0
- package/src/cli/models-runtime.ts +72 -8
- package/src/cli/observe-stream.ts +2 -0
- package/src/cli/observe.ts +16 -4
- package/src/cli/provider.ts +27 -5
- package/src/cli/registry.ts +41 -9
- package/src/cli/restart-scope.ts +3 -1
- package/src/cli/runtime-api.ts +5 -3
- package/src/cli/system-command.ts +40 -8
- package/src/cli/uninstall-client-state.ts +32 -0
- package/src/cli/usage-compare.ts +309 -0
- package/src/cli/usage-model-search.ts +4 -4
- package/src/cli/usage-report.ts +2 -2
- package/src/cli/v2.ts +1 -1
- package/src/client/machine-listener.ts +1 -3
- package/src/client/runtime.ts +1 -0
- package/src/clients/client-path.ts +51 -0
- package/src/clients/config-export/contracts.ts +3 -1
- package/src/clients/config-export/model-metadata.ts +3 -2
- package/src/clients/config-export/qoder.ts +93 -0
- package/src/clients/config-export.ts +35 -48
- package/src/clients/gentle-shell-path.ts +87 -0
- package/src/codex/account-auto-switch.ts +2 -0
- package/src/codex/account-identity.ts +29 -0
- package/src/codex/account-label.ts +1 -1
- package/src/codex/account-lifecycle.ts +21 -5
- package/src/codex/account-preservation.ts +28 -0
- package/src/codex/account-use-remaining.ts +23 -0
- package/src/codex/app-server-processes.ts +97 -7
- package/src/codex/app-server-restart-service.ts +55 -4
- package/src/codex/auth-api/account-list.ts +4 -0
- package/src/codex/auth-api/account-pause-group.ts +6 -50
- package/src/codex/auth-api/account-preservation.ts +57 -0
- package/src/codex/auth-api/pool-mode-gate.ts +5 -2
- package/src/codex/auth-api/routes.ts +8 -0
- package/src/codex/auth-api/use-remaining-route.ts +36 -0
- package/src/codex/auth-api.ts +0 -1
- package/src/codex/auth-context.ts +81 -7
- package/src/codex/autostart-health.ts +4 -0
- package/src/codex/catalog/auto-review.ts +20 -3
- package/src/codex/catalog/build-entries.ts +19 -2
- package/src/codex/catalog/combo-member.ts +14 -5
- package/src/codex/catalog/configured-tiers.ts +50 -0
- package/src/codex/catalog/effort.ts +4 -1
- package/src/codex/catalog/gather-capture.ts +2 -0
- package/src/codex/catalog/metadata.ts +11 -9
- package/src/codex/catalog/model-hints.ts +42 -19
- package/src/codex/catalog/model-visibility.ts +3 -1
- package/src/codex/catalog/native-ultrafast.ts +106 -0
- package/src/codex/catalog/parsing.ts +35 -86
- package/src/codex/catalog/provider-models.ts +40 -34
- package/src/codex/catalog/retained-sync.ts +2 -0
- package/src/codex/catalog/routed-gather.ts +33 -16
- package/src/codex/catalog/vendor-context.ts +82 -0
- package/src/codex/cli-install-provenance.ts +105 -17
- package/src/codex/cli-update-plan.ts +545 -0
- package/src/codex/config-write-lock.ts +63 -4
- package/src/codex/convergence.ts +2 -0
- package/src/codex/desktop-app/picker-freshness.ts +96 -0
- package/src/codex/desktop-app/types.ts +2 -0
- package/src/codex/desktop-app/windows.ts +29 -16
- package/src/codex/desktop-app-restart.ts +25 -2
- package/src/codex/desktop-compatibility/certificate-service.ts +99 -0
- package/src/codex/desktop-compatibility/certificate-store.ts +193 -0
- package/src/codex/desktop-compatibility/connection-store.ts +87 -0
- package/src/codex/desktop-compatibility/installed-build.ts +73 -0
- package/src/codex/desktop-compatibility/json-body.ts +29 -0
- package/src/codex/desktop-compatibility/native-identity.ts +62 -0
- package/src/codex/desktop-compatibility/relay-listener.ts +93 -0
- package/src/codex/desktop-compatibility/routing-binding.ts +10 -0
- package/src/codex/desktop-compatibility/routing-preflight.ts +69 -0
- package/src/codex/desktop-compatibility/runtime-ownership.ts +28 -0
- package/src/codex/desktop-compatibility/runtime.ts +182 -0
- package/src/codex/desktop-compatibility/service.ts +30 -0
- package/src/codex/desktop-compatibility/startup-settings.ts +50 -0
- package/src/codex/desktop-compatibility/usage-activation.ts +86 -0
- package/src/codex/desktop-compatibility/usage-controlled-fetch.ts +59 -0
- package/src/codex/desktop-compatibility/usage-controller.ts +107 -0
- package/src/codex/desktop-compatibility/usage-policy.ts +59 -0
- package/src/codex/desktop-compatibility/usage-refresh.ts +33 -0
- package/src/codex/desktop-compatibility/usage-sse-controller.ts +86 -0
- package/src/codex/desktop-compatibility/windows-activation-source.ts +44 -0
- package/src/codex/desktop-compatibility/windows-certificate-trust.ts +81 -0
- package/src/codex/desktop-compatibility/windows-key-protection.ts +165 -0
- package/src/codex/desktop-compatibility/windows-package-command.ts +86 -0
- package/src/codex/desktop-compatibility/windows-package-launch.ts +28 -0
- package/src/codex/features.ts +85 -45
- package/src/codex/history-provider.ts +1 -1
- package/src/codex/inject/config-write-section.ts +4 -1
- package/src/codex/inject/history-failure.ts +27 -0
- package/src/codex/inject/remove.ts +18 -6
- package/src/codex/inject/restore.ts +24 -2
- package/src/codex/inject/routing-classify.ts +4 -3
- package/src/codex/inject.ts +18 -27
- package/src/codex/journal.ts +16 -1
- package/src/codex/main-account-hard-lock.ts +30 -1
- package/src/codex/main-account.ts +99 -15
- package/src/codex/native-main-refresh-mode.ts +217 -0
- package/src/codex/native-profile-startup.ts +1 -1
- package/src/codex/ocx-compaction-history.ts +12 -10
- package/src/codex/paths.ts +86 -1
- package/src/codex/provider-routing.ts +174 -0
- package/src/codex/refresh.ts +2 -2
- package/src/codex/routing/health-store.ts +2 -2
- package/src/codex/routing/pool-recovery.ts +79 -0
- package/src/codex/routing/selection.ts +4 -3
- package/src/codex/routing/thread-affinity.ts +1 -1
- package/src/codex/shim-diagnostics.ts +6 -0
- package/src/codex/shim-overlay.ts +7 -2
- package/src/codex/signed-in-identity.ts +43 -0
- package/src/codex/subagent-model-fallback.ts +1 -1
- package/src/codex/sync.ts +6 -1
- package/src/codex/user-identity.ts +16 -5
- package/src/codex/windows-local-appdata.ts +84 -0
- package/src/combos/failover.ts +6 -1
- package/src/combos/index.ts +1 -0
- package/src/combos/resolve.ts +46 -10
- package/src/combos/types.ts +15 -0
- package/src/config/diagnostics.ts +35 -7
- package/src/config/live-reconcile.ts +51 -2
- package/src/config/load-degrade.ts +23 -1
- package/src/config/opencode-wire-upgrade.ts +54 -0
- package/src/config/opencode-zen-upgrade.ts +52 -0
- package/src/config/owner-registry.ts +22 -17
- package/src/config/paths.ts +10 -3
- package/src/config/provider-validation.ts +45 -2
- package/src/config/schema/config-schema.ts +39 -0
- package/src/config/schema/desktop-compatibility.ts +9 -0
- package/src/config/schema/leaf-validators.ts +39 -9
- package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
- package/src/config/schema/native-reasoning-retention.ts +26 -0
- package/src/config.ts +2 -0
- package/src/generated/compatibility-version.json +962 -350
- package/src/generated/model-metadata.ts +1 -1
- package/src/grok/sync.ts +1 -1
- package/src/images/loop.ts +46 -8
- package/src/integrations/catalog-refresh.ts +1 -1
- package/src/integrations/config-io.ts +20 -2
- package/src/integrations/journal.ts +15 -1
- package/src/integrations/mutation-plan.ts +2 -0
- package/src/integrations/registry.ts +15 -0
- package/src/integrations/store.ts +3 -0
- package/src/integrations/writer.ts +10 -1
- package/src/lib/advisor-activation.ts +16 -0
- package/src/lib/background-work.ts +65 -0
- package/src/lib/bounded-file-read.ts +58 -0
- package/src/lib/bun-path-runtime.d.mts +10 -1
- package/src/lib/bun-path-runtime.mjs +62 -3
- package/src/lib/codex-restart-contract.ts +15 -0
- package/src/lib/desktop-proxy-route.ts +30 -0
- package/src/lib/desktop-upstream-tunnel.ts +72 -0
- package/src/lib/empty-tool-catalog.ts +62 -0
- package/src/lib/errors.ts +26 -3
- package/src/lib/gcp-adc.ts +96 -9
- package/src/lib/gcp-credential-input.ts +12 -0
- package/src/lib/lab-live-route-production.ts +5 -0
- package/src/lib/local-internal-call-capability.ts +55 -0
- package/src/lib/opaque-proxy-tunnel.ts +217 -0
- package/src/lib/package-tree-integrity.ts +2 -2
- package/src/lib/redact.ts +2 -2
- package/src/lib/socks5-fetch.ts +48 -71
- package/src/lib/socks5-handshake.ts +112 -0
- package/src/lib/translator-budget.ts +7 -1
- package/src/oauth/account-quota-rank.ts +69 -2
- package/src/oauth/anthropic-account-refusal.ts +20 -2
- package/src/oauth/anthropic-oauth-definitions.ts +3 -1
- package/src/oauth/anthropic-routing.ts +1 -21
- package/src/oauth/anthropic.ts +38 -7
- package/src/oauth/callback-server.ts +27 -1
- package/src/oauth/chatgpt-device.ts +1 -1
- package/src/oauth/chatgpt-shared.ts +83 -0
- package/src/oauth/chatgpt.ts +8 -72
- package/src/oauth/dsh.ts +203 -0
- package/src/oauth/generic-account-failover.ts +62 -12
- package/src/oauth/generic-session-affinity.ts +125 -0
- package/src/oauth/index.ts +188 -111
- package/src/oauth/kiro-device-login.ts +2 -1
- package/src/oauth/kiro.ts +7 -1
- package/src/oauth/local-token-detect.ts +21 -1
- package/src/oauth/login-cli-errors.ts +44 -0
- package/src/oauth/login-cli.ts +69 -7
- package/src/oauth/login-flow-state.ts +371 -23
- package/src/oauth/meta-muse-errors.ts +41 -0
- package/src/oauth/meta-muse-keychain.ts +52 -0
- package/src/oauth/meta-muse.ts +51 -84
- package/src/oauth/model-discovery-auth.ts +3 -0
- package/src/oauth/pool-settings-capability.ts +4 -2
- package/src/oauth/refresh-flight-retirement.ts +48 -0
- package/src/oauth/session-affinity-key.ts +23 -0
- package/src/oauth/store-anthropic-instance.ts +9 -2
- package/src/oauth/store.ts +12 -5
- package/src/protocols/codecs/chat-ir.ts +467 -0
- package/src/protocols/codecs/chat.ts +10 -1
- package/src/protocols/codecs/messages-ir.ts +500 -0
- package/src/protocols/encoders/adapter-events.ts +5 -4
- package/src/protocols/encoders/messages.ts +9 -6
- package/src/protocols/features.ts +10 -2
- package/src/protocols/path.ts +11 -1
- package/src/protocols/plan-snapshot.ts +39 -16
- package/src/protocols/plan.ts +9 -1
- package/src/protocols/provider-summary.ts +2 -1
- package/src/protocols/settings.ts +8 -0
- package/src/providers/antigravity-account-roster.ts +102 -0
- package/src/providers/antigravity-models.ts +85 -7
- package/src/providers/api-key-cooldowns.ts +49 -0
- package/src/providers/api-key-resolve.ts +11 -6
- package/src/providers/api-key-response-ownership.ts +57 -0
- package/src/providers/api-key-selection.ts +31 -6
- package/src/providers/api-keys.ts +214 -3
- package/src/providers/claude-cli-usage.ts +96 -0
- package/src/providers/dsh-account-destination.ts +31 -0
- package/src/providers/dsh-account-models.ts +41 -0
- package/src/providers/gcp-credential-cleanup.ts +59 -0
- package/src/providers/key-failover.ts +54 -50
- package/src/providers/key-store.ts +7 -2
- package/src/providers/model-rename-fields.ts +5 -0
- package/src/providers/model-rename-migration.ts +7 -5
- package/src/providers/openai-tiers-destination.ts +11 -2
- package/src/providers/openai-tiers.ts +5 -12
- package/src/providers/opencode-go-transport.ts +3 -1
- package/src/providers/quota/account-cache.ts +6 -5
- package/src/providers/quota/account-row.ts +34 -0
- package/src/providers/quota/antigravity.ts +28 -7
- package/src/providers/quota/dsh-account.ts +70 -0
- package/src/providers/quota/vendor-probes-oauth.ts +1 -93
- package/src/providers/quota-types.ts +2 -0
- package/src/providers/quota.ts +14 -20
- package/src/providers/registry/entries-core.ts +44 -14
- package/src/providers/registry/entries-extended.ts +19 -0
- package/src/providers/registry/types.ts +1 -1
- package/src/providers/request-pacing.ts +77 -19
- package/src/providers/routed-config.ts +339 -0
- package/src/providers/service-tier.ts +2 -1
- package/src/quota/window-mapping.ts +5 -2
- package/src/responses/anthropic-progress.ts +34 -0
- package/src/responses/assistant-replay.ts +35 -0
- package/src/responses/compaction-history-framing.ts +65 -0
- package/src/responses/compaction.ts +6 -1
- package/src/responses/incomplete-reason.ts +31 -0
- package/src/responses/parser.ts +78 -22
- package/src/responses/reasoning-envelope.ts +4 -0
- package/src/responses/reasoning-replay-cache.ts +24 -2
- package/src/responses/reasoning-retention.ts +173 -0
- package/src/responses/retained-compaction.ts +46 -0
- package/src/responses/schema.ts +23 -0
- package/src/responses/state.ts +32 -29
- package/src/router.ts +8 -321
- package/src/routing/health.ts +37 -22
- package/src/routing/history/build-file.ts +92 -0
- package/src/routing/history/indexer.ts +254 -221
- package/src/routing/history/ingest.ts +242 -0
- package/src/routing/history/rebuild-job.ts +111 -0
- package/src/routing/history/rebuild-protocol.ts +15 -0
- package/src/routing/history/rebuild-worker.ts +34 -0
- package/src/routing/profile.ts +1 -1
- package/src/server/admission-model-scope.ts +21 -1
- package/src/server/antigravity-direct-eligibility.ts +208 -0
- package/src/server/auth-cors.ts +15 -0
- package/src/server/chat-completions.ts +82 -10
- package/src/server/chat-native-reasoning.ts +123 -0
- package/src/server/chat-native-sse.ts +110 -7
- package/src/server/chat-native.ts +76 -17
- package/src/server/claude-messages.ts +164 -433
- package/src/server/effort-policy.ts +1 -1
- package/src/server/images.ts +15 -2
- package/src/server/index/desktop-compatibility-startup.ts +56 -0
- package/src/server/index/model-alias-id.ts +36 -0
- package/src/server/index/optional-listeners.ts +2 -0
- package/src/server/index/serve-options.ts +11 -3
- package/src/server/index/startup-warnings.ts +11 -0
- package/src/server/index/websocket-handler.ts +9 -0
- package/src/server/index.ts +14 -11
- package/src/server/inference/advisor-diagnostics.ts +31 -0
- package/src/server/inference/client-encoder-delivery.ts +6 -5
- package/src/server/login-shell-path.ts +146 -0
- package/src/server/management/advisor-routes.ts +202 -0
- package/src/server/management/agent-settings-routes.ts +22 -4
- package/src/server/management/claude-desktop-picker-routes.ts +1 -1
- package/src/server/management/combo-routes.ts +176 -50
- package/src/server/management/companion-routes.ts +4 -0
- package/src/server/management/config-routes.ts +77 -6
- package/src/server/management/context.ts +4 -0
- package/src/server/management/cursor-integration-routes.ts +1 -1
- package/src/server/management/desktop-compatibility-routes.ts +46 -0
- package/src/server/management/desktop-compatibility-runtime-routes.ts +46 -0
- package/src/server/management/desktop-compatibility-settings-routes.ts +27 -0
- package/src/server/management/model-routes.ts +13 -8
- package/src/server/management/model-rows.ts +14 -0
- package/src/server/management/native-integration-routes.ts +2 -7
- package/src/server/management/native-reasoning-retention-routes.ts +41 -0
- package/src/server/management/oauth-account-routes.ts +87 -14
- package/src/server/management/protocol-settings-patch.ts +1 -0
- package/src/server/management/provider-gcp-credential-routes.ts +29 -0
- package/src/server/management/provider-key-pacing-routes.ts +31 -0
- package/src/server/management/provider-overwrite-carry.ts +7 -0
- package/src/server/management/provider-routes.ts +25 -30
- package/src/server/management/route-registry.ts +21 -1
- package/src/server/management/sibling-guard.ts +1 -0
- package/src/server/management-api.ts +9 -1
- package/src/server/messages-antigravity-direct.ts +195 -0
- package/src/server/messages-native-tool-guard.ts +185 -0
- package/src/server/messages-native.ts +106 -22
- package/src/server/messages-shared.ts +431 -0
- package/src/server/relay.ts +1 -1
- package/src/server/request-log-terminal-status.ts +1 -1
- package/src/server/request-log.ts +13 -1
- package/src/server/responses/account-change-state.ts +8 -2
- package/src/server/responses/adapter-continuation.ts +48 -19
- package/src/server/responses/adapter-delivery.ts +43 -8
- package/src/server/responses/adapter-dispatch.ts +48 -4
- package/src/server/responses/advisor-plan-slot.ts +27 -0
- package/src/server/responses/advisor-retention.ts +117 -0
- package/src/server/responses/advisor-slot.ts +368 -0
- package/src/server/responses/code-mode-collab-surface.ts +116 -8
- package/src/server/responses/codex-ws-wire.ts +15 -8
- package/src/server/responses/compact.ts +303 -125
- package/src/server/responses/compaction-recovery.ts +18 -10
- package/src/server/responses/compaction-retention.ts +61 -0
- package/src/server/responses/context-overflow.ts +11 -6
- package/src/server/responses/core-auth.ts +6 -0
- package/src/server/responses/core-codex-account.ts +11 -1
- package/src/server/responses/core-combo-failure.ts +12 -1
- package/src/server/responses/core-combo.ts +141 -36
- package/src/server/responses/core-errors.ts +3 -3
- package/src/server/responses/core-lifetime.ts +7 -2
- package/src/server/responses/core-normalize.ts +11 -0
- package/src/server/responses/core-opaque-recovery.ts +35 -0
- package/src/server/responses/core-options.ts +51 -0
- package/src/server/responses/core-pipeline.ts +141 -0
- package/src/server/responses/core-replay.ts +25 -6
- package/src/server/responses/core.ts +3 -116
- package/src/server/responses/fetch-helpers.ts +73 -19
- package/src/server/responses/main-hard-lock-routing.ts +109 -0
- package/src/server/responses/native-response-control.ts +4 -2
- package/src/server/responses/passthrough-delivery.ts +19 -11
- package/src/server/responses/passthrough-dispatch.ts +29 -16
- package/src/server/responses/request-prepare.ts +144 -17
- package/src/server/responses/request-sidecar-auth.ts +2 -2
- package/src/server/responses/request-transport.ts +120 -27
- package/src/server/responses/response-effects.ts +1 -0
- package/src/server/responses/run-turn-execution.ts +166 -38
- package/src/server/responses/sidecar-execution.ts +98 -5
- package/src/server/responses/terminal-guard.ts +4 -17
- package/src/server/responses-undeclared-tool-guard.ts +30 -9
- package/src/server/startup-action-control.ts +16 -2
- package/src/server/startup-health-cache.ts +1 -0
- package/src/service/auth-preflight.ts +71 -0
- package/src/service/cli.ts +4 -2
- package/src/service/definition.ts +97 -0
- package/src/service/desktop-startup.ts +14 -0
- package/src/service/guards.ts +1 -61
- package/src/service/health-sentinel-linux.ts +112 -0
- package/src/service/health-sentinel-main.ts +99 -61
- package/src/service/health-sentinel-probe.ts +24 -7
- package/src/service/health.ts +5 -89
- package/src/service/launchd.ts +27 -7
- package/src/service/logging.ts +135 -0
- package/src/service/repair.ts +2 -1
- package/src/service/state.ts +7 -8
- package/src/service/systemd.ts +1 -1
- package/src/service/windows-guarded-manager.ts +2 -1
- package/src/service/windows-ops.ts +1 -1
- package/src/service/windows-scheduler.ts +2 -7
- package/src/service/windows-taskxml.ts +2 -2
- package/src/service/windows-wscript.ts +14 -0
- package/src/service.ts +4 -2
- package/src/sidecar/auth.ts +2 -0
- package/src/tray/windows-tray.ps1 +43 -24
- package/src/types/config.ts +124 -6
- package/src/types/opencode-go.ts +61 -0
- package/src/types/opencode-zen.ts +29 -0
- package/src/types/provider.ts +39 -6
- package/src/types/request.ts +38 -2
- package/src/types/tools.ts +2 -0
- package/src/types/wire.ts +29 -37
- package/src/types.ts +1 -0
- package/src/update/async-check.ts +1 -1
- package/src/update/badge.ts +2 -2
- package/src/update/index.ts +88 -15
- package/src/update/job-supervised-restart.ts +107 -0
- package/src/update/job.ts +32 -32
- package/src/update/notify.ts +1 -1
- package/src/update/npm-invocation.mjs +12 -2
- package/src/update/refresh-scheduler.ts +2 -2
- package/src/update/supervised-recovery.d.mts +27 -0
- package/src/update/supervised-recovery.mjs +157 -0
- package/src/usage/cache-diagnostic.ts +2 -0
- package/src/usage/cost.ts +48 -12
- package/src/usage/expected-prices.ts +15 -0
- package/src/usage/ledger-retention.ts +2 -1
- package/src/usage/ledger-scanner.ts +6 -5
- package/src/usage/log.ts +17 -8
- package/src/usage/summary.ts +22 -9
- package/src/usage/user-cost-overlays.ts +14 -19
- package/src/usage/user-cost-validation.ts +38 -0
- package/src/vision/eligibility.ts +13 -0
- package/src/web-search/gemini-executor.ts +2 -2
- package/src/web-search/loop.ts +55 -5
- package/src/web-search/progress-stream.ts +4 -1
- package/src/web-search/run-turn-loop.ts +9 -1
- package/assets/sponsors/packycode.png +0 -0
- package/gui/dist/assets/App-CSJvmjNs.css +0 -1
- package/gui/dist/assets/App-CZtqiGcw.js +0 -56
- package/gui/dist/assets/index-BB6uK6tU.css +0 -1
- package/gui/dist/assets/index-CTm4l-HQ.js +0 -94
- 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
|
-
|
|
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
|
-
|
|
158
|
-
|
|
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
|
|
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
|
|
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 !==
|
|
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 {
|