@iislee/opencodex 2.11.0 → 2.35.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 +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -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 +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -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 +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- 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 +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- 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 +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- 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 +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- 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 +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- 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 +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- 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 +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- 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 +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -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 +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- 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 +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -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/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -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 +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -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 +360 -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 +622 -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 +675 -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 +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -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 +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -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 +157 -33
- package/src/images/plan.ts +24 -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-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -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/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- 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 +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- 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/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- 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/service-secrets.ts +15 -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 +253 -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 +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -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/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- 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/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -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 +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -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 +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -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 +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -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 +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -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 +155 -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 +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- 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 +1021 -190
- package/src/server/lifecycle.ts +336 -14
- 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 +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -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 +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -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 +289 -33
- 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 +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- 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/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -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 +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -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 +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -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 +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- 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 +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- 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 +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- 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 +27 -16
- 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 +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- 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
|
@@ -3,12 +3,13 @@ import type { OcxContentPart, OcxParsedRequest } from "../types";
|
|
|
3
3
|
import { antigravityUserAgent } from "./client-fingerprint";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Antigravity request User-Agent. Mirrors the real Antigravity
|
|
7
|
-
* (`antigravity/
|
|
6
|
+
* Antigravity request User-Agent. Mirrors the real Antigravity IDE UA
|
|
7
|
+
* (`antigravity/ide/{ver} (aidev_client; os_type=windows; arch=amd64)`) so the request fingerprint
|
|
8
8
|
* matches the OAuth credential — the prior literal `"antigravity"` was a giveaway no real client
|
|
9
|
-
* sends.
|
|
9
|
+
* sends. The IDE client family is also required to unlock newer agent models (the backend 404s
|
|
10
|
+
* CLI-shaped UAs for `gemini-3.7-*`). A `GOOGLE_ANTIGRAVITY_USER_AGENT` override still wins.
|
|
10
11
|
*/
|
|
11
|
-
export const ANTIGRAVITY_REQUEST_UA =
|
|
12
|
+
export const ANTIGRAVITY_REQUEST_UA = antigravityUserAgent();
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Whether a stored `OcxToolCall.thoughtSignature` is a REAL upstream Gemini signature versus a
|
|
@@ -28,6 +29,11 @@ export const ANTIGRAVITY_REQUEST_UA = process.env.GOOGLE_ANTIGRAVITY_USER_AGENT
|
|
|
28
29
|
*/
|
|
29
30
|
export function isLikelyRealThoughtSignature(sig: string | undefined): boolean {
|
|
30
31
|
if (typeof sig !== "string" || sig.length < 16) return false;
|
|
32
|
+
// The validator-bypass sentinel is something WE fabricate for outbound requests when no real
|
|
33
|
+
// signature exists. It is alphanumeric with underscores, so it would otherwise satisfy every
|
|
34
|
+
// check below and be re-ingested as genuine — cached, replayed, and eventually treated as
|
|
35
|
+
// evidence that a turn was signed. It is never a real signature.
|
|
36
|
+
if (sig === "skip_thought_signature_validator") return false;
|
|
31
37
|
// Reject synthetic Responses/tool-call ids and Anthropic tool-use ids (`_` or `-` separators).
|
|
32
38
|
if (/^(fc|ctc|tsc|call|msg|rs|resp|reasoning|item|ws|toolu|tool|func|function)[-_]/i.test(sig)) return false;
|
|
33
39
|
// Real Gemini thought signatures are opaque base64/base64url blobs: only [A-Za-z0-9+/_=-].
|
|
@@ -51,18 +57,50 @@ function firstUserText(parsed: OcxParsedRequest): string | undefined {
|
|
|
51
57
|
* 0x7FFFFFFFFFFFFFFF, prefixed with "-". Falls back to a random "-<digits>" id when there is no text.
|
|
52
58
|
*/
|
|
53
59
|
export function antigravitySessionId(parsed: OcxParsedRequest): string {
|
|
54
|
-
//
|
|
55
|
-
// turn
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
+
// The id must be IDENTICAL on turn N and turn N+1: the replay cache observes thought signatures
|
|
61
|
+
// on turn N's response and re-injects them on turn N+1's request, so a changing id loses the
|
|
62
|
+
// association entirely. (A *shared* id does not — signatures are keyed on functionCall identity,
|
|
63
|
+
// name+args, so cross-conversation collisions stay harmless. Instability is the failure mode.)
|
|
64
|
+
//
|
|
65
|
+
// First-user text does not guarantee that. It is stable only while the first user message
|
|
66
|
+
// survives verbatim in what this adapter sees, and Codex compacts, summarises, and trims long
|
|
67
|
+
// histories — at which point the anchor changes mid-conversation (#1295's sibling, #1297).
|
|
68
|
+
//
|
|
69
|
+
// `_clientThreadId` is Codex's own thread identity from `x-codex-parent-thread-id`. It survives
|
|
70
|
+
// compaction because it does not depend on message content, which is the property first-user
|
|
71
|
+
// text fails to provide. Deliberately NOT `promptCacheKey`: that is arbitrary Responses input
|
|
72
|
+
// and is explicitly shared across conversations for some clients
|
|
73
|
+
// (`adapters/cursor/request-builder.ts`), so it identifies a cache cohort, not a conversation.
|
|
74
|
+
//
|
|
75
|
+
// What is NOT claimed: that Google treats this id as anything but opaque, or that upstream
|
|
76
|
+
// signatures are not session-bound. Only the local association is verified here.
|
|
77
|
+
//
|
|
78
|
+
// Clients that send no thread header keep the text anchor and its instability; this is a scoped
|
|
79
|
+
// repair, not a universal one.
|
|
80
|
+
const text = clientThreadAnchor(parsed) ?? firstUserText(parsed);
|
|
60
81
|
if (!text) return `-${Math.floor(Math.random() * 9e18).toString()}`;
|
|
61
82
|
const digest = createHash("sha256").update(text, "utf8").digest();
|
|
62
83
|
const masked = digest.readBigUInt64BE(0) & 0x7fffffffffffffffn;
|
|
63
84
|
return `-${masked.toString()}`;
|
|
64
85
|
}
|
|
65
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Codex's stable client thread id, prefixed before hashing so it does not collide with a first
|
|
89
|
+
* user message equal to the bare thread id.
|
|
90
|
+
*
|
|
91
|
+
* This is a prefix, not full domain separation: a textless-anchor request whose first message is
|
|
92
|
+
* literally `codex-thread:<id>` still hashes the same preimage. Tagging BOTH anchor classes would
|
|
93
|
+
* separate them completely, but it would also change every existing text-derived id — a
|
|
94
|
+
* Google-visible wire value for live conversations — which is a larger blast radius than the
|
|
95
|
+
* collision it removes. A collision is harmless here anyway: the replay cache keys signatures on
|
|
96
|
+
* functionCall identity (name+args), so a shared id does not misattribute them. Instability, not
|
|
97
|
+
* collision, is the failure mode this function exists to prevent.
|
|
98
|
+
*/
|
|
99
|
+
function clientThreadAnchor(parsed: OcxParsedRequest): string | undefined {
|
|
100
|
+
const threadId = parsed._clientThreadId?.trim();
|
|
101
|
+
return threadId ? `codex-thread:${threadId}` : undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
66
104
|
/** A Gemini content part as it appears in an Antigravity request body. */
|
|
67
105
|
interface GeminiPart {
|
|
68
106
|
thought?: boolean;
|
|
@@ -15,14 +15,50 @@ function googleErrorDetail(payloadText: string): { message?: string; status?: st
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const GOOGLE_QUOTA_EXHAUSTED_NEEDLES = [
|
|
21
|
+
"quotafailure",
|
|
22
|
+
"quota exceeded",
|
|
23
|
+
"exceeded your current quota",
|
|
24
|
+
"billing",
|
|
25
|
+
"individual quota reached",
|
|
26
|
+
"quota reached",
|
|
27
|
+
"enable overages",
|
|
28
|
+
"exhausted your capacity",
|
|
29
|
+
"daily limit reached",
|
|
30
|
+
"weekly limit reached",
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
// Per-minute / per-second / concurrency limits are transient rate limits: they should be
|
|
34
|
+
// retried, not treated as hard quota exhaustion. These guards run before the needles so a
|
|
35
|
+
// message like "Per-minute quota exceeded" stays in the retryable bucket.
|
|
36
|
+
const GOOGLE_TRANSIENT_RATE_LIMIT_PATTERNS = [
|
|
37
|
+
"per minute",
|
|
38
|
+
"per-minute",
|
|
39
|
+
"per min",
|
|
40
|
+
"rpm",
|
|
41
|
+
"requests per minute",
|
|
42
|
+
"too many requests",
|
|
43
|
+
"rate limit",
|
|
44
|
+
"retry after",
|
|
45
|
+
// Upstream writes the header name both ways in prose ("retry-after: 60"); matching only the
|
|
46
|
+
// spaced spelling let a transient 429 fall through to the exhaustion needles below.
|
|
47
|
+
"retry-after",
|
|
48
|
+
"concurrent request limit",
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
export function isGoogleQuotaExhaustedText(text: string): boolean {
|
|
52
|
+
const lower = text.toLowerCase();
|
|
53
|
+
if (GOOGLE_TRANSIENT_RATE_LIMIT_PATTERNS.some(needle => lower.includes(needle))) return false;
|
|
54
|
+
return GOOGLE_QUOTA_EXHAUSTED_NEEDLES.some(needle => lower.includes(needle));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
18
58
|
function classifyGoogle(label: string, status: number | undefined, enumStatus: string | undefined, text: string): string {
|
|
19
59
|
const lower = `${enumStatus ?? ""} ${text}`.toLowerCase();
|
|
20
|
-
const quotaExhausted =
|
|
21
|
-
|
|
22
|
-
lower.includes("quota exceeded") ||
|
|
23
|
-
lower.includes("exceeded your current quota") ||
|
|
24
|
-
lower.includes("billing");
|
|
25
|
-
if (enumStatus === "RESOURCE_EXHAUSTED" && quotaExhausted) return `${label} quota exhausted`;
|
|
60
|
+
const quotaExhausted = isGoogleQuotaExhaustedText(lower);
|
|
61
|
+
if ((!enumStatus || enumStatus === "RESOURCE_EXHAUSTED") && quotaExhausted) return `${label} quota exhausted`;
|
|
26
62
|
if (status === 429 || enumStatus === "RESOURCE_EXHAUSTED" || lower.includes("rate limit")) {
|
|
27
63
|
return `${label} rate limit exceeded`;
|
|
28
64
|
}
|
|
@@ -76,10 +112,6 @@ export function retryableGoogleStatus(status: number): boolean {
|
|
|
76
112
|
*/
|
|
77
113
|
export function isQuotaExhaustedBody(payloadText: string): boolean {
|
|
78
114
|
const { message, status } = googleErrorDetail(payloadText);
|
|
79
|
-
if (status !== "RESOURCE_EXHAUSTED") return false;
|
|
80
|
-
|
|
81
|
-
return lower.includes("quotafailure")
|
|
82
|
-
|| lower.includes("quota exceeded")
|
|
83
|
-
|| lower.includes("exceeded your current quota")
|
|
84
|
-
|| lower.includes("billing");
|
|
115
|
+
if (status && status !== "RESOURCE_EXHAUSTED") return false;
|
|
116
|
+
return isGoogleQuotaExhaustedText(message ?? payloadText);
|
|
85
117
|
}
|
|
@@ -14,6 +14,11 @@ const GOOGLE_RETRY_ATTEMPTS = 3;
|
|
|
14
14
|
const GOOGLE_RETRY_BASE_MS = 250;
|
|
15
15
|
const GOOGLE_RETRY_MAX_MS = 2_000;
|
|
16
16
|
|
|
17
|
+
export interface GoogleRetryOptions {
|
|
18
|
+
/** Repair-and-replay structurally invalid 400 bodies (Vertex/Antigravity behavior). */
|
|
19
|
+
repairInvalid400?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
async function normalizeFinalGoogleError(label: string, res: Response, signal?: AbortSignal): Promise<Response> {
|
|
18
23
|
return normalizeUpstreamHttpErrorResponse(res, {
|
|
19
24
|
signal,
|
|
@@ -22,13 +27,21 @@ async function normalizeFinalGoogleError(label: string, res: Response, signal?:
|
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
|
-
* Fetch a Google-family upstream
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* error body. `label` is the provider-facing prefix used in error
|
|
30
|
+
* Fetch a Google-family upstream with Kiro-style hardening: per-attempt timeout
|
|
31
|
+
* (`AbortSignal.any([parent, timeout])`), bounded retry on transient status / network errors,
|
|
32
|
+
* `Retry-After` honoring, jittered exponential backoff, and (unless raw mode is used) a
|
|
33
|
+
* classified + redacted final error body. `label` is the provider-facing prefix used in error
|
|
34
|
+
* messages.
|
|
29
35
|
*/
|
|
30
|
-
export async function fetchGoogleWithRetry(
|
|
36
|
+
export async function fetchGoogleWithRetry(
|
|
37
|
+
label: string,
|
|
38
|
+
request: AdapterRequest,
|
|
39
|
+
ctx: AdapterFetchContext = {},
|
|
40
|
+
opts: GoogleRetryOptions = {},
|
|
41
|
+
): Promise<Response> {
|
|
42
|
+
const repairInvalid400 = opts.repairInvalid400 ?? true;
|
|
31
43
|
const timeoutMs = ctx.timeoutMs ?? 200_000;
|
|
44
|
+
const executor = ctx.executor ?? globalThis.fetch;
|
|
32
45
|
let lastError: unknown;
|
|
33
46
|
let activeRequest = request;
|
|
34
47
|
let compatibilityReplayUsed = false;
|
|
@@ -39,8 +52,8 @@ export async function fetchGoogleWithRetry(label: string, request: AdapterReques
|
|
|
39
52
|
method: activeRequest.method,
|
|
40
53
|
headers: activeRequest.headers,
|
|
41
54
|
body: activeRequest.body,
|
|
42
|
-
}, timeoutMs, ctx.abortSignal, ctx.stream);
|
|
43
|
-
if (res.status === 400 && !compatibilityReplayUsed) {
|
|
55
|
+
}, timeoutMs, ctx.abortSignal, ctx.stream, executor);
|
|
56
|
+
if (res.status === 400 && repairInvalid400 && !compatibilityReplayUsed) {
|
|
44
57
|
let payloadText = "";
|
|
45
58
|
try {
|
|
46
59
|
payloadText = await readDisplaySafeErrorPayloadText(res.clone(), ctx.abortSignal);
|
|
@@ -61,10 +74,11 @@ export async function fetchGoogleWithRetry(label: string, request: AdapterReques
|
|
|
61
74
|
}
|
|
62
75
|
// A 429 may be a transient rate limit (retry) or hard quota exhaustion (do NOT retry —
|
|
63
76
|
// it won't recover for hours and burns retries). Peek the body to tell them apart.
|
|
64
|
-
if (res.status === 429
|
|
65
|
-
const
|
|
77
|
+
if (res.status === 429) {
|
|
78
|
+
const peekTarget = ctx.returnRawErrors ? res.clone() : res;
|
|
79
|
+
const peek = await readDisplaySafeErrorPayloadText(peekTarget, ctx.abortSignal);
|
|
66
80
|
if (isQuotaExhaustedBody(peek)) {
|
|
67
|
-
return normalizeUpstreamHttpErrorResponse(res, {
|
|
81
|
+
return ctx.returnRawErrors ? res : normalizeUpstreamHttpErrorResponse(res, {
|
|
68
82
|
signal: ctx.abortSignal,
|
|
69
83
|
formatMessage: payloadText => safeGoogleHttpErrorMessage(label, res.status, payloadText || peek),
|
|
70
84
|
});
|
|
@@ -89,6 +103,20 @@ export async function fetchGoogleWithRetry(label: string, request: AdapterReques
|
|
|
89
103
|
throw lastError ?? new Error(`${label} fetch failed`);
|
|
90
104
|
}
|
|
91
105
|
|
|
106
|
+
/**
|
|
107
|
+
* AI Studio direct (`generativelanguage.googleapis.com`) retry wrapper.
|
|
108
|
+
*
|
|
109
|
+
* Direct requests keep the default server error surface — the raw `Provider error <status>:
|
|
110
|
+
* <body>` text the shared Responses path formats — and keep single-shot 400 semantics (no
|
|
111
|
+
* request-shape compatibility replay). The wrapper exists for the failure mode observed in
|
|
112
|
+
* production: AI Studio's transient `503 UNAVAILABLE` "model is currently experiencing high
|
|
113
|
+
* demand" spikes, plus plain rate-limit 429s, both of which previously failed immediately
|
|
114
|
+
* because the default server fetch path only retries connection resets.
|
|
115
|
+
*/
|
|
116
|
+
export function fetchDirectGeminiWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise<Response> {
|
|
117
|
+
return fetchGoogleWithRetry("Gemini", request, { ...ctx, returnRawErrors: true }, { repairInvalid400: false });
|
|
118
|
+
}
|
|
119
|
+
|
|
92
120
|
/** Vertex AI retry wrapper. */
|
|
93
121
|
export function fetchVertexWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise<Response> {
|
|
94
122
|
return fetchGoogleWithRetry("Vertex AI", request, ctx);
|
|
@@ -7,6 +7,27 @@ type Schema = Record<string, unknown>;
|
|
|
7
7
|
const ALLOWED_TYPES = new Set(["string", "integer", "number", "boolean", "array", "object"]);
|
|
8
8
|
const MAX_SCHEMA_DEPTH = 24; // Google's documented nesting limit is 32; leave headroom for CCA.
|
|
9
9
|
const MAX_DEREF_DEPTH = 16;
|
|
10
|
+
const MAX_SCHEMA_NODES = 1_024;
|
|
11
|
+
const BUDGET_EXHAUSTED = Symbol("schema-budget-exhausted");
|
|
12
|
+
const MERGED_SCHEMA_KEYS = [
|
|
13
|
+
"type",
|
|
14
|
+
"nullable",
|
|
15
|
+
"description",
|
|
16
|
+
"format",
|
|
17
|
+
"enum",
|
|
18
|
+
"const",
|
|
19
|
+
"properties",
|
|
20
|
+
"items",
|
|
21
|
+
"required",
|
|
22
|
+
"anyOf",
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
type SanitizeResult = Schema | typeof BUDGET_EXHAUSTED;
|
|
26
|
+
|
|
27
|
+
interface SanitizeState {
|
|
28
|
+
activeRefs: Set<string>;
|
|
29
|
+
remainingNodes: number;
|
|
30
|
+
}
|
|
10
31
|
|
|
11
32
|
function isRecord(value: unknown): value is Schema {
|
|
12
33
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -34,6 +55,16 @@ function collectDefs(root: unknown, defs: Map<string, unknown>): void {
|
|
|
34
55
|
}
|
|
35
56
|
}
|
|
36
57
|
|
|
58
|
+
function mergeRefTarget(target: Schema, overlay: Schema): Schema {
|
|
59
|
+
const merged: Schema = {};
|
|
60
|
+
if (Object.hasOwn(target, "$ref")) merged.$ref = target.$ref;
|
|
61
|
+
for (const key of MERGED_SCHEMA_KEYS) {
|
|
62
|
+
if (Object.hasOwn(overlay, key)) merged[key] = overlay[key];
|
|
63
|
+
else if (Object.hasOwn(target, key)) merged[key] = target[key];
|
|
64
|
+
}
|
|
65
|
+
return merged;
|
|
66
|
+
}
|
|
67
|
+
|
|
37
68
|
function normalizeType(value: unknown, out: Schema, preserveNullType: boolean): void {
|
|
38
69
|
const candidates = Array.isArray(value) ? value : [value];
|
|
39
70
|
let sawNull = false;
|
|
@@ -65,9 +96,16 @@ function normalizeAnyOf(
|
|
|
65
96
|
defs: Map<string, unknown>,
|
|
66
97
|
depth: number,
|
|
67
98
|
refDepth: number,
|
|
99
|
+
state: SanitizeState,
|
|
68
100
|
): Schema {
|
|
69
101
|
if (!Array.isArray(value) || value.length === 0) return {};
|
|
70
|
-
const schemas =
|
|
102
|
+
const schemas: Schema[] = [];
|
|
103
|
+
for (let index = 0; index < value.length; index++) {
|
|
104
|
+
if (state.remainingNodes <= 0) return {};
|
|
105
|
+
const schema = sanitizeSchema(value[index], defs, depth + 1, refDepth, true, state);
|
|
106
|
+
if (schema === BUDGET_EXHAUSTED) return {};
|
|
107
|
+
schemas.push(schema);
|
|
108
|
+
}
|
|
71
109
|
|
|
72
110
|
const nonNullSchemas = schemas.filter(schema => schema.type !== "null");
|
|
73
111
|
const nullSchemas = schemas.filter(schema => schema.type === "null");
|
|
@@ -100,12 +138,17 @@ function sanitizeProperties(
|
|
|
100
138
|
defs: Map<string, unknown>,
|
|
101
139
|
depth: number,
|
|
102
140
|
refDepth: number,
|
|
141
|
+
state: SanitizeState,
|
|
103
142
|
): Record<string, Schema> | undefined {
|
|
104
143
|
if (!isRecord(value)) return undefined;
|
|
105
144
|
const properties: Record<string, Schema> = Object.create(null) as Record<string, Schema>;
|
|
106
|
-
for (const
|
|
145
|
+
for (const name in value) {
|
|
146
|
+
if (!Object.hasOwn(value, name)) continue;
|
|
147
|
+
if (state.remainingNodes <= 0) break;
|
|
107
148
|
// Property names form a name bag and must never be interpreted as schema keywords.
|
|
108
|
-
|
|
149
|
+
const schema = sanitizeSchema(value[name], defs, depth + 1, refDepth, false, state);
|
|
150
|
+
if (schema === BUDGET_EXHAUSTED) break;
|
|
151
|
+
properties[name] = schema;
|
|
109
152
|
}
|
|
110
153
|
return properties;
|
|
111
154
|
}
|
|
@@ -116,17 +159,25 @@ function sanitizeSchema(
|
|
|
116
159
|
depth: number,
|
|
117
160
|
refDepth: number,
|
|
118
161
|
preserveNullType: boolean,
|
|
119
|
-
|
|
162
|
+
state: SanitizeState,
|
|
163
|
+
): SanitizeResult {
|
|
164
|
+
if (state.remainingNodes <= 0) return BUDGET_EXHAUSTED;
|
|
165
|
+
state.remainingNodes -= 1;
|
|
120
166
|
if (depth >= MAX_SCHEMA_DEPTH || !isRecord(node)) return {};
|
|
121
167
|
|
|
122
168
|
if (typeof node.$ref === "string" && refDepth < MAX_DEREF_DEPTH) {
|
|
123
169
|
const target = resolveRef(node.$ref, defs);
|
|
124
170
|
if (isRecord(target)) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
171
|
+
if (state.activeRefs.has(node.$ref)) return {};
|
|
172
|
+
state.activeRefs.add(node.$ref);
|
|
173
|
+
// Select only inputs the sanitizer can consume. Spreading an untrusted definition here would
|
|
174
|
+
// enumerate and allocate every unsupported annotation before the node budget can stop work.
|
|
175
|
+
const merged = mergeRefTarget(target, node);
|
|
176
|
+
try {
|
|
177
|
+
return sanitizeSchema(merged, defs, depth, refDepth + 1, preserveNullType, state);
|
|
178
|
+
} finally {
|
|
179
|
+
state.activeRefs.delete(node.$ref);
|
|
128
180
|
}
|
|
129
|
-
return sanitizeSchema(merged, defs, depth, refDepth + 1, preserveNullType);
|
|
130
181
|
}
|
|
131
182
|
}
|
|
132
183
|
|
|
@@ -140,18 +191,27 @@ function sanitizeSchema(
|
|
|
140
191
|
const enumValues = sanitizeEnum(node.enum ?? (typeof node.const === "string" ? [node.const] : undefined));
|
|
141
192
|
if (enumValues) out.enum = enumValues;
|
|
142
193
|
|
|
143
|
-
const properties = sanitizeProperties(node.properties, defs, depth, refDepth);
|
|
194
|
+
const properties = sanitizeProperties(node.properties, defs, depth, refDepth, state);
|
|
144
195
|
if (properties) out.properties = properties;
|
|
145
196
|
|
|
146
|
-
if (
|
|
147
|
-
|
|
197
|
+
if (properties && Array.isArray(node.required)) {
|
|
198
|
+
const required = [...new Set(node.required.filter((item): item is string => (
|
|
199
|
+
typeof item === "string" && Object.hasOwn(properties, item)
|
|
200
|
+
)))];
|
|
201
|
+
if (required.length > 0) out.required = required;
|
|
148
202
|
}
|
|
149
203
|
|
|
150
|
-
if (
|
|
151
|
-
|
|
204
|
+
if (state.remainingNodes <= 0) return out;
|
|
205
|
+
|
|
206
|
+
if (isRecord(node.items)) {
|
|
207
|
+
const items = sanitizeSchema(node.items, defs, depth + 1, refDepth, false, state);
|
|
208
|
+
if (items !== BUDGET_EXHAUSTED) out.items = items;
|
|
152
209
|
}
|
|
153
210
|
|
|
154
|
-
if (
|
|
211
|
+
if (state.remainingNodes <= 0) return out;
|
|
212
|
+
if (node.anyOf !== undefined) {
|
|
213
|
+
Object.assign(out, normalizeAnyOf(node.anyOf, defs, depth, refDepth, state));
|
|
214
|
+
}
|
|
155
215
|
return out;
|
|
156
216
|
}
|
|
157
217
|
|
|
@@ -159,7 +219,12 @@ export function sanitizeGeminiToolParameters(parameters: unknown): Record<string
|
|
|
159
219
|
try {
|
|
160
220
|
const defs = new Map<string, unknown>();
|
|
161
221
|
collectDefs(parameters, defs);
|
|
162
|
-
const
|
|
222
|
+
const state: SanitizeState = {
|
|
223
|
+
activeRefs: new Set(),
|
|
224
|
+
remainingNodes: MAX_SCHEMA_NODES,
|
|
225
|
+
};
|
|
226
|
+
const sanitized = sanitizeSchema(parameters, defs, 0, 0, false, state);
|
|
227
|
+
const root = sanitized === BUDGET_EXHAUSTED ? {} : sanitized;
|
|
163
228
|
|
|
164
229
|
// Function arguments are always an object. Claude additionally rejects root composition and a
|
|
165
230
|
// missing root type even when those forms are valid general-purpose JSON Schema.
|
|
@@ -11,3 +11,14 @@ export function vertexTruncationErrorMessage(reason?: string): string {
|
|
|
11
11
|
const suffix = reason ? ` (${redactSecretString(reason).slice(0, 160)})` : "";
|
|
12
12
|
return `Vertex AI response truncated upstream before the turn completed${suffix}`;
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether a finished turn must fail closed. A truncation reason arriving mid tool call always
|
|
17
|
+
* does. MALFORMED_FUNCTION_CALL fails closed even with zero started calls: the malformed call
|
|
18
|
+
* is dropped upstream and usually never materializes as a part, so the turn is incomplete
|
|
19
|
+
* despite looking empty. MAX_TOKENS with no started call stays a plain token-limit stop.
|
|
20
|
+
*/
|
|
21
|
+
export function isVertexTruncatedTurn(finishReason: string | undefined, toolCallsStarted: number): boolean {
|
|
22
|
+
if (!isVertexTruncationReason(finishReason)) return false;
|
|
23
|
+
return toolCallsStarted > 0 || finishReason === "MALFORMED_FUNCTION_CALL";
|
|
24
|
+
}
|