@iislee/opencodex 2.11.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
package/src/chat/inbound.ts
CHANGED
|
@@ -8,12 +8,25 @@
|
|
|
8
8
|
export class ChatCompletionsRequestError extends Error {}
|
|
9
9
|
|
|
10
10
|
type Rec = Record<string, unknown>;
|
|
11
|
+
type ChatCompletionsRoutingBody = Rec & { model: string; messages: unknown[] };
|
|
11
12
|
|
|
12
13
|
function isRec(v: unknown): v is Rec {
|
|
13
14
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
/** Validate only the fields needed before Chat routing, without projecting the body. */
|
|
18
|
+
export function assertChatCompletionsRoutingBody(raw: unknown): asserts raw is ChatCompletionsRoutingBody {
|
|
19
|
+
if (!isRec(raw)) throw new ChatCompletionsRequestError("request body must be a JSON object");
|
|
20
|
+
if (typeof raw.model !== "string" || raw.model.length === 0) {
|
|
21
|
+
throw new ChatCompletionsRequestError("model is required");
|
|
22
|
+
}
|
|
23
|
+
if (!Array.isArray(raw.messages) || raw.messages.length === 0) {
|
|
24
|
+
throw new ChatCompletionsRequestError("messages must be a non-empty array");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
const OUTPUT_CONFIG_EFFORTS = new Set(["minimal", "low", "medium", "high", "xhigh", "max", "ultra"]);
|
|
29
|
+
const OUTPUT_CONFIG_SUMMARIES = new Set(["auto", "concise", "detailed", "none"]);
|
|
17
30
|
|
|
18
31
|
function contentToText(content: unknown): string {
|
|
19
32
|
if (typeof content === "string") return content;
|
|
@@ -40,6 +53,14 @@ function imageUrlFromPart(part: Rec): string | null {
|
|
|
40
53
|
return null;
|
|
41
54
|
}
|
|
42
55
|
|
|
56
|
+
function videoUrlFromPart(part: Rec): string | null {
|
|
57
|
+
if (part.type !== "video_url") return null;
|
|
58
|
+
const videoUrl = part.video_url;
|
|
59
|
+
if (typeof videoUrl === "string" && videoUrl.length > 0) return videoUrl;
|
|
60
|
+
if (isRec(videoUrl) && typeof videoUrl.url === "string" && videoUrl.url.length > 0) return videoUrl.url;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
43
64
|
function userContentToBlocks(content: unknown): Rec[] {
|
|
44
65
|
if (typeof content === "string") {
|
|
45
66
|
return content.length > 0 ? [{ type: "input_text", text: content }] : [];
|
|
@@ -57,7 +78,12 @@ function userContentToBlocks(content: unknown): Rec[] {
|
|
|
57
78
|
continue;
|
|
58
79
|
}
|
|
59
80
|
const imageUrl = imageUrlFromPart(raw);
|
|
60
|
-
if (imageUrl)
|
|
81
|
+
if (imageUrl) {
|
|
82
|
+
blocks.push({ type: "input_image", image_url: imageUrl });
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const videoUrl = videoUrlFromPart(raw);
|
|
86
|
+
if (videoUrl) blocks.push({ type: "input_video", video_url: videoUrl });
|
|
61
87
|
}
|
|
62
88
|
return blocks;
|
|
63
89
|
}
|
|
@@ -86,17 +112,8 @@ function pushSystemText(parts: string[], content: unknown): void {
|
|
|
86
112
|
if (text) parts.push(text);
|
|
87
113
|
}
|
|
88
114
|
|
|
89
|
-
function toolCallsToItems(toolCalls: unknown, input: Rec[]): void {
|
|
115
|
+
function toolCallsToItems(toolCalls: unknown, input: Rec[], knownNameByCallId: Map<string, string>): void {
|
|
90
116
|
if (!Array.isArray(toolCalls)) return;
|
|
91
|
-
// Recover names from earlier function_call items in the same transcript when a client
|
|
92
|
-
// re-sends tool_calls with only id/arguments (replace-style merge lost function.name).
|
|
93
|
-
const knownNameByCallId = new Map<string, string>();
|
|
94
|
-
for (const item of input) {
|
|
95
|
-
if (!isRec(item) || item.type !== "function_call") continue;
|
|
96
|
-
if (typeof item.call_id === "string" && typeof item.name === "string" && item.name.length > 0) {
|
|
97
|
-
knownNameByCallId.set(item.call_id, item.name);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
117
|
for (const raw of toolCalls) {
|
|
101
118
|
if (!isRec(raw)) continue;
|
|
102
119
|
const fn = isRec(raw.function) ? raw.function : null;
|
|
@@ -205,21 +222,34 @@ function resolveReasoningEffort(raw: Rec): string | undefined {
|
|
|
205
222
|
return undefined;
|
|
206
223
|
}
|
|
207
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Chat Completions clients (Grok Build, Copilot, OpenAI-compatible SDKs) expect
|
|
227
|
+
* `delta.reasoning_content` whenever the model thinks. The internal Responses
|
|
228
|
+
* parser hides thinking unless `reasoning.summary` is set and is not `"none"`.
|
|
229
|
+
* Map the common Chat Completions knobs onto that field. When the client only
|
|
230
|
+
* sent an effort, default the summary to `"auto"` so traces are not swallowed.
|
|
231
|
+
*/
|
|
232
|
+
function resolveReasoningSummary(raw: Rec): string | undefined {
|
|
233
|
+
if (isRec(raw.reasoning) && typeof raw.reasoning.summary === "string" && OUTPUT_CONFIG_SUMMARIES.has(raw.reasoning.summary)) {
|
|
234
|
+
return raw.reasoning.summary;
|
|
235
|
+
}
|
|
236
|
+
if (raw.include_reasoning === false) return "none";
|
|
237
|
+
if (raw.include_reasoning === true) return "auto";
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
|
|
208
241
|
/**
|
|
209
242
|
* Translate an OpenAI Chat Completions request body into a /v1/responses request body.
|
|
210
243
|
* Throws ChatCompletionsRequestError (-> 400) on malformed input.
|
|
211
244
|
*/
|
|
212
245
|
export function chatCompletionsToResponsesBody(raw: unknown): Rec {
|
|
213
|
-
|
|
214
|
-
if (typeof raw.model !== "string" || raw.model.length === 0) {
|
|
215
|
-
throw new ChatCompletionsRequestError("model is required");
|
|
216
|
-
}
|
|
217
|
-
if (!Array.isArray(raw.messages) || raw.messages.length === 0) {
|
|
218
|
-
throw new ChatCompletionsRequestError("messages must be a non-empty array");
|
|
219
|
-
}
|
|
246
|
+
assertChatCompletionsRoutingBody(raw);
|
|
220
247
|
|
|
221
248
|
const systemParts: string[] = [];
|
|
222
249
|
const input: Rec[] = [];
|
|
250
|
+
// Recover replace-style tool calls incrementally instead of rebuilding the
|
|
251
|
+
// call-id index from the entire translated transcript for every message.
|
|
252
|
+
const knownNameByCallId = new Map<string, string>();
|
|
223
253
|
|
|
224
254
|
for (const msg of raw.messages) {
|
|
225
255
|
if (!isRec(msg)) continue;
|
|
@@ -237,7 +267,7 @@ export function chatCompletionsToResponsesBody(raw: unknown): Rec {
|
|
|
237
267
|
case "assistant": {
|
|
238
268
|
const blocks = assistantContentToBlocks(msg.content);
|
|
239
269
|
if (blocks.length > 0) input.push({ type: "message", role: "assistant", content: blocks });
|
|
240
|
-
if (msg.tool_calls !== undefined) toolCallsToItems(msg.tool_calls, input);
|
|
270
|
+
if (msg.tool_calls !== undefined) toolCallsToItems(msg.tool_calls, input, knownNameByCallId);
|
|
241
271
|
break;
|
|
242
272
|
}
|
|
243
273
|
case "tool": {
|
|
@@ -282,11 +312,18 @@ export function chatCompletionsToResponsesBody(raw: unknown): Rec {
|
|
|
282
312
|
if (raw.stop !== undefined) body.stop = raw.stop;
|
|
283
313
|
if (typeof raw.user === "string") body.user = raw.user;
|
|
284
314
|
if (typeof raw.parallel_tool_calls === "boolean") body.parallel_tool_calls = raw.parallel_tool_calls;
|
|
315
|
+
if (typeof raw.service_tier === "string") body.service_tier = raw.service_tier;
|
|
285
316
|
if (typeof raw.prompt_cache_key === "string") body.prompt_cache_key = raw.prompt_cache_key;
|
|
286
317
|
if (raw.metadata !== undefined) body.metadata = raw.metadata;
|
|
287
318
|
|
|
288
319
|
const effort = resolveReasoningEffort(raw);
|
|
289
|
-
|
|
320
|
+
const summary = resolveReasoningSummary(raw);
|
|
321
|
+
if (effort || summary !== undefined) {
|
|
322
|
+
body.reasoning = {
|
|
323
|
+
...(effort ? { effort } : {}),
|
|
324
|
+
summary: summary ?? "auto",
|
|
325
|
+
};
|
|
326
|
+
}
|
|
290
327
|
|
|
291
328
|
const text = responseFormatToText(raw.response_format);
|
|
292
329
|
if (text) body.text = text;
|
package/src/chat/outbound.ts
CHANGED
|
@@ -7,9 +7,16 @@
|
|
|
7
7
|
*/
|
|
8
8
|
type Rec = Record<string, unknown>;
|
|
9
9
|
|
|
10
|
-
import { decodeServerSentEvents } from "../lib/sse-decoder";
|
|
10
|
+
import { decodeServerSentEvents, sseFieldValue } from "../lib/sse-decoder";
|
|
11
11
|
import { isTranslatorBudgetExceededError, type TranslatorBudget } from "../lib/translator-budget";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
classifyError,
|
|
14
|
+
cyberPolicyErrorType,
|
|
15
|
+
CYBER_POLICY_ERROR_CODE,
|
|
16
|
+
isCyberPolicyCode,
|
|
17
|
+
isCyberPolicyMessage,
|
|
18
|
+
} from "../lib/errors";
|
|
19
|
+
import { redactSecretString } from "../lib/redact";
|
|
13
20
|
|
|
14
21
|
function isRec(v: unknown): v is Rec {
|
|
15
22
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -48,14 +55,14 @@ export function chatCompletionsUsage(usage: unknown): Rec {
|
|
|
48
55
|
export function chatCompletionsErrorBody(
|
|
49
56
|
status: number,
|
|
50
57
|
message: string,
|
|
51
|
-
type
|
|
58
|
+
type?: string,
|
|
52
59
|
code?: string | null,
|
|
53
60
|
): Rec {
|
|
54
61
|
if (isCyberPolicyCode(code) || isCyberPolicyMessage(message)) {
|
|
55
62
|
return {
|
|
56
63
|
error: {
|
|
57
64
|
message,
|
|
58
|
-
type:
|
|
65
|
+
type: cyberPolicyErrorType(type),
|
|
59
66
|
param: null,
|
|
60
67
|
code: CYBER_POLICY_ERROR_CODE,
|
|
61
68
|
},
|
|
@@ -64,7 +71,7 @@ export function chatCompletionsErrorBody(
|
|
|
64
71
|
return {
|
|
65
72
|
error: {
|
|
66
73
|
message,
|
|
67
|
-
type,
|
|
74
|
+
type: type ?? "invalid_request_error",
|
|
68
75
|
param: null,
|
|
69
76
|
code: code !== undefined
|
|
70
77
|
? code
|
|
@@ -311,18 +318,21 @@ export function responsesSseToChatCompletionsSse(
|
|
|
311
318
|
// Deliver the error frame then close the stream abnormally (no [DONE]).
|
|
312
319
|
// Do not controller.error() — that can drop already-enqueued bytes from consumers
|
|
313
320
|
// like response.text().
|
|
314
|
-
const
|
|
315
|
-
const
|
|
321
|
+
const safeMessage = redactSecretString(message);
|
|
322
|
+
const statusHint = details?.status ?? streamErrorStatus(safeMessage);
|
|
323
|
+
const classified = classifyError(statusHint, details?.type ?? "upstream_error", safeMessage);
|
|
316
324
|
const translatorOverflow = details?.code === "translation_buffer_limit";
|
|
317
325
|
if (translatorOverflow) {
|
|
318
326
|
upstreamAbort.abort(new Error("upstream translation buffer exceeded the safe limit"));
|
|
319
327
|
closeToolCalls();
|
|
320
328
|
try { void sseIterator?.return(undefined).catch(() => {}); } catch { /* already closed */ }
|
|
321
329
|
classified.code = "translation_buffer_limit";
|
|
322
|
-
|
|
330
|
+
// Provider-controlled overflow is an upstream failure on every path:
|
|
331
|
+
// streaming frame, collector, and defensive JSON agree on 502.
|
|
332
|
+
classified.type = "upstream_error";
|
|
323
333
|
} else if (isCyberPolicyCode(details?.code) || classified.code === CYBER_POLICY_ERROR_CODE) {
|
|
324
334
|
classified.code = CYBER_POLICY_ERROR_CODE;
|
|
325
|
-
classified.type =
|
|
335
|
+
classified.type = cyberPolicyErrorType(details?.type);
|
|
326
336
|
} else if (details?.code !== undefined && details.code !== null && !classified.code) {
|
|
327
337
|
classified.code = details.code;
|
|
328
338
|
}
|
|
@@ -468,7 +478,7 @@ export function responsesSseToChatCompletionsSse(
|
|
|
468
478
|
fail(message, {
|
|
469
479
|
code,
|
|
470
480
|
...(code === "translation_buffer_limit"
|
|
471
|
-
? { status:
|
|
481
|
+
? { status: 502, type: "upstream_error" }
|
|
472
482
|
: { type, ...(code === CYBER_POLICY_ERROR_CODE ? { status: 400 } : {}) }),
|
|
473
483
|
});
|
|
474
484
|
break;
|
|
@@ -514,7 +524,7 @@ export function responsesSseToChatCompletionsSse(
|
|
|
514
524
|
if (isTranslatorBudgetExceededError(err)) {
|
|
515
525
|
upstreamAbort.abort(err);
|
|
516
526
|
closeToolCalls();
|
|
517
|
-
fail(err.message, { status:
|
|
527
|
+
fail(err.message, { status: 502, type: "upstream_error", code: err.code });
|
|
518
528
|
} else {
|
|
519
529
|
fail(err instanceof Error ? err.message : String(err));
|
|
520
530
|
}
|
|
@@ -629,6 +639,9 @@ export async function collectChatCompletion(
|
|
|
629
639
|
let content = "";
|
|
630
640
|
let reasoning = "";
|
|
631
641
|
const toolCalls = new Map<number, { id: string; name: string; arguments: string; argumentBytes: number }>();
|
|
642
|
+
// Per-call budget scopes (2 MiB/call enforced by the budget): the map key is the
|
|
643
|
+
// wire index, which is stable across deltas and present before the call id.
|
|
644
|
+
const callScope = (index: number) => `chat_collect_${index}`;
|
|
632
645
|
let finishReason = "stop";
|
|
633
646
|
let usage: unknown;
|
|
634
647
|
let streamError: ChatCompletionsStreamError | null = null;
|
|
@@ -648,9 +661,11 @@ export async function collectChatCompletion(
|
|
|
648
661
|
} catch (err) {
|
|
649
662
|
if (isChatCompletionsStreamError(err)) throw err;
|
|
650
663
|
if (isTranslatorBudgetExceededError(err)) {
|
|
664
|
+
// Provider-controlled overflow is an upstream failure, not a client
|
|
665
|
+
// request error: match the adapter/bridge contract (502 upstream_error).
|
|
651
666
|
throw new ChatCompletionsStreamError(err.message, {
|
|
652
|
-
status:
|
|
653
|
-
type: "
|
|
667
|
+
status: 502,
|
|
668
|
+
type: "upstream_error",
|
|
654
669
|
code: err.code,
|
|
655
670
|
});
|
|
656
671
|
}
|
|
@@ -664,8 +679,9 @@ export async function collectChatCompletion(
|
|
|
664
679
|
const rawFrame = buffer.slice(0, sep);
|
|
665
680
|
buffer = replaceRetained(buffer, buffer.slice(sep + 2), "live_transient");
|
|
666
681
|
for (const line of rawFrame.split("\n")) {
|
|
667
|
-
|
|
668
|
-
|
|
682
|
+
const rawData = sseFieldValue(line, "data");
|
|
683
|
+
if (rawData === null) continue;
|
|
684
|
+
const data = rawData.trim();
|
|
669
685
|
if (!data || data === "[DONE]") continue;
|
|
670
686
|
let parsed: unknown;
|
|
671
687
|
try { parsed = JSON.parse(data); } catch { continue; }
|
|
@@ -677,11 +693,15 @@ export async function collectChatCompletion(
|
|
|
677
693
|
const type = typeof parsed.error.type === "string" ? parsed.error.type : "server_error";
|
|
678
694
|
const code = typeof parsed.error.code === "string" ? parsed.error.code : null;
|
|
679
695
|
const status = code === "translation_buffer_limit"
|
|
680
|
-
?
|
|
696
|
+
? 502
|
|
681
697
|
: code === CYBER_POLICY_ERROR_CODE || isCyberPolicyMessage(message)
|
|
682
698
|
? 400
|
|
683
699
|
: streamErrorStatus(message);
|
|
684
|
-
streamError = new ChatCompletionsStreamError(message, {
|
|
700
|
+
streamError = new ChatCompletionsStreamError(message, {
|
|
701
|
+
status,
|
|
702
|
+
type: code === "translation_buffer_limit" ? "upstream_error" : type,
|
|
703
|
+
code,
|
|
704
|
+
});
|
|
685
705
|
continue;
|
|
686
706
|
}
|
|
687
707
|
if (parsed.usage) usage = parsed.usage;
|
|
@@ -697,7 +717,12 @@ export async function collectChatCompletion(
|
|
|
697
717
|
for (const tc of delta.tool_calls) {
|
|
698
718
|
if (!isRec(tc)) continue;
|
|
699
719
|
const index = typeof tc.index === "number" ? tc.index : 0;
|
|
700
|
-
|
|
720
|
+
let current = toolCalls.get(index);
|
|
721
|
+
if (!current) {
|
|
722
|
+
current = { id: "", name: "", arguments: "", argumentBytes: 0 };
|
|
723
|
+
toolCalls.set(index, current);
|
|
724
|
+
translatorBudget.openCall(callScope(index));
|
|
725
|
+
}
|
|
701
726
|
if (typeof tc.id === "string") current.id = tc.id;
|
|
702
727
|
const fn = isRec(tc.function) ? tc.function : {};
|
|
703
728
|
// Done-frame final arguments are authoritative last-write-wins snapshots.
|
|
@@ -707,27 +732,43 @@ export async function collectChatCompletion(
|
|
|
707
732
|
const nextBytes = replace
|
|
708
733
|
? Buffer.byteLength(fn.arguments)
|
|
709
734
|
: appendedUtf8Bytes(current.arguments, current.argumentBytes, fn.arguments);
|
|
710
|
-
const reservation = translatorBudget.reserveTransient(nextBytes, { kind: "
|
|
735
|
+
const reservation = translatorBudget.reserveTransient(nextBytes, { kind: "tool_args", callId: callScope(index) });
|
|
711
736
|
try {
|
|
712
737
|
current.arguments = replace ? fn.arguments : current.arguments + fn.arguments;
|
|
713
738
|
reservation.commitRetained();
|
|
714
|
-
translatorBudget.releaseRetained(current.argumentBytes, { kind: "
|
|
739
|
+
translatorBudget.releaseRetained(current.argumentBytes, { kind: "tool_args", callId: callScope(index) });
|
|
715
740
|
current.argumentBytes = nextBytes;
|
|
716
741
|
} catch (error) {
|
|
717
742
|
reservation.release();
|
|
718
743
|
throw error;
|
|
719
744
|
}
|
|
720
745
|
}
|
|
721
|
-
toolCalls.set(index, current);
|
|
722
746
|
}
|
|
723
747
|
}
|
|
724
748
|
}
|
|
725
749
|
}
|
|
726
750
|
}
|
|
751
|
+
} catch (error) {
|
|
752
|
+
// Never leak an open call scope on the error path; the turn budget's
|
|
753
|
+
// dispose is a backstop, not the owner of this transfer.
|
|
754
|
+
for (const index of toolCalls.keys()) translatorBudget.closeCall(callScope(index));
|
|
755
|
+
// Processing-time overflow (per-call or turn cap) gets the same typed
|
|
756
|
+
// contract as read-time overflow: 502 upstream_error.
|
|
757
|
+
if (isTranslatorBudgetExceededError(error)) {
|
|
758
|
+
throw new ChatCompletionsStreamError(error.message, {
|
|
759
|
+
status: 502,
|
|
760
|
+
type: "upstream_error",
|
|
761
|
+
code: error.code,
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
throw error;
|
|
727
765
|
} finally {
|
|
728
766
|
reader.releaseLock();
|
|
729
767
|
}
|
|
730
|
-
if (streamError)
|
|
768
|
+
if (streamError) {
|
|
769
|
+
for (const index of toolCalls.keys()) translatorBudget.closeCall(callScope(index));
|
|
770
|
+
throw streamError;
|
|
771
|
+
}
|
|
731
772
|
|
|
732
773
|
const message: Rec = {
|
|
733
774
|
role: "assistant",
|
|
@@ -735,17 +776,40 @@ export async function collectChatCompletion(
|
|
|
735
776
|
};
|
|
736
777
|
if (reasoning) message.reasoning_content = reasoning;
|
|
737
778
|
if (toolCalls.size > 0) {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
779
|
+
// Final owner transfer is itself a charging operation: if it overflows,
|
|
780
|
+
// release every copy already charged in this loop and close every scope
|
|
781
|
+
// still open — the error must not escape as a raw budget exception.
|
|
782
|
+
const chargedCopies: number[] = [];
|
|
783
|
+
try {
|
|
784
|
+
message.tool_calls = [...toolCalls.entries()]
|
|
785
|
+
.sort((a, b) => a[0] - b[0])
|
|
786
|
+
.map(([index, tc]) => {
|
|
787
|
+
const copy = {
|
|
788
|
+
id: tc.id || `call_${uuid().slice(0, 16)}`,
|
|
789
|
+
type: "function",
|
|
790
|
+
function: { name: tc.name, arguments: tc.arguments },
|
|
791
|
+
};
|
|
792
|
+
const copyBytes = Buffer.byteLength(JSON.stringify(copy));
|
|
793
|
+
translatorBudget.chargeRetained(copyBytes, { kind: "retained_collectors" });
|
|
794
|
+
chargedCopies.push(copyBytes);
|
|
795
|
+
// The serialized owner is charged; release the per-call accumulation.
|
|
796
|
+
translatorBudget.closeCall(callScope(index));
|
|
797
|
+
return copy;
|
|
798
|
+
});
|
|
799
|
+
} catch (error) {
|
|
800
|
+
for (const copyBytes of chargedCopies) {
|
|
801
|
+
translatorBudget.releaseRetained(copyBytes, { kind: "retained_collectors" });
|
|
802
|
+
}
|
|
803
|
+
for (const index of toolCalls.keys()) translatorBudget.closeCall(callScope(index));
|
|
804
|
+
if (isTranslatorBudgetExceededError(error)) {
|
|
805
|
+
throw new ChatCompletionsStreamError(error.message, {
|
|
806
|
+
status: 502,
|
|
807
|
+
type: "upstream_error",
|
|
808
|
+
code: error.code,
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
throw error;
|
|
812
|
+
}
|
|
749
813
|
if (finishReason === "stop") finishReason = "tool_calls";
|
|
750
814
|
}
|
|
751
815
|
|
|
@@ -11,16 +11,17 @@
|
|
|
11
11
|
* Ownership contract: this module only creates/overwrites/deletes files matching
|
|
12
12
|
* `ocx-*.md` inside the agents dir. User-authored agents are never touched.
|
|
13
13
|
*/
|
|
14
|
-
import { lstatSync, mkdirSync, readdirSync, readFileSync,
|
|
14
|
+
import { lstatSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import type { OcxConfig } from "../types";
|
|
17
|
+
import { renameAtomicFile } from "../lib/windows-atomic-replace";
|
|
17
18
|
import { claudeCodeAlias, claudeCodeNativeAlias } from "./alias";
|
|
18
|
-
import {
|
|
19
|
+
import { AUTO_CONTEXT_OFF, shouldMarkOneMillion, stripOneMillionMarker, withOneMillionMarker } from "./context-windows";
|
|
19
20
|
import { claudeConfigDir } from "./gateway-cache";
|
|
20
21
|
import { DEFAULT_SUBAGENT_MODELS, hasOwnProvider } from "../config";
|
|
21
22
|
import { effectiveBlockedSkillNames, resolveInboundModel } from "./inbound";
|
|
22
23
|
import { knownModelIdsForProvider } from "../router";
|
|
23
|
-
import {
|
|
24
|
+
import { decodeRoutedModelIdOrThrow } from "../providers/slug-codec";
|
|
24
25
|
|
|
25
26
|
export interface ClaudeAgentDef {
|
|
26
27
|
file: string;
|
|
@@ -58,13 +59,34 @@ function pickerDefaultModel(configDir: string): string | null {
|
|
|
58
59
|
/** Roster entry -> alias + display parts. Entries are bare native slugs or "provider/id".
|
|
59
60
|
* Codex-facing encoded ids (`provider/vendor-model`) decode to the native slash id first
|
|
60
61
|
* so the alias joins the raw-native context-window map (context-windows.ts). */
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generated subagent defs cannot rely on the parent's auto-context compaction
|
|
65
|
+
* pairing, so their [1m] marker follows the AUTHORITATIVE window only: mark when
|
|
66
|
+
* the effective window (exact selector, then the canonical [1m] form, then bare)
|
|
67
|
+
* is genuinely >= 1M; strip an inherited unsafe marker back to the bare selector;
|
|
68
|
+
* with no window information, keep the selector as it was. Genuine routed [1m]
|
|
69
|
+
* ids are preserved through the canonical-exact lookup. (#854)
|
|
70
|
+
*/
|
|
71
|
+
function withSubagentContextMarker(selector: string, windows: Record<string, number>): string {
|
|
72
|
+
const bare = stripOneMillionMarker(selector);
|
|
73
|
+
const wasMarked = selector !== bare;
|
|
74
|
+
const canonicalExact = wasMarked ? `${bare}[1m]` : selector;
|
|
75
|
+
const authoritativeWindow = windows[selector] ?? windows[canonicalExact] ?? windows[bare];
|
|
76
|
+
if (typeof authoritativeWindow === "number" && authoritativeWindow > 0) {
|
|
77
|
+
return shouldMarkOneMillion(authoritativeWindow, AUTO_CONTEXT_OFF)
|
|
78
|
+
? (withOneMillionMarker(selector, windows) ?? selector)
|
|
79
|
+
: bare;
|
|
80
|
+
}
|
|
81
|
+
return wasMarked ? selector : bare;
|
|
82
|
+
}
|
|
61
83
|
function entryParts(entry: string, config: OcxConfig): { alias: string; id: string; provider: string } {
|
|
62
84
|
const slash = entry.indexOf("/");
|
|
63
85
|
if (slash > 0) {
|
|
64
86
|
const provider = entry.slice(0, slash);
|
|
65
87
|
const prov = hasOwnProvider(config.providers, provider) ? config.providers[provider] : undefined;
|
|
66
88
|
const id = prov
|
|
67
|
-
?
|
|
89
|
+
? decodeRoutedModelIdOrThrow(entry.slice(slash + 1), knownModelIdsForProvider(provider, prov, config))
|
|
68
90
|
: entry.slice(slash + 1);
|
|
69
91
|
return { alias: claudeCodeAlias(provider, id), id, provider };
|
|
70
92
|
}
|
|
@@ -72,7 +94,6 @@ function entryParts(entry: string, config: OcxConfig): { alias: string; id: stri
|
|
|
72
94
|
}
|
|
73
95
|
|
|
74
96
|
export function buildClaudeAgentDefs(config: OcxConfig, windows: Record<string, number>, configDir = claudeConfigDir()): ClaudeAgentDef[] {
|
|
75
|
-
const auto = resolveAutoContext(config.claudeCode);
|
|
76
97
|
const blockedSkills = effectiveBlockedSkillNames(config.claudeCode);
|
|
77
98
|
const blockedSkillsFor = (model: string): readonly string[] => {
|
|
78
99
|
const unmarked = stripOneMillionMarker(model);
|
|
@@ -87,8 +108,10 @@ export function buildClaudeAgentDefs(config: OcxConfig, windows: Record<string,
|
|
|
87
108
|
const coveredModels = new Set<string>();
|
|
88
109
|
|
|
89
110
|
const push = (name: string, alias: string, description: string) => {
|
|
90
|
-
//
|
|
91
|
-
|
|
111
|
+
// Generated defs mark [1m] on the authoritative window only — never the
|
|
112
|
+
// main-session auto-context predicate (a 372K route marked [1m] would be
|
|
113
|
+
// accounted at 1M with no compaction safety net in the subagent).
|
|
114
|
+
const model = withSubagentContextMarker(alias, windows);
|
|
92
115
|
const bare = alias.toLowerCase();
|
|
93
116
|
if (coveredModels.has(bare)) return;
|
|
94
117
|
coveredModels.add(bare);
|
|
@@ -120,7 +143,7 @@ export function buildClaudeAgentDefs(config: OcxConfig, windows: Record<string,
|
|
|
120
143
|
// the next launch sync — documented limit. No resolvable default -> no self def.
|
|
121
144
|
const selfModel = pickerDefaultModel(configDir) ?? (config.claudeCode?.model?.trim() || null);
|
|
122
145
|
if (selfModel) {
|
|
123
|
-
const marked =
|
|
146
|
+
const marked = withSubagentContextMarker(selfModel, windows);
|
|
124
147
|
defs.push({
|
|
125
148
|
file: `${OWNED_PREFIX}self.md`,
|
|
126
149
|
name: `${OWNED_PREFIX}self`,
|
|
@@ -195,7 +218,14 @@ function isOwnedFile(path: string): boolean {
|
|
|
195
218
|
export function syncClaudeAgentDefs(defs: readonly ClaudeAgentDef[], configDir = claudeConfigDir()): string[] | null {
|
|
196
219
|
try {
|
|
197
220
|
const dir = join(configDir, "agents");
|
|
198
|
-
|
|
221
|
+
if (defs.length === 0) {
|
|
222
|
+
try { lstatSync(dir); } catch (error) {
|
|
223
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
mkdirSync(dir, { recursive: true });
|
|
228
|
+
}
|
|
199
229
|
const keep = new Set(defs.map(d => d.file));
|
|
200
230
|
for (const existing of readdirSync(dir)) {
|
|
201
231
|
if (!existing.startsWith(OWNED_PREFIX) || !existing.endsWith(".md")) continue;
|
|
@@ -213,7 +243,7 @@ export function syncClaudeAgentDefs(defs: readonly ClaudeAgentDef[], configDir =
|
|
|
213
243
|
} catch { /* does not exist: ours to create */ }
|
|
214
244
|
const tmp = `${target}.tmp-${process.pid}`;
|
|
215
245
|
writeFileSync(tmp, renderAgentDef(def), { encoding: "utf8", mode: 0o644 });
|
|
216
|
-
|
|
246
|
+
renameAtomicFile(tmp, target, undefined, "claude-agents");
|
|
217
247
|
written.push(def.file);
|
|
218
248
|
}
|
|
219
249
|
return written;
|
|
@@ -10,12 +10,24 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { aliasForNative, aliasForRoute } from "./alias";
|
|
12
12
|
import { desktop3pAlias } from "./desktop-3p";
|
|
13
|
-
import { nativeOpenAiContextWindow, type CatalogModel } from "../codex/catalog";
|
|
13
|
+
import { nativeOpenAiContextWindow, type CatalogModel, type NativeContextLimitsInput } from "../codex/catalog";
|
|
14
14
|
|
|
15
15
|
const ONE_MILLION = 1_000_000;
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Auto-context defaults (devlog 260712 020, user-approved).
|
|
19
|
+
*
|
|
20
|
+
* The compact window is the token count at which Claude Code starts compacting, and it is
|
|
21
|
+
* also the floor `shouldMarkOneMillion` uses — a model may only carry the marker if it can
|
|
22
|
+
* host this window. 350,000 was chosen when the widest native row advertised 372,000.
|
|
23
|
+
*
|
|
24
|
+
* It now matches the auto-compaction limit the Codex catalog ships for the same models
|
|
25
|
+
* (`nativeAutoCompactLimit`: 829,800 against the 922,000 native window). Leaving the two
|
|
26
|
+
* apart meant one model compacting at 350k under Claude Code and at 829,800 under Codex.
|
|
27
|
+
* The value stays clear of the measured 922,000 ceiling by ~92k, so compaction still has
|
|
28
|
+
* room to run before the upstream refuses.
|
|
29
|
+
*/
|
|
30
|
+
export const AUTO_COMPACT_WINDOW_DEFAULT = 829_800;
|
|
19
31
|
export const AUTO_CONTEXT_FLOOR = 200_000;
|
|
20
32
|
/** Binary-verified accepted range for CLAUDE_CODE_AUTO_COMPACT_WINDOW (2.1.207: pSo=1e5, yDs=1e6). */
|
|
21
33
|
export const AUTO_COMPACT_WINDOW_MIN = 100_000;
|
|
@@ -59,7 +71,7 @@ function inAutoCompactRange(value: number): boolean {
|
|
|
59
71
|
* predicate so marker and threshold never separate (audit 021 #2); an invalid
|
|
60
72
|
* value disables auto marking entirely (the CLI would ignore it, leaving marked
|
|
61
73
|
* sub-1M models without their safety net). Out-of-range CONFIG values fall back
|
|
62
|
-
* to
|
|
74
|
+
* to AUTO_COMPACT_WINDOW_DEFAULT (the management API rejects them; this guards hand-edits).
|
|
63
75
|
*/
|
|
64
76
|
export function resolveAutoContext(claudeCode: AutoContextConfigSlice | undefined, envOverride?: string): AutoContextMode {
|
|
65
77
|
if (claudeCode?.autoContext === false) return AUTO_CONTEXT_OFF;
|
|
@@ -89,6 +101,10 @@ export function shouldMarkOneMillion(window: number | undefined, auto: AutoConte
|
|
|
89
101
|
export function buildClaudeContextWindows(
|
|
90
102
|
nativeSlugs: readonly string[],
|
|
91
103
|
routedModels: readonly CatalogModel[],
|
|
104
|
+
// A configured providerContextCaps.openai has to reach the native rows here too. Without
|
|
105
|
+
// it the Claude surface keeps advertising the uncapped authoritative window while the
|
|
106
|
+
// Codex catalog advertises the capped one, and the two disagree about the same model.
|
|
107
|
+
nativeContextCap?: NativeContextLimitsInput,
|
|
92
108
|
): Record<string, number> {
|
|
93
109
|
const out: Record<string, number> = {};
|
|
94
110
|
const put = (key: string | null, value: number) => {
|
|
@@ -96,23 +112,30 @@ export function buildClaudeContextWindows(
|
|
|
96
112
|
if (out[key] === undefined) out[key] = value; // first-wins (registry policy)
|
|
97
113
|
};
|
|
98
114
|
for (const slug of nativeSlugs) {
|
|
99
|
-
const window = nativeOpenAiContextWindow(slug);
|
|
115
|
+
const window = nativeOpenAiContextWindow(slug, nativeContextCap);
|
|
100
116
|
if (typeof window !== "number" || window <= 0) continue;
|
|
101
117
|
put(slug, window);
|
|
102
118
|
put(desktop3pAlias("native", slug), window);
|
|
103
119
|
put(aliasForNative(slug), window);
|
|
104
120
|
}
|
|
121
|
+
// Anthropic passthrough guard (audit 021 #3): canonical claude ids ride the
|
|
122
|
+
// subscription passthrough — marking a sub-1M one would strap [1m]/1M-beta onto
|
|
123
|
+
// a model that cannot host it. Register anthropic rows only at >=1M.
|
|
124
|
+
const registrable = routedModels.filter(
|
|
125
|
+
m =>
|
|
126
|
+
typeof m.contextWindow === "number" &&
|
|
127
|
+
m.contextWindow > 0 &&
|
|
128
|
+
!(m.provider === "anthropic" && m.contextWindow < ONE_MILLION),
|
|
129
|
+
);
|
|
105
130
|
// Bare routed ids are registered only when unambiguous across providers (audit
|
|
106
|
-
// 021 #5) — natives are registered first, so a native slug always wins the bare
|
|
131
|
+
// 021 #5) — natives are registered first, so a native slug always wins the bare
|
|
132
|
+
// key. Counted over the rows that can actually claim the key: a row this loop
|
|
133
|
+
// skips contributes no window, so letting it veto the bare key withholds an
|
|
134
|
+
// answer that was never in doubt.
|
|
107
135
|
const bareCounts = new Map<string, number>();
|
|
108
|
-
for (const m of
|
|
109
|
-
for (const m of
|
|
110
|
-
const window = m.contextWindow;
|
|
111
|
-
if (typeof window !== "number" || window <= 0) continue;
|
|
112
|
-
// Anthropic passthrough guard (audit 021 #3): canonical claude ids ride the
|
|
113
|
-
// subscription passthrough — marking a sub-1M one would strap [1m]/1M-beta onto
|
|
114
|
-
// a model that cannot host it. Register anthropic rows only at >=1M.
|
|
115
|
-
if (m.provider === "anthropic" && window < ONE_MILLION) continue;
|
|
136
|
+
for (const m of registrable) bareCounts.set(m.id, (bareCounts.get(m.id) ?? 0) + 1);
|
|
137
|
+
for (const m of registrable) {
|
|
138
|
+
const window = m.contextWindow as number;
|
|
116
139
|
put(`${m.provider}/${m.id}`, window);
|
|
117
140
|
put(desktop3pAlias(m.provider, m.id), window);
|
|
118
141
|
put(aliasForRoute(m.provider, m.id), window);
|