@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
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-server readiness gate for the opencodex proxy.
|
|
3
|
+
*
|
|
4
|
+
* `GET /healthz` answers "is the process alive and serving HTTP?" the instant the
|
|
5
|
+
* listener binds. Readiness is stricter: the proxy is "ready" only after the
|
|
6
|
+
* post-startup Codex catalog/config sync (`syncModelsToCodex`) has settled with
|
|
7
|
+
* `ok=true` and no catalog-sync warning. Until then the process is live (Codex can
|
|
8
|
+
* open a socket) but not ready (a request would race the sync or hit a stale
|
|
9
|
+
* catalog), so clients should back off.
|
|
10
|
+
*
|
|
11
|
+
* Design contract (per P1 review):
|
|
12
|
+
* - NO module-global mutable state. Each `startServer` invocation gets its own
|
|
13
|
+
* private gate via `createReadinessGate()`, captured by that listener's
|
|
14
|
+
* closure. Starting/failing a second server in the same process can never
|
|
15
|
+
* reset or mutate the first server's gate.
|
|
16
|
+
* - Only the fixed sanitized status enum `pending | ready | failed` is stored
|
|
17
|
+
* and exposed. There is no `changedAt`, no free-form failure reason, no sync
|
|
18
|
+
* message, no warning text, no catalog path, no provider output, and no
|
|
19
|
+
* account data — those are private diagnostic data and are never exposed by
|
|
20
|
+
* `/readyz`.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Sanitized readiness state. Exactly these three values, nothing else. */
|
|
24
|
+
export type ReadinessStatus = "pending" | "ready" | "failed";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Private per-server readiness controller. The status starts at `pending` and
|
|
28
|
+
* transitions at most once (to `ready` or `failed`) when the post-startup sync
|
|
29
|
+
* settles. The gate is owned by the listener closure that requested it.
|
|
30
|
+
*/
|
|
31
|
+
export interface ReadinessGate {
|
|
32
|
+
/** Current sanitized status. */
|
|
33
|
+
getStatus(): ReadinessStatus;
|
|
34
|
+
/** Mark the proxy ready (post-startup sync settled cleanly). */
|
|
35
|
+
markReady(): void;
|
|
36
|
+
/** Mark the proxy failed. No reason is stored or exposed. */
|
|
37
|
+
markFailed(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Create a fresh private gate for one `startServer` invocation. The returned
|
|
42
|
+
* gate is the only way to read or mutate this server's readiness.
|
|
43
|
+
*/
|
|
44
|
+
export function createReadinessGate(): ReadinessGate {
|
|
45
|
+
let status: ReadinessStatus = "pending";
|
|
46
|
+
return {
|
|
47
|
+
getStatus: () => status,
|
|
48
|
+
markReady: () => {
|
|
49
|
+
if (status === "pending") status = "ready";
|
|
50
|
+
},
|
|
51
|
+
markFailed: () => {
|
|
52
|
+
if (status === "pending") status = "failed";
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Minimal shape of the post-startup sync outcome the gate cares about. */
|
|
58
|
+
export interface SyncOutcomeLike {
|
|
59
|
+
ok?: boolean;
|
|
60
|
+
warning?: string;
|
|
61
|
+
/** #1046: whether the sync actually rewrote the on-disk catalog/cache. */
|
|
62
|
+
catalogWritten?: boolean;
|
|
63
|
+
cacheSynced?: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Drive the gate from the post-startup sync. Awaits `syncFn`; the gate goes to
|
|
68
|
+
* `ready` ONLY on `ok=true` with no nonempty warning. A throw, `null`, `ok=false`,
|
|
69
|
+
* or a nonempty warning transitions to `failed`. Used directly by `handleStart`
|
|
70
|
+
* so the startup transition is unit-testable without spawning the proxy. Returns
|
|
71
|
+
* the raw sync outcome so a caller that also needs the #1046 write flags (did the
|
|
72
|
+
* sync actually write the catalog/cache?) can keep them without a second call.
|
|
73
|
+
*/
|
|
74
|
+
export async function runStartupReadinessSync(
|
|
75
|
+
gate: ReadinessGate,
|
|
76
|
+
syncFn: () => Promise<SyncOutcomeLike | null>,
|
|
77
|
+
): Promise<SyncOutcomeLike | null> {
|
|
78
|
+
let result: SyncOutcomeLike | null;
|
|
79
|
+
try {
|
|
80
|
+
result = await syncFn();
|
|
81
|
+
} catch {
|
|
82
|
+
gate.markFailed();
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
if (result === null) {
|
|
86
|
+
gate.markFailed();
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
if (result.ok !== true) {
|
|
90
|
+
gate.markFailed();
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
if (result.warning !== undefined && result.warning !== "") {
|
|
94
|
+
gate.markFailed();
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
gate.markReady();
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
@@ -24,11 +24,18 @@
|
|
|
24
24
|
* up to the drain window.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
adapterEofIncompleteFrame,
|
|
29
|
+
createSseTerminalOutputBoundary,
|
|
30
|
+
doneFrame,
|
|
31
|
+
failedTailFrame,
|
|
32
|
+
} from "./relay";
|
|
28
33
|
import {
|
|
29
34
|
nextSseBlock,
|
|
35
|
+
payloadRewriteAsBlockRewrite,
|
|
30
36
|
replaceSseDataPayload,
|
|
31
37
|
sseDataPayload,
|
|
38
|
+
type SseBlockRewrite,
|
|
32
39
|
type SsePayloadRewrite,
|
|
33
40
|
} from "./sse-payload-rewrite";
|
|
34
41
|
import type { TranslatorBudget } from "../lib/translator-budget";
|
|
@@ -43,6 +50,12 @@ export type EagerRelayHooks = {
|
|
|
43
50
|
* Bun#32111-unsafe tee()+JS-pull chain (#864).
|
|
44
51
|
*/
|
|
45
52
|
rewritePayload?: SsePayloadRewrite;
|
|
53
|
+
/**
|
|
54
|
+
* Optional block-level rewrite (zero or more blocks out per upstream
|
|
55
|
+
* block) for lifecycle event injection (#893). Takes precedence over
|
|
56
|
+
* rewritePayload when both are set.
|
|
57
|
+
*/
|
|
58
|
+
rewriteBlocks?: SseBlockRewrite;
|
|
46
59
|
/** Flush inspection at upstream end (createSseInspector.finish). */
|
|
47
60
|
finishInspection: () => void;
|
|
48
61
|
/** Drop inspector-owned frame/item state during producer teardown. */
|
|
@@ -92,9 +105,21 @@ export function relaySseEagerBounded(
|
|
|
92
105
|
const now = opts?.now ?? Date.now;
|
|
93
106
|
|
|
94
107
|
const reader = body.getReader();
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const
|
|
108
|
+
const terminalEncoder = new TextEncoder();
|
|
109
|
+
const adapterEofFrame = adapterEofIncompleteFrame(terminalEncoder);
|
|
110
|
+
const terminalSentinel = doneFrame(terminalEncoder);
|
|
111
|
+
const terminalBoundary = createSseTerminalOutputBoundary();
|
|
112
|
+
const activeRewrite: SseBlockRewrite | undefined = hooks.rewriteBlocks
|
|
113
|
+
?? (hooks.rewritePayload ? payloadRewriteAsBlockRewrite(hooks.rewritePayload) : undefined);
|
|
114
|
+
const encodeFailedTail = (error: unknown): Uint8Array | null => {
|
|
115
|
+
try {
|
|
116
|
+
return failedTailFrame(terminalEncoder, error);
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const rewriteDecoder = activeRewrite ? new TextDecoder() : null;
|
|
122
|
+
const rewriteEncoder = activeRewrite ? new TextEncoder() : null;
|
|
98
123
|
const rewriteBudget = opts?.rewriteBudget;
|
|
99
124
|
let frameBuffer = "";
|
|
100
125
|
let frameBufferBytes = 0;
|
|
@@ -121,15 +146,9 @@ export function relaySseEagerBounded(
|
|
|
121
146
|
for (;;) {
|
|
122
147
|
const next = nextSseBlock(frameBuffer);
|
|
123
148
|
if (!next) break;
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// multi-data-line events and normalizes newline style even when the
|
|
128
|
-
// payload is identical, which corrupts valid streams.
|
|
129
|
-
const block = payload !== null && rewrittenPayload !== payload
|
|
130
|
-
? replaceSseDataPayload(next.block, rewrittenPayload!)
|
|
131
|
-
: next.block;
|
|
132
|
-
out += block + next.delimiter;
|
|
149
|
+
for (const outBlock of activeRewrite!(next.block)) {
|
|
150
|
+
out += outBlock + next.delimiter;
|
|
151
|
+
}
|
|
133
152
|
frameBuffer = next.rest;
|
|
134
153
|
}
|
|
135
154
|
if (rewriteBudget) {
|
|
@@ -143,14 +162,13 @@ export function relaySseEagerBounded(
|
|
|
143
162
|
};
|
|
144
163
|
/** Flush any trailing partial block at upstream end (rewrite applied, matching the pull relay). */
|
|
145
164
|
const flushRewriteTail = (): Uint8Array => {
|
|
146
|
-
if (!
|
|
165
|
+
if (!activeRewrite) return new Uint8Array(0);
|
|
147
166
|
// Decoder-flushed bytes logically follow everything already decoded.
|
|
148
167
|
let tail = frameBuffer + rewriteDecoder!.decode();
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
168
|
+
const rewritten = activeRewrite(tail);
|
|
169
|
+
// Multiple emitted blocks must stay separately framed (#893 review);
|
|
170
|
+
// join places the delimiter only between blocks, never after the last.
|
|
171
|
+
tail = rewritten.join(tail.includes("\r\n") ? "\r\n\r\n" : "\n\n");
|
|
154
172
|
frameBuffer = "";
|
|
155
173
|
if (rewriteBudget && frameBufferBytes > 0) {
|
|
156
174
|
rewriteBudget.releaseRetained(frameBufferBytes, { kind: "live_transient" });
|
|
@@ -166,7 +184,16 @@ export function relaySseEagerBounded(
|
|
|
166
184
|
// turn unregistration stay reachable, drainAndShutdown never hangs).
|
|
167
185
|
let wake: (() => void) | null = null;
|
|
168
186
|
const wakeUp = () => { const w = wake; wake = null; w?.(); };
|
|
169
|
-
const paused = () => new Promise<void>(resolve => {
|
|
187
|
+
const paused = () => new Promise<void>(resolve => {
|
|
188
|
+
wake = resolve;
|
|
189
|
+
// A pull, cancel, or abort can win the tiny window between the loop's
|
|
190
|
+
// predicate check and installing this resolver. Re-check every wake
|
|
191
|
+
// predicate after installation so that an already-fired wake cannot leave
|
|
192
|
+
// the producer parked forever.
|
|
193
|
+
if (queuedBytes <= maxQueueBytes || cancelled || upstream.signal.aborted) {
|
|
194
|
+
wakeUp();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
170
197
|
upstream.signal.addEventListener("abort", wakeUp, { once: true });
|
|
171
198
|
|
|
172
199
|
let controllerRef: ReadableStreamDefaultController<Uint8Array> | null = null;
|
|
@@ -192,35 +219,78 @@ export function relaySseEagerBounded(
|
|
|
192
219
|
|
|
193
220
|
const producer = async () => {
|
|
194
221
|
let syntheticKind: "incomplete" | "failed" | null = null;
|
|
222
|
+
let deliveryFallbackSent = false;
|
|
223
|
+
let priorRewriteFailure = false;
|
|
224
|
+
let priorRewriteError: unknown;
|
|
195
225
|
// reader.read() is not intrinsically tied to the upstream AbortController
|
|
196
226
|
// (a fetch body usually rejects on abort, but that coupling is the fetch
|
|
197
|
-
// implementation's, not the stream's)
|
|
198
|
-
//
|
|
199
|
-
// loop
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
});
|
|
227
|
+
// implementation's, not the stream's), so abort must break a parked read on
|
|
228
|
+
// a silent upstream. Cancelling the reader does that: the pending read
|
|
229
|
+
// settles and the loop observes the abort. This is deliberately NOT a
|
|
230
|
+
// shared `Promise.race([reader.read(), aborted])` companion — racing every
|
|
231
|
+
// read against one never-settled promise retains a reaction per chunk, and
|
|
232
|
+
// that is the exact retention class relay.ts avoids at its own drain.
|
|
233
|
+
const wakeParkedRead = () => { reader.cancel(upstream.signal.reason).catch(() => {}); };
|
|
234
|
+
if (upstream.signal.aborted) wakeParkedRead();
|
|
235
|
+
else upstream.signal.addEventListener("abort", wakeParkedRead, { once: true });
|
|
204
236
|
try {
|
|
205
237
|
for (;;) {
|
|
206
|
-
const result = await
|
|
207
|
-
if (result === "aborted") break;
|
|
238
|
+
const result = await reader.read();
|
|
208
239
|
const { done: upstreamDone, value } = result;
|
|
240
|
+
// A chunk that already settled is INSPECTED before abort is honored. A read
|
|
241
|
+
// can settle with a real chunk in the same tick the signal fires (post-cancel
|
|
242
|
+
// drain: the terminal frame arrives, then the drain timer aborts upstream).
|
|
243
|
+
// Checking the signal first discarded that frame, so the terminal was never
|
|
244
|
+
// recorded and the turn was accounted as a plain cancel.
|
|
245
|
+
if (!upstreamDone && value !== undefined) hooks.inspectChunk(value);
|
|
246
|
+
if (upstream.signal.aborted) break;
|
|
209
247
|
if (upstreamDone) {
|
|
210
248
|
hooks.finishInspection();
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
249
|
+
const boundedTail = terminalBoundary.finish();
|
|
250
|
+
let clientTail = boundedTail;
|
|
251
|
+
let rewriteFailed = false;
|
|
252
|
+
let rewriteError: unknown;
|
|
253
|
+
if (activeRewrite) {
|
|
254
|
+
try {
|
|
255
|
+
const rewritten = rewriteOutbound(boundedTail);
|
|
256
|
+
clientTail = joinUint8Arrays(rewritten, flushRewriteTail());
|
|
257
|
+
} catch (error) {
|
|
258
|
+
rewriteFailed = true;
|
|
259
|
+
rewriteError = error;
|
|
260
|
+
clientTail = new Uint8Array(0);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (rewriteFailed) {
|
|
264
|
+
const safeTail = encodeFailedTail(rewriteError);
|
|
265
|
+
if (safeTail && !cancelled && !upstream.signal.aborted) {
|
|
266
|
+
if (!hooks.sawTerminal()) syntheticKind = "failed";
|
|
267
|
+
queuedBytes += safeTail.byteLength;
|
|
268
|
+
try { controllerRef?.enqueue(safeTail); } catch { /* client already torn down */ }
|
|
269
|
+
try { controllerRef?.close(); } catch { /* client already gone */ }
|
|
216
270
|
}
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
if (clientTail.byteLength > 0 && !cancelled) {
|
|
274
|
+
queuedBytes += clientTail.byteLength;
|
|
275
|
+
try { controllerRef?.enqueue(clientTail); } catch { /* client already gone */ }
|
|
217
276
|
}
|
|
218
|
-
if (
|
|
277
|
+
if (terminalBoundary.terminalSeen()) {
|
|
278
|
+
if (!terminalBoundary.doneSeen() && !cancelled) {
|
|
279
|
+
queuedBytes += terminalSentinel.byteLength;
|
|
280
|
+
try { controllerRef?.enqueue(terminalSentinel); } catch { /* client already gone */ }
|
|
281
|
+
}
|
|
282
|
+
} else if (!hooks.sawTerminal() && !cancelled && !upstream.signal.aborted) {
|
|
283
|
+
// A clean 200 EOF without a Responses terminal must be visible to
|
|
284
|
+
// Codex as one incomplete turn, followed by the normal sentinel.
|
|
285
|
+
queuedBytes += adapterEofFrame.byteLength + terminalSentinel.byteLength;
|
|
286
|
+
try {
|
|
287
|
+
controllerRef?.enqueue(adapterEofFrame);
|
|
288
|
+
controllerRef?.enqueue(terminalSentinel);
|
|
289
|
+
} catch { /* client already gone */ }
|
|
219
290
|
syntheticKind = "incomplete";
|
|
220
291
|
}
|
|
221
292
|
break;
|
|
222
293
|
}
|
|
223
|
-
hooks.inspectChunk(value);
|
|
224
294
|
if (cancelled) {
|
|
225
295
|
// Discard-drain: inspection only, nothing queued. Stop at terminal
|
|
226
296
|
// or when the bounded window expires.
|
|
@@ -230,17 +300,44 @@ export function relaySseEagerBounded(
|
|
|
230
300
|
}
|
|
231
301
|
continue;
|
|
232
302
|
}
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
303
|
+
const terminalBounded = terminalBoundary.feed(value);
|
|
304
|
+
let outbound: Uint8Array;
|
|
305
|
+
if (activeRewrite) {
|
|
306
|
+
try {
|
|
307
|
+
outbound = rewriteOutbound(terminalBounded);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
// Preserve the first rewrite failure across the teardown flush. A
|
|
310
|
+
// second empty flush may succeed, but the terminal bytes still
|
|
311
|
+
// must not bypass the failed rewrite or become DONE-only output.
|
|
312
|
+
priorRewriteFailure = true;
|
|
313
|
+
priorRewriteError = error;
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
outbound = terminalBounded;
|
|
318
|
+
}
|
|
319
|
+
if (outbound.byteLength > 0) {
|
|
320
|
+
queuedBytes += outbound.byteLength;
|
|
321
|
+
try {
|
|
322
|
+
controllerRef?.enqueue(outbound);
|
|
323
|
+
} catch {
|
|
324
|
+
// Controller already torn down (client went away without cancel()).
|
|
325
|
+
cancelled = true;
|
|
326
|
+
drainDeadline = now() + drainMs;
|
|
327
|
+
armDrainTimer();
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (terminalBoundary.terminalSeen()) {
|
|
332
|
+
// The Responses terminal event ends the turn even when a compatible
|
|
333
|
+
// gateway keeps its HTTP connection alive. Add the conventional
|
|
334
|
+
// sentinel and stop the single-reader relay at that protocol boundary.
|
|
335
|
+
if (!terminalBoundary.doneSeen()) {
|
|
336
|
+
queuedBytes += terminalSentinel.byteLength;
|
|
337
|
+
try { controllerRef?.enqueue(terminalSentinel); } catch { /* client already gone */ }
|
|
338
|
+
}
|
|
339
|
+
reader.cancel("Responses terminal event received").catch(() => {});
|
|
340
|
+
break;
|
|
244
341
|
}
|
|
245
342
|
while (queuedBytes > maxQueueBytes && !cancelled && !upstream.signal.aborted) {
|
|
246
343
|
await paused();
|
|
@@ -249,16 +346,75 @@ export function relaySseEagerBounded(
|
|
|
249
346
|
} catch (err) {
|
|
250
347
|
// Upstream read failure. Distinguish genuine mid-stream reset from
|
|
251
348
|
// abort-driven teardown (shutdown/cancel-expiry) — audit M3.
|
|
252
|
-
|
|
349
|
+
// A read can fail after delivering an unterminated terminal block. Flush
|
|
350
|
+
// both observers before deciding whether this is a synthetic reset so
|
|
351
|
+
// eager mode matches the tee/pull boundary semantics at EOF.
|
|
352
|
+
let boundedTail: Uint8Array<ArrayBufferLike> = new Uint8Array(0);
|
|
353
|
+
let tailTerminal = false;
|
|
354
|
+
let tailDone = false;
|
|
355
|
+
try { hooks.finishInspection(); } catch { /* preserve the original read failure */ }
|
|
356
|
+
try {
|
|
357
|
+
boundedTail = terminalBoundary.finish();
|
|
358
|
+
tailTerminal = terminalBoundary.terminalSeen();
|
|
359
|
+
tailDone = terminalBoundary.doneSeen();
|
|
360
|
+
} catch {
|
|
361
|
+
// A near-cap ambiguous delimiter tail may itself overflow at EOF.
|
|
362
|
+
// Preserve the original read/framing failure and continue emitting
|
|
363
|
+
// the bounded failed tail instead of letting cleanup throw again.
|
|
364
|
+
}
|
|
365
|
+
let clientTail: Uint8Array<ArrayBufferLike> = boundedTail;
|
|
366
|
+
let rewriteFailed = false;
|
|
367
|
+
let rewriteError: unknown;
|
|
368
|
+
if (priorRewriteFailure) {
|
|
369
|
+
rewriteFailed = true;
|
|
370
|
+
rewriteError = priorRewriteError;
|
|
371
|
+
clientTail = new Uint8Array(0);
|
|
372
|
+
} else if (activeRewrite) {
|
|
373
|
+
try {
|
|
374
|
+
const rewritten = rewriteOutbound(boundedTail);
|
|
375
|
+
clientTail = joinUint8Arrays(rewritten, flushRewriteTail());
|
|
376
|
+
} catch (error) {
|
|
377
|
+
rewriteFailed = true;
|
|
378
|
+
rewriteError = error;
|
|
379
|
+
clientTail = new Uint8Array(0);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (clientTail.byteLength > 0 && !cancelled && !upstream.signal.aborted) {
|
|
383
|
+
queuedBytes += clientTail.byteLength;
|
|
384
|
+
try { controllerRef?.enqueue(clientTail); } catch { /* client already torn down */ }
|
|
385
|
+
}
|
|
386
|
+
if (rewriteFailed && !cancelled && !upstream.signal.aborted) {
|
|
387
|
+
// Never bypass a client rewrite after it fails: boundedTail can contain
|
|
388
|
+
// provider metadata or content that the active rewrite was required to
|
|
389
|
+
// remove. Emit one safe failed envelope instead. When inspection has
|
|
390
|
+
// already reported the real upstream terminal, this is a delivery
|
|
391
|
+
// fallback only and must not create a second accounting outcome.
|
|
392
|
+
const safeTail = encodeFailedTail(rewriteError ?? err);
|
|
393
|
+
if (safeTail && !cancelled && !upstream.signal.aborted) {
|
|
394
|
+
if (!hooks.sawTerminal()) syntheticKind = "failed";
|
|
395
|
+
deliveryFallbackSent = true;
|
|
396
|
+
queuedBytes += safeTail.byteLength;
|
|
397
|
+
try { controllerRef?.enqueue(safeTail); } catch { /* client already torn down */ }
|
|
398
|
+
try { controllerRef?.close(); } catch { /* client already gone */ }
|
|
399
|
+
}
|
|
400
|
+
} else if (tailTerminal && !cancelled && !upstream.signal.aborted) {
|
|
401
|
+
if (!tailDone) {
|
|
402
|
+
queuedBytes += terminalSentinel.byteLength;
|
|
403
|
+
try { controllerRef?.enqueue(terminalSentinel); } catch { /* client already gone */ }
|
|
404
|
+
}
|
|
405
|
+
} else if (!tailTerminal && !cancelled && !upstream.signal.aborted) {
|
|
253
406
|
// Serializing `err` can run user-defined accessors (Error.message
|
|
254
407
|
// getters, toString) that re-entrantly cancel the client or abort the
|
|
255
408
|
// upstream. Build the tail FIRST, then re-check eligibility before
|
|
256
409
|
// committing to the synthetic terminal (adversarial review blocker).
|
|
257
|
-
const tail =
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
410
|
+
const tail = encodeFailedTail(err);
|
|
411
|
+
if (tail && !cancelled && !upstream.signal.aborted) {
|
|
412
|
+
// Inspection and client framing have separate bounded parsers. If
|
|
413
|
+
// inspection resynchronized after an oversized frame and observed a
|
|
414
|
+
// later real terminal, it still must not suppress a terminal delivery
|
|
415
|
+
// to the client. Only accounting remains tied to the inspected result.
|
|
416
|
+
if (!hooks.sawTerminal()) syntheticKind = "failed";
|
|
417
|
+
deliveryFallbackSent = true;
|
|
262
418
|
queuedBytes += tail.byteLength;
|
|
263
419
|
try { controllerRef?.enqueue(tail); } catch { /* client already torn down */ }
|
|
264
420
|
try { controllerRef?.close(); } catch { /* client already torn down */ }
|
|
@@ -272,11 +428,12 @@ export function relaySseEagerBounded(
|
|
|
272
428
|
try { rewriteBudget.releaseRetained(frameBufferBytes, { kind: "live_transient" }); } catch { /* teardown must not throw */ }
|
|
273
429
|
frameBufferBytes = 0;
|
|
274
430
|
}
|
|
431
|
+
terminalBoundary.dispose();
|
|
275
432
|
if (syntheticKind) hooks.onSynthetic(syntheticKind);
|
|
276
433
|
if (cancelled && !hooks.sawTerminal()) {
|
|
277
434
|
hooks.onClientCancel();
|
|
278
435
|
}
|
|
279
|
-
if (cancelled || upstream.signal.aborted || syntheticKind === "failed") {
|
|
436
|
+
if (cancelled || upstream.signal.aborted || syntheticKind === "failed" || deliveryFallbackSent) {
|
|
280
437
|
upstream.abort();
|
|
281
438
|
reader.cancel().catch(() => {});
|
|
282
439
|
}
|
|
@@ -284,6 +441,7 @@ export function relaySseEagerBounded(
|
|
|
284
441
|
try { controllerRef?.close(); } catch { /* already closed/errored */ }
|
|
285
442
|
}
|
|
286
443
|
try { hooks.disposeInspection?.(); } catch { /* inspection teardown must not block lifecycle cleanup */ }
|
|
444
|
+
try { activeRewrite?.dispose?.(); } catch { /* rewrite teardown must not block lifecycle cleanup */ }
|
|
287
445
|
fireDone();
|
|
288
446
|
}
|
|
289
447
|
};
|
|
@@ -311,3 +469,12 @@ export function relaySseEagerBounded(
|
|
|
311
469
|
},
|
|
312
470
|
});
|
|
313
471
|
}
|
|
472
|
+
|
|
473
|
+
function joinUint8Arrays(first: Uint8Array, second: Uint8Array): Uint8Array {
|
|
474
|
+
if (first.byteLength === 0) return second;
|
|
475
|
+
if (second.byteLength === 0) return first;
|
|
476
|
+
const joined = new Uint8Array(first.byteLength + second.byteLength);
|
|
477
|
+
joined.set(first);
|
|
478
|
+
joined.set(second, first.byteLength);
|
|
479
|
+
return joined;
|
|
480
|
+
}
|