@iislee/opencodex 2.11.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -7,8 +7,11 @@ type RepairableItemType = "message" | "reasoning";
|
|
|
7
7
|
|
|
8
8
|
interface ResponsesItemIdRepairState {
|
|
9
9
|
readonly repairMissingTerminalIds: boolean;
|
|
10
|
+
readonly repairInvalidIds: boolean;
|
|
10
11
|
readonly placeholders: Record<RepairableItemType, ReadonlySet<string>>;
|
|
11
12
|
readonly outputIds: Record<RepairableItemType, Map<number, string>>;
|
|
13
|
+
/** JSON [outputIndex, rawId] -> canonical id, for exact item_id rewrites on part/delta events. */
|
|
14
|
+
readonly rawIds: Map<string, string>;
|
|
12
15
|
readonly scope: string;
|
|
13
16
|
readonly budget?: TranslatorBudget;
|
|
14
17
|
}
|
|
@@ -53,6 +56,7 @@ function mintCanonicalId(type: RepairableItemType, scope: string, outputIndex: n
|
|
|
53
56
|
function createRepairState(config: ResponsesItemIdRepairConfig, budget?: TranslatorBudget): ResponsesItemIdRepairState {
|
|
54
57
|
const state = {
|
|
55
58
|
repairMissingTerminalIds: config.repairMissingTerminalIds === true,
|
|
59
|
+
repairInvalidIds: config.repairInvalidIds === true,
|
|
56
60
|
placeholders: {
|
|
57
61
|
message: new Set(config.message ?? []),
|
|
58
62
|
reasoning: new Set(config.reasoning ?? []),
|
|
@@ -61,6 +65,7 @@ function createRepairState(config: ResponsesItemIdRepairConfig, budget?: Transla
|
|
|
61
65
|
message: new Map<number, string>(),
|
|
62
66
|
reasoning: new Map<number, string>(),
|
|
63
67
|
},
|
|
68
|
+
rawIds: new Map<string, string>(),
|
|
64
69
|
scope: randomUUID().replace(/-/g, ""),
|
|
65
70
|
budget,
|
|
66
71
|
};
|
|
@@ -85,12 +90,19 @@ function rememberMappedId(
|
|
|
85
90
|
if (!rawId) return null;
|
|
86
91
|
const mapped = state.placeholders[type].has(rawId)
|
|
87
92
|
? mintCanonicalId(type, state.scope, outputIndex)
|
|
88
|
-
: state.
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
: state.repairInvalidIds && !rawId.startsWith(REPAIRABLE_PREFIXES[type])
|
|
94
|
+
// An existing id without the canonical msg_/rs_ prefix (bare UUIDs from
|
|
95
|
+
// DeepSeek's Responses route) leaves Codex stuck on Thinking (#938).
|
|
96
|
+
? mintCanonicalId(type, state.scope, outputIndex)
|
|
97
|
+
: state.repairMissingTerminalIds
|
|
98
|
+
? rawId
|
|
99
|
+
: null;
|
|
91
100
|
if (!mapped) return null;
|
|
92
101
|
state.budget?.chargeRetained(new TextEncoder().encode(JSON.stringify([outputIndex, rawId, mapped])).byteLength, { kind: "item_ids" });
|
|
93
102
|
state.outputIds[type].set(outputIndex, mapped);
|
|
103
|
+
// Keyed by (index, rawId): an upstream that reuses one placeholder id across
|
|
104
|
+
// several items must not collapse them into the last item's canonical id.
|
|
105
|
+
if (rawId !== mapped) state.rawIds.set(JSON.stringify([outputIndex, rawId]), mapped);
|
|
94
106
|
return mapped;
|
|
95
107
|
}
|
|
96
108
|
|
|
@@ -114,11 +126,24 @@ function rewriteItemIdField(
|
|
|
114
126
|
): { event: Record<string, unknown>; changed: boolean } {
|
|
115
127
|
const eventType = typeof event.type === "string" ? ITEM_ID_EVENT_TYPES[event.type] : undefined;
|
|
116
128
|
if (!eventType) return { event, changed: false };
|
|
129
|
+
const currentId = typeof event.item_id === "string" ? event.item_id : undefined;
|
|
130
|
+
// content_part.* events are shared between message and reasoning items (DeepSeek's
|
|
131
|
+
// streamed reasoning wraps its text in content parts), so the static event-type map
|
|
132
|
+
// can point at the wrong id table. The rewrite is therefore exact-only when the
|
|
133
|
+
// event carries an item_id: it fires when (output_index, item_id) names an id the
|
|
134
|
+
// item stream already repaired, and otherwise leaves the event alone — an unknown
|
|
135
|
+
// id belongs to an item this repair never touched (function_call, already-canonical
|
|
136
|
+
// ids), and guessing by index could borrow a sibling item's identity. The index
|
|
137
|
+
// table serves only events with NO item_id, where repairMissingTerminalIds
|
|
138
|
+
// explicitly opts into the positional guess (the pre-existing contract).
|
|
139
|
+
if (currentId !== undefined) {
|
|
140
|
+
const mapped = state.rawIds.get(JSON.stringify([outputIndex, currentId]));
|
|
141
|
+
if (!mapped || currentId === mapped) return { event, changed: false };
|
|
142
|
+
return { event: { ...event, item_id: mapped }, changed: true };
|
|
143
|
+
}
|
|
144
|
+
if (!state.repairMissingTerminalIds) return { event, changed: false };
|
|
117
145
|
const mapped = state.outputIds[eventType].get(outputIndex);
|
|
118
146
|
if (!mapped) return { event, changed: false };
|
|
119
|
-
const currentId = typeof event.item_id === "string" ? event.item_id : undefined;
|
|
120
|
-
if (currentId === mapped) return { event, changed: false };
|
|
121
|
-
if (currentId === undefined && !state.repairMissingTerminalIds) return { event, changed: false };
|
|
122
147
|
return { event: { ...event, item_id: mapped }, changed: true };
|
|
123
148
|
}
|
|
124
149
|
|
|
@@ -219,6 +244,29 @@ export function relaySseWithResponsesItemIdRepair(
|
|
|
219
244
|
|
|
220
245
|
export function hasResponsesItemIdRepair(config: ResponsesItemIdRepairConfig | undefined): boolean {
|
|
221
246
|
return config?.repairMissingTerminalIds === true
|
|
247
|
+
|| config?.repairInvalidIds === true
|
|
222
248
|
|| (config?.message?.length ?? 0) > 0
|
|
223
249
|
|| (config?.reasoning?.length ?? 0) > 0;
|
|
224
250
|
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Client-facing id normalization for a WHOLE bounded-JSON Responses object.
|
|
254
|
+
*
|
|
255
|
+
* The bounded-JSON policy (#875) answers a streaming client by synthesizing SSE
|
|
256
|
+
* from a completed JSON body, and reframes the same body into events for WS
|
|
257
|
+
* turns. Neither path goes through the SSE relay, so neither picks up the SSE
|
|
258
|
+
* item-id rewrite — a provider that needs id repair would get it on a streaming
|
|
259
|
+
* response and silently lose it the moment the reliability policy switched the
|
|
260
|
+
* upstream to bounded JSON. This applies the same rewrite to the object so all
|
|
261
|
+
* three paths agree. Raw recorded state is untouched: recording happens before
|
|
262
|
+
* any normalization.
|
|
263
|
+
*/
|
|
264
|
+
export function repairResponsesJsonItemIds(
|
|
265
|
+
response: Record<string, unknown>,
|
|
266
|
+
config: ResponsesItemIdRepairConfig,
|
|
267
|
+
budget?: TranslatorBudget,
|
|
268
|
+
): Record<string, unknown> {
|
|
269
|
+
const state = createRepairState(config, budget);
|
|
270
|
+
const rewritten = rewriteResponseSnapshot(state, response);
|
|
271
|
+
return rewritten.changed ? rewritten.response : response;
|
|
272
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared bounded-JSON → Responses event sequence (#875): the same pure event
|
|
3
|
+
* list used by the WebSocket bridge (sendResponsesJsonAsEvents) and by the
|
|
4
|
+
* HTTP SSE synthesis for models whose reliability policy forces a bounded
|
|
5
|
+
* JSON upstream. One algorithm, two serializations — no duplicated drift.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type ResponsesJsonEventFrame = Record<string, unknown>;
|
|
9
|
+
|
|
10
|
+
export const MAX_SYNTHESIZED_OUTPUT_ITEMS = 10_000;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The canonical minimal sequence Codex commits: response.created (empty
|
|
14
|
+
* output, in_progress) → one response.output_item.done per output item → a
|
|
15
|
+
* status-preserving terminal (completed / failed / incomplete).
|
|
16
|
+
*/
|
|
17
|
+
export function responsesJsonEventSequence(
|
|
18
|
+
response: Record<string, unknown>,
|
|
19
|
+
rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
|
|
20
|
+
): ResponsesJsonEventFrame[] {
|
|
21
|
+
return [...iterateResponsesJsonEvents(response, rewritePayload)];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function* iterateResponsesJsonEvents(
|
|
25
|
+
response: Record<string, unknown>,
|
|
26
|
+
rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
|
|
27
|
+
): Generator<ResponsesJsonEventFrame> {
|
|
28
|
+
const rewrite = rewritePayload ?? ((payload: Record<string, unknown>) => payload);
|
|
29
|
+
const output = Array.isArray(response.output) ? response.output : [];
|
|
30
|
+
if (output.length > MAX_SYNTHESIZED_OUTPUT_ITEMS) {
|
|
31
|
+
throw new RangeError(
|
|
32
|
+
`Responses JSON output contains ${output.length} items; maximum is ${MAX_SYNTHESIZED_OUTPUT_ITEMS}`,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const finalStatus = response.status === "failed" || response.status === "incomplete"
|
|
36
|
+
? response.status
|
|
37
|
+
: "completed";
|
|
38
|
+
yield rewrite({
|
|
39
|
+
type: "response.created",
|
|
40
|
+
response: { ...response, status: "in_progress", output: [] },
|
|
41
|
+
});
|
|
42
|
+
for (const [outputIndex, item] of output.entries()) {
|
|
43
|
+
yield rewrite({
|
|
44
|
+
type: "response.output_item.done",
|
|
45
|
+
output_index: outputIndex,
|
|
46
|
+
item,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
yield rewrite({
|
|
50
|
+
type: `response.${finalStatus}`,
|
|
51
|
+
response: { ...response, status: finalStatus },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Serialize the event sequence as one SSE body with exactly one
|
|
57
|
+
* `data: [DONE]\n\n` trailer.
|
|
58
|
+
*/
|
|
59
|
+
export function responsesJsonToSseBody(
|
|
60
|
+
response: Record<string, unknown>,
|
|
61
|
+
rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
|
|
62
|
+
): string {
|
|
63
|
+
const frames = responsesJsonEventSequence(response, rewritePayload)
|
|
64
|
+
.map(frame => `data: ${JSON.stringify(frame)}\n\n`);
|
|
65
|
+
return `${frames.join("")}data: [DONE]\n\n`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Stream synthesized SSE frames without retaining the expanded body in memory. */
|
|
69
|
+
export function responsesJsonToSseStream(
|
|
70
|
+
response: Record<string, unknown>,
|
|
71
|
+
rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
|
|
72
|
+
): ReadableStream<Uint8Array> {
|
|
73
|
+
const output = Array.isArray(response.output) ? response.output : [];
|
|
74
|
+
if (output.length > MAX_SYNTHESIZED_OUTPUT_ITEMS) {
|
|
75
|
+
throw new RangeError(
|
|
76
|
+
`Responses JSON output contains ${output.length} items; maximum is ${MAX_SYNTHESIZED_OUTPUT_ITEMS}`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
const frames = iterateResponsesJsonEvents(response, rewritePayload);
|
|
80
|
+
const encoder = new TextEncoder();
|
|
81
|
+
return new ReadableStream({
|
|
82
|
+
pull(controller) {
|
|
83
|
+
const next = frames.next();
|
|
84
|
+
controller.enqueue(encoder.encode(
|
|
85
|
+
next.done ? "data: [DONE]\n\n" : `data: ${JSON.stringify(next.value)}\n\n`,
|
|
86
|
+
));
|
|
87
|
+
if (next.done) controller.close();
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SsePayloadRewrite } from "./sse-payload-rewrite";
|
|
2
|
+
|
|
3
|
+
function rewriteResponseObjectModel(value: unknown, responseModelId: string): boolean {
|
|
4
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
5
|
+
const response = value as Record<string, unknown>;
|
|
6
|
+
if (typeof response.model !== "string" || response.model === responseModelId) return false;
|
|
7
|
+
response.model = responseModelId;
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Rewrite only existing Responses model metadata; unrelated and malformed payloads stay byte-identical. */
|
|
12
|
+
export function rewriteResponsesModelJson(json: string, responseModelId: string): string {
|
|
13
|
+
let parsed: unknown;
|
|
14
|
+
try {
|
|
15
|
+
parsed = JSON.parse(json);
|
|
16
|
+
} catch {
|
|
17
|
+
return json;
|
|
18
|
+
}
|
|
19
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return json;
|
|
20
|
+
const record = parsed as Record<string, unknown>;
|
|
21
|
+
const rootChanged = rewriteResponseObjectModel(record, responseModelId);
|
|
22
|
+
const nestedChanged = rewriteResponseObjectModel(record.response, responseModelId);
|
|
23
|
+
const changed = rootChanged || nestedChanged;
|
|
24
|
+
return changed ? JSON.stringify(record) : json;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createResponsesModelPayloadRewrite(responseModelId: string): SsePayloadRewrite {
|
|
28
|
+
return payload => rewriteResponsesModelJson(payload, responseModelId);
|
|
29
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { SsePayloadRewrite } from "./sse-payload-rewrite";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Route content-channel reasoning from native-Responses upstreams through the
|
|
5
|
+
* expandable summary channel (issue #45).
|
|
6
|
+
*
|
|
7
|
+
* Codex renders the expandable reasoning trace from the Responses reasoning
|
|
8
|
+
* item's `summary[]` channel. DeepSeek's native `/responses` endpoint emits
|
|
9
|
+
* raw thinking on the content channel instead (`response.reasoning_text.delta`
|
|
10
|
+
* plus items with `content: [{type: "reasoning_text", text}]` and an empty
|
|
11
|
+
* `summary`), so routed DeepSeek turns showed the "Worked for Xs" timer with
|
|
12
|
+
* nothing to expand. Native OpenAI upstreams already emit summary-channel
|
|
13
|
+
* events; this rewrite is a no-op for them (no reasoning_text events to
|
|
14
|
+
* rewrite) and only engages when the upstream produces content-channel
|
|
15
|
+
* reasoning.
|
|
16
|
+
*
|
|
17
|
+
* Replay compatibility: Codex echoes the reasoning item it received back into
|
|
18
|
+
* the next request's input. DeepSeek's Responses API accepts summary-shaped
|
|
19
|
+
* reasoning input items (verified live), so the rewrite round-trips.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
23
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function reasoningTextOf(item: Record<string, unknown>): string {
|
|
27
|
+
if (!Array.isArray(item.content)) return "";
|
|
28
|
+
return item.content
|
|
29
|
+
.filter((part): part is Record<string, unknown> => isPlainObject(part) && part.type === "reasoning_text")
|
|
30
|
+
.map(part => (typeof part.text === "string" ? part.text : ""))
|
|
31
|
+
.join("");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Move a reasoning item's content channel into the summary channel. */
|
|
35
|
+
function reasoningItemToSummaryShape(item: Record<string, unknown>): Record<string, unknown> {
|
|
36
|
+
if (item.type !== "reasoning") return item;
|
|
37
|
+
// `encrypted_content` is opaque, state-bearing provider data, so the entire item must retain its
|
|
38
|
+
// upstream shape unless that backend has an explicit replay contract permitting a rewrite. This
|
|
39
|
+
// defensively protects content-channel backends that do issue blobs when the client replays the
|
|
40
|
+
// stored item. The delta rewrite can still provide the expandable trace for the live turn.
|
|
41
|
+
// DeepSeek — the provider this rewrite was verified against — is `statelessResponses` and issues
|
|
42
|
+
// no blob, so it is unaffected.
|
|
43
|
+
if (typeof item.encrypted_content === "string" && item.encrypted_content.length > 0) return item;
|
|
44
|
+
const text = reasoningTextOf(item);
|
|
45
|
+
// Items that already use the summary channel (or carry no content text at
|
|
46
|
+
// all) are left untouched: rewriting them could clear a valid summary.
|
|
47
|
+
if (text.length === 0) return item;
|
|
48
|
+
const next: Record<string, unknown> = { ...item };
|
|
49
|
+
delete next.content;
|
|
50
|
+
next.summary = [{ type: "summary_text", text }];
|
|
51
|
+
return next;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Rewrite one parsed SSE payload in place of the content channel, or return
|
|
56
|
+
* `null` when nothing changed (caller keeps the original payload).
|
|
57
|
+
*/
|
|
58
|
+
function rewritePayload(payload: Record<string, unknown>): Record<string, unknown> | null {
|
|
59
|
+
switch (payload.type) {
|
|
60
|
+
case "response.reasoning_text.delta": {
|
|
61
|
+
const next: Record<string, unknown> = {
|
|
62
|
+
type: "response.reasoning_summary_text.delta",
|
|
63
|
+
item_id: payload.item_id,
|
|
64
|
+
output_index: payload.output_index,
|
|
65
|
+
summary_index: 0,
|
|
66
|
+
delta: payload.delta,
|
|
67
|
+
};
|
|
68
|
+
if (payload.sequence_number !== undefined) next.sequence_number = payload.sequence_number;
|
|
69
|
+
return next;
|
|
70
|
+
}
|
|
71
|
+
case "response.reasoning_text.done": {
|
|
72
|
+
const next: Record<string, unknown> = {
|
|
73
|
+
type: "response.reasoning_summary_text.done",
|
|
74
|
+
item_id: payload.item_id,
|
|
75
|
+
output_index: payload.output_index,
|
|
76
|
+
summary_index: 0,
|
|
77
|
+
text: payload.text,
|
|
78
|
+
};
|
|
79
|
+
if (payload.sequence_number !== undefined) next.sequence_number = payload.sequence_number;
|
|
80
|
+
return next;
|
|
81
|
+
}
|
|
82
|
+
default: {
|
|
83
|
+
let changed = false;
|
|
84
|
+
const next: Record<string, unknown> = { ...payload };
|
|
85
|
+
if (isPlainObject(next.item) && next.item.type === "reasoning") {
|
|
86
|
+
const rewritten = reasoningItemToSummaryShape(next.item);
|
|
87
|
+
if (rewritten !== next.item) {
|
|
88
|
+
next.item = rewritten;
|
|
89
|
+
changed = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// SSE event shape: {type: "response.completed", response: {output}}.
|
|
93
|
+
const response = isPlainObject(next.response) ? { ...next.response } : null;
|
|
94
|
+
if (response && Array.isArray(response.output)) {
|
|
95
|
+
const output = response.output.map(item => {
|
|
96
|
+
if (!isPlainObject(item) || item.type !== "reasoning") return item;
|
|
97
|
+
const rewritten = reasoningItemToSummaryShape(item);
|
|
98
|
+
if (rewritten !== item) changed = true;
|
|
99
|
+
return rewritten;
|
|
100
|
+
});
|
|
101
|
+
if (changed) {
|
|
102
|
+
response.output = output;
|
|
103
|
+
next.response = response;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Bare response document shape (non-streaming passthrough):
|
|
107
|
+
// {object: "response", output: [...]}.
|
|
108
|
+
if (Array.isArray(next.output)) {
|
|
109
|
+
const output = next.output.map(item => {
|
|
110
|
+
if (!isPlainObject(item) || item.type !== "reasoning") return item;
|
|
111
|
+
const rewritten = reasoningItemToSummaryShape(item);
|
|
112
|
+
if (rewritten !== item) changed = true;
|
|
113
|
+
return rewritten;
|
|
114
|
+
});
|
|
115
|
+
if (changed) next.output = output;
|
|
116
|
+
}
|
|
117
|
+
return changed ? next : null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Payload rewrite for passthrough relays whose upstream emits content-channel reasoning. */
|
|
123
|
+
export function createReasoningSummaryChannelPayloadRewrite(): SsePayloadRewrite {
|
|
124
|
+
return (payload: string): string => {
|
|
125
|
+
let parsed: unknown;
|
|
126
|
+
try {
|
|
127
|
+
parsed = JSON.parse(payload);
|
|
128
|
+
} catch {
|
|
129
|
+
return payload;
|
|
130
|
+
}
|
|
131
|
+
if (!isPlainObject(parsed)) return payload;
|
|
132
|
+
const rewritten = rewritePayload(parsed);
|
|
133
|
+
return rewritten !== null ? JSON.stringify(rewritten) : payload;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Object-level variant for the non-streaming passthrough: the bounded-JSON
|
|
139
|
+
* relay bypasses the SSE payload rewrite, so reasoning items inside a full
|
|
140
|
+
* Responses JSON document need the same normalization before plain JSON
|
|
141
|
+
* serialization or forced JSON-to-SSE reframing. Returns the same reference
|
|
142
|
+
* when nothing changed.
|
|
143
|
+
*/
|
|
144
|
+
export function rewriteReasoningSummaryInJson(value: unknown): unknown {
|
|
145
|
+
if (!isPlainObject(value)) return value;
|
|
146
|
+
const rewritten = rewritePayload(value);
|
|
147
|
+
return rewritten !== null ? rewritten : value;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** String-level variant of {@link rewriteReasoningSummaryInJson}. */
|
|
151
|
+
export function rewriteReasoningSummaryInJsonString(json: string): string {
|
|
152
|
+
let parsed: unknown;
|
|
153
|
+
try {
|
|
154
|
+
parsed = JSON.parse(json);
|
|
155
|
+
} catch {
|
|
156
|
+
return json;
|
|
157
|
+
}
|
|
158
|
+
const rewritten = rewriteReasoningSummaryInJson(parsed);
|
|
159
|
+
return rewritten === parsed ? json : JSON.stringify(rewritten);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* True when a routed native-Responses provider emits content-channel reasoning
|
|
164
|
+
* (raw `reasoning_text`) instead of the summary channel. DeepSeek's
|
|
165
|
+
* `/responses` endpoint is the current example: it ships raw thinking with an
|
|
166
|
+
* empty `summary` and keeps `preserveReasoningContentModels` so multi-turn
|
|
167
|
+
* replays round-trip.
|
|
168
|
+
*/
|
|
169
|
+
export function routeUsesContentChannelReasoning(
|
|
170
|
+
provider: { statelessResponses?: boolean; preserveReasoningContentModels?: string[] },
|
|
171
|
+
modelId: string,
|
|
172
|
+
): boolean {
|
|
173
|
+
if (provider.statelessResponses === true) return true;
|
|
174
|
+
const preserved = provider.preserveReasoningContentModels;
|
|
175
|
+
const normalizedModelId = modelId.toLowerCase();
|
|
176
|
+
return Array.isArray(preserved)
|
|
177
|
+
&& preserved.some(id => id.toLowerCase() === normalizedModelId);
|
|
178
|
+
}
|