@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
package/src/images/loop.ts
CHANGED
|
@@ -14,12 +14,15 @@ import type { AdapterRequest, IncomingMeta, ProviderAdapter } from "../adapters/
|
|
|
14
14
|
import { existsSync } from "node:fs";
|
|
15
15
|
import { pathToFileURL } from "node:url";
|
|
16
16
|
import { createAdapterEventQueue } from "../adapters/run-turn-queue";
|
|
17
|
-
import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderContinuationState, OcxRequestOptions, OcxThinkingContent, OcxUsage } from "../types";
|
|
18
|
-
import { namespacedToolName } from "../types";
|
|
17
|
+
import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderContinuationState, OcxProviderOpaqueToolCallMetadata, OcxRequestOptions, OcxThinkingContent, OcxUsage, RateLimitRetryPolicy } from "../types";
|
|
18
|
+
import { namespacedToolName, toolChoiceToolPredicate } from "../types";
|
|
19
|
+
import { cloneProviderOpaqueToolCallMetadata } from "../responses/provider-opaque-metadata";
|
|
20
|
+
import type { AttemptRecoveryKind } from "../usage/log";
|
|
19
21
|
import { bridgeToResponsesSSE } from "../bridge";
|
|
20
22
|
import { clearableDeadline, idleDeadline } from "../lib/abort";
|
|
21
23
|
import { readBoundedResponseBody } from "../lib/bounded-body";
|
|
22
|
-
import { fetchWithResetRetry } from "../lib/upstream-retry";
|
|
24
|
+
import { fetchWithResetRetry, prepareSameTarget429Wait } from "../lib/upstream-retry";
|
|
25
|
+
import { rateLimitRetryDelayMs } from "../providers/key-failover";
|
|
23
26
|
import {
|
|
24
27
|
isTranslatorBudgetExceededError,
|
|
25
28
|
TRANSLATOR_MAX_TURN_BYTES,
|
|
@@ -91,6 +94,11 @@ interface ImageCall {
|
|
|
91
94
|
id: string;
|
|
92
95
|
name: string;
|
|
93
96
|
args: string;
|
|
97
|
+
/**
|
|
98
|
+
* Provider-opaque metadata from the originating part (issue #1735). Stored PER CALL: a
|
|
99
|
+
* signature belongs to one specific part, so parallel calls must not share one value.
|
|
100
|
+
*/
|
|
101
|
+
providerMetadata?: OcxProviderOpaqueToolCallMetadata;
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
/**
|
|
@@ -107,13 +115,13 @@ function scanEventsForImageCall(events: AdapterEvent[], toolNames: Set<string>):
|
|
|
107
115
|
const calls: ImageCall[] = [];
|
|
108
116
|
const passthrough: AdapterEvent[] = [];
|
|
109
117
|
let hasRealToolCall = false;
|
|
110
|
-
let pending: { name: string; id: string; argsBuf: string; events: AdapterEvent[] } | null = null;
|
|
118
|
+
let pending: { name: string; id: string; argsBuf: string; events: AdapterEvent[]; providerMetadata?: OcxProviderOpaqueToolCallMetadata } | null = null;
|
|
111
119
|
const flushPending = (): void => {
|
|
112
120
|
if (!pending) return;
|
|
113
121
|
if (toolNames.has(pending.name)) {
|
|
114
122
|
// Unterminated image call still carries buffered args — fulfill so malformed JSON
|
|
115
123
|
// becomes a normal tool_result error instead of silently vanishing.
|
|
116
|
-
calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf });
|
|
124
|
+
calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf, providerMetadata: pending.providerMetadata });
|
|
117
125
|
} else {
|
|
118
126
|
passthrough.push(...pending.events);
|
|
119
127
|
hasRealToolCall = true;
|
|
@@ -123,14 +131,14 @@ function scanEventsForImageCall(events: AdapterEvent[], toolNames: Set<string>):
|
|
|
123
131
|
for (const e of events) {
|
|
124
132
|
if (e.type === "tool_call_start") {
|
|
125
133
|
flushPending();
|
|
126
|
-
pending = { name: e.name, id: e.id, argsBuf: "", events: [e] };
|
|
134
|
+
pending = { name: e.name, id: e.id, argsBuf: "", events: [e], providerMetadata: e.providerMetadata };
|
|
127
135
|
} else if (e.type === "tool_call_delta" && pending) {
|
|
128
136
|
pending.argsBuf += e.arguments;
|
|
129
137
|
pending.events.push(e);
|
|
130
138
|
} else if (e.type === "tool_call_end" && pending) {
|
|
131
139
|
pending.events.push(e);
|
|
132
140
|
if (toolNames.has(pending.name)) {
|
|
133
|
-
calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf });
|
|
141
|
+
calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf, providerMetadata: pending.providerMetadata });
|
|
134
142
|
} else {
|
|
135
143
|
passthrough.push(...pending.events);
|
|
136
144
|
hasRealToolCall = true;
|
|
@@ -159,6 +167,7 @@ function extractIterationThinking(events: AdapterEvent[]): OcxThinkingContent[]
|
|
|
159
167
|
const parts: OcxThinkingContent[] = [];
|
|
160
168
|
let thinking = "";
|
|
161
169
|
let signature: string | undefined;
|
|
170
|
+
let rawReasoning = "";
|
|
162
171
|
|
|
163
172
|
const flushVisible = () => {
|
|
164
173
|
if (!thinking && !signature) return;
|
|
@@ -170,19 +179,33 @@ function extractIterationThinking(events: AdapterEvent[]): OcxThinkingContent[]
|
|
|
170
179
|
thinking = "";
|
|
171
180
|
signature = undefined;
|
|
172
181
|
};
|
|
182
|
+
const flushRaw = () => {
|
|
183
|
+
if (!rawReasoning) return;
|
|
184
|
+
parts.push({ type: "thinking", thinking: rawReasoning });
|
|
185
|
+
rawReasoning = "";
|
|
186
|
+
};
|
|
173
187
|
|
|
174
188
|
for (const e of events) {
|
|
175
189
|
if (e.type === "thinking_delta") {
|
|
190
|
+
flushRaw();
|
|
176
191
|
thinking += e.thinking;
|
|
192
|
+
} else if (e.type === "reasoning_raw_delta") {
|
|
193
|
+
// OpenAI-compatible providers emit raw reasoning instead of signed
|
|
194
|
+
// thinking; DeepSeek thinking mode requires it back alongside replayed
|
|
195
|
+
// tool_calls (mirrors src/web-search/loop.ts, issue #950).
|
|
196
|
+
flushVisible();
|
|
197
|
+
rawReasoning += e.text;
|
|
177
198
|
} else if (e.type === "thinking_signature") {
|
|
178
199
|
signature = e.signature;
|
|
179
200
|
flushVisible();
|
|
180
201
|
} else if (e.type === "redacted_thinking") {
|
|
181
202
|
flushVisible();
|
|
203
|
+
flushRaw();
|
|
182
204
|
parts.push({ type: "thinking", thinking: "", redacted: [e.data] });
|
|
183
205
|
}
|
|
184
206
|
}
|
|
185
207
|
flushVisible();
|
|
208
|
+
flushRaw();
|
|
186
209
|
return parts;
|
|
187
210
|
}
|
|
188
211
|
|
|
@@ -202,6 +225,10 @@ class LoopError extends Error {
|
|
|
202
225
|
}
|
|
203
226
|
}
|
|
204
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Dependencies for one image-bridge iteration: parsed request, active adapter, incoming
|
|
230
|
+
* metadata, and the optional image/video bridge plans.
|
|
231
|
+
*/
|
|
205
232
|
export interface ImageBridgeDeps {
|
|
206
233
|
parsed: OcxParsedRequest;
|
|
207
234
|
adapter: ProviderAdapter;
|
|
@@ -212,8 +239,8 @@ export interface ImageBridgeDeps {
|
|
|
212
239
|
videoTimeoutMs?: number;
|
|
213
240
|
/** Headers forwarded from the original request (e.g. Codex auth). Cloned per iteration. */
|
|
214
241
|
forwardHeaders?: Headers;
|
|
215
|
-
/** Called before each routed-model dispatch in the bridge loop, for attempt telemetry. */
|
|
216
|
-
onAttemptSend?: () => void;
|
|
242
|
+
/** Called before each routed-model dispatch in the bridge loop, for attempt telemetry. Same-target 429 replays pass the `rate-limit-429` recovery kind. */
|
|
243
|
+
onAttemptSend?: (recovery?: AttemptRecoveryKind) => void;
|
|
217
244
|
/** Called after each upstream request is built (parity with web-search / normal path). */
|
|
218
245
|
onRequestBuilt?: (request: AdapterRequest) => void;
|
|
219
246
|
abortSignal?: AbortSignal;
|
|
@@ -226,6 +253,8 @@ export interface ImageBridgeDeps {
|
|
|
226
253
|
stallTimeoutSec?: number;
|
|
227
254
|
/** Provider-specific fetch (e.g. xAI transport wrapper). Falls back to global fetch. */
|
|
228
255
|
fetchImpl?: typeof globalThis.fetch;
|
|
256
|
+
/** Reserve the routed provider's next request-start slot before each adapter dispatch. */
|
|
257
|
+
waitForRequestSlot?: (signal?: AbortSignal) => Promise<void>;
|
|
229
258
|
/** Raw adapter usage at the terminal event, pre wire-normalization (see bridgeToResponsesSSE onUsage). */
|
|
230
259
|
onUsage?: (usage: OcxUsage | undefined) => void;
|
|
231
260
|
/**
|
|
@@ -233,6 +262,8 @@ export interface ImageBridgeDeps {
|
|
|
233
262
|
* rotated key, or null when the pool is exhausted.
|
|
234
263
|
*/
|
|
235
264
|
on429?: (retryAfterHeader: string | null) => ProviderAdapter | null;
|
|
265
|
+
/** Opt-in same-target 429 policy (key-auth providers). When present, 429 replays on the SAME key before on429 rotation. */
|
|
266
|
+
retryOn429Policy?: Required<RateLimitRetryPolicy> | null;
|
|
236
267
|
/** Called when the bridged Responses stream completes (parity with runTurn / routed paths). */
|
|
237
268
|
onCompletedResponse?: (response: Record<string, unknown>, providerState?: OcxProviderContinuationState) => void;
|
|
238
269
|
/** WebSocket Responses path only — leave response id empty for protocol compatibility. */
|
|
@@ -331,9 +362,20 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
331
362
|
}
|
|
332
363
|
type IterationSplit = ReturnType<typeof scanEventsForImageCall>;
|
|
333
364
|
|
|
365
|
+
// Same-target 429 budget is per REQUEST, not per model iteration: later image rounds inherit
|
|
366
|
+
// what earlier rounds left of `attempts`, so a bounded multi-round turn can never exceed the
|
|
367
|
+
// configured replay count in total (a per-round reset would multiply it by maxRounds).
|
|
368
|
+
const rateLimitRetryPolicy = deps.retryOn429Policy ?? null;
|
|
369
|
+
let rateLimitRetries = 0;
|
|
370
|
+
|
|
334
371
|
// Acquire one iteration's final response headers. The first call is drained eagerly so an initial
|
|
335
372
|
// connect/header/HTTP failure stays a non-2xx JSON response — except for runTurn adapters, which
|
|
336
373
|
// have no HTTP status surface and must not block SSE headers behind queue.collect().
|
|
374
|
+
/**
|
|
375
|
+
* Fetch one image-bridge iteration's final response headers, applying the response-header
|
|
376
|
+
* deadline and the same-target 429 retry policy (with awaited body release and deadline
|
|
377
|
+
* restart) before the `on429` key rotation.
|
|
378
|
+
*/
|
|
337
379
|
const prepareIterationEvents = async function* (forceFinal: boolean): AsyncGenerator<AdapterEvent, IterationResponse> {
|
|
338
380
|
const iterParsed: OcxParsedRequest = {
|
|
339
381
|
...parsed,
|
|
@@ -346,6 +388,7 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
346
388
|
// expose buildRequest/fetchResponse/parseStream to the bridge, so collect their events through
|
|
347
389
|
// an AdapterEventQueue and wrap them in a pseudo-response whose parseStream replays them.
|
|
348
390
|
if (adapter.runTurn) {
|
|
391
|
+
await deps.waitForRequestSlot?.(signal);
|
|
349
392
|
const queue = createAdapterEventQueue({
|
|
350
393
|
onBacklogExceeded: () => internalAbort.abort("runTurn backlog exceeded"),
|
|
351
394
|
});
|
|
@@ -422,27 +465,59 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
422
465
|
return { response: new Response(new Uint8Array(0), { status: 200 }), responseAdapter: wrappedAdapter };
|
|
423
466
|
}
|
|
424
467
|
|
|
425
|
-
|
|
468
|
+
let headerDeadline = clearableDeadline(connectTimeoutMs, signal);
|
|
469
|
+
const paceThenResetHeaderDeadline = async (): Promise<void> => {
|
|
470
|
+
headerDeadline.clear();
|
|
471
|
+
await deps.waitForRequestSlot?.(signal);
|
|
472
|
+
headerDeadline = clearableDeadline(connectTimeoutMs, signal);
|
|
473
|
+
};
|
|
426
474
|
try {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
475
|
+
/**
|
|
476
|
+
* Build and fetch one image-bridge iteration on the given adapter, under the iteration
|
|
477
|
+
* header deadline. The caller owns same-target 429 replays and key rotation around it.
|
|
478
|
+
* The outbound request is cached per adapter so a same-target replay reuses the EXACT
|
|
479
|
+
* URL, serialized body, and headers (builder runs once per target sequence).
|
|
480
|
+
*/
|
|
481
|
+
let cachedRequest: AdapterRequest | undefined;
|
|
482
|
+
let cachedAdapter: ProviderAdapter | undefined;
|
|
483
|
+
/**
|
|
484
|
+
* Build and fetch one image-bridge iteration on the given adapter, under the iteration
|
|
485
|
+
* header deadline. The caller owns same-target 429 replays and key rotation around it.
|
|
486
|
+
*/
|
|
487
|
+
const fetchOnce = async (requestAdapter: ProviderAdapter, recovery?: AttemptRecoveryKind): Promise<IterationResponse> => {
|
|
488
|
+
let request: AdapterRequest;
|
|
489
|
+
if (cachedRequest !== undefined && cachedAdapter === requestAdapter) {
|
|
490
|
+
request = cachedRequest;
|
|
491
|
+
} else {
|
|
492
|
+
request = await requestAdapter.buildRequest(iterParsed, {
|
|
493
|
+
headers: deps.forwardHeaders ? new Headers(deps.forwardHeaders) : new Headers(),
|
|
494
|
+
abortSignal: headerDeadline.signal,
|
|
495
|
+
translatorBudget,
|
|
496
|
+
});
|
|
497
|
+
try { deps.onRequestBuilt?.(request); } catch { /* diagnostics are best-effort */ }
|
|
498
|
+
cachedRequest = request;
|
|
499
|
+
cachedAdapter = requestAdapter;
|
|
500
|
+
}
|
|
435
501
|
let response: Response;
|
|
436
502
|
try {
|
|
437
|
-
|
|
438
|
-
|
|
503
|
+
if (requestAdapter.fetchResponse) {
|
|
504
|
+
await paceThenResetHeaderDeadline();
|
|
505
|
+
deps.onAttemptSend?.(recovery);
|
|
506
|
+
response = await requestAdapter.fetchResponse(request, {
|
|
439
507
|
abortSignal: headerDeadline.signal,
|
|
440
508
|
timeoutMs: connectTimeoutMs,
|
|
441
509
|
returnRawErrors: true,
|
|
442
510
|
stream: true,
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
511
|
+
executor: fetchImpl,
|
|
512
|
+
});
|
|
513
|
+
} else {
|
|
514
|
+
response = await fetchWithResetRetry(
|
|
515
|
+
async (retryRecovery) => {
|
|
516
|
+
await paceThenResetHeaderDeadline();
|
|
517
|
+
// Record every helper-driven send (the callback runs for the first attempt and
|
|
518
|
+
// each connection-reset replay); preserve the caller's recovery kind
|
|
519
|
+
// (rate-limit-429 / key-429) when the retry layer supplies none.
|
|
520
|
+
deps.onAttemptSend?.(retryRecovery ?? recovery);
|
|
446
521
|
const h = new Headers(request.headers);
|
|
447
522
|
if (!h.has("accept-encoding")) h.set("accept-encoding", "identity");
|
|
448
523
|
return fetchImpl(request.url, {
|
|
@@ -453,7 +528,8 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
453
528
|
});
|
|
454
529
|
},
|
|
455
530
|
{ abortSignal: headerDeadline.signal, label: "image-bridge-loop" },
|
|
456
|
-
|
|
531
|
+
);
|
|
532
|
+
}
|
|
457
533
|
} finally {
|
|
458
534
|
request.releaseBodyObservation?.();
|
|
459
535
|
}
|
|
@@ -461,6 +537,39 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
461
537
|
};
|
|
462
538
|
|
|
463
539
|
let prepared = await fetchOnce(adapter);
|
|
540
|
+
// Same-target 429 wait-and-retry (opt-in `retryOn429`) BEFORE key rotation: a primary-key
|
|
541
|
+
// rate-limit blip replays on the SAME key; rotation only runs after attempts exhaust.
|
|
542
|
+
while (
|
|
543
|
+
prepared.response.status === 429
|
|
544
|
+
&& rateLimitRetryPolicy !== null
|
|
545
|
+
&& rateLimitRetries < rateLimitRetryPolicy.attempts
|
|
546
|
+
) {
|
|
547
|
+
rateLimitRetries += 1;
|
|
548
|
+
// Release unread body + heartbeat-fed wait via the shared same-target helper.
|
|
549
|
+
const retryAfterHeader = prepared.response.headers.get("retry-after");
|
|
550
|
+
// The old header deadline must not stay armed across the deliberate wait: clear it
|
|
551
|
+
// before sleeping so a stale expiry can never race the client-cancel path.
|
|
552
|
+
headerDeadline.clear();
|
|
553
|
+
try {
|
|
554
|
+
yield* prepareSameTarget429Wait({
|
|
555
|
+
body: prepared.response.body,
|
|
556
|
+
signal,
|
|
557
|
+
delayMs: rateLimitRetryDelayMs(rateLimitRetryPolicy, retryAfterHeader, Date.now()),
|
|
558
|
+
heartbeatIntervalMs: Math.min(10_000, Math.max(250, stallTimeoutMs / 2)),
|
|
559
|
+
});
|
|
560
|
+
} catch {
|
|
561
|
+
throw new LoopError(499, "client closed request during image-bridge");
|
|
562
|
+
}
|
|
563
|
+
// Client cancellation wins over any stale-deadline edge: re-check before telemetry/replay.
|
|
564
|
+
if (signal.aborted) throw new LoopError(499, "client closed request during image-bridge");
|
|
565
|
+
// The deliberate backoff must not consume the cumulative response-header deadline:
|
|
566
|
+
// start a fresh one so the replay gets a new connect budget (504 stays reserved for real
|
|
567
|
+
// upstream latency).
|
|
568
|
+
headerDeadline = clearableDeadline(connectTimeoutMs, signal);
|
|
569
|
+
// Stall-watchdog seam between bounded retry fetches.
|
|
570
|
+
yield { type: "heartbeat" };
|
|
571
|
+
prepared = await fetchOnce(adapter, "rate-limit-429");
|
|
572
|
+
}
|
|
464
573
|
// 429 key-failover parity with web-search / normal routed path.
|
|
465
574
|
while (prepared.response.status === 429 && deps.on429) {
|
|
466
575
|
const rotated = deps.on429(prepared.response.headers.get("retry-after"));
|
|
@@ -468,7 +577,7 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
468
577
|
try { void prepared.response.body?.cancel().catch(() => {}); } catch { /* already closed */ }
|
|
469
578
|
adapter = rotated;
|
|
470
579
|
yield { type: "heartbeat" };
|
|
471
|
-
prepared = await fetchOnce(adapter);
|
|
580
|
+
prepared = await fetchOnce(adapter, "key-429");
|
|
472
581
|
}
|
|
473
582
|
|
|
474
583
|
// Final headers have arrived. Clear only the deadline timer before ANY body read.
|
|
@@ -567,11 +676,20 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
567
676
|
}
|
|
568
677
|
}
|
|
569
678
|
|
|
570
|
-
const toolNsMap = new Map<string, { namespace: string; name: string }>();
|
|
679
|
+
const toolNsMap = new Map<string, { namespace: string; name: string; freeform?: true }>();
|
|
571
680
|
const freeform = new Set<string>();
|
|
572
681
|
const toolSearch = new Set<string>();
|
|
573
|
-
|
|
574
|
-
|
|
682
|
+
const requestedTools = parsed.context.tools ?? [];
|
|
683
|
+
const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice, requestedTools);
|
|
684
|
+
for (const t of requestedTools) {
|
|
685
|
+
if (!toolAllowed(t)) continue;
|
|
686
|
+
if (t.namespace) {
|
|
687
|
+
toolNsMap.set(namespacedToolName(t.namespace, t.name), {
|
|
688
|
+
namespace: t.namespace,
|
|
689
|
+
name: t.name,
|
|
690
|
+
...(t.freeform ? { freeform: true } : {}),
|
|
691
|
+
});
|
|
692
|
+
}
|
|
575
693
|
if (t.freeform) freeform.add(t.name);
|
|
576
694
|
if (t.toolSearch) toolSearch.add(t.name);
|
|
577
695
|
}
|
|
@@ -767,6 +885,10 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
767
885
|
id: call.id,
|
|
768
886
|
name: call.name,
|
|
769
887
|
arguments: args,
|
|
888
|
+
// Clone per call: parallel media calls each keep their own signature.
|
|
889
|
+
...(cloneProviderOpaqueToolCallMetadata(call.providerMetadata)
|
|
890
|
+
? { providerMetadata: cloneProviderOpaqueToolCallMetadata(call.providerMetadata) }
|
|
891
|
+
: {}),
|
|
770
892
|
})),
|
|
771
893
|
],
|
|
772
894
|
timestamp: now,
|
|
@@ -808,11 +930,12 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
808
930
|
}
|
|
809
931
|
|
|
810
932
|
const sse = bridgeToResponsesSSE(
|
|
811
|
-
produce(), parsed.modelId, toolNsMap, freeform, toolSearch, () => {
|
|
933
|
+
produce(), parsed._responseModelId ?? parsed.modelId, toolNsMap, freeform, toolSearch, () => {
|
|
812
934
|
internalAbort.abort("client closed responses stream");
|
|
813
935
|
}, 2_000,
|
|
814
936
|
{
|
|
815
937
|
translatorBudget,
|
|
938
|
+
replayCacheScope: parsed._reasoningReplayScope,
|
|
816
939
|
...(deps.forceEmptyResponseId ? { responseId: "" } : {}),
|
|
817
940
|
hideThinkingSummary: parsed.options.hideThinkingSummary,
|
|
818
941
|
stallTimeoutSec: deps.stallTimeoutSec,
|
package/src/images/plan.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../types";
|
|
2
|
+
import { toolChoiceToolPredicate } from "../types";
|
|
2
3
|
import type { ImageBridgePlan, VideoBridgePlan } from "./types";
|
|
3
4
|
import { resolveEnvValue } from "../config";
|
|
4
5
|
import { getProviderRegistryEntry } from "../providers/registry";
|
|
@@ -46,6 +47,12 @@ export async function planImageBridge(
|
|
|
46
47
|
): Promise<ImageBridgePlan | undefined> {
|
|
47
48
|
if (config.images?.bridgeEnabled !== true) return undefined;
|
|
48
49
|
if (!parsed._imageGeneration) return undefined;
|
|
50
|
+
const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice);
|
|
51
|
+
const toolNames = new Set(
|
|
52
|
+
[...parsed._imageGeneration.toolNames, IMAGE_GEN_TOOL_NAME]
|
|
53
|
+
.filter(name => toolAllowed({ name })),
|
|
54
|
+
);
|
|
55
|
+
if (toolNames.size === 0) return undefined;
|
|
49
56
|
// Don't intercept for OpenAI native passthrough
|
|
50
57
|
const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
|
|
51
58
|
if (host === "api.openai.com") return undefined;
|
|
@@ -57,9 +64,7 @@ export async function planImageBridge(
|
|
|
57
64
|
const registryEntry = getProviderRegistryEntry("xai");
|
|
58
65
|
const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
|
|
59
66
|
// The synthetic tool injected into the conversation is named IMAGE_GEN_TOOL_NAME,
|
|
60
|
-
// which is what the model will actually call.
|
|
61
|
-
const toolNames = new Set(parsed._imageGeneration.toolNames);
|
|
62
|
-
toolNames.add(IMAGE_GEN_TOOL_NAME);
|
|
67
|
+
// which is what the model will actually call. toolNames also retains authorized hosted aliases.
|
|
63
68
|
const original = parsed._imageGeneration.originalTool;
|
|
64
69
|
const hostedSize = typeof original?.size === "string" ? original.size : undefined;
|
|
65
70
|
const hostedQuality = typeof original?.quality === "string" ? original.quality : undefined;
|
|
@@ -95,16 +100,6 @@ export async function planVideoBridge(
|
|
|
95
100
|
routedProvider: OcxProviderConfig,
|
|
96
101
|
): Promise<VideoBridgePlan | undefined> {
|
|
97
102
|
if (config.images?.videoBridgeEnabled !== true) return undefined;
|
|
98
|
-
// Don't intercept for OpenAI native passthrough
|
|
99
|
-
const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
|
|
100
|
-
if (host === "api.openai.com") return undefined;
|
|
101
|
-
const found = findXaiProvider(config);
|
|
102
|
-
if (!found) return undefined;
|
|
103
|
-
const token = resolveXaiImageApiKey(found.provider);
|
|
104
|
-
if (!token) return undefined;
|
|
105
|
-
// Pin the baseUrl to the registry entry, ignoring any config-level baseUrl override.
|
|
106
|
-
const registryEntry = getProviderRegistryEntry("xai");
|
|
107
|
-
const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
|
|
108
103
|
const toolNames = new Set<string>();
|
|
109
104
|
toolNames.add(VIDEO_GEN_TOOL_NAME);
|
|
110
105
|
// Collect any existing function tools whose name matches a video_gen alias
|
|
@@ -118,6 +113,21 @@ export async function planVideoBridge(
|
|
|
118
113
|
toolNames.add(fnName);
|
|
119
114
|
}
|
|
120
115
|
}
|
|
116
|
+
const toolAllowed = toolChoiceToolPredicate(parsed.options?.toolChoice);
|
|
117
|
+
for (const name of toolNames) {
|
|
118
|
+
if (!toolAllowed({ name })) toolNames.delete(name);
|
|
119
|
+
}
|
|
120
|
+
if (toolNames.size === 0) return undefined;
|
|
121
|
+
// Don't intercept for OpenAI native passthrough
|
|
122
|
+
const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
|
|
123
|
+
if (host === "api.openai.com") return undefined;
|
|
124
|
+
const found = findXaiProvider(config);
|
|
125
|
+
if (!found) return undefined;
|
|
126
|
+
const token = resolveXaiImageApiKey(found.provider);
|
|
127
|
+
if (!token) return undefined;
|
|
128
|
+
// Pin the baseUrl to the registry entry, ignoring any config-level baseUrl override.
|
|
129
|
+
const registryEntry = getProviderRegistryEntry("xai");
|
|
130
|
+
const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
|
|
121
131
|
const timeoutMs = clampImageTimeoutMs(config.images?.videoTimeoutMs);
|
|
122
132
|
const keepRaw = config.images?.artifactsKeepCount;
|
|
123
133
|
const artifactsKeepCount =
|