@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
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Modelled after src/codex/routing.ts cooldown logic but scoped to plain API-key pools.
|
|
10
10
|
*/
|
|
11
11
|
import { saveConfigPreservingClaudeCode } from "../config";
|
|
12
|
-
import type { OcxConfig, OcxProviderConfig } from "../types";
|
|
12
|
+
import type { OcxConfig, OcxProviderConfig, RateLimitRetryPolicy } from "../types";
|
|
13
13
|
import { resolveProviderTransport, type OcxProviderTransport } from "./xai-transport";
|
|
14
14
|
import { sweepExpiredOnWrite } from "../lib/state-store-sweeper";
|
|
15
15
|
|
|
@@ -22,6 +22,18 @@ interface KeyCooldown {
|
|
|
22
22
|
const DEFAULT_COOLDOWN_MS = 60_000;
|
|
23
23
|
const MAX_COOLDOWN_MS = 10 * 60_000; // cap at 10 min for api-key rotation
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Default same-target 429 retry policy used when a provider opts in via a bare
|
|
27
|
+
* `retryOn429: {}` (presence = opt-in with these defaults).
|
|
28
|
+
*/
|
|
29
|
+
const DEFAULT_RATE_LIMIT_RETRY = {
|
|
30
|
+
enabled: true,
|
|
31
|
+
attempts: 3,
|
|
32
|
+
intervalMs: 5_000,
|
|
33
|
+
maxIntervalMs: 60_000,
|
|
34
|
+
respectRetryAfter: true,
|
|
35
|
+
} as const satisfies Required<RateLimitRetryPolicy>;
|
|
36
|
+
|
|
25
37
|
/** Map<`${providerName}\0${keyId}`, KeyCooldown> */
|
|
26
38
|
const keyCooldowns = new Map<string, KeyCooldown>();
|
|
27
39
|
|
|
@@ -29,21 +41,32 @@ function cooldownKey(providerName: string, keyId: string): string {
|
|
|
29
41
|
return `${providerName}\0${keyId}`;
|
|
30
42
|
}
|
|
31
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Parse an upstream `Retry-After` header: numeric seconds (including `0`) or an HTTP-date.
|
|
46
|
+
* Returns a bounded delay in ms (1..MAX_COOLDOWN_MS), or undefined when the value is
|
|
47
|
+
* malformed. An HTTP-date already in the past yields an immediate (1 ms) retry.
|
|
48
|
+
*/
|
|
32
49
|
function parseRetryAfterMs(value: string | null | undefined, now = Date.now()): number | undefined {
|
|
33
50
|
const text = value?.trim();
|
|
34
51
|
if (!text) return undefined;
|
|
35
52
|
if (/^\d+(?:\.\d+)?$/.test(text)) {
|
|
36
53
|
const seconds = Number(text);
|
|
37
|
-
if (Number.isFinite(seconds) && seconds
|
|
54
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
38
55
|
return Math.min(Math.max(Math.ceil(seconds * 1000), 1), MAX_COOLDOWN_MS);
|
|
39
56
|
}
|
|
40
57
|
}
|
|
41
58
|
const timestamp = Date.parse(text);
|
|
42
59
|
if (!Number.isFinite(timestamp)) return undefined;
|
|
43
60
|
const delay = timestamp - now;
|
|
44
|
-
|
|
61
|
+
// A valid HTTP-date whose retry time has already passed is an immediate retry, exactly like
|
|
62
|
+
// numeric `Retry-After: 0` — never a malformed-header fallback to the fixed interval.
|
|
63
|
+
return Math.min(Math.max(delay, 1), MAX_COOLDOWN_MS);
|
|
45
64
|
}
|
|
46
65
|
|
|
66
|
+
/**
|
|
67
|
+
* True while the given key is inside its 429 cooldown window (lazily evicting the entry once the
|
|
68
|
+
* window expires). Used to skip keys that the upstream just rate-limited during failover.
|
|
69
|
+
*/
|
|
47
70
|
function isKeyInCooldown(providerName: string, keyId: string, now = Date.now()): boolean {
|
|
48
71
|
const entry = keyCooldowns.get(cooldownKey(providerName, keyId));
|
|
49
72
|
if (!entry) return false;
|
|
@@ -65,6 +88,51 @@ export function hasKeyPoolFailover(provider: OcxProviderConfig): boolean {
|
|
|
65
88
|
return (provider.apiKeyPool?.length ?? 0) >= 2;
|
|
66
89
|
}
|
|
67
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Normalize a provider's `retryOn429` policy, or return null when the knob is absent,
|
|
93
|
+
* explicitly disabled, or the provider is not key-auth (OAuth/forward credentials must not be
|
|
94
|
+
* replayed on the same token, forward passthrough never reaches the recovery loop anyway, and
|
|
95
|
+
* local runtimes have no remote key to preserve). The returned policy is fully defaulted so
|
|
96
|
+
* callers never re-check fields.
|
|
97
|
+
*/
|
|
98
|
+
export function rateLimitRetryPolicyFor(
|
|
99
|
+
provider: Pick<OcxProviderConfig, "retryOn429" | "authMode">,
|
|
100
|
+
): Required<RateLimitRetryPolicy> | null {
|
|
101
|
+
const policy = provider.retryOn429;
|
|
102
|
+
if (!policy || policy.enabled === false) return null;
|
|
103
|
+
// Fail closed: only explicit key auth or the documented omitted-default (undefined == key for
|
|
104
|
+
// custom API-key providers) may use same-key replays. OAuth/forward are never replayed on the
|
|
105
|
+
// same token, local runtimes have no remote key to preserve, and unknown/custom values are
|
|
106
|
+
// rejected rather than guessed at.
|
|
107
|
+
if (provider.authMode !== undefined && provider.authMode !== "key") return null;
|
|
108
|
+
return {
|
|
109
|
+
enabled: policy.enabled ?? DEFAULT_RATE_LIMIT_RETRY.enabled,
|
|
110
|
+
attempts: policy.attempts ?? DEFAULT_RATE_LIMIT_RETRY.attempts,
|
|
111
|
+
intervalMs: policy.intervalMs ?? DEFAULT_RATE_LIMIT_RETRY.intervalMs,
|
|
112
|
+
maxIntervalMs: policy.maxIntervalMs ?? DEFAULT_RATE_LIMIT_RETRY.maxIntervalMs,
|
|
113
|
+
respectRetryAfter: policy.respectRetryAfter ?? DEFAULT_RATE_LIMIT_RETRY.respectRetryAfter,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Wait before the next same-target replay: upstream Retry-After (seconds or HTTP-date) when
|
|
119
|
+
* `respectRetryAfter` is on and the header parses, capped at `maxIntervalMs`; otherwise the
|
|
120
|
+
* fixed `intervalMs`, also capped at `maxIntervalMs` (a single wait never exceeds the cap).
|
|
121
|
+
* Malformed headers fall back to the fixed interval.
|
|
122
|
+
*/
|
|
123
|
+
export function rateLimitRetryDelayMs(
|
|
124
|
+
policy: Required<RateLimitRetryPolicy>,
|
|
125
|
+
retryAfterHeader: string | null | undefined,
|
|
126
|
+
now = Date.now(),
|
|
127
|
+
): number {
|
|
128
|
+
const raw = retryAfterHeader?.trim();
|
|
129
|
+
if (policy.respectRetryAfter && raw) {
|
|
130
|
+
const parsed = parseRetryAfterMs(raw, now);
|
|
131
|
+
if (parsed !== undefined) return Math.min(parsed, policy.maxIntervalMs);
|
|
132
|
+
}
|
|
133
|
+
return Math.min(policy.intervalMs, policy.maxIntervalMs);
|
|
134
|
+
}
|
|
135
|
+
|
|
68
136
|
/**
|
|
69
137
|
* Record a 429 for the current key and attempt to switch to the next available one.
|
|
70
138
|
*
|
package/src/providers/label.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { CODEX_ACCOUNT_LOG_LABEL_RE } from "../codex/account-label";
|
|
1
|
+
import { CODEX_ACCOUNT_LOG_LABEL_RE, oauthAccountLogLabel } from "../codex/account-label";
|
|
2
|
+
import type { OcxProviderConfig } from "../types";
|
|
2
3
|
|
|
3
|
-
function canonicalUsageProviderLabel(provider: string): string {
|
|
4
|
+
export function canonicalUsageProviderLabel(provider: string): string {
|
|
4
5
|
return provider === "chatgpt" || provider === "openai-multi" ? "openai" : provider;
|
|
5
6
|
}
|
|
6
7
|
|
|
@@ -17,3 +18,35 @@ export function baseProviderLabel(provider: string): string {
|
|
|
17
18
|
if (suffix === "main") return canonicalUsageProviderLabel(provider.slice(0, cut));
|
|
18
19
|
return CODEX_ACCOUNT_LOG_LABEL_RE.test(suffix) ? canonicalUsageProviderLabel(provider.slice(0, cut)) : provider;
|
|
19
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Stamp the per-account usage label for a non-Codex OAuth provider (#2699).
|
|
24
|
+
*
|
|
25
|
+
* Call this where the resolved credential is known and NOT inside a failover gate. The obvious
|
|
26
|
+
* place -- next to the `genericFailoverAccountId` assignment in `core.ts` -- sits inside
|
|
27
|
+
* `isGenericFailoverProvider`, and the rotation paths additionally require two or more stored
|
|
28
|
+
* accounts. Stamping there would leave the ordinary case (one xai account, failover off) with no
|
|
29
|
+
* label at all while every test still passed, which is the bug this fixes rather than a variant
|
|
30
|
+
* of it.
|
|
31
|
+
*
|
|
32
|
+
* Two providers are skipped because they already have attribution:
|
|
33
|
+
* - `openai` produces its own `p`-labels through `codexAuthContextLogLabel`.
|
|
34
|
+
* - `anthropic` folds the account into the provider label (`formatAnthropicProviderForLog`).
|
|
35
|
+
*
|
|
36
|
+
* It lives here rather than in `account-label.ts` because it needs `baseProviderLabel`, and this
|
|
37
|
+
* module already imports from that one -- the reverse direction would be an import cycle. This
|
|
38
|
+
* file stays Lab-clean, which matters because `core.ts` is one of the three files
|
|
39
|
+
* `tests/core-lab-boundary.test.ts` guards.
|
|
40
|
+
*/
|
|
41
|
+
export function stampOAuthAccountLabel(
|
|
42
|
+
logCtx: { accountLogLabel?: string },
|
|
43
|
+
providerName: string,
|
|
44
|
+
provider: Pick<OcxProviderConfig, "authMode">,
|
|
45
|
+
accountId: string | undefined,
|
|
46
|
+
): void {
|
|
47
|
+
if (!accountId) return;
|
|
48
|
+
if (provider.authMode !== "oauth") return;
|
|
49
|
+
const base = baseProviderLabel(providerName);
|
|
50
|
+
if (base === "openai" || base === "anthropic") return;
|
|
51
|
+
logCtx.accountLogLabel = oauthAccountLogLabel(accountId, base);
|
|
52
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Hard process-wide limits shared by all live model-discovery parsers. */
|
|
2
|
+
export const MODEL_DISCOVERY_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
|
|
3
|
+
export const MODEL_DISCOVERY_MAX_MODELS = 2_000;
|
|
4
|
+
export const MODEL_DISCOVERY_MAX_MODEL_ID_LENGTH = 1_024;
|
|
5
|
+
|
|
6
|
+
const MODEL_DISCOVERY_MODEL_ID_CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/;
|
|
7
|
+
|
|
8
|
+
/** Reject model IDs that cannot safely be published as callable catalog selectors. */
|
|
9
|
+
export function isValidModelDiscoveryModelId(value: unknown): value is string {
|
|
10
|
+
if (typeof value !== "string") return false;
|
|
11
|
+
const normalized = value.trim();
|
|
12
|
+
return Boolean(normalized)
|
|
13
|
+
&& normalized === value
|
|
14
|
+
&& normalized.length <= MODEL_DISCOVERY_MAX_MODEL_ID_LENGTH
|
|
15
|
+
&& !MODEL_DISCOVERY_MODEL_ID_CONTROL_CHARS.test(normalized);
|
|
16
|
+
}
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import type { OcxProviderConfig } from "../types";
|
|
2
|
+
import {
|
|
3
|
+
isValidModelDiscoveryModelId,
|
|
4
|
+
MODEL_DISCOVERY_MAX_MODEL_ID_LENGTH,
|
|
5
|
+
MODEL_DISCOVERY_MAX_MODELS,
|
|
6
|
+
MODEL_DISCOVERY_MAX_RESPONSE_BYTES,
|
|
7
|
+
} from "./model-discovery-limits";
|
|
8
|
+
export {
|
|
9
|
+
isValidModelDiscoveryModelId,
|
|
10
|
+
MODEL_DISCOVERY_MAX_MODEL_ID_LENGTH,
|
|
11
|
+
MODEL_DISCOVERY_MAX_MODELS,
|
|
12
|
+
MODEL_DISCOVERY_MAX_RESPONSE_BYTES,
|
|
13
|
+
} from "./model-discovery-limits";
|
|
2
14
|
import {
|
|
3
15
|
getProviderRegistryEntry,
|
|
4
16
|
providerMatchesRegistryTransport,
|
|
17
|
+
registryEntryForProviderDestination,
|
|
5
18
|
type ProviderModelDiscoveryFilter,
|
|
6
19
|
type ProviderModelDiscoveryPredicate,
|
|
7
20
|
type ProviderModelDiscoveryScalar,
|
|
8
21
|
type ProviderModelDiscoverySpec,
|
|
9
22
|
} from "./registry";
|
|
10
23
|
|
|
11
|
-
/** Hard process-wide limits. Registry entries may lower, but never raise, these ceilings. */
|
|
12
|
-
export const MODEL_DISCOVERY_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
|
|
13
|
-
export const MODEL_DISCOVERY_MAX_MODELS = 2_000;
|
|
14
|
-
export const MODEL_DISCOVERY_MAX_MODEL_ID_LENGTH = 1_024;
|
|
15
24
|
const MODEL_DISCOVERY_MAX_FILTER_VALUES = 256;
|
|
16
25
|
const MODEL_DISCOVERY_MAX_FILTER_STRING_LENGTH = 1_024;
|
|
17
|
-
const MODEL_DISCOVERY_MODEL_ID_CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/;
|
|
18
26
|
|
|
19
27
|
export interface ResolvedProviderModelDiscovery {
|
|
20
28
|
spec?: ProviderModelDiscoverySpec;
|
|
@@ -91,7 +99,12 @@ export function providerModelDiscoverySpecError(spec: ProviderModelDiscoverySpec
|
|
|
91
99
|
return "discovery path must be a query-free relative/origin path";
|
|
92
100
|
}
|
|
93
101
|
if (path.includes("\\")) return "discovery path must use forward slashes";
|
|
94
|
-
|
|
102
|
+
const segments = path.split("/");
|
|
103
|
+
if (segments.some((segment, index) => {
|
|
104
|
+
const decoded = segment.replace(/%2e/gi, ".");
|
|
105
|
+
if (decoded !== "..") return false;
|
|
106
|
+
return index !== 0 || segments.filter(s => s.replace(/%2e/gi, ".") === "..").length !== 1;
|
|
107
|
+
})) {
|
|
95
108
|
return "discovery path must not contain parent-directory segments";
|
|
96
109
|
}
|
|
97
110
|
}
|
|
@@ -124,9 +137,14 @@ export function resolveProviderModelDiscovery(
|
|
|
124
137
|
providerName: string,
|
|
125
138
|
provider: Pick<OcxProviderConfig, "baseUrl" | "adapter"> & Partial<Pick<OcxProviderConfig, "authMode">>,
|
|
126
139
|
): ResolvedProviderModelDiscovery {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
140
|
+
// The dashboard permits a canonical preset to be saved under a different name. Recover its
|
|
141
|
+
// registry-owned discovery policy by transport in that case. The destination helper is limited
|
|
142
|
+
// to exact fixed-key baseUrl + adapter matches, so custom endpoints, OAuth rows, templates, and
|
|
143
|
+
// overridable destinations cannot acquire another provider's discovery URL or filter.
|
|
144
|
+
const namedEntry = getProviderRegistryEntry(providerName);
|
|
145
|
+
const entry = namedEntry
|
|
146
|
+
? (providerMatchesRegistryTransport(providerName, provider) ? namedEntry : undefined)
|
|
147
|
+
: registryEntryForProviderDestination(provider);
|
|
130
148
|
const spec = entry?.modelDiscovery;
|
|
131
149
|
return {
|
|
132
150
|
...(spec ? { spec } : {}),
|
|
@@ -313,12 +331,83 @@ export function extractModelEnvelopeRows(
|
|
|
313
331
|
}
|
|
314
332
|
|
|
315
333
|
/** Validate, bound, deduplicate, and declaratively filter OpenAI `{data:[...]}` or top-level arrays (Together `#617`). */
|
|
334
|
+
/**
|
|
335
|
+
* Metadata a sibling `models[]` array may contribute to an ALREADY-ADMITTED
|
|
336
|
+
* `data[]` row (#1797).
|
|
337
|
+
*
|
|
338
|
+
* llama.cpp serves a dual-envelope body: an Ollama-style `models[]` array
|
|
339
|
+
* carrying `capabilities` alongside the OpenAI-style `data[]` array carrying
|
|
340
|
+
* `meta`, so the two halves of one model's metadata never meet and a server
|
|
341
|
+
* that truthfully advertises "multimodal" produced an image-blind row.
|
|
342
|
+
*
|
|
343
|
+
* Two boundaries make this safe, and both were added after review found the
|
|
344
|
+
* first attempt unsound:
|
|
345
|
+
*
|
|
346
|
+
* 1. It runs AFTER admission filtering. Enriching first let a sibling supply
|
|
347
|
+
* the exact field a provider filter requires — reproduced against the real
|
|
348
|
+
* Chutes policy, where a row lacking `supported_features: ["tools"]` was
|
|
349
|
+
* admitted once a same-id sibling provided it. Enrichment may change what is
|
|
350
|
+
* KNOWN about a model, never WHICH models are published.
|
|
351
|
+
* 2. Only the capability keys #1797 needs are copied. A blanket "fill every
|
|
352
|
+
* absent key" made the untrusted `models[]` array a way into any field the
|
|
353
|
+
* pipeline consumes.
|
|
354
|
+
*
|
|
355
|
+
* The list deliberately EXCLUDES `supported_features` and `features`, even
|
|
356
|
+
* though both are capability-shaped: they are the two keys real provider
|
|
357
|
+
* filters test (`registry.ts:1591` requires `supported_features` to contain
|
|
358
|
+
* "tools"; `registry.ts:1883` tests `features.tool_use`). Ordering already
|
|
359
|
+
* prevents a sibling from flipping an admission verdict, but a key that is
|
|
360
|
+
* both enrichable and filter-relevant is one refactor away from becoming a
|
|
361
|
+
* bypass again. #1797 does not need them.
|
|
362
|
+
*/
|
|
363
|
+
const SIBLING_ENRICHABLE_KEYS = new Set(["capabilities", "modalities", "input_modalities"]);
|
|
364
|
+
|
|
365
|
+
type SiblingIndex = Map<string, Record<string, unknown> | null>;
|
|
366
|
+
|
|
367
|
+
function buildSiblingIndex(value: unknown, limit: number): SiblingIndex | null {
|
|
368
|
+
const record = plainObject(value);
|
|
369
|
+
const sibling = record?.models;
|
|
370
|
+
if (!Array.isArray(sibling) || sibling.length === 0 || sibling.length > limit) return null;
|
|
371
|
+
|
|
372
|
+
const byId: SiblingIndex = new Map();
|
|
373
|
+
for (const raw of sibling) {
|
|
374
|
+
const entry = plainObject(raw);
|
|
375
|
+
if (!entry) continue;
|
|
376
|
+
for (const key of ["id", "model", "name"]) {
|
|
377
|
+
const id = entry[key];
|
|
378
|
+
if (typeof id !== "string" || id.length === 0) continue;
|
|
379
|
+
// `null` marks an ambiguous id: two sibling entries claim it, so neither
|
|
380
|
+
// can be attributed with confidence and both are ignored.
|
|
381
|
+
byId.set(id, byId.has(id) && byId.get(id) !== entry ? null : entry);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return byId.size > 0 ? byId : null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function enrichAdmittedModel(item: ProviderModelsApiItem, siblings: SiblingIndex): ProviderModelsApiItem {
|
|
388
|
+
const extra = siblings.get(item.id);
|
|
389
|
+
if (!extra) return item;
|
|
390
|
+
let merged: Record<string, unknown> | null = null;
|
|
391
|
+
for (const key of SIBLING_ENRICHABLE_KEYS) {
|
|
392
|
+
if (!(key in extra) || key in item) continue;
|
|
393
|
+
merged ??= { ...(item as Record<string, unknown>) };
|
|
394
|
+
merged[key] = extra[key];
|
|
395
|
+
}
|
|
396
|
+
return (merged ?? item) as ProviderModelsApiItem;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function plainObject(value: unknown): Record<string, unknown> | null {
|
|
400
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
401
|
+
? value as Record<string, unknown>
|
|
402
|
+
: null;
|
|
403
|
+
}
|
|
316
404
|
export function extractProviderModelItems(
|
|
317
405
|
value: unknown,
|
|
318
406
|
discovery: ResolvedProviderModelDiscovery,
|
|
319
407
|
): ProviderModelItemsResult {
|
|
320
408
|
const limit = positiveIntegerAtMost(discovery.maxModels, MODEL_DISCOVERY_MAX_MODELS);
|
|
321
409
|
let data: unknown[];
|
|
410
|
+
let siblings: SiblingIndex | null = null;
|
|
322
411
|
if (Array.isArray(value)) {
|
|
323
412
|
// Together-style top-level /models arrays. Catalog discovery must not treat a stray
|
|
324
413
|
// `models` key on openai-chat responses as valid — only `data` envelopes or top-level arrays.
|
|
@@ -328,6 +417,7 @@ export function extractProviderModelItems(
|
|
|
328
417
|
const envelope = extractModelEnvelopeRows(value, discovery.maxModels, ["data"]);
|
|
329
418
|
if (!envelope.ok) return envelope;
|
|
330
419
|
data = envelope.rows;
|
|
420
|
+
siblings = buildSiblingIndex(value, limit);
|
|
331
421
|
}
|
|
332
422
|
|
|
333
423
|
const items: ProviderModelsApiItem[] = [];
|
|
@@ -337,20 +427,23 @@ export function extractProviderModelItems(
|
|
|
337
427
|
return { ok: false, reason: "invalid_shape" };
|
|
338
428
|
}
|
|
339
429
|
const id = (raw as { id?: unknown }).id;
|
|
340
|
-
if (
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|| MODEL_DISCOVERY_MODEL_ID_CONTROL_CHARS.test(normalizedId)
|
|
347
|
-
) {
|
|
348
|
-
return { ok: false, reason: "invalid_shape" };
|
|
430
|
+
if (!isValidModelDiscoveryModelId(id)) return { ok: false, reason: "invalid_shape" };
|
|
431
|
+
const prefix = discovery.spec?.stripIdPrefix;
|
|
432
|
+
let finalId = id;
|
|
433
|
+
if (prefix && finalId.startsWith(prefix)) {
|
|
434
|
+
finalId = finalId.slice(prefix.length);
|
|
435
|
+
if (!isValidModelDiscoveryModelId(finalId)) continue;
|
|
349
436
|
}
|
|
350
|
-
const item = raw as ProviderModelsApiItem;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
437
|
+
const item = finalId === id ? raw as ProviderModelsApiItem : { ...(raw as ProviderModelsApiItem), id: finalId };
|
|
438
|
+
// Admission is decided on the ORIGINAL `data[]` row, before any sibling
|
|
439
|
+
// enrichment. Merging first let a `models[]` entry supply the very field a
|
|
440
|
+
// provider filter requires — reproduced against the real Chutes policy,
|
|
441
|
+
// where a row lacking `supported_features: ["tools"]` was admitted once a
|
|
442
|
+
// same-id sibling provided it. Enrichment must never change WHICH models
|
|
443
|
+
// are published, only what is known about an already-admitted one.
|
|
444
|
+
if (!providerModelMatchesDiscoveryFilter(item, discovery.spec?.filter) || seen.has(finalId)) continue;
|
|
445
|
+
seen.add(finalId);
|
|
446
|
+
items.push(siblings ? enrichAdmittedModel(item, siblings) : item);
|
|
354
447
|
}
|
|
355
448
|
return { ok: true, items, rawCount: data.length };
|
|
356
449
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shipped per-provider "latest/core" model presets (#2465).
|
|
3
|
+
*
|
|
4
|
+
* Adding a high-volume provider exposes its entire catalog to the Codex picker on day one:
|
|
5
|
+
* openrouter ships 400+ rows, an Anthropic provider ships every historical snapshot. The useful
|
|
6
|
+
* set is a handful of current flagships, so a newly added provider seeds from a curated preset
|
|
7
|
+
* and "everything" stays one click away.
|
|
8
|
+
*
|
|
9
|
+
* Rules are ID PATTERNS rather than literal id lists so a vendor snapshot suffix does not stale
|
|
10
|
+
* the preset between releases: `claude-opus-5-20260814` and `claude-opus-5` both match one rule.
|
|
11
|
+
*
|
|
12
|
+
* The preset is a SEED, not a lock. Materialization evaluates these rules against the provider's
|
|
13
|
+
* current catalog and stores CONCRETE ids in `selectedModels`, so the visibility hot path
|
|
14
|
+
* (`filterCatalogVisibleModels`) never learns about patterns and an older binary still sees a
|
|
15
|
+
* plain allowlist. Design: devlog/_plan/260824_model_ux_aliases_and_defaults/030_default_preset.md
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { OcxProviderConfig } from "../types";
|
|
19
|
+
|
|
20
|
+
export interface ModelPresetRule {
|
|
21
|
+
readonly pattern: RegExp;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ModelPreset {
|
|
25
|
+
/** Bumped whenever this provider's rules change; drives upgrade reconciliation. */
|
|
26
|
+
readonly version: number;
|
|
27
|
+
readonly rules: readonly ModelPresetRule[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Curated on the same release train as the provider registry. A provider WITHOUT an entry has no
|
|
32
|
+
* preset and behaves exactly as today (mode "all").
|
|
33
|
+
*
|
|
34
|
+
* Deliberately limited to high-volume catalogs. A provider that already ships a short curated
|
|
35
|
+
* list gains nothing from a preset and would only add a marker to reconcile.
|
|
36
|
+
*/
|
|
37
|
+
export const MODEL_PRESETS: Readonly<Record<string, ModelPreset>> = Object.freeze({
|
|
38
|
+
openrouter: {
|
|
39
|
+
version: 1,
|
|
40
|
+
rules: [
|
|
41
|
+
{ pattern: /^anthropic\/claude-(opus|sonnet|haiku)-[45]/ },
|
|
42
|
+
{ pattern: /^google\/gemini-3(\.\d+)?-(pro|flash)/ },
|
|
43
|
+
{ pattern: /^openai\/gpt-5(\.\d+)?/ },
|
|
44
|
+
{ pattern: /^deepseek\/deepseek-(v4|r2)/ },
|
|
45
|
+
{ pattern: /^x-ai\/grok-4(\.\d+)?/ },
|
|
46
|
+
{ pattern: /^moonshotai\/kimi-k[23]/ },
|
|
47
|
+
{ pattern: /^z-ai\/glm-[45]/ },
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
anthropic: {
|
|
51
|
+
version: 1,
|
|
52
|
+
rules: [
|
|
53
|
+
{ pattern: /^claude-opus-[45]/ },
|
|
54
|
+
{ pattern: /^claude-sonnet-[45]/ },
|
|
55
|
+
{ pattern: /^claude-haiku-[45]/ },
|
|
56
|
+
{ pattern: /^claude-fable-5/ },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
"anthropic-apikey": {
|
|
60
|
+
version: 1,
|
|
61
|
+
rules: [
|
|
62
|
+
{ pattern: /^claude-opus-[45]/ },
|
|
63
|
+
{ pattern: /^claude-sonnet-[45]/ },
|
|
64
|
+
{ pattern: /^claude-haiku-[45]/ },
|
|
65
|
+
{ pattern: /^claude-fable-5/ },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/** The preset for a provider, or undefined when none is shipped. */
|
|
71
|
+
export function modelPresetFor(providerName: string): ModelPreset | undefined {
|
|
72
|
+
return MODEL_PRESETS[providerName];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** True when a provider has a shipped preset at all. */
|
|
76
|
+
export function hasModelPreset(providerName: string): boolean {
|
|
77
|
+
return modelPresetFor(providerName) !== undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Evaluate a provider's rules against concrete catalog ids.
|
|
82
|
+
*
|
|
83
|
+
* Input order is preserved so a caller can show the preset in the same order the picker does.
|
|
84
|
+
* Duplicates are collapsed; a model matching several rules is selected once.
|
|
85
|
+
*/
|
|
86
|
+
export function materializeModelPreset(
|
|
87
|
+
providerName: string,
|
|
88
|
+
catalogModelIds: Iterable<string>,
|
|
89
|
+
): string[] {
|
|
90
|
+
const preset = modelPresetFor(providerName);
|
|
91
|
+
if (!preset) return [];
|
|
92
|
+
const seen = new Set<string>();
|
|
93
|
+
const out: string[] = [];
|
|
94
|
+
for (const id of catalogModelIds) {
|
|
95
|
+
if (seen.has(id)) continue;
|
|
96
|
+
// `RegExp.test` on a shared literal is safe here because no rule uses the `g` flag; a
|
|
97
|
+
// sticky/global pattern would carry lastIndex between calls and skip rows.
|
|
98
|
+
if (preset.rules.some(rule => rule.pattern.test(id))) {
|
|
99
|
+
seen.add(id);
|
|
100
|
+
out.push(id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Flip a provider out of preset mode when the user edits its selection (#2465).
|
|
109
|
+
*
|
|
110
|
+
* No-op unless the provider is currently in preset mode: "all" has no marker to keep, and
|
|
111
|
+
* "custom" is already terminal. The applied version is retained so the GUI can still offer
|
|
112
|
+
* "a newer preset is available" without losing what the user chose.
|
|
113
|
+
*/
|
|
114
|
+
export function markModelPresetDiverged(provider: OcxProviderConfig): void {
|
|
115
|
+
const marker = provider.modelPreset;
|
|
116
|
+
if (marker?.mode !== "preset") return;
|
|
117
|
+
provider.modelPreset = { ...marker, mode: "custom" };
|
|
118
|
+
}
|
|
119
|
+
|