@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
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,13 +253,18 @@ 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
|
/**
|
|
232
|
-
* Optional 429
|
|
233
|
-
* rotated
|
|
261
|
+
* Optional 429 failover for the routed (non-xAI) model. Return a rebuilt adapter for the
|
|
262
|
+
* rotated credential, or null when the pool is exhausted. Async hooks support OAuth refresh;
|
|
263
|
+
* existing synchronous key-pool hooks remain valid.
|
|
234
264
|
*/
|
|
235
|
-
on429?: (retryAfterHeader: string | null) => ProviderAdapter | null
|
|
265
|
+
on429?: (retryAfterHeader: string | null) => ProviderAdapter | null | Promise<ProviderAdapter | null>;
|
|
266
|
+
/** Opt-in same-target 429 policy (key-auth providers). When present, 429 replays on the SAME key before on429 rotation. */
|
|
267
|
+
retryOn429Policy?: Required<RateLimitRetryPolicy> | null;
|
|
236
268
|
/** Called when the bridged Responses stream completes (parity with runTurn / routed paths). */
|
|
237
269
|
onCompletedResponse?: (response: Record<string, unknown>, providerState?: OcxProviderContinuationState) => void;
|
|
238
270
|
/** WebSocket Responses path only — leave response id empty for protocol compatibility. */
|
|
@@ -331,9 +363,20 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
331
363
|
}
|
|
332
364
|
type IterationSplit = ReturnType<typeof scanEventsForImageCall>;
|
|
333
365
|
|
|
366
|
+
// Same-target 429 budget is per REQUEST, not per model iteration: later image rounds inherit
|
|
367
|
+
// what earlier rounds left of `attempts`, so a bounded multi-round turn can never exceed the
|
|
368
|
+
// configured replay count in total (a per-round reset would multiply it by maxRounds).
|
|
369
|
+
const rateLimitRetryPolicy = deps.retryOn429Policy ?? null;
|
|
370
|
+
let rateLimitRetries = 0;
|
|
371
|
+
|
|
334
372
|
// Acquire one iteration's final response headers. The first call is drained eagerly so an initial
|
|
335
373
|
// connect/header/HTTP failure stays a non-2xx JSON response — except for runTurn adapters, which
|
|
336
374
|
// have no HTTP status surface and must not block SSE headers behind queue.collect().
|
|
375
|
+
/**
|
|
376
|
+
* Fetch one image-bridge iteration's final response headers, applying the response-header
|
|
377
|
+
* deadline and the same-target 429 retry policy (with awaited body release and deadline
|
|
378
|
+
* restart) before the `on429` key rotation.
|
|
379
|
+
*/
|
|
337
380
|
const prepareIterationEvents = async function* (forceFinal: boolean): AsyncGenerator<AdapterEvent, IterationResponse> {
|
|
338
381
|
const iterParsed: OcxParsedRequest = {
|
|
339
382
|
...parsed,
|
|
@@ -346,6 +389,7 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
346
389
|
// expose buildRequest/fetchResponse/parseStream to the bridge, so collect their events through
|
|
347
390
|
// an AdapterEventQueue and wrap them in a pseudo-response whose parseStream replays them.
|
|
348
391
|
if (adapter.runTurn) {
|
|
392
|
+
await deps.waitForRequestSlot?.(signal);
|
|
349
393
|
const queue = createAdapterEventQueue({
|
|
350
394
|
onBacklogExceeded: () => internalAbort.abort("runTurn backlog exceeded"),
|
|
351
395
|
});
|
|
@@ -422,27 +466,59 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
422
466
|
return { response: new Response(new Uint8Array(0), { status: 200 }), responseAdapter: wrappedAdapter };
|
|
423
467
|
}
|
|
424
468
|
|
|
425
|
-
|
|
469
|
+
let headerDeadline = clearableDeadline(connectTimeoutMs, signal);
|
|
470
|
+
const paceThenResetHeaderDeadline = async (): Promise<void> => {
|
|
471
|
+
headerDeadline.clear();
|
|
472
|
+
await deps.waitForRequestSlot?.(signal);
|
|
473
|
+
headerDeadline = clearableDeadline(connectTimeoutMs, signal);
|
|
474
|
+
};
|
|
426
475
|
try {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
476
|
+
/**
|
|
477
|
+
* Build and fetch one image-bridge iteration on the given adapter, under the iteration
|
|
478
|
+
* header deadline. The caller owns same-target 429 replays and key rotation around it.
|
|
479
|
+
* The outbound request is cached per adapter so a same-target replay reuses the EXACT
|
|
480
|
+
* URL, serialized body, and headers (builder runs once per target sequence).
|
|
481
|
+
*/
|
|
482
|
+
let cachedRequest: AdapterRequest | undefined;
|
|
483
|
+
let cachedAdapter: ProviderAdapter | undefined;
|
|
484
|
+
/**
|
|
485
|
+
* Build and fetch one image-bridge iteration on the given adapter, under the iteration
|
|
486
|
+
* header deadline. The caller owns same-target 429 replays and key rotation around it.
|
|
487
|
+
*/
|
|
488
|
+
const fetchOnce = async (requestAdapter: ProviderAdapter, recovery?: AttemptRecoveryKind): Promise<IterationResponse> => {
|
|
489
|
+
let request: AdapterRequest;
|
|
490
|
+
if (cachedRequest !== undefined && cachedAdapter === requestAdapter) {
|
|
491
|
+
request = cachedRequest;
|
|
492
|
+
} else {
|
|
493
|
+
request = await requestAdapter.buildRequest(iterParsed, {
|
|
494
|
+
headers: deps.forwardHeaders ? new Headers(deps.forwardHeaders) : new Headers(),
|
|
495
|
+
abortSignal: headerDeadline.signal,
|
|
496
|
+
translatorBudget,
|
|
497
|
+
});
|
|
498
|
+
try { deps.onRequestBuilt?.(request); } catch { /* diagnostics are best-effort */ }
|
|
499
|
+
cachedRequest = request;
|
|
500
|
+
cachedAdapter = requestAdapter;
|
|
501
|
+
}
|
|
435
502
|
let response: Response;
|
|
436
503
|
try {
|
|
437
|
-
|
|
438
|
-
|
|
504
|
+
if (requestAdapter.fetchResponse) {
|
|
505
|
+
await paceThenResetHeaderDeadline();
|
|
506
|
+
deps.onAttemptSend?.(recovery);
|
|
507
|
+
response = await requestAdapter.fetchResponse(request, {
|
|
439
508
|
abortSignal: headerDeadline.signal,
|
|
440
509
|
timeoutMs: connectTimeoutMs,
|
|
441
510
|
returnRawErrors: true,
|
|
442
511
|
stream: true,
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
512
|
+
executor: fetchImpl,
|
|
513
|
+
});
|
|
514
|
+
} else {
|
|
515
|
+
response = await fetchWithResetRetry(
|
|
516
|
+
async (retryRecovery) => {
|
|
517
|
+
await paceThenResetHeaderDeadline();
|
|
518
|
+
// Record every helper-driven send (the callback runs for the first attempt and
|
|
519
|
+
// each connection-reset replay); preserve the caller's recovery kind
|
|
520
|
+
// (rate-limit-429 / key-429) when the retry layer supplies none.
|
|
521
|
+
deps.onAttemptSend?.(retryRecovery ?? recovery);
|
|
446
522
|
const h = new Headers(request.headers);
|
|
447
523
|
if (!h.has("accept-encoding")) h.set("accept-encoding", "identity");
|
|
448
524
|
return fetchImpl(request.url, {
|
|
@@ -453,7 +529,8 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
453
529
|
});
|
|
454
530
|
},
|
|
455
531
|
{ abortSignal: headerDeadline.signal, label: "image-bridge-loop" },
|
|
456
|
-
|
|
532
|
+
);
|
|
533
|
+
}
|
|
457
534
|
} finally {
|
|
458
535
|
request.releaseBodyObservation?.();
|
|
459
536
|
}
|
|
@@ -461,14 +538,47 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
461
538
|
};
|
|
462
539
|
|
|
463
540
|
let prepared = await fetchOnce(adapter);
|
|
541
|
+
// Same-target 429 wait-and-retry (opt-in `retryOn429`) BEFORE key rotation: a primary-key
|
|
542
|
+
// rate-limit blip replays on the SAME key; rotation only runs after attempts exhaust.
|
|
543
|
+
while (
|
|
544
|
+
prepared.response.status === 429
|
|
545
|
+
&& rateLimitRetryPolicy !== null
|
|
546
|
+
&& rateLimitRetries < rateLimitRetryPolicy.attempts
|
|
547
|
+
) {
|
|
548
|
+
rateLimitRetries += 1;
|
|
549
|
+
// Release unread body + heartbeat-fed wait via the shared same-target helper.
|
|
550
|
+
const retryAfterHeader = prepared.response.headers.get("retry-after");
|
|
551
|
+
// The old header deadline must not stay armed across the deliberate wait: clear it
|
|
552
|
+
// before sleeping so a stale expiry can never race the client-cancel path.
|
|
553
|
+
headerDeadline.clear();
|
|
554
|
+
try {
|
|
555
|
+
yield* prepareSameTarget429Wait({
|
|
556
|
+
body: prepared.response.body,
|
|
557
|
+
signal,
|
|
558
|
+
delayMs: rateLimitRetryDelayMs(rateLimitRetryPolicy, retryAfterHeader, Date.now()),
|
|
559
|
+
heartbeatIntervalMs: Math.min(10_000, Math.max(250, stallTimeoutMs / 2)),
|
|
560
|
+
});
|
|
561
|
+
} catch {
|
|
562
|
+
throw new LoopError(499, "client closed request during image-bridge");
|
|
563
|
+
}
|
|
564
|
+
// Client cancellation wins over any stale-deadline edge: re-check before telemetry/replay.
|
|
565
|
+
if (signal.aborted) throw new LoopError(499, "client closed request during image-bridge");
|
|
566
|
+
// The deliberate backoff must not consume the cumulative response-header deadline:
|
|
567
|
+
// start a fresh one so the replay gets a new connect budget (504 stays reserved for real
|
|
568
|
+
// upstream latency).
|
|
569
|
+
headerDeadline = clearableDeadline(connectTimeoutMs, signal);
|
|
570
|
+
// Stall-watchdog seam between bounded retry fetches.
|
|
571
|
+
yield { type: "heartbeat" };
|
|
572
|
+
prepared = await fetchOnce(adapter, "rate-limit-429");
|
|
573
|
+
}
|
|
464
574
|
// 429 key-failover parity with web-search / normal routed path.
|
|
465
575
|
while (prepared.response.status === 429 && deps.on429) {
|
|
466
|
-
const rotated = deps.on429(prepared.response.headers.get("retry-after"));
|
|
576
|
+
const rotated = await deps.on429(prepared.response.headers.get("retry-after"));
|
|
467
577
|
if (!rotated) break;
|
|
468
578
|
try { void prepared.response.body?.cancel().catch(() => {}); } catch { /* already closed */ }
|
|
469
579
|
adapter = rotated;
|
|
470
580
|
yield { type: "heartbeat" };
|
|
471
|
-
prepared = await fetchOnce(adapter);
|
|
581
|
+
prepared = await fetchOnce(adapter, "key-429");
|
|
472
582
|
}
|
|
473
583
|
|
|
474
584
|
// Final headers have arrived. Clear only the deadline timer before ANY body read.
|
|
@@ -567,11 +677,20 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
567
677
|
}
|
|
568
678
|
}
|
|
569
679
|
|
|
570
|
-
const toolNsMap = new Map<string, { namespace: string; name: string }>();
|
|
680
|
+
const toolNsMap = new Map<string, { namespace: string; name: string; freeform?: true }>();
|
|
571
681
|
const freeform = new Set<string>();
|
|
572
682
|
const toolSearch = new Set<string>();
|
|
573
|
-
|
|
574
|
-
|
|
683
|
+
const requestedTools = parsed.context.tools ?? [];
|
|
684
|
+
const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice, requestedTools);
|
|
685
|
+
for (const t of requestedTools) {
|
|
686
|
+
if (!toolAllowed(t)) continue;
|
|
687
|
+
if (t.namespace) {
|
|
688
|
+
toolNsMap.set(namespacedToolName(t.namespace, t.name), {
|
|
689
|
+
namespace: t.namespace,
|
|
690
|
+
name: t.name,
|
|
691
|
+
...(t.freeform ? { freeform: true } : {}),
|
|
692
|
+
});
|
|
693
|
+
}
|
|
575
694
|
if (t.freeform) freeform.add(t.name);
|
|
576
695
|
if (t.toolSearch) toolSearch.add(t.name);
|
|
577
696
|
}
|
|
@@ -767,6 +886,10 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
767
886
|
id: call.id,
|
|
768
887
|
name: call.name,
|
|
769
888
|
arguments: args,
|
|
889
|
+
// Clone per call: parallel media calls each keep their own signature.
|
|
890
|
+
...(cloneProviderOpaqueToolCallMetadata(call.providerMetadata)
|
|
891
|
+
? { providerMetadata: cloneProviderOpaqueToolCallMetadata(call.providerMetadata) }
|
|
892
|
+
: {}),
|
|
770
893
|
})),
|
|
771
894
|
],
|
|
772
895
|
timestamp: now,
|
|
@@ -808,11 +931,12 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
|
|
|
808
931
|
}
|
|
809
932
|
|
|
810
933
|
const sse = bridgeToResponsesSSE(
|
|
811
|
-
produce(), parsed.modelId, toolNsMap, freeform, toolSearch, () => {
|
|
934
|
+
produce(), parsed._responseModelId ?? parsed.modelId, toolNsMap, freeform, toolSearch, () => {
|
|
812
935
|
internalAbort.abort("client closed responses stream");
|
|
813
936
|
}, 2_000,
|
|
814
937
|
{
|
|
815
938
|
translatorBudget,
|
|
939
|
+
replayCacheScope: parsed._reasoningReplayScope,
|
|
816
940
|
...(deps.forceEmptyResponseId ? { responseId: "" } : {}),
|
|
817
941
|
hideThinkingSummary: parsed.options.hideThinkingSummary,
|
|
818
942
|
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,13 @@ 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([...parsed._imageGeneration.toolNames].filter(name => toolAllowed({ name })));
|
|
52
|
+
if (toolAllowed({ name: IMAGE_GEN_TOOL_NAME })) toolNames.add(IMAGE_GEN_TOOL_NAME);
|
|
53
|
+
if (toolNames.size === 0) return undefined;
|
|
54
|
+
// Responses advertises and rewrites authorized aliases to this synthetic name, so the loop
|
|
55
|
+
// must always intercept it once any image-generation name has armed the bridge.
|
|
56
|
+
toolNames.add(IMAGE_GEN_TOOL_NAME);
|
|
49
57
|
// Don't intercept for OpenAI native passthrough
|
|
50
58
|
const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
|
|
51
59
|
if (host === "api.openai.com") return undefined;
|
|
@@ -57,9 +65,7 @@ export async function planImageBridge(
|
|
|
57
65
|
const registryEntry = getProviderRegistryEntry("xai");
|
|
58
66
|
const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
|
|
59
67
|
// 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);
|
|
68
|
+
// which is what the model will actually call. toolNames also retains authorized hosted aliases.
|
|
63
69
|
const original = parsed._imageGeneration.originalTool;
|
|
64
70
|
const hostedSize = typeof original?.size === "string" ? original.size : undefined;
|
|
65
71
|
const hostedQuality = typeof original?.quality === "string" ? original.quality : undefined;
|
|
@@ -95,16 +101,6 @@ export async function planVideoBridge(
|
|
|
95
101
|
routedProvider: OcxProviderConfig,
|
|
96
102
|
): Promise<VideoBridgePlan | undefined> {
|
|
97
103
|
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
104
|
const toolNames = new Set<string>();
|
|
109
105
|
toolNames.add(VIDEO_GEN_TOOL_NAME);
|
|
110
106
|
// Collect any existing function tools whose name matches a video_gen alias
|
|
@@ -118,6 +114,21 @@ export async function planVideoBridge(
|
|
|
118
114
|
toolNames.add(fnName);
|
|
119
115
|
}
|
|
120
116
|
}
|
|
117
|
+
const toolAllowed = toolChoiceToolPredicate(parsed.options?.toolChoice);
|
|
118
|
+
for (const name of toolNames) {
|
|
119
|
+
if (!toolAllowed({ name })) toolNames.delete(name);
|
|
120
|
+
}
|
|
121
|
+
if (toolNames.size === 0) return undefined;
|
|
122
|
+
// Don't intercept for OpenAI native passthrough
|
|
123
|
+
const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
|
|
124
|
+
if (host === "api.openai.com") return undefined;
|
|
125
|
+
const found = findXaiProvider(config);
|
|
126
|
+
if (!found) return undefined;
|
|
127
|
+
const token = resolveXaiImageApiKey(found.provider);
|
|
128
|
+
if (!token) return undefined;
|
|
129
|
+
// Pin the baseUrl to the registry entry, ignoring any config-level baseUrl override.
|
|
130
|
+
const registryEntry = getProviderRegistryEntry("xai");
|
|
131
|
+
const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
|
|
121
132
|
const timeoutMs = clampImageTimeoutMs(config.images?.videoTimeoutMs);
|
|
122
133
|
const keepRaw = config.images?.artifactsKeepCount;
|
|
123
134
|
const artifactsKeepCount =
|