@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
|
@@ -4,17 +4,18 @@ import { copyFileSync, existsSync, mkdirSync, readFileSync, realpathSync } from
|
|
|
4
4
|
import { delimiter, dirname, join, resolve } from "node:path";
|
|
5
5
|
import { atomicWriteFile, expandUserPath, getConfigDir, websocketsEnabled } from "../../config";
|
|
6
6
|
import { CODEX_CONFIG_PATH, CODEX_MODELS_CACHE_PATH, DEFAULT_CATALOG_PATH, readRootTomlString, resolveCodexConfigPath } from "../paths";
|
|
7
|
+
import { codexAccountNamespaceEntries, isMainCodexAccountTarget } from "../account-namespaces";
|
|
7
8
|
import { clearModelCache, DEFAULT_MODEL_CACHE_TTL_MS, getFreshCached, getStaleCached, isModelsFetchCoolingDown, markModelsFetchFailure, setCached } from "../model-cache";
|
|
8
9
|
import { buildModelsRequest, resolveModelsAuthToken } from "../../oauth";
|
|
9
10
|
import type { OcxConfig, OcxProviderConfig } from "../../types";
|
|
10
11
|
import { modelInList } from "../../types";
|
|
11
12
|
import { CODEX_REASONING_LEVELS, codexEffortRank, configuredReasoningEfforts, modelRecordValue, sanitizeCodexReasoningEfforts } from "../../reasoning-effort";
|
|
12
|
-
import {
|
|
13
|
+
import { getModelMetadata, getModelMetadataCaseInsensitive, listModelMetadata, resolveMetadataProvider } from "../../generated/model-metadata";
|
|
13
14
|
import { enrichProviderFromRegistry, shouldCaseFoldMetadataModelId } from "../../providers/derive";
|
|
14
|
-
import { getProviderRegistryEntry } from "../../providers/registry";
|
|
15
|
+
import { getProviderRegistryEntry, providerCodexAccountMode } from "../../providers/registry";
|
|
15
16
|
import { applyProviderContextCap, providerContextCap } from "../../providers/context-cap";
|
|
16
17
|
import { routedSlug, slugEquals, slugsEquivalent } from "../../providers/slug-codec";
|
|
17
|
-
import {
|
|
18
|
+
import { identifyRoutedModel } from "../../adapters/identity";
|
|
18
19
|
import { filterCursorConfiguredModelsByLiveDiscovery } from "../../adapters/cursor/discovery";
|
|
19
20
|
import { fetchCursorUsableModels } from "../../adapters/cursor/live-models";
|
|
20
21
|
import { isCanonicalOpenAiForwardProvider, OPENAI_API_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID } from "../../providers/openai-tiers";
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
COMBO_NAMESPACE,
|
|
23
24
|
comboModelId,
|
|
24
25
|
getCombo,
|
|
26
|
+
isNativeAliasCombo,
|
|
25
27
|
listComboIds,
|
|
26
28
|
targetKey,
|
|
27
29
|
} from "../../combos";
|
|
@@ -31,21 +33,68 @@ import { redactSecretString } from "../../lib/redact";
|
|
|
31
33
|
import upstreamModelsSnapshot from "../data/upstream-models.json";
|
|
32
34
|
|
|
33
35
|
|
|
34
|
-
import { filterSupportedNativeSlugs } from "./parsing";
|
|
35
36
|
import type { RawEntry } from "./parsing";
|
|
36
|
-
import { readCurrentCatalogOrCache, unique } from "./bundled";
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
import { readCurrentCatalogOrCache, readCurrentCodexCatalog, readCurrentCodexModelsCache, unique } from "./bundled";
|
|
38
|
+
import { trustedAccountBoundNativeCatalogSlug, visibleCodexAccountSelectors } from "./account-models";
|
|
39
|
+
import { CODEX_NATIVE_ALIAS_CATALOG_KIND } from "./kinds";
|
|
40
|
+
import {
|
|
41
|
+
ACCOUNT_GATED_NATIVE_OPENAI_MODELS,
|
|
42
|
+
NATIVE_DAYBREAK_BLUE_MODEL,
|
|
43
|
+
NATIVE_OPENAI_CAPABILITY_ALIAS_MODELS,
|
|
44
|
+
NATIVE_OPENAI_MODELS,
|
|
45
|
+
SUPPORTED_NATIVE_OPENAI_SLUGS,
|
|
46
|
+
isNativeOpenAiCapabilityAliasModel,
|
|
47
|
+
nativeOpenAiCapabilitySourceSlug,
|
|
48
|
+
} from "./native-models";
|
|
49
|
+
import { cachedAvailableAccountGatedNativeModels } from "../model-entitlements";
|
|
50
|
+
import { MAIN_CODEX_ACCOUNT_ID } from "../main-account";
|
|
51
|
+
export { CODEX_NATIVE_ALIAS_CATALOG_KIND } from "./kinds";
|
|
52
|
+
export {
|
|
53
|
+
NATIVE_DAYBREAK_BLUE_MODEL,
|
|
54
|
+
NATIVE_OPENAI_CAPABILITY_ALIAS_MODELS,
|
|
55
|
+
NATIVE_OPENAI_MODELS,
|
|
56
|
+
SUPPORTED_NATIVE_OPENAI_SLUGS,
|
|
57
|
+
isNativeOpenAiCapabilityAliasModel,
|
|
58
|
+
nativeOpenAiCapabilitySourceSlug,
|
|
59
|
+
} from "./native-models";
|
|
42
60
|
|
|
43
61
|
export const DOCUMENTED_NATIVE_OPENAI_ADDITIONS = [
|
|
44
62
|
"gpt-5.3-codex-spark",
|
|
45
63
|
"gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna",
|
|
46
64
|
];
|
|
47
65
|
|
|
48
|
-
export
|
|
66
|
+
export function configuredNativeAliasSlugs(
|
|
67
|
+
config: Pick<OcxConfig, "combos">,
|
|
68
|
+
): Set<string> {
|
|
69
|
+
const aliases = new Set<string>();
|
|
70
|
+
for (const raw of Object.values(config.combos ?? {})) {
|
|
71
|
+
if (!isNativeAliasCombo(raw)) continue;
|
|
72
|
+
const alias = raw.alias!.trim();
|
|
73
|
+
if (SUPPORTED_NATIVE_OPENAI_SLUGS.has(alias)) aliases.add(alias);
|
|
74
|
+
}
|
|
75
|
+
return aliases;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Bare native rows that must be absent, rather than merely hidden, while Desktop native-alias
|
|
80
|
+
* compatibility is active. Codex Desktop's remote allowlist can ignore `visibility: "hide"`;
|
|
81
|
+
* omitting disabled native rows is therefore part of the explicit native-alias opt-in.
|
|
82
|
+
*/
|
|
83
|
+
export function desktopAllowlistSuppressedNativeSlugs(
|
|
84
|
+
config: Pick<OcxConfig, "combos" | "disabledModels">,
|
|
85
|
+
): Set<string> {
|
|
86
|
+
const suppressed = configuredNativeAliasSlugs(config);
|
|
87
|
+
if (suppressed.size === 0) return suppressed;
|
|
88
|
+
const disabled = disabledNativeSlugs(config);
|
|
89
|
+
for (const slug of NATIVE_OPENAI_MODELS) {
|
|
90
|
+
if (disabled.has(slug)) suppressed.add(slug);
|
|
91
|
+
}
|
|
92
|
+
return suppressed;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function isNativeAliasCatalogEntry(entry: RawEntry): boolean {
|
|
96
|
+
return entry.opencodex_catalog_kind === CODEX_NATIVE_ALIAS_CATALOG_KIND;
|
|
97
|
+
}
|
|
49
98
|
|
|
50
99
|
export function isUnsupportedOpenAiNativeSlug(slug: string): boolean {
|
|
51
100
|
if (slug.includes("/")) return false;
|
|
@@ -53,26 +102,183 @@ export function isUnsupportedOpenAiNativeSlug(slug: string): boolean {
|
|
|
53
102
|
return /^(?:gpt|codex)-/.test(slug);
|
|
54
103
|
}
|
|
55
104
|
|
|
56
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Advertised context for the Codex-login native GPT-5.6 family.
|
|
107
|
+
*
|
|
108
|
+
* This is an OPERATING CAP, not the hard ceiling — the same shape upstream uses. The live
|
|
109
|
+
* catalog reports `context_window: 272000` against a `max_context_window: 872000` for these
|
|
110
|
+
* slugs, and gpt-5.4 runs 272,000 against 1,000,000: the advertised window is always well
|
|
111
|
+
* inside what the model can take.
|
|
112
|
+
*
|
|
113
|
+
* The hard ceiling here was measured on 2026-08-17 against a real Codex-login account:
|
|
114
|
+
* `POST /backend-api/codex/responses` admitted 921,508 input tokens and refused 922,013 with
|
|
115
|
+
* `error.code: context_length_exceeded` on sol, terra and luna alike.
|
|
116
|
+
*
|
|
117
|
+
* Codex spends `context_window * effective_context_window_percent`, which defaults to 95%
|
|
118
|
+
* (codex-rs `openai_models.rs` / `turn_context.rs`). So this value yields a 875,900-token
|
|
119
|
+
* budget and leaves ~46k of headroom under the measured ceiling. An earlier release shipped
|
|
120
|
+
* 1,050,000 here, which spent 997,500 — past what the upstream accepts.
|
|
121
|
+
*
|
|
122
|
+
* Do NOT back-solve this from the ceiling (970,000 would land the budget at 921,500, inside
|
|
123
|
+
* the 1,840-token gap between the last success and the first refusal). The 95% is a safety
|
|
124
|
+
* margin to keep, not a discount to cancel out.
|
|
125
|
+
*
|
|
126
|
+
* Evidence: devlog/_plan/260817_native_gpt56_1m_context/001_measurement_evidence.md
|
|
127
|
+
* and 014_final_922k_with_margin.md.
|
|
128
|
+
*/
|
|
129
|
+
export const NATIVE_GPT56_CONTEXT_WINDOW = 272_000;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Hard ceiling: the largest input the native GPT-5.6 family actually accepts (measured).
|
|
133
|
+
*
|
|
134
|
+
* Equal to the advertised window above rather than below it, because that window is already
|
|
135
|
+
* capped under this ceiling. The clamp stays because routed and API-key rows carry the same
|
|
136
|
+
* family at a 1,050,000 window, where 90% (945,000) WOULD overshoot this limit.
|
|
137
|
+
*/
|
|
138
|
+
export const NATIVE_GPT56_MAX_INPUT_TOKENS = 922_000;
|
|
139
|
+
|
|
140
|
+
/** User-facing 1M opt-in: the largest window the native 5.6 family may advertise. */
|
|
141
|
+
export const NATIVE_GPT56_OPT_IN_CONTEXT_WINDOW = NATIVE_GPT56_MAX_INPUT_TOKENS;
|
|
142
|
+
|
|
143
|
+
const NATIVE_GPT56_FAMILY = new Set<string>([
|
|
144
|
+
"gpt-5.6-sol",
|
|
145
|
+
"gpt-5.6-terra",
|
|
146
|
+
"gpt-5.6-luna",
|
|
147
|
+
NATIVE_DAYBREAK_BLUE_MODEL,
|
|
148
|
+
]);
|
|
57
149
|
|
|
58
|
-
export const NATIVE_OPENAI_CONTEXT_OVERRIDES: Record<string, { contextWindow?: number; maxContextWindow?: number }> = {
|
|
150
|
+
export const NATIVE_OPENAI_CONTEXT_OVERRIDES: Record<string, { contextWindow?: number; maxContextWindow?: number; maxInputTokens?: number }> = {
|
|
59
151
|
"gpt-5.5": { contextWindow: 272_000, maxContextWindow: 272_000 },
|
|
60
152
|
"gpt-5.4": { contextWindow: 1_000_000, maxContextWindow: 1_000_000 },
|
|
61
153
|
"gpt-5.3-codex-spark": { contextWindow: 100_000, maxContextWindow: 100_000 },
|
|
62
|
-
"gpt-5.6-sol": { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow:
|
|
63
|
-
"gpt-5.6-terra": { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow:
|
|
64
|
-
"gpt-5.6-luna": { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow:
|
|
154
|
+
"gpt-5.6-sol": { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow: NATIVE_GPT56_MAX_INPUT_TOKENS, maxInputTokens: NATIVE_GPT56_MAX_INPUT_TOKENS },
|
|
155
|
+
"gpt-5.6-terra": { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow: NATIVE_GPT56_MAX_INPUT_TOKENS, maxInputTokens: NATIVE_GPT56_MAX_INPUT_TOKENS },
|
|
156
|
+
"gpt-5.6-luna": { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow: NATIVE_GPT56_MAX_INPUT_TOKENS, maxInputTokens: NATIVE_GPT56_MAX_INPUT_TOKENS },
|
|
157
|
+
// Daybreak Blue borrows Sol's capability metadata and rides the same family contract.
|
|
158
|
+
// Unlike sol/terra/luna its window was NOT measured here: this account cannot reach it
|
|
159
|
+
// (`400 "The 'gpt-daybreak-blue-latest' model is not supported when using Codex with a
|
|
160
|
+
// ChatGPT account."`), so the promotion rests on a report from an account that has
|
|
161
|
+
// access rather than on a probe. Treat it as the weaker evidence of the four.
|
|
162
|
+
[NATIVE_DAYBREAK_BLUE_MODEL]: { contextWindow: NATIVE_GPT56_CONTEXT_WINDOW, maxContextWindow: NATIVE_GPT56_MAX_INPUT_TOKENS, maxInputTokens: NATIVE_GPT56_MAX_INPUT_TOKENS },
|
|
65
163
|
};
|
|
66
164
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
165
|
+
const PINNED_UPSTREAM_MODELS: Map<string, RawEntry> = new Map(
|
|
166
|
+
((upstreamModelsSnapshot as unknown as { models?: RawEntry[] }).models ?? [])
|
|
167
|
+
.flatMap(model => typeof model.slug === "string" ? [[model.slug, model] as const] : []),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
function pinnedNativeCapabilityEntry(slug: string): RawEntry | undefined {
|
|
171
|
+
return PINNED_UPSTREAM_MODELS.get(nativeOpenAiCapabilitySourceSlug(slug));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Pinned capability metadata is safe to use as a fallback for every supported native model.
|
|
176
|
+
* Keep it separate from UPSTREAM_NATIVE_ENTRIES: that narrower map also authorizes replacing
|
|
177
|
+
* persisted native rows during sync, which is currently intentional only for the GPT-5.6 family.
|
|
178
|
+
*/
|
|
179
|
+
const PINNED_NATIVE_CAPABILITY_ENTRIES: Map<string, RawEntry> = new Map(
|
|
180
|
+
[...NATIVE_OPENAI_MODELS, ...NATIVE_OPENAI_CAPABILITY_ALIAS_MODELS].flatMap(slug => {
|
|
181
|
+
const entry = pinnedNativeCapabilityEntry(slug);
|
|
182
|
+
return entry ? [[slug, entry] as const] : [];
|
|
183
|
+
}),
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The user-owned levers that set a native window, carried together.
|
|
188
|
+
*
|
|
189
|
+
* For the GPT-5.6 family these may raise the Codex 272k default up to the measured
|
|
190
|
+
* 922k ceiling. Other native slugs still only ever lower.
|
|
191
|
+
*
|
|
192
|
+
* This travels as an ARGUMENT rather than module state on purpose. `grok/sync.ts` runs in
|
|
193
|
+
* the `ocx ensure` parent process, outside the server, so an injected global would never
|
|
194
|
+
* reach it — that failure is recorded in
|
|
195
|
+
* devlog/_plan/260817_native_gpt56_1m_context/006_root_cause_replan.md. Every call site
|
|
196
|
+
* already holds a config or a cap, so passing one more field costs nothing.
|
|
197
|
+
*
|
|
198
|
+
* A bare number is still accepted for the many call sites that only know the cap.
|
|
199
|
+
*/
|
|
200
|
+
export interface NativeContextLimits {
|
|
201
|
+
/** `providerContextCaps.openai` */
|
|
202
|
+
readonly cap?: number;
|
|
203
|
+
/** `providers.openai.contextWindow` — a floor-wide user override. */
|
|
204
|
+
readonly providerWindow?: number;
|
|
205
|
+
/** `providers.openai.modelContextWindows` — per-model, wins over `providerWindow`. */
|
|
206
|
+
readonly modelWindows?: Readonly<Record<string, number>>;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export type NativeContextLimitsInput = NativeContextLimits | number | undefined;
|
|
210
|
+
|
|
211
|
+
function positiveInt(value: unknown): number | undefined {
|
|
212
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function asLimits(input: NativeContextLimitsInput): NativeContextLimits {
|
|
216
|
+
if (input === undefined) return {};
|
|
217
|
+
return typeof input === "number" ? { cap: input } : input;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Read both levers out of a config once, for call sites that hold one. */
|
|
221
|
+
export function nativeContextLimits(
|
|
222
|
+
config: Pick<OcxConfig, "providers" | "providerContextCaps">,
|
|
223
|
+
): NativeContextLimits {
|
|
224
|
+
const provider = config.providers?.[OPENAI_CODEX_PROVIDER_ID];
|
|
225
|
+
const modelWindows: Record<string, number> = {};
|
|
226
|
+
for (const [slug, value] of Object.entries(provider?.modelContextWindows ?? {})) {
|
|
227
|
+
const window = positiveInt(value);
|
|
228
|
+
if (window !== undefined) modelWindows[slug] = window;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
...(positiveInt(providerContextCap(config, OPENAI_CODEX_PROVIDER_ID)) !== undefined
|
|
232
|
+
? { cap: providerContextCap(config, OPENAI_CODEX_PROVIDER_ID) }
|
|
233
|
+
: {}),
|
|
234
|
+
...(positiveInt(provider?.contextWindow) !== undefined ? { providerWindow: provider!.contextWindow } : {}),
|
|
235
|
+
...(Object.keys(modelWindows).length > 0 ? { modelWindows } : {}),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Apply the user levers to an authoritative value. */
|
|
240
|
+
function narrowToLimits(raw: number | undefined, slug: string, input: NativeContextLimitsInput): number | undefined {
|
|
241
|
+
if (raw === undefined) return undefined;
|
|
242
|
+
const limits = asLimits(input);
|
|
243
|
+
const overlay = positiveInt(limits.modelWindows?.[slug]) ?? positiveInt(limits.providerWindow);
|
|
244
|
+
const cap = positiveInt(limits.cap);
|
|
245
|
+
if (NATIVE_GPT56_FAMILY.has(slug)) {
|
|
246
|
+
const ceiling = NATIVE_GPT56_MAX_INPUT_TOKENS;
|
|
247
|
+
const chosen = overlay ?? cap ?? raw;
|
|
248
|
+
const window = Math.min(chosen, ceiling);
|
|
249
|
+
return overlay !== undefined && cap !== undefined ? Math.min(window, cap) : window;
|
|
250
|
+
}
|
|
251
|
+
const narrowed = overlay === undefined ? raw : Math.min(raw, overlay);
|
|
252
|
+
// 922k is the GPT-5.6 1M opt-in, not a request to shrink gpt-5.4's 1M window.
|
|
253
|
+
if (cap === NATIVE_GPT56_MAX_INPUT_TOKENS) return narrowed;
|
|
254
|
+
return applyProviderContextCap(narrowed, cap) ?? narrowed;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function nativeOpenAiContextWindow(slug: string, limits?: NativeContextLimitsInput): number | undefined {
|
|
258
|
+
const raw = NATIVE_OPENAI_CONTEXT_OVERRIDES[slug]?.contextWindow
|
|
259
|
+
?? (typeof PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug)?.context_window === "number"
|
|
260
|
+
? PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug)!.context_window as number
|
|
71
261
|
: undefined);
|
|
262
|
+
return narrowToLimits(raw, slug, limits);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Largest input a native slug accepts, or undefined when no separate limit is known
|
|
267
|
+
* (the caller then falls back to the context window).
|
|
268
|
+
*
|
|
269
|
+
* A provider context cap lowers this too: a capped 272k window must not keep advertising a
|
|
270
|
+
* 922k input ceiling, or the cap would be cosmetic on every input-side surface.
|
|
271
|
+
*/
|
|
272
|
+
export function nativeOpenAiMaxInputTokens(slug: string, limits?: NativeContextLimitsInput): number | undefined {
|
|
273
|
+
const raw = NATIVE_OPENAI_CONTEXT_OVERRIDES[slug]?.maxInputTokens;
|
|
274
|
+
if (raw === undefined) return undefined;
|
|
275
|
+
const window = nativeOpenAiContextWindow(slug, limits);
|
|
276
|
+
const narrowed = narrowToLimits(raw, slug, limits) ?? raw;
|
|
277
|
+
return window === undefined ? narrowed : Math.min(narrowed, window);
|
|
72
278
|
}
|
|
73
279
|
|
|
74
280
|
export function nativeInputModalities(slug: string): string[] {
|
|
75
|
-
const upstream =
|
|
281
|
+
const upstream = PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug);
|
|
76
282
|
if (Array.isArray(upstream?.input_modalities) && upstream!.input_modalities!.length > 0) {
|
|
77
283
|
return [...upstream!.input_modalities as string[]];
|
|
78
284
|
}
|
|
@@ -82,7 +288,7 @@ export function nativeInputModalities(slug: string): string[] {
|
|
|
82
288
|
}
|
|
83
289
|
|
|
84
290
|
export function nativeReasoningEfforts(slug: string): string[] {
|
|
85
|
-
const upstream =
|
|
291
|
+
const upstream = PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug);
|
|
86
292
|
const levels = Array.isArray(upstream?.supported_reasoning_levels)
|
|
87
293
|
? upstream!.supported_reasoning_levels as Array<{ effort?: string }>
|
|
88
294
|
: [];
|
|
@@ -97,12 +303,18 @@ export function nativeReasoningEfforts(slug: string): string[] {
|
|
|
97
303
|
|
|
98
304
|
/** Upstream-pinned default for a native slug, when present and non-empty. */
|
|
99
305
|
export function nativeDefaultReasoningEffort(slug: string): string | undefined {
|
|
100
|
-
const level =
|
|
306
|
+
const level = PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug)?.default_reasoning_level;
|
|
101
307
|
return typeof level === "string" && level.length > 0 ? level : undefined;
|
|
102
308
|
}
|
|
103
309
|
|
|
310
|
+
/** Upstream-pinned multi-agent surface for a supported native slug, when present. */
|
|
311
|
+
export function nativeMultiAgentVersion(slug: string): string | undefined {
|
|
312
|
+
const version = PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug)?.multi_agent_version;
|
|
313
|
+
return typeof version === "string" && version.length > 0 ? version : undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
104
316
|
export function nativeParallelToolCalls(slug: string): boolean {
|
|
105
|
-
return
|
|
317
|
+
return PINNED_NATIVE_CAPABILITY_ENTRIES.get(slug)?.supports_parallel_tool_calls === true
|
|
106
318
|
|| false;
|
|
107
319
|
}
|
|
108
320
|
|
|
@@ -116,40 +328,145 @@ export function disabledNativeSlugs(config: Pick<OcxConfig, "disabledModels">):
|
|
|
116
328
|
return new Set((config.disabledModels ?? []).filter(id => !id.includes("/")));
|
|
117
329
|
}
|
|
118
330
|
|
|
119
|
-
export function visibleNativeSlugs(config: Pick<OcxConfig, "disabledModels">): string[] {
|
|
331
|
+
export function visibleNativeSlugs(config: Pick<OcxConfig, "disabledModels" | "combos">): string[] {
|
|
120
332
|
const disabled = disabledNativeSlugs(config);
|
|
121
|
-
|
|
333
|
+
const shadowed = configuredNativeAliasSlugs(config);
|
|
334
|
+
return nativeOpenAiSlugs().filter(slug => !disabled.has(slug) && !shadowed.has(slug));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** Whether an enabled canonical OpenAI provider can serve exact account-qualified routes. */
|
|
338
|
+
export function shouldIncludeAccountBoundNativeOpenAi(
|
|
339
|
+
config: Pick<OcxConfig, "providers">,
|
|
340
|
+
): boolean {
|
|
341
|
+
const provider = config.providers[OPENAI_CODEX_PROVIDER_ID];
|
|
342
|
+
if (!provider || provider.disabled === true) return false;
|
|
343
|
+
// Registry routing defaults an omitted authMode on the built-in OpenAI row to forward.
|
|
344
|
+
const canonical = provider.authMode === undefined
|
|
345
|
+
? { ...provider, authMode: "forward" as const }
|
|
346
|
+
: provider;
|
|
347
|
+
return isCanonicalOpenAiForwardProvider(canonical);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Whether native ChatGPT/Codex rows belong in this provider configuration. */
|
|
351
|
+
export function shouldIncludeNativeOpenAi(config: Pick<OcxConfig, "providers">): boolean {
|
|
352
|
+
const hasEnabledProvider = Object.values(config.providers)
|
|
353
|
+
.some(provider => provider.disabled !== true);
|
|
354
|
+
// Preserve the existing no-enabled-provider catalog bootstrap, but do not use that bootstrap
|
|
355
|
+
// exception for account-qualified rows: exact-account routing requires a live OpenAI provider.
|
|
356
|
+
return !hasEnabledProvider || shouldIncludeAccountBoundNativeOpenAi(config);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
type AccountSelectorConfig = Pick<
|
|
360
|
+
OcxConfig,
|
|
361
|
+
"codexAccounts" | "codexAccountNamespaces" | "codexAccountPickerEnabled"
|
|
362
|
+
>;
|
|
363
|
+
|
|
364
|
+
function mainAccountSelectors(config: AccountSelectorConfig): string[] {
|
|
365
|
+
const targets = new Map(codexAccountNamespaceEntries(config));
|
|
366
|
+
return visibleCodexAccountSelectors(config).filter(selector =>
|
|
367
|
+
isMainCodexAccountTarget(targets.get(selector) ?? ""));
|
|
122
368
|
}
|
|
123
369
|
|
|
124
370
|
/** Native slugs exposed to Claude Desktop show/export/apply (opt-out via claudeCode.desktopNativeModels). */
|
|
125
|
-
export function desktopVisibleNativeSlugs(
|
|
371
|
+
export function desktopVisibleNativeSlugs(
|
|
372
|
+
config: Pick<OcxConfig, "claudeCode" | "disabledModels" | "combos" | "providers"
|
|
373
|
+
| "codexAccounts" | "codexAccountNamespaces" | "codexAccountPickerEnabled">,
|
|
374
|
+
): string[] {
|
|
126
375
|
if (config.claudeCode?.desktopNativeModels === false) return [];
|
|
127
|
-
|
|
376
|
+
const visible = visibleNativeSlugs(config);
|
|
377
|
+
if (!shouldIncludeAccountBoundNativeOpenAi(config)) return visible;
|
|
378
|
+
const qualified = [...accountBoundNativeOpenAiSlugsBySelector(config).entries()].flatMap(([selector, slugs]) =>
|
|
379
|
+
slugs
|
|
380
|
+
.filter(slug => !SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug))
|
|
381
|
+
.map(slug => `${selector}/${slug}`),
|
|
382
|
+
);
|
|
383
|
+
const disabled = new Set(config.disabledModels ?? []);
|
|
384
|
+
return unique([
|
|
385
|
+
...visible,
|
|
386
|
+
...qualified.filter(slug => !disabled.has(slug) && !disabled.has(slug.slice(slug.indexOf("/") + 1))),
|
|
387
|
+
]);
|
|
128
388
|
}
|
|
129
389
|
|
|
130
|
-
export function nativeModelRows(config: Pick<OcxConfig, "disabledModels">): Array<{ slug: string; disabled: boolean; contextWindow?: number }> {
|
|
390
|
+
export function nativeModelRows(config: Pick<OcxConfig, "disabledModels" | "combos" | "providerContextCaps" | "providers">): Array<{ slug: string; disabled: boolean; contextWindow?: number; maxInputTokens?: number }> {
|
|
131
391
|
const disabled = disabledNativeSlugs(config);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
392
|
+
const shadowed = configuredNativeAliasSlugs(config);
|
|
393
|
+
// Both user levers, not just the cap: a per-model window set from the dashboard has to show
|
|
394
|
+
// up on the row the dashboard itself renders.
|
|
395
|
+
const limits = nativeContextLimits(config);
|
|
396
|
+
const bareEligibleAccountIds = providerCodexAccountMode(
|
|
397
|
+
OPENAI_CODEX_PROVIDER_ID,
|
|
398
|
+
config.providers?.[OPENAI_CODEX_PROVIDER_ID],
|
|
399
|
+
) === "direct" ? new Set([MAIN_CODEX_ACCOUNT_ID]) : undefined;
|
|
400
|
+
const availableGated = cachedAvailableAccountGatedNativeModels(Date.now(), bareEligibleAccountIds);
|
|
401
|
+
return NATIVE_OPENAI_MODELS
|
|
402
|
+
.filter(slug => !ACCOUNT_GATED_NATIVE_OPENAI_MODELS.has(slug) || availableGated.has(slug))
|
|
403
|
+
.filter(slug => !shadowed.has(slug)).map(slug => {
|
|
404
|
+
const contextWindow = nativeOpenAiContextWindow(slug, limits);
|
|
405
|
+
const maxInputTokens = nativeOpenAiMaxInputTokens(slug, limits);
|
|
406
|
+
return {
|
|
407
|
+
slug,
|
|
408
|
+
disabled: disabled.has(slug),
|
|
409
|
+
...(contextWindow !== undefined ? { contextWindow } : {}),
|
|
410
|
+
...(maxInputTokens !== undefined ? { maxInputTokens } : {}),
|
|
411
|
+
};
|
|
135
412
|
});
|
|
136
413
|
}
|
|
137
414
|
|
|
138
|
-
export function applyNativeVisibility(
|
|
415
|
+
export function applyNativeVisibility(
|
|
416
|
+
entries: RawEntry[],
|
|
417
|
+
disabledModels: ReadonlySet<string>,
|
|
418
|
+
hideBareNative = false,
|
|
419
|
+
observedNativeSlugs: ReadonlySet<string> = new Set(),
|
|
420
|
+
): RawEntry[] {
|
|
139
421
|
for (const entry of entries) {
|
|
422
|
+
if (isNativeAliasCatalogEntry(entry)) continue;
|
|
140
423
|
const slug = typeof entry.slug === "string" ? entry.slug : "";
|
|
141
|
-
|
|
142
|
-
|
|
424
|
+
const accountBoundSlug = trustedAccountBoundNativeCatalogSlug(entry);
|
|
425
|
+
const nativeSlug = accountBoundSlug ?? slug;
|
|
426
|
+
if (!nativeSlug
|
|
427
|
+
|| (!accountBoundSlug && slug.includes("/"))
|
|
428
|
+
|| (!SUPPORTED_NATIVE_OPENAI_SLUGS.has(nativeSlug) && !observedNativeSlugs.has(nativeSlug))) continue;
|
|
429
|
+
const disabled = disabledModels.has(nativeSlug)
|
|
430
|
+
|| (accountBoundSlug !== undefined && disabledModels.has(slug));
|
|
431
|
+
entry.visibility = disabled || (!accountBoundSlug && hideBareNative)
|
|
432
|
+
? "hide"
|
|
433
|
+
: "list";
|
|
143
434
|
}
|
|
144
435
|
return entries;
|
|
145
436
|
}
|
|
146
437
|
|
|
438
|
+
function upstreamNativeEntryForSlug(slug: string): RawEntry | undefined {
|
|
439
|
+
const sourceSlug = nativeOpenAiCapabilitySourceSlug(slug);
|
|
440
|
+
if (!sourceSlug.startsWith("gpt-5.6-")) return undefined;
|
|
441
|
+
const source = PINNED_UPSTREAM_MODELS.get(sourceSlug);
|
|
442
|
+
if (!source) return undefined;
|
|
443
|
+
if (slug === sourceSlug) return source;
|
|
444
|
+
|
|
445
|
+
const alias = structuredClone(source) as RawEntry;
|
|
446
|
+
alias.slug = slug;
|
|
447
|
+
alias.display_name = "Daybreak Blue";
|
|
448
|
+
alias.description = "Frontier general-purpose model with safeguards for defensive cybersecurity work.";
|
|
449
|
+
if (typeof alias.base_instructions === "string") {
|
|
450
|
+
alias.base_instructions = identifyRoutedModel(alias.base_instructions, slug);
|
|
451
|
+
}
|
|
452
|
+
if (alias.model_messages && typeof alias.model_messages === "object" && !Array.isArray(alias.model_messages)) {
|
|
453
|
+
const modelMessages = alias.model_messages as Record<string, unknown>;
|
|
454
|
+
if (typeof modelMessages.instructions_template === "string") {
|
|
455
|
+
alias.model_messages = {
|
|
456
|
+
...modelMessages,
|
|
457
|
+
instructions_template: identifyRoutedModel(modelMessages.instructions_template, slug),
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
delete alias.availability_nux;
|
|
462
|
+
return alias;
|
|
463
|
+
}
|
|
464
|
+
|
|
147
465
|
export const UPSTREAM_NATIVE_ENTRIES: Map<string, RawEntry> = new Map(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
.map(m => [m.slug as string, m]),
|
|
466
|
+
[...NATIVE_OPENAI_MODELS, ...NATIVE_OPENAI_CAPABILITY_ALIAS_MODELS].flatMap(slug => {
|
|
467
|
+
const entry = upstreamNativeEntryForSlug(slug);
|
|
468
|
+
return entry ? [[slug, entry] as const] : [];
|
|
469
|
+
}),
|
|
153
470
|
);
|
|
154
471
|
|
|
155
472
|
export function upstreamNativeEntry(slug: string): RawEntry | null {
|
|
@@ -167,14 +484,181 @@ export function shouldUpgradeToUpstreamEntry(entry: RawEntry): boolean {
|
|
|
167
484
|
}
|
|
168
485
|
|
|
169
486
|
export function nativeOpenAiSlugs(): string[] {
|
|
170
|
-
const live =
|
|
171
|
-
|
|
487
|
+
const live = catalogNativeSlugs();
|
|
488
|
+
const availableGated = cachedAvailableAccountGatedNativeModels();
|
|
489
|
+
const candidates = live.length > 0 ? unique([...live, ...DOCUMENTED_NATIVE_OPENAI_ADDITIONS]) : NATIVE_OPENAI_MODELS;
|
|
490
|
+
return candidates.filter(slug => (
|
|
491
|
+
!ACCOUNT_GATED_NATIVE_OPENAI_MODELS.has(slug) || availableGated.has(slug)
|
|
492
|
+
));
|
|
172
493
|
}
|
|
173
494
|
|
|
174
|
-
|
|
495
|
+
const ACCOUNT_BOUND_OPENAI_NATIVE_PREFIX = /^(?:gpt-|o1-|o3-|o4-)/;
|
|
496
|
+
const ACCOUNT_BOUND_OBSERVED_NATIVE_MARKER = "opencodex_account_observed_native";
|
|
497
|
+
const ACCOUNT_BOUND_OBSERVED_SELECTORS_MARKER = "opencodex_account_observed_selectors";
|
|
498
|
+
|
|
499
|
+
function isAccountBoundOpenAiNativeSlug(slug: string): boolean {
|
|
500
|
+
return !slug.includes("/") && ACCOUNT_BOUND_OPENAI_NATIVE_PREFIX.test(slug);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Shape/plausibility filter for a candidate account-native row. **This is not a trust control.**
|
|
505
|
+
*
|
|
506
|
+
* It checks that a row carries the field shape a real Codex catalog row has, which rejects
|
|
507
|
+
* malformed and minimal hand-written rows. It cannot distinguish a genuine upstream observation
|
|
508
|
+
* from a complete row typed by hand into `$CODEX_HOME/models_cache.json`: there is no signature,
|
|
509
|
+
* source identity, or server attestation to check. A full-shape forged row is accepted, and
|
|
510
|
+
* `observedFullShapeRowIsAccepted` in tests/native-model-toggle.test.ts pins that so nobody
|
|
511
|
+
* later mistakes this predicate for a security boundary.
|
|
512
|
+
*
|
|
513
|
+
* That is acceptable here because the file is user-owned and written by Codex itself: anyone
|
|
514
|
+
* able to rewrite it can already edit `config.json` or run `ocx` directly, and `router.ts`
|
|
515
|
+
* accepts any bare `gpt-*` id under an account namespace regardless of this catalog. What the
|
|
516
|
+
* filter buys is that garbage rows do not get advertised through discovery — not that an
|
|
517
|
+
* advertised row is proven genuine.
|
|
518
|
+
*/
|
|
519
|
+
function hasNativeCatalogRowShape(entry: RawEntry): boolean {
|
|
520
|
+
const levels = entry.supported_reasoning_levels;
|
|
521
|
+
const messages = entry.model_messages;
|
|
522
|
+
return typeof entry.base_instructions === "string"
|
|
523
|
+
&& entry.base_instructions.length > 0
|
|
524
|
+
&& (typeof entry.comp_hash === "string" || entry.comp_hash === null)
|
|
525
|
+
&& entry.shell_type === "shell_command"
|
|
526
|
+
&& Array.isArray(levels)
|
|
527
|
+
&& levels.length > 0
|
|
528
|
+
&& levels.every(level => typeof level === "object" && level !== null
|
|
529
|
+
&& typeof (level as { effort?: unknown }).effort === "string")
|
|
530
|
+
&& typeof messages === "object"
|
|
531
|
+
&& messages !== null
|
|
532
|
+
&& !Array.isArray(messages);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function observedAccountBoundNativeSlug(entry: RawEntry): string | undefined {
|
|
536
|
+
const accountBound = trustedAccountBoundNativeCatalogSlug(entry);
|
|
537
|
+
const slug = accountBound ?? (typeof entry.slug === "string" ? entry.slug : "");
|
|
538
|
+
if (!isAccountBoundOpenAiNativeSlug(slug)
|
|
539
|
+
|| entry.supported_in_api !== true
|
|
540
|
+
|| !hasNativeCatalogRowShape(entry)
|
|
541
|
+
|| (entry.visibility !== "list" && entry[ACCOUNT_BOUND_OBSERVED_NATIVE_MARKER] !== true)) {
|
|
542
|
+
return undefined;
|
|
543
|
+
}
|
|
544
|
+
return slug;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Return exact, previously observed account-native rows that are not in the static release set.
|
|
549
|
+
* The result is used only to carry a hidden observation across startup cache invalidation.
|
|
550
|
+
*/
|
|
551
|
+
export function observedAccountBoundNativeEntries(
|
|
552
|
+
observedEntries: readonly RawEntry[],
|
|
553
|
+
): RawEntry[] {
|
|
554
|
+
const seen = new Set<string>();
|
|
555
|
+
return observedEntries.flatMap(entry => {
|
|
556
|
+
const slug = observedAccountBoundNativeSlug(entry);
|
|
557
|
+
// Only carry bare upstream observations across cache replacement. Account-qualified rows are
|
|
558
|
+
// already a projection of the current selector map and must not preserve private/stale labels.
|
|
559
|
+
if (!slug
|
|
560
|
+
|| typeof entry.slug !== "string"
|
|
561
|
+
|| entry.slug.includes("/")
|
|
562
|
+
|| SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug)
|
|
563
|
+
|| seen.has(slug)) return [];
|
|
564
|
+
seen.add(slug);
|
|
565
|
+
return [structuredClone(entry)];
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Native ids observed in the user's Codex catalog/cache for account-qualified discovery.
|
|
571
|
+
*
|
|
572
|
+
* Unknown ids are deliberately returned only to callers that build selector-qualified rows. The
|
|
573
|
+
* static bare set remains the source of truth for global/API-key discovery, while this preserves
|
|
574
|
+
* exact account-scoped ids such as `gpt-daybreak-blue-latest` until the static set catches up.
|
|
575
|
+
*/
|
|
576
|
+
export function accountBoundNativeOpenAiSlugs(
|
|
577
|
+
observedEntries: readonly RawEntry[] = [
|
|
578
|
+
...(readCurrentCodexModelsCache()?.models ?? []),
|
|
579
|
+
// Existing generated rows are also safe to reuse after a process starts without a cache
|
|
580
|
+
// invalidation pass; bare user-authored catalog rows are intentionally not trusted here.
|
|
581
|
+
...(readCurrentCodexCatalog()?.models ?? []).filter(entry =>
|
|
582
|
+
trustedAccountBoundNativeCatalogSlug(entry) !== undefined),
|
|
583
|
+
],
|
|
584
|
+
): string[] {
|
|
585
|
+
const observed = observedEntries.flatMap(entry => {
|
|
586
|
+
const slug = observedAccountBoundNativeSlug(entry);
|
|
587
|
+
return slug === undefined ? [] : [slug];
|
|
588
|
+
});
|
|
589
|
+
return unique([...NATIVE_OPENAI_MODELS, ...observed]);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Resolve account-native ids per public selector. Bare observations come from Codex's main
|
|
594
|
+
* catalog/cache, so they are eligible only for selectors that target the main account. A
|
|
595
|
+
* generated qualified row carries its own selector and never gets copied to an unrelated pool
|
|
596
|
+
* account. An explicit observation marker is public selector metadata only; private account ids
|
|
597
|
+
* never enter the catalog or cache.
|
|
598
|
+
*/
|
|
599
|
+
export function accountBoundNativeOpenAiSlugsBySelector(
|
|
600
|
+
config: AccountSelectorConfig,
|
|
601
|
+
observedEntries: readonly RawEntry[] = [
|
|
602
|
+
...(readCurrentCodexModelsCache()?.models ?? []),
|
|
603
|
+
...(readCurrentCodexCatalog()?.models ?? []).filter(entry =>
|
|
604
|
+
trustedAccountBoundNativeCatalogSlug(entry) !== undefined),
|
|
605
|
+
],
|
|
606
|
+
): ReadonlyMap<string, readonly string[]> {
|
|
607
|
+
const selectors = visibleCodexAccountSelectors(config);
|
|
608
|
+
const mainSelectors = new Set(mainAccountSelectors(config));
|
|
609
|
+
const result = new Map<string, Set<string>>(
|
|
610
|
+
selectors.map(selector => [selector, new Set(NATIVE_OPENAI_MODELS)]),
|
|
611
|
+
);
|
|
612
|
+
for (const entry of observedEntries) {
|
|
613
|
+
const slug = observedAccountBoundNativeSlug(entry);
|
|
614
|
+
if (slug === undefined || SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug)) continue;
|
|
615
|
+
const generated = trustedAccountBoundNativeCatalogSlug(entry);
|
|
616
|
+
const generatedSelector = generated === undefined || typeof entry.slug !== "string"
|
|
617
|
+
? undefined
|
|
618
|
+
: entry.slug.slice(0, entry.slug.indexOf("/"));
|
|
619
|
+
const markedSelectors = Array.isArray(entry[ACCOUNT_BOUND_OBSERVED_SELECTORS_MARKER])
|
|
620
|
+
? entry[ACCOUNT_BOUND_OBSERVED_SELECTORS_MARKER].filter((value): value is string => typeof value === "string")
|
|
621
|
+
: [];
|
|
622
|
+
const eligible = generatedSelector !== undefined
|
|
623
|
+
? (mainSelectors.has(generatedSelector) ? [generatedSelector] : [])
|
|
624
|
+
: markedSelectors.length > 0
|
|
625
|
+
? markedSelectors.filter(selector => mainSelectors.has(selector))
|
|
626
|
+
: [...mainSelectors];
|
|
627
|
+
for (const selector of eligible) {
|
|
628
|
+
const rows = result.get(selector);
|
|
629
|
+
if (rows) rows.add(slug);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return new Map([...result.entries()].map(([selector, slugs]) => [selector, [...slugs]]));
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/** Unknown native ids observed from Codex, excluding the static release set. */
|
|
636
|
+
export function observedAccountBoundNativeOpenAiSlugs(
|
|
637
|
+
observedEntries?: readonly RawEntry[],
|
|
638
|
+
): string[] {
|
|
639
|
+
const all = accountBoundNativeOpenAiSlugs(observedEntries);
|
|
640
|
+
return all.filter(slug => !SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug));
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
function catalogNativeSlugs(): string[] {
|
|
175
644
|
const cat = readCurrentCatalogOrCache();
|
|
176
|
-
const
|
|
645
|
+
const models = cat?.models ?? [];
|
|
646
|
+
const live = models.flatMap(entry => {
|
|
647
|
+
const slug = typeof entry.slug === "string" ? entry.slug : "";
|
|
648
|
+
return !slug.includes("/") && SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug) ? [slug] : [];
|
|
649
|
+
});
|
|
650
|
+
const accountBound = models.flatMap(entry => {
|
|
651
|
+
const slug = trustedAccountBoundNativeCatalogSlug(entry);
|
|
652
|
+
return slug !== undefined && SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug) ? [slug] : [];
|
|
653
|
+
});
|
|
654
|
+
// Deliberately ignore `visibility`: it is a rendered projection of disabledModels and account
|
|
655
|
+
// selectors, so treating it as fresh availability would shrink the supported set between syncs.
|
|
656
|
+
// visibleNativeSlugs applies the current disabledModels source of truth for public consumers.
|
|
657
|
+
return unique([...live, ...accountBound]);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
export function listCatalogNativeSlugs(): string[] {
|
|
177
661
|
// Ensure documented additions (e.g. gpt-5.3-codex-spark) appear even when the bundled catalog
|
|
178
662
|
// predates the slug — mirrors nativeOpenAiSlugs() which already merges them for /v1/models.
|
|
179
|
-
return unique([...
|
|
663
|
+
return unique([...catalogNativeSlugs(), ...DOCUMENTED_NATIVE_OPENAI_ADDITIONS]);
|
|
180
664
|
}
|