@iislee/opencodex 2.11.0 → 2.31.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/AGENTS_INSTALL.md +109 -0
- package/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* unchanged. The Responses output (SSE or JSON) is converted back to Anthropic shape.
|
|
8
8
|
*/
|
|
9
9
|
import { FORWARD_HEADERS } from "../adapters/openai-responses";
|
|
10
|
-
import {
|
|
10
|
+
import { sseFieldValue } from "../lib/sse-decoder";
|
|
11
|
+
import { enforceAnthropicImageLimits, sniffImageDimensions } from "../adapters/anthropic-image-guard";
|
|
11
12
|
import { normalizeAnthropicImages } from "../adapters/anthropic-image-normalize";
|
|
12
13
|
import { AnthropicRequestError, anthropicToResponsesTranslation, extractOcxEffortDirective, extractOcxRouteDirective, resolveInboundModel, type ClaudeCacheKeySource } from "../claude/inbound";
|
|
13
14
|
import { resolveDesktop3pAlias } from "../claude/desktop-3p";
|
|
@@ -25,15 +26,24 @@ import {
|
|
|
25
26
|
} from "../claude/outbound";
|
|
26
27
|
import { clearableDeadline, idleDeadline } from "../lib/abort";
|
|
27
28
|
import { estimateTokens } from "../lib/token-estimate";
|
|
28
|
-
import { routeModel } from "../router";
|
|
29
|
+
import { NoEligiblePolicyCandidateError, routeModel } from "../router";
|
|
30
|
+
import { evidenceFromBody } from "../routing/request-evidence";
|
|
29
31
|
import { resolveWireProtocolOverride } from "./adapter-resolve";
|
|
30
32
|
import type { OcxConfig } from "../types";
|
|
31
33
|
import { readJsonRequestBody } from "./request-decompress";
|
|
32
|
-
import { addFinalRequestLog,
|
|
34
|
+
import { addFinalRequestLog, httpStatusForRequestLogTerminal, recordFirstOutput, type RequestLogContext, type RequestLogEntry } from "./request-log";
|
|
33
35
|
import { conversationIdFromClaudeMetadata } from "./request-log-conversation";
|
|
34
36
|
import { responseWithDeferredRequestLog } from "./relay";
|
|
35
37
|
import { handleResponses } from "./responses";
|
|
38
|
+
import {
|
|
39
|
+
isApiAuthRequired,
|
|
40
|
+
isDataPlaneAdmissionSecret,
|
|
41
|
+
isProxyAdmissionSecret,
|
|
42
|
+
type RequestPolicyView,
|
|
43
|
+
} from "./auth-cors";
|
|
36
44
|
import type { AdmissionLease } from "../lib/admission";
|
|
45
|
+
import { tryClaimNativeMainProfileForTurn } from "../codex/native-main-admission";
|
|
46
|
+
import { CODEX_MAIN_PROFILE_MAINTENANCE_MESSAGE } from "../codex/auth-context";
|
|
37
47
|
import {
|
|
38
48
|
createTranslatorBudget,
|
|
39
49
|
finalizeTranslatorBudgetResponse,
|
|
@@ -92,20 +102,54 @@ const PASSTHROUGH_STRIP_HEADERS = new Set([
|
|
|
92
102
|
"accept-encoding", "x-opencodex-api-key", "origin",
|
|
93
103
|
]);
|
|
94
104
|
|
|
95
|
-
function
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
function singleCredentialToken(name: "authorization" | "x-api-key", value: string | null): string | null {
|
|
106
|
+
const raw = value?.trim() ?? "";
|
|
107
|
+
// Fetch Headers comma-joins duplicate fields. Neither Anthropic credential format permits a
|
|
108
|
+
// comma, so treating a joined value as one token could hide an admission secret behind a real
|
|
109
|
+
// provider credential. Ambiguous credential headers fail closed.
|
|
110
|
+
if (!raw || raw.includes(",")) return null;
|
|
111
|
+
if (name === "authorization") {
|
|
112
|
+
const match = /^Bearer\s+(.+)$/i.exec(raw);
|
|
113
|
+
return match?.[1]?.trim() || null;
|
|
114
|
+
}
|
|
115
|
+
return raw;
|
|
99
116
|
}
|
|
100
117
|
|
|
101
|
-
function
|
|
118
|
+
function hasAnthropicNativeCredential(req: Request, config: OcxConfig): boolean {
|
|
119
|
+
const bearer = singleCredentialToken("authorization", req.headers.get("authorization"));
|
|
120
|
+
const apiKey = singleCredentialToken("x-api-key", req.headers.get("x-api-key"));
|
|
121
|
+
return (!!bearer && bearer.startsWith("sk-ant-") && !isProxyAdmissionSecret(bearer, config))
|
|
122
|
+
|| (!!apiKey && apiKey.startsWith("sk-ant-") && !isProxyAdmissionSecret(apiKey, config));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function wantsNativePassthrough(
|
|
126
|
+
req: Request,
|
|
127
|
+
config: OcxConfig,
|
|
128
|
+
requestPolicy: RequestPolicyView,
|
|
129
|
+
model: unknown,
|
|
130
|
+
): model is string {
|
|
102
131
|
if (config.claudeCode?.nativePassthrough === false) return false;
|
|
103
132
|
if (typeof model !== "string" || !/^(claude|anthropic)/i.test(model)) return false;
|
|
104
|
-
|
|
133
|
+
// Authorization and x-api-key both belong to the upstream on this branch. An exposed listener
|
|
134
|
+
// therefore requires the dedicated admission header even though the routed Messages surface
|
|
135
|
+
// keeps accepting all three legacy admission forms.
|
|
136
|
+
if (isApiAuthRequired(requestPolicy)) {
|
|
137
|
+
const dedicated = req.headers.get("x-opencodex-api-key")?.trim() ?? "";
|
|
138
|
+
if (!isDataPlaneAdmissionSecret(dedicated, config)) return false;
|
|
139
|
+
}
|
|
140
|
+
if (!hasAnthropicNativeCredential(req, config)) return false;
|
|
105
141
|
// An alias or modelMap hit means the user asked for a ROUTED model: translate instead.
|
|
106
142
|
return resolveInboundModel(model, config.claudeCode) === model;
|
|
107
143
|
}
|
|
108
144
|
|
|
145
|
+
function shouldForwardNativeHeader(name: string, value: string, config: OcxConfig): boolean {
|
|
146
|
+
const lowerName = name.toLowerCase();
|
|
147
|
+
if (PASSTHROUGH_STRIP_HEADERS.has(lowerName)) return false;
|
|
148
|
+
if (lowerName !== "authorization" && lowerName !== "x-api-key") return true;
|
|
149
|
+
const token = singleCredentialToken(lowerName, value);
|
|
150
|
+
return !!token && !isProxyAdmissionSecret(token, config);
|
|
151
|
+
}
|
|
152
|
+
|
|
109
153
|
/** Format a 32-hex cache key as a uuid-shaped session id (version/variant nibbles forced). */
|
|
110
154
|
function uuidFromHex(hex32: string): string {
|
|
111
155
|
const h = (hex32 + "0".repeat(32)).slice(0, 32);
|
|
@@ -168,7 +212,11 @@ export function tapAnthropicSseForLog(
|
|
|
168
212
|
while ((sep = buffer.indexOf("\n\n")) !== -1) {
|
|
169
213
|
const frame = buffer.slice(0, sep);
|
|
170
214
|
buffer = buffer.slice(sep + 2);
|
|
171
|
-
const dataLine = frame
|
|
215
|
+
const dataLine = frame
|
|
216
|
+
.split("\n")
|
|
217
|
+
.map(l => sseFieldValue(l, "data"))
|
|
218
|
+
.filter((v): v is string => v !== null)
|
|
219
|
+
.join("");
|
|
172
220
|
if (!dataLine) continue;
|
|
173
221
|
let data: unknown;
|
|
174
222
|
try { data = JSON.parse(dataLine); } catch { continue; }
|
|
@@ -322,7 +370,7 @@ async function anthropicNativePassthrough(
|
|
|
322
370
|
}
|
|
323
371
|
const headers = new Headers();
|
|
324
372
|
req.headers.forEach((value, name) => {
|
|
325
|
-
if (
|
|
373
|
+
if (shouldForwardNativeHeader(name, value, config)) headers.set(name, value);
|
|
326
374
|
});
|
|
327
375
|
headers.set("content-type", "application/json");
|
|
328
376
|
|
|
@@ -520,11 +568,12 @@ export async function handleClaudeMessages(
|
|
|
520
568
|
config: OcxConfig,
|
|
521
569
|
logCtx: RequestLogContext,
|
|
522
570
|
logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease },
|
|
571
|
+
requestPolicy: RequestPolicyView = config,
|
|
523
572
|
): Promise<Response> {
|
|
524
573
|
const translatorBudget = createTranslatorBudget();
|
|
525
574
|
try {
|
|
526
575
|
return finalizeTranslatorBudgetResponse(
|
|
527
|
-
await handleClaudeMessagesWithBudget(req, config, logCtx, translatorBudget, logIds),
|
|
576
|
+
await handleClaudeMessagesWithBudget(req, config, logCtx, translatorBudget, logIds, requestPolicy),
|
|
528
577
|
translatorBudget,
|
|
529
578
|
);
|
|
530
579
|
} catch (error) {
|
|
@@ -539,6 +588,7 @@ async function handleClaudeMessagesWithBudget(
|
|
|
539
588
|
logCtx: RequestLogContext,
|
|
540
589
|
translatorBudget: TranslatorBudget,
|
|
541
590
|
logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease },
|
|
591
|
+
requestPolicy: RequestPolicyView = config,
|
|
542
592
|
): Promise<Response> {
|
|
543
593
|
logCtx.surface = "claude";
|
|
544
594
|
const disabled = claudeInboundDisabled(config);
|
|
@@ -593,11 +643,14 @@ async function handleClaudeMessagesWithBudget(
|
|
|
593
643
|
);
|
|
594
644
|
if (claudeConversationId) logCtx.conversationId = claudeConversationId;
|
|
595
645
|
}
|
|
596
|
-
if (isRec(anthropicBody) && wantsNativePassthrough(req, config, anthropicBody.model)) {
|
|
646
|
+
if (isRec(anthropicBody) && wantsNativePassthrough(req, config, requestPolicy, anthropicBody.model)) {
|
|
597
647
|
return await anthropicNativePassthrough(req, config, logCtx, logIds, anthropicBody, "/v1/messages");
|
|
598
648
|
}
|
|
599
649
|
if (isRec(anthropicBody) && effortOverride) {
|
|
600
|
-
anthropicBody.output_config = {
|
|
650
|
+
anthropicBody.output_config = {
|
|
651
|
+
...(isRec(anthropicBody.output_config) ? anthropicBody.output_config : {}),
|
|
652
|
+
effort: effortOverride,
|
|
653
|
+
};
|
|
601
654
|
delete anthropicBody.thinking;
|
|
602
655
|
}
|
|
603
656
|
const translation = anthropicToResponsesTranslation(anthropicBody, config.claudeCode);
|
|
@@ -627,10 +680,11 @@ async function handleClaudeMessagesWithBudget(
|
|
|
627
680
|
// verified live 2026-07-11). Strip them for that route; routed providers keep them.
|
|
628
681
|
let nativeRoute = false;
|
|
629
682
|
try {
|
|
630
|
-
const route = routeModel(config, internalBody.model as string);
|
|
683
|
+
const route = routeModel(config, internalBody.model as string, evidenceFromBody(internalBody));
|
|
631
684
|
// Settle the wire once so the sampling decision below reads the effective
|
|
632
685
|
// adapter rather than the provider-wide default (#404).
|
|
633
686
|
route.provider = resolveWireProtocolOverride(route.providerName, route.modelId, route.provider, "anthropic");
|
|
687
|
+
logCtx.routeDecision = route.routeDecision;
|
|
634
688
|
if (route.provider.adapter === "openai-responses") {
|
|
635
689
|
nativeRoute = true;
|
|
636
690
|
delete internalBody.max_output_tokens;
|
|
@@ -644,12 +698,7 @@ async function handleClaudeMessagesWithBudget(
|
|
|
644
698
|
// accurate-usage adapters — the request-log merge is max(reported, estimate) and
|
|
645
699
|
// would overwrite real usage (audit 133 R1#7).
|
|
646
700
|
if (route.provider.adapter === "cursor" || route.provider.adapter === "kiro") {
|
|
647
|
-
|
|
648
|
-
const parts: string[] = [];
|
|
649
|
-
if (raw.system !== undefined) parts.push(typeof raw.system === "string" ? raw.system : JSON.stringify(raw.system));
|
|
650
|
-
if (raw.messages !== undefined) parts.push(JSON.stringify(raw.messages));
|
|
651
|
-
if (raw.tools !== undefined) parts.push(JSON.stringify(raw.tools));
|
|
652
|
-
logCtx.usageLogInputTokens = Math.max(1, estimateTokens(parts.join("\n"), requestedModel));
|
|
701
|
+
logCtx.usageLogInputTokens = estimateClaudeRequestTokens(anthropicBody as Rec, requestedModel);
|
|
653
702
|
}
|
|
654
703
|
// Effort safety valve (devlog 136 B6, audit 139 R2#2): opus-shaped aliases make
|
|
655
704
|
// every routed model look like a reasoning model to Claude clients, so a forced
|
|
@@ -661,7 +710,14 @@ async function handleClaudeMessagesWithBudget(
|
|
|
661
710
|
const ladder = supportedLadderFor({ provider: route.provider, modelId: route.modelId });
|
|
662
711
|
if (ladder !== undefined && ladder.length === 0) delete internalBody.reasoning;
|
|
663
712
|
}
|
|
664
|
-
} catch {
|
|
713
|
+
} catch (err) {
|
|
714
|
+
if (err instanceof NoEligiblePolicyCandidateError) {
|
|
715
|
+
logCtx.routeDecision = err.trace;
|
|
716
|
+
if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, 404, { closeReason: "non_stream" });
|
|
717
|
+
return anthropicErrorResponse(404, err.message, "invalid_request_error");
|
|
718
|
+
}
|
|
719
|
+
/* unknown model: let handleResponses shape the 404 */
|
|
720
|
+
}
|
|
665
721
|
|
|
666
722
|
const headers = new Headers({ "content-type": "application/json" });
|
|
667
723
|
for (const name of FORWARD_HEADERS) {
|
|
@@ -671,8 +727,11 @@ async function handleClaudeMessagesWithBudget(
|
|
|
671
727
|
const value = req.headers.get(name);
|
|
672
728
|
if (value) headers.set(name, value);
|
|
673
729
|
}
|
|
674
|
-
|
|
675
|
-
|
|
730
|
+
// Routed replays need main ChatGPT auth so OpenAI-backed sidecars remain reachable;
|
|
731
|
+
// native replays have no caller ChatGPT credential. This enrichment is optional:
|
|
732
|
+
// auth-context later rejects a real physical-main selection, while routed/pool
|
|
733
|
+
// traffic continues without reading native credentials during a fence/recovery.
|
|
734
|
+
if (tryClaimNativeMainProfileForTurn(logIds?.turnAdmissionLease)) {
|
|
676
735
|
const { getMainAccountToken } = await import("../codex/main-account");
|
|
677
736
|
const token = getMainAccountToken();
|
|
678
737
|
if (token) {
|
|
@@ -681,14 +740,6 @@ async function handleClaudeMessagesWithBudget(
|
|
|
681
740
|
}
|
|
682
741
|
}
|
|
683
742
|
if (nativeRoute) {
|
|
684
|
-
// No forwarded ChatGPT auth exists on this surface. Attach the main codex login
|
|
685
|
-
// (read-only auth.json token); account-pool rotation still overrides downstream.
|
|
686
|
-
const { getMainAccountToken } = await import("../codex/main-account");
|
|
687
|
-
const token = getMainAccountToken();
|
|
688
|
-
if (token) {
|
|
689
|
-
headers.set("authorization", `Bearer ${token.accessToken}`);
|
|
690
|
-
headers.set("chatgpt-account-id", token.chatgptAccountId);
|
|
691
|
-
}
|
|
692
743
|
// ChatGPT-backend prompt-cache affinity rides the session_id HEADER (codex
|
|
693
744
|
// clients always send their session uuid; devlog 090 follow-up: body-level
|
|
694
745
|
// prompt_cache_key alone still yielded cached_tokens:0). Claude Code never sends
|
|
@@ -726,9 +777,10 @@ async function handleClaudeMessagesWithBudget(
|
|
|
726
777
|
// Without this the replay would look native and a Responses-scoped wire default
|
|
727
778
|
// would fire, disagreeing with the pre-flight decision above.
|
|
728
779
|
inboundWire: "anthropic",
|
|
780
|
+
stripClaudeMainAuthForNoncanonicalForward: true,
|
|
729
781
|
translatorBudget,
|
|
730
782
|
...(logIds ? { onFirstOutput: () => recordFirstOutput(logCtx, logIds.start) } : {}),
|
|
731
|
-
onNativePassthroughTerminal: status => finalizeNativeLog(
|
|
783
|
+
onNativePassthroughTerminal: status => finalizeNativeLog(httpStatusForRequestLogTerminal(status, logCtx), { terminalStatus: status, closeReason: "terminal" }),
|
|
732
784
|
onNativePassthroughCancel: () => finalizeNativeLog(499, { closeReason: "client_cancel" }),
|
|
733
785
|
});
|
|
734
786
|
const response = logIds ? responseWithDeferredRequestLog(upstream, logIds.requestId, logIds.start, logCtx) : upstream;
|
|
@@ -763,8 +815,11 @@ async function handleClaudeMessagesWithBudget(
|
|
|
763
815
|
// rewrite): log = upstream truth, client = retry signal.
|
|
764
816
|
// Retryable 429s also get Retry-After (#507) so Codex-shaped clients and Claude Code
|
|
765
817
|
// share a backoff hint when the upstream omitted the header.
|
|
766
|
-
const
|
|
767
|
-
|
|
818
|
+
const nativeMainFence = response.status === 503
|
|
819
|
+
&& upstreamRetryAfter?.trim() === "1"
|
|
820
|
+
&& message === CODEX_MAIN_PROFILE_MAINTENANCE_MESSAGE;
|
|
821
|
+
const transient = !nativeMainFence && isTransientUpstreamStatus(response.status);
|
|
822
|
+
const outStatus = nativeMainFence ? 503 : transient ? 529 : response.status;
|
|
768
823
|
const out = new Response(JSON.stringify(anthropicErrorBody(outStatus, message)), {
|
|
769
824
|
status: outStatus,
|
|
770
825
|
headers: {
|
|
@@ -865,8 +920,73 @@ async function handleClaudeMessagesWithBudget(
|
|
|
865
920
|
});
|
|
866
921
|
}
|
|
867
922
|
|
|
868
|
-
/**
|
|
869
|
-
|
|
923
|
+
/** Per-attachment token estimate for a base64 payload: real image dimensions when the
|
|
924
|
+
* header is sniffable (Anthropic prices images at ~pixels/750), else decoded bytes/512,
|
|
925
|
+
* min 256 — the same shape as the Kiro usage estimator (estimateKiroImageTokens). */
|
|
926
|
+
function estimateBase64AttachmentTokens(data: string): number {
|
|
927
|
+
const dims = sniffImageDimensions(data);
|
|
928
|
+
if (dims) return Math.max(256, Math.ceil((dims.width * dims.height) / 750));
|
|
929
|
+
const unpadded = data.endsWith("==") ? data.length - 2 : data.endsWith("=") ? data.length - 1 : data.length;
|
|
930
|
+
return Math.max(256, Math.ceil(Math.floor((unpadded * 3) / 4) / 512));
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Char-based token estimate for an Anthropic-shaped request body. Base64 attachment
|
|
935
|
+
* payloads (image/document blocks in message content, including blocks nested in
|
|
936
|
+
* tool_result.content) are counted as a bounded per-attachment estimate instead of raw
|
|
937
|
+
* characters: one 2MB screenshot is ~2.7M base64 chars, which the plain chars/token
|
|
938
|
+
* divide reports as hundreds of thousands of tokens versus a real cost around 1.6k.
|
|
939
|
+
* That breaks the >2x drift bound the estimator is held to (devlog 260711_claude_inbound
|
|
940
|
+
* 040 §3). Text and url sources are left in place and counted as characters, as is
|
|
941
|
+
* anything outside protocol content positions (tool_use.input, tool schemas).
|
|
942
|
+
*/
|
|
943
|
+
export function estimateClaudeRequestTokens(
|
|
944
|
+
raw: { system?: unknown; messages?: unknown; tools?: unknown },
|
|
945
|
+
modelId: string | undefined,
|
|
946
|
+
): number {
|
|
947
|
+
let attachmentTokens = 0;
|
|
948
|
+
// Blank base64 payloads ONLY in protocol content positions: message content blocks and
|
|
949
|
+
// blocks nested in tool_result.content. tool_use.input and tool schemas can legitimately
|
|
950
|
+
// contain attachment-shaped JSON, and those bytes ARE serialized into function_call
|
|
951
|
+
// arguments / tool definitions for routed providers, so they must keep counting as text.
|
|
952
|
+
// system is text-only per the Anthropic protocol (no attachment sources), so it is
|
|
953
|
+
// stringified as-is.
|
|
954
|
+
const sanitizeBlock = (block: unknown): unknown => {
|
|
955
|
+
if (!block || typeof block !== "object") return block;
|
|
956
|
+
const b = block as Record<string, unknown>;
|
|
957
|
+
if (b.type === "image" || b.type === "document") {
|
|
958
|
+
const source = b.source as { type?: unknown; data?: unknown } | undefined;
|
|
959
|
+
if (source && typeof source === "object" && source.type === "base64" && typeof source.data === "string") {
|
|
960
|
+
attachmentTokens += estimateBase64AttachmentTokens(source.data);
|
|
961
|
+
return { ...b, source: { ...(source as Record<string, unknown>), data: "" } };
|
|
962
|
+
}
|
|
963
|
+
return block;
|
|
964
|
+
}
|
|
965
|
+
if (b.type === "tool_result" && Array.isArray(b.content)) {
|
|
966
|
+
return { ...b, content: (b.content as unknown[]).map(sanitizeBlock) };
|
|
967
|
+
}
|
|
968
|
+
return block;
|
|
969
|
+
};
|
|
970
|
+
const sanitizedMessages = (messages: unknown): unknown =>
|
|
971
|
+
Array.isArray(messages)
|
|
972
|
+
? messages.map(message => {
|
|
973
|
+
if (!message || typeof message !== "object") return message;
|
|
974
|
+
const m = message as Record<string, unknown>;
|
|
975
|
+
return Array.isArray(m.content) ? { ...m, content: (m.content as unknown[]).map(sanitizeBlock) } : message;
|
|
976
|
+
})
|
|
977
|
+
: messages;
|
|
978
|
+
const parts: string[] = [];
|
|
979
|
+
if (raw.system !== undefined) parts.push(typeof raw.system === "string" ? raw.system : JSON.stringify(raw.system));
|
|
980
|
+
if (raw.messages !== undefined) parts.push(JSON.stringify(sanitizedMessages(raw.messages)));
|
|
981
|
+
if (raw.tools !== undefined) parts.push(JSON.stringify(raw.tools));
|
|
982
|
+
return Math.max(1, estimateTokens(parts.join("\n"), modelId) + attachmentTokens);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
export async function handleClaudeCountTokens(
|
|
986
|
+
req: Request,
|
|
987
|
+
config: OcxConfig,
|
|
988
|
+
requestPolicy: RequestPolicyView = config,
|
|
989
|
+
): Promise<Response> {
|
|
870
990
|
const disabled = claudeInboundDisabled(config);
|
|
871
991
|
if (disabled) return disabled;
|
|
872
992
|
|
|
@@ -899,14 +1019,10 @@ export async function handleClaudeCountTokens(req: Request, config: OcxConfig):
|
|
|
899
1019
|
raw.model = model;
|
|
900
1020
|
}
|
|
901
1021
|
captureClaudeInbound("count_tokens", raw, resolveInboundModel(model, config.claudeCode), req.headers.get("anthropic-beta") ?? undefined);
|
|
902
|
-
if (wantsNativePassthrough(req, config, model)) {
|
|
1022
|
+
if (wantsNativePassthrough(req, config, requestPolicy, model)) {
|
|
903
1023
|
return await anthropicNativePassthrough(req, config, { model, provider: "anthropic-native", surface: "claude" }, undefined, raw, "/v1/messages/count_tokens");
|
|
904
1024
|
}
|
|
905
|
-
const
|
|
906
|
-
if (raw.system !== undefined) parts.push(typeof raw.system === "string" ? raw.system : JSON.stringify(raw.system));
|
|
907
|
-
if (raw.messages !== undefined) parts.push(JSON.stringify(raw.messages));
|
|
908
|
-
if (raw.tools !== undefined) parts.push(JSON.stringify(raw.tools));
|
|
909
|
-
const inputTokens = Math.max(1, estimateTokens(parts.join("\n"), model));
|
|
1025
|
+
const inputTokens = estimateClaudeRequestTokens(raw, model);
|
|
910
1026
|
return new Response(JSON.stringify({ input_tokens: inputTokens }), {
|
|
911
1027
|
status: 200,
|
|
912
1028
|
headers: { "Content-Type": "application/json" },
|