@yansigit/opencodex 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/LICENSE +21 -0
- package/README.md +303 -0
- package/assets/architecture.png +0 -0
- package/assets/banner.png +0 -0
- package/assets/claude-code-models.gif +0 -0
- package/assets/codex-app-picker.png +0 -0
- package/bin/ocx.mjs +587 -0
- package/bin/package-main.mjs +9 -0
- package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
- package/gui/dist/assets/index-CGoDO3uO.css +1 -0
- package/gui/dist/favicon.png +0 -0
- package/gui/dist/icons.svg +24 -0
- package/gui/dist/index.html +25 -0
- package/gui/dist/logo.png +0 -0
- package/gui/dist/provider-icons/alibaba-color.svg +1 -0
- package/gui/dist/provider-icons/antigravity-color.svg +1 -0
- package/gui/dist/provider-icons/claude-color.svg +1 -0
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -0
- package/gui/dist/provider-icons/cursor-color.svg +2 -0
- package/gui/dist/provider-icons/deepseek-color.svg +1 -0
- package/gui/dist/provider-icons/discord.svg +1 -0
- package/gui/dist/provider-icons/firepass-color.svg +1 -0
- package/gui/dist/provider-icons/fireworks-color.svg +1 -0
- package/gui/dist/provider-icons/gemini-color.svg +1 -0
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
- package/gui/dist/provider-icons/grok.svg +1 -0
- package/gui/dist/provider-icons/groq-color.svg +1 -0
- package/gui/dist/provider-icons/huggingface-color.svg +1 -0
- package/gui/dist/provider-icons/kimi-color.svg +1 -0
- package/gui/dist/provider-icons/kiro-color.svg +15 -0
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
- package/gui/dist/provider-icons/mistral-color.svg +1 -0
- package/gui/dist/provider-icons/moonshot-color.svg +1 -0
- package/gui/dist/provider-icons/nvidia-color.svg +1 -0
- package/gui/dist/provider-icons/ollama-color.svg +1 -0
- package/gui/dist/provider-icons/openai.svg +1 -0
- package/gui/dist/provider-icons/opencode.svg +2 -0
- package/gui/dist/provider-icons/openrouter-color.svg +1 -0
- package/gui/dist/provider-icons/pi.svg +21 -0
- package/gui/dist/provider-icons/qianfan-color.svg +1 -0
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
- package/gui/dist/provider-icons/telegram.svg +1 -0
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/vllm-color.svg +1 -0
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
- package/package.json +108 -0
- package/src/AGENTS.md +28 -0
- package/src/adapters/anthropic-image-guard.ts +251 -0
- package/src/adapters/anthropic-image-normalize.ts +518 -0
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +1327 -0
- package/src/adapters/azure.ts +36 -0
- package/src/adapters/base.ts +121 -0
- package/src/adapters/client-fingerprint.ts +65 -0
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/arg-codec.ts +38 -0
- package/src/adapters/cursor/arg-normalize.ts +104 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +288 -0
- package/src/adapters/cursor/discovery.ts +333 -0
- package/src/adapters/cursor/effort-map.ts +151 -0
- package/src/adapters/cursor/exec-policy.ts +88 -0
- package/src/adapters/cursor/framing.ts +250 -0
- package/src/adapters/cursor/gen/agent_pb.ts +15274 -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/kv-store.ts +52 -0
- package/src/adapters/cursor/live-models.ts +269 -0
- package/src/adapters/cursor/live-smoke-gate.ts +41 -0
- package/src/adapters/cursor/live-transport.ts +1653 -0
- package/src/adapters/cursor/mcp-config.ts +42 -0
- package/src/adapters/cursor/mcp-manager.ts +333 -0
- package/src/adapters/cursor/message-mapper.ts +49 -0
- package/src/adapters/cursor/native-exec-common.ts +76 -0
- package/src/adapters/cursor/native-exec-desktop.ts +184 -0
- package/src/adapters/cursor/native-exec-fs.ts +332 -0
- package/src/adapters/cursor/native-exec-mcp.ts +153 -0
- package/src/adapters/cursor/native-exec-network.ts +43 -0
- package/src/adapters/cursor/native-exec-shell.ts +547 -0
- package/src/adapters/cursor/native-exec-tools.ts +118 -0
- package/src/adapters/cursor/native-exec.ts +663 -0
- package/src/adapters/cursor/protobuf-events.ts +1381 -0
- package/src/adapters/cursor/protobuf-request.ts +1032 -0
- package/src/adapters/cursor/request-builder.ts +461 -0
- package/src/adapters/cursor/thread-continuity.ts +67 -0
- package/src/adapters/cursor/tool-definitions.ts +735 -0
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport-retry.ts +132 -0
- package/src/adapters/cursor/transport.ts +79 -0
- package/src/adapters/cursor/types.ts +79 -0
- package/src/adapters/cursor.ts +322 -0
- package/src/adapters/google-antigravity-hosts.ts +48 -0
- package/src/adapters/google-antigravity-replay.ts +827 -0
- package/src/adapters/google-antigravity-tools.ts +105 -0
- package/src/adapters/google-antigravity-wire.ts +141 -0
- package/src/adapters/google-errors.ts +92 -0
- package/src/adapters/google-http.ts +460 -0
- package/src/adapters/google-tool-schema.ts +238 -0
- package/src/adapters/google-truncation.ts +24 -0
- package/src/adapters/google-wire-compiler.ts +232 -0
- package/src/adapters/google.ts +1377 -0
- package/src/adapters/identity.ts +77 -0
- package/src/adapters/image.ts +23 -0
- package/src/adapters/kiro-constants.ts +16 -0
- package/src/adapters/kiro-errors.ts +208 -0
- package/src/adapters/kiro-events.ts +197 -0
- package/src/adapters/kiro-images.ts +129 -0
- package/src/adapters/kiro-retry.ts +312 -0
- package/src/adapters/kiro-thinking.ts +112 -0
- package/src/adapters/kiro-tool-fallback.ts +36 -0
- package/src/adapters/kiro-tools.ts +224 -0
- package/src/adapters/kiro-truncation.ts +33 -0
- package/src/adapters/kiro-wire.ts +129 -0
- package/src/adapters/kiro.ts +1936 -0
- package/src/adapters/mimo-free.ts +280 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1980 -0
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1911 -0
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +114 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +154 -0
- package/src/adapters/upstream-http-error.ts +48 -0
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +1986 -0
- package/src/chat/inbound.ts +319 -0
- package/src/chat/outbound.ts +821 -0
- package/src/claude/agents-inject.ts +266 -0
- package/src/claude/alias.ts +149 -0
- package/src/claude/auth-detect.ts +229 -0
- package/src/claude/auth-mode-migration.ts +32 -0
- package/src/claude/auth-mode.ts +62 -0
- package/src/claude/context-windows.ts +205 -0
- package/src/claude/desktop-3p-guard.ts +35 -0
- package/src/claude/desktop-3p-paths.ts +84 -0
- package/src/claude/desktop-3p.ts +615 -0
- package/src/claude/desktop-health.ts +26 -0
- package/src/claude/desktop-profile.ts +263 -0
- package/src/claude/gateway-cache.ts +107 -0
- package/src/claude/inbound-debug.ts +163 -0
- package/src/claude/inbound.ts +578 -0
- package/src/claude/model-info.ts +174 -0
- package/src/claude/outbound.ts +926 -0
- package/src/cli/access.ts +108 -0
- package/src/cli/account-api.ts +302 -0
- package/src/cli/account-auth.ts +250 -0
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +737 -0
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +299 -0
- package/src/cli/agent-driven.ts +70 -0
- package/src/cli/agent.ts +290 -0
- package/src/cli/catalog-prewarm.ts +27 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +213 -0
- package/src/cli/claude.ts +355 -0
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +47 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +127 -0
- package/src/cli/config-command.ts +209 -0
- package/src/cli/debug.ts +228 -0
- package/src/cli/dispatch.ts +585 -0
- package/src/cli/doctor.ts +1202 -0
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +213 -0
- package/src/cli/help.ts +101 -0
- package/src/cli/index.ts +973 -0
- package/src/cli/init.ts +211 -0
- package/src/cli/integrations.ts +260 -0
- package/src/cli/interactive-confirm.ts +133 -0
- 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 +245 -0
- package/src/cli/models.ts +422 -0
- package/src/cli/observe.ts +206 -0
- package/src/cli/opencode.ts +588 -0
- package/src/cli/provider-replit.ts +232 -0
- package/src/cli/provider-runtime.ts +179 -0
- package/src/cli/provider.ts +492 -0
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +422 -0
- package/src/cli/replit-gateway-key-input.ts +138 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +328 -0
- package/src/cli/star-prompt.ts +211 -0
- package/src/cli/status-oauth.ts +78 -0
- package/src/cli/status.ts +328 -0
- package/src/cli/system-command.ts +112 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +199 -0
- package/src/cli/v2.ts +268 -0
- package/src/cli.ts +10 -0
- package/src/clients/config-export.ts +1704 -0
- package/src/codex/account-id.ts +34 -0
- package/src/codex/account-label.ts +47 -0
- package/src/codex/account-lifecycle.ts +172 -0
- package/src/codex/account-namespace-match.ts +63 -0
- package/src/codex/account-namespaces.ts +195 -0
- package/src/codex/account-pause.ts +20 -0
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-runtime-state.ts +31 -0
- package/src/codex/account-store.ts +544 -0
- package/src/codex/account-usability.ts +43 -0
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/agent-roles-sync.ts +225 -0
- package/src/codex/agent-roles.ts +238 -0
- package/src/codex/app-server-processes.ts +1143 -0
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +2147 -0
- package/src/codex/auth-collision.ts +109 -0
- package/src/codex/auth-context.ts +665 -0
- package/src/codex/autostart-health.ts +156 -0
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +436 -0
- package/src/codex/catalog/bundled.ts +549 -0
- package/src/codex/catalog/effort.ts +446 -0
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +664 -0
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +650 -0
- package/src/codex/catalog/provider-fetch.ts +2064 -0
- package/src/codex/catalog/sync.ts +1883 -0
- 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 +14 -0
- 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/data/upstream-models.json +830 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/exec-invocation.ts +22 -0
- package/src/codex/features.ts +1566 -0
- 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 +108 -0
- package/src/codex/history-provider.ts +979 -0
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/home.ts +206 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1733 -0
- package/src/codex/injected-marker.ts +106 -0
- 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 +225 -0
- 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 +56 -0
- package/src/codex/main-account.ts +68 -0
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +273 -0
- 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 +144 -0
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +242 -0
- package/src/codex/pool-rotation.ts +295 -0
- package/src/codex/project-config-warnings.ts +425 -0
- 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 +573 -0
- package/src/codex/refresh.ts +62 -0
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +1888 -0
- package/src/codex/runtime.ts +659 -0
- package/src/codex/shim.ts +2170 -0
- package/src/codex/subagent-defaults.ts +550 -0
- package/src/codex/subagent-model-fallback.ts +784 -0
- package/src/codex/sync.ts +319 -0
- 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 +298 -0
- package/src/codex/websocket-registry.ts +100 -0
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +160 -0
- package/src/combos/index.ts +45 -0
- package/src/combos/request.ts +94 -0
- package/src/combos/resolve.ts +232 -0
- package/src/combos/types.ts +398 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +4041 -0
- package/src/fork/register.ts +3 -0
- package/src/generated/compatibility-version.json +3116 -0
- package/src/generated/model-metadata.ts +106 -0
- package/src/github/star-state.ts +203 -0
- package/src/grok/inject.ts +530 -0
- package/src/grok/inspect.ts +45 -0
- package/src/grok/status.ts +121 -0
- package/src/grok/sync.ts +66 -0
- package/src/images/artifacts.ts +516 -0
- package/src/images/fulfill-video.ts +163 -0
- package/src/images/fulfill.ts +149 -0
- package/src/images/index.ts +4 -0
- package/src/images/loop.ts +955 -0
- package/src/images/plan.ts +143 -0
- package/src/images/synthetic-tool.ts +133 -0
- package/src/images/types.ts +41 -0
- package/src/images/xai-client.ts +141 -0
- package/src/images/xai-video-client.ts +163 -0
- package/src/index.ts +22 -0
- 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/abort.ts +146 -0
- package/src/lib/admin-secrets.ts +25 -0
- package/src/lib/admission.ts +83 -0
- package/src/lib/app-owned-memory-stores.ts +195 -0
- package/src/lib/app-owned-memory.ts +265 -0
- package/src/lib/bounded-body.ts +346 -0
- package/src/lib/bun-binary-validator.d.mts +3 -0
- package/src/lib/bun-binary-validator.mjs +18 -0
- package/src/lib/bun-runtime.ts +184 -0
- package/src/lib/bun-stream-caps.ts +130 -0
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +364 -0
- package/src/lib/crash-guard.ts +344 -0
- package/src/lib/debug-log-buffer.ts +83 -0
- package/src/lib/debug-settings.ts +108 -0
- package/src/lib/debug.ts +31 -0
- package/src/lib/destination-policy.ts +380 -0
- package/src/lib/errors.ts +406 -0
- package/src/lib/eventstream-decoder.ts +253 -0
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/gcp-adc.ts +341 -0
- package/src/lib/injection-debug-log.ts +58 -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/open-url.ts +25 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +270 -0
- package/src/lib/privacy.ts +20 -0
- package/src/lib/process-control.ts +168 -0
- package/src/lib/provider-outbound.ts +210 -0
- package/src/lib/provider-url.ts +14 -0
- package/src/lib/proxy-env.ts +18 -0
- package/src/lib/redact.ts +521 -0
- package/src/lib/retry-after.ts +55 -0
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +25 -0
- package/src/lib/shadow-call.ts +61 -0
- package/src/lib/sidecar-tracker.ts +52 -0
- package/src/lib/sse-decoder.ts +364 -0
- package/src/lib/state-store-registrations.ts +119 -0
- package/src/lib/state-store-sweeper.ts +184 -0
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/test-home-guard.ts +90 -0
- package/src/lib/token-estimate.ts +86 -0
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +400 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +392 -0
- package/src/lib/win-exec.ts +115 -0
- package/src/lib/win-paths.ts +68 -0
- package/src/lib/windows-atomic-replace.ts +156 -0
- package/src/lib/windows-elevation.ts +773 -0
- package/src/lib/windows-secret-acl.ts +854 -0
- 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 +403 -0
- 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-routing.ts +594 -0
- package/src/oauth/anthropic.ts +188 -0
- package/src/oauth/antigravity-routing.ts +151 -0
- package/src/oauth/callback-server.ts +300 -0
- package/src/oauth/chatgpt.ts +161 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +252 -0
- package/src/oauth/github-copilot.ts +428 -0
- package/src/oauth/google-antigravity.ts +262 -0
- package/src/oauth/health.ts +407 -0
- package/src/oauth/index.ts +1504 -0
- package/src/oauth/key-providers.ts +124 -0
- package/src/oauth/kimi.ts +227 -0
- package/src/oauth/kiro-credentials.ts +726 -0
- package/src/oauth/kiro.ts +621 -0
- package/src/oauth/local-token-detect.ts +130 -0
- package/src/oauth/log.ts +50 -0
- package/src/oauth/login-cli.ts +223 -0
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/pkce.ts +15 -0
- package/src/oauth/store.ts +728 -0
- package/src/oauth/token-guardian.ts +309 -0
- package/src/oauth/types.ts +62 -0
- package/src/oauth/xai.ts +241 -0
- package/src/providers/alibaba-region-backup.ts +75 -0
- package/src/providers/alibaba-region-migration.ts +156 -0
- package/src/providers/alibaba-region-startup.ts +36 -0
- package/src/providers/antigravity-models.ts +695 -0
- package/src/providers/antigravity-quota.ts +216 -0
- package/src/providers/api-keys.ts +140 -0
- package/src/providers/base-url-choices.ts +74 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +82 -0
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +586 -0
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +187 -0
- package/src/providers/github-copilot-transport.ts +56 -0
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +271 -0
- package/src/providers/kiro-models.ts +67 -0
- package/src/providers/label.ts +19 -0
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +449 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +243 -0
- package/src/providers/openai-tier-startup.ts +56 -0
- package/src/providers/openai-tiers.ts +423 -0
- package/src/providers/openai-virtual-models.ts +83 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/openrouter-routing.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +185 -0
- package/src/providers/quota.ts +2345 -0
- package/src/providers/registry.ts +2918 -0
- package/src/providers/replit/constants.ts +27 -0
- package/src/providers/replit/derive.ts +85 -0
- package/src/providers/replit/headers.ts +28 -0
- package/src/providers/replit/origin.ts +55 -0
- package/src/providers/replit/pair-install-response.ts +72 -0
- package/src/providers/replit/probe.ts +199 -0
- package/src/providers/replit/setup.ts +350 -0
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +103 -0
- 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 +148 -0
- package/src/reasoning-effort.ts +183 -0
- package/src/responses/compaction.ts +142 -0
- 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 +838 -0
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +60 -0
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +165 -0
- package/src/responses/spill-store.ts +459 -0
- package/src/responses/state.ts +1433 -0
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-groups.ts +19 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +761 -0
- 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 +53 -0
- package/src/server/auth-cors.ts +751 -0
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +442 -0
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +1030 -0
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +190 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +152 -0
- package/src/server/image-retry.ts +42 -0
- package/src/server/images.ts +568 -0
- package/src/server/index.ts +1813 -0
- package/src/server/lifecycle.ts +498 -0
- package/src/server/live.ts +717 -0
- 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 +1433 -0
- package/src/server/management/api-access.ts +141 -0
- package/src/server/management/api-key-usage.ts +193 -0
- package/src/server/management/body.ts +41 -0
- package/src/server/management/combo-routes.ts +263 -0
- package/src/server/management/config-routes.ts +835 -0
- package/src/server/management/context.ts +113 -0
- 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 +586 -0
- package/src/server/management/model-routes.ts +560 -0
- 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 +637 -0
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +1033 -0
- package/src/server/management/replit-provider-routes.ts +86 -0
- 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 +385 -0
- package/src/server/management/shared.ts +286 -0
- package/src/server/management/sidebar-routes.ts +106 -0
- 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 +435 -0
- package/src/server/management/system-routes.ts +194 -0
- package/src/server/management/usage-summary-cache.ts +94 -0
- 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 +314 -0
- package/src/server/management-auth.ts +482 -0
- package/src/server/memory-watchdog.ts +156 -0
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +307 -0
- package/src/server/ports.ts +156 -0
- package/src/server/proxy-liveness.ts +328 -0
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +353 -0
- package/src/server/relay.ts +1209 -0
- package/src/server/request-decompress.ts +239 -0
- package/src/server/request-log-conversation.ts +168 -0
- package/src/server/request-log.ts +1259 -0
- 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 +551 -0
- package/src/server/responses/compact.ts +771 -0
- package/src/server/responses/core.ts +5389 -0
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +331 -0
- package/src/server/responses/fetch-helpers.ts +232 -0
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +78 -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 +251 -0
- package/src/server/responses/upstream-error.ts +53 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-image-gen-repair.ts +132 -0
- package/src/server/responses-item-id-repair.ts +272 -0
- 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 +25 -0
- package/src/server/search.ts +201 -0
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +263 -0
- package/src/server/startup-action-control.ts +315 -0
- package/src/server/startup-health-cache.ts +131 -0
- package/src/server/system-env.ts +484 -0
- package/src/server/windows-tcp-drop.ts +184 -0
- package/src/server/windows-tray-control.ts +41 -0
- package/src/server/ws-bridge.ts +472 -0
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +3575 -0
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/stall-timeout.ts +20 -0
- package/src/storage/cleanup-job.ts +57 -0
- package/src/storage/cleanup.ts +3085 -0
- package/src/storage/policy-job.ts +457 -0
- package/src/storage/policy-scheduler.ts +40 -0
- package/src/storage/policy-worker.ts +59 -0
- package/src/storage/policy.ts +527 -0
- package/src/storage/restore-job.ts +299 -0
- package/src/storage/restore-worker.ts +58 -0
- package/src/storage/scanner.ts +238 -0
- package/src/storage/storage-mutation-coordinator.ts +139 -0
- package/src/storage/worker-lifecycle.ts +215 -0
- package/src/tray/assets/opencodex-tray-offline.ico +0 -0
- package/src/tray/assets/opencodex-tray-online.ico +0 -0
- package/src/tray/assets/opencodex-tray-warning.ico +0 -0
- package/src/tray/assets/opencodex-tray.png +0 -0
- package/src/tray/windows-tray.ps1 +364 -0
- package/src/tray/windows.ts +757 -0
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +876 -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 +106 -0
- package/src/update/badge.ts +72 -0
- package/src/update/index.ts +415 -0
- package/src/update/job.ts +1887 -0
- package/src/update/notify.ts +263 -0
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/npm-invocation.d.mts +23 -0
- package/src/update/npm-invocation.mjs +94 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/update/tray-update-plan.d.mts +18 -0
- package/src/update/tray-update-plan.mjs +38 -0
- package/src/usage/cost.ts +625 -0
- package/src/usage/debug.ts +97 -0
- package/src/usage/expected-prices.ts +416 -0
- package/src/usage/log.ts +1223 -0
- package/src/usage/summary.ts +753 -0
- package/src/usage/totals.ts +14 -0
- 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 +189 -0
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +131 -0
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +681 -0
- 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 +195 -0
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +113 -0
- package/src/web-search/format-result.ts +89 -0
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +331 -0
- package/src/web-search/loop.ts +896 -0
- package/src/web-search/parse.ts +315 -0
- package/src/web-search/progress-stream.ts +342 -0
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/synthetic-tool.ts +47 -0
- package/src/web-search/xai-executor.ts +219 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
export type ProviderAccessGroup =
|
|
2
|
+
| "recurring-or-keyless"
|
|
3
|
+
| "recurring-uncapped"
|
|
4
|
+
| "recurring-credit"
|
|
5
|
+
| "signup-credit";
|
|
6
|
+
|
|
7
|
+
export const FREE_PROVIDER_ACCESS_GROUPS = {
|
|
8
|
+
"recurring-or-keyless": [
|
|
9
|
+
"agy", "aihorde", "api-airforce", "arcee-ai", "bazaarlink", "blackbox", "bluesminds", "cerebras",
|
|
10
|
+
"cloudflare-ai", "cohere", "coze", "duckduckgo-web", "felo-web", "friendliai", "gemini", "github-models",
|
|
11
|
+
"groq", "hackclub", "huggingchat", "huggingface", "iflytek", "inference-net", "kiro", "liquid", "llm7",
|
|
12
|
+
"mistral", "morph", "muse-spark-web", "nara", "navy", "nlpcloud", "ollama-cloud", "opencode", "openrouter",
|
|
13
|
+
"ovhcloud", "pollinations", "puter", "qwen-web", "reka", "sambanova", "sparkdesk", "t3-web", "uncloseai",
|
|
14
|
+
],
|
|
15
|
+
"recurring-uncapped": [
|
|
16
|
+
"agnes", "ainative", "aion", "baidu", "glm", "glm-cn", "kilo-gateway", "opencode-zen", "requesty",
|
|
17
|
+
"routeway", "sealion", "siliconflow", "tencent",
|
|
18
|
+
],
|
|
19
|
+
"recurring-credit": ["bytez", "nous-research"],
|
|
20
|
+
"signup-credit": [
|
|
21
|
+
"agentrouter", "ai21", "baichuan", "baseten", "deepinfra", "deepseek", "doubao", "fireworks", "freemodel-dev", "glm-cn",
|
|
22
|
+
"hyperbolic", "longcat", "monsterapi", "nebius", "novita", "nscale", "nvidia", "predibase", "publicai", "qoder",
|
|
23
|
+
"scaleway", "sensenova", "stepfun", "together", "vertex",
|
|
24
|
+
],
|
|
25
|
+
} as const satisfies Record<ProviderAccessGroup, readonly string[]>;
|
|
26
|
+
|
|
27
|
+
export interface FreeDirectoryProvider {
|
|
28
|
+
id: string;
|
|
29
|
+
label: string;
|
|
30
|
+
adapter: string;
|
|
31
|
+
baseUrl: string;
|
|
32
|
+
authKind: "oauth" | "key";
|
|
33
|
+
accessGroups: readonly ProviderAccessGroup[];
|
|
34
|
+
supportLevel: "supported" | "experimental" | "reference";
|
|
35
|
+
verification: "official" | "primary" | "unverified";
|
|
36
|
+
documentationUrl?: string;
|
|
37
|
+
modelsUrl?: string;
|
|
38
|
+
discovery: "live" | "static" | "hybrid" | "unsupported";
|
|
39
|
+
/**
|
|
40
|
+
* Date the endpoint was checked against provider documentation. Only rows that were actually
|
|
41
|
+
* verified carry it — a uniform date on an `unverified` row is a claim nobody made.
|
|
42
|
+
*/
|
|
43
|
+
lastVerified?: string;
|
|
44
|
+
dashboardUrl?: string;
|
|
45
|
+
keyOptional?: boolean;
|
|
46
|
+
models?: string[];
|
|
47
|
+
liveModels: boolean;
|
|
48
|
+
/** Anthropic-compatible gateways that may close streams before terminal frames. */
|
|
49
|
+
anthropicEofTolerance?: boolean;
|
|
50
|
+
note?: string;
|
|
51
|
+
googleMode?: "ai-studio" | "vertex";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type ConnectableOverride = Partial<Omit<FreeDirectoryProvider, "id" | "accessGroups">>;
|
|
55
|
+
|
|
56
|
+
const LAST_VERIFIED = "2026-07-23";
|
|
57
|
+
/**
|
|
58
|
+
* Connectable rows carry `lastVerified` because their endpoint was checked against provider
|
|
59
|
+
* documentation on that date. Reference rows built by the generator below deliberately omit it:
|
|
60
|
+
* stamping a verification date on a row marked `unverified` asserts provenance nobody produced.
|
|
61
|
+
*/
|
|
62
|
+
const openAi = (baseUrl: string, dashboardUrl: string, extra: Partial<ConnectableOverride> = {}): ConnectableOverride => ({
|
|
63
|
+
baseUrl,
|
|
64
|
+
dashboardUrl,
|
|
65
|
+
adapter: "openai-chat",
|
|
66
|
+
authKind: "key",
|
|
67
|
+
supportLevel: "experimental",
|
|
68
|
+
verification: "primary",
|
|
69
|
+
discovery: "live",
|
|
70
|
+
liveModels: true,
|
|
71
|
+
lastVerified: LAST_VERIFIED,
|
|
72
|
+
...extra,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// API roots are limited to documented or primary-source integrations. Consumer-web/session
|
|
76
|
+
// providers remain reference-only: this directory never asks users to paste cookies or bypass WAFs.
|
|
77
|
+
const CONNECTABLE: Record<string, ConnectableOverride> = {
|
|
78
|
+
kiro: { baseUrl: "https://runtime.us-east-1.kiro.dev", dashboardUrl: "https://kiro.dev", adapter: "kiro", authKind: "oauth", supportLevel: "supported", verification: "official", documentationUrl: "https://kiro.dev/docs/cli/authentication/", lastVerified: LAST_VERIFIED, discovery: "static", liveModels: false },
|
|
79
|
+
aihorde: openAi("https://oai.aihorde.net/v1", "https://aihorde.net", { modelsUrl: "https://oai.aihorde.net/v1/models" }),
|
|
80
|
+
"arcee-ai": openAi("https://conductor.arcee.ai/v1", "https://conductor.arcee.ai", { verification: "official", documentationUrl: "https://docs.arcee.ai/" }),
|
|
81
|
+
cerebras: openAi("https://api.cerebras.ai/v1", "https://cloud.cerebras.ai/platform/apikeys", { supportLevel: "supported", verification: "official", documentationUrl: "https://inference-docs.cerebras.ai/api-reference/models/list" }),
|
|
82
|
+
"cloudflare-ai": openAi("https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1", "https://dash.cloudflare.com/?to=/:account/ai/workers-ai", { supportLevel: "supported", verification: "official", documentationUrl: "https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/", discovery: "static", liveModels: false, models: ["@cf/meta/llama-3.3-70b-instruct-fp8-fast", "@cf/qwen/qwq-32b"] }),
|
|
83
|
+
cohere: openAi("https://api.cohere.com/compatibility/v1", "https://dashboard.cohere.com/api-keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.cohere.com/reference/list-models", modelsUrl: "https://api.cohere.com/compatibility/v1/models" }),
|
|
84
|
+
friendliai: openAi("https://api.friendli.ai/serverless/v1", "https://suite.friendli.ai", { modelsUrl: "https://api.friendli.ai/serverless/v1/models" }),
|
|
85
|
+
gemini: { baseUrl: "https://generativelanguage.googleapis.com", dashboardUrl: "https://aistudio.google.com/apikey", adapter: "google", authKind: "key", supportLevel: "supported", verification: "official", documentationUrl: "https://ai.google.dev/api/models", lastVerified: LAST_VERIFIED, discovery: "live", liveModels: true, googleMode: "ai-studio", models: ["gemini-3.7-flash", "gemini-3.6-flash", "gemini-3.5-flash", "gemini-3.5-flash-lite", "gemini-3.1-pro-preview"] },
|
|
86
|
+
"github-models": openAi("https://models.github.ai/inference", "https://github.com/settings/tokens", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.github.com/en/github-models/prototyping-with-ai-models", discovery: "static", liveModels: false, models: ["openai/gpt-4.1", "meta/llama-4-scout-17b-16e-instruct"] }),
|
|
87
|
+
groq: openAi("https://api.groq.com/openai/v1", "https://console.groq.com/keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://console.groq.com/docs/api-reference#models" }),
|
|
88
|
+
hackclub: openAi("https://ai.hackclub.com/proxy/v1", "https://ai.hackclub.com", { modelsUrl: "https://ai.hackclub.com/proxy/v1/models" }),
|
|
89
|
+
huggingface: openAi("https://router.huggingface.co/v1", "https://huggingface.co/settings/tokens", { supportLevel: "supported", verification: "official", documentationUrl: "https://huggingface.co/docs/inference-providers/index", modelsUrl: "https://router.huggingface.co/v1/models" }),
|
|
90
|
+
// The OpenAI-compatible base URL is documented in the HTTP guide; Web.html covers the
|
|
91
|
+
// WebSocket protocol and does not describe this endpoint.
|
|
92
|
+
iflytek: openAi("https://spark-api-open.xf-yun.com/v1", "https://console.xfyun.cn", { verification: "official", documentationUrl: "https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html" }),
|
|
93
|
+
liquid: openAi("https://inference.liquid.ai/v1", "https://playground.liquid.ai", { modelsUrl: "https://inference.liquid.ai/v1/models" }),
|
|
94
|
+
mistral: openAi("https://api.mistral.ai/v1", "https://console.mistral.ai/api-keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.mistral.ai/api/endpoint/models" }),
|
|
95
|
+
morph: openAi("https://api.morphllm.com/v1", "https://morphllm.com", { verification: "official", documentationUrl: "https://docs.morphllm.com/api-reference/introduction" }),
|
|
96
|
+
"ollama-cloud": openAi("https://ollama.com/v1", "https://ollama.com/settings/keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.ollama.com/cloud", modelsUrl: "https://ollama.com/api/tags" }),
|
|
97
|
+
opencode: openAi("https://opencode.ai/zen/v1", "https://opencode.ai/auth", { supportLevel: "supported", verification: "official", documentationUrl: "https://opencode.ai/docs/zen/", modelsUrl: "https://opencode.ai/zen/v1/models" }),
|
|
98
|
+
openrouter: openAi("https://openrouter.ai/api/v1", "https://openrouter.ai/keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://openrouter.ai/docs/api/api-reference/models/get-models" }),
|
|
99
|
+
ovhcloud: openAi("https://oai.endpoints.kepler.ai.cloud.ovh.net/v1", "https://console.ovhcloud.com", { keyOptional: true, modelsUrl: "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1/models" }),
|
|
100
|
+
pollinations: openAi("https://gen.pollinations.ai/v1", "https://pollinations.ai", { keyOptional: true }),
|
|
101
|
+
reka: openAi("https://api.reka.ai/v1", "https://platform.reka.ai"),
|
|
102
|
+
sambanova: openAi("https://api.sambanova.ai/v1", "https://cloud.sambanova.ai/apis", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.sambanova.ai/docs/en/get-started/api-keys-urls", modelsUrl: "https://api.sambanova.ai/v1/models", lastVerified: "2026-08-02" }),
|
|
103
|
+
sparkdesk: openAi("https://spark-api-open.xf-yun.com/v1", "https://console.xfyun.cn", { verification: "official", documentationUrl: "https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html" }),
|
|
104
|
+
agnes: openAi("https://apihub.agnes-ai.com/v1", "https://agnes-ai.com"),
|
|
105
|
+
ainative: openAi("https://api.ainative.studio/api/v1", "https://ainative.studio", { modelsUrl: "https://api.ainative.studio/api/v1/models" }),
|
|
106
|
+
aion: openAi("https://api.aionlabs.ai/v1", "https://aionlabs.ai", { modelsUrl: "https://api.aionlabs.ai/v1/models" }),
|
|
107
|
+
baidu: openAi("https://qianfan.baidubce.com/v2", "https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application", { verification: "official", documentationUrl: "https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Fm2vrveyu", discovery: "static", liveModels: false, models: ["ernie-5.1", "ernie-5.0", "ernie-4.5-turbo-128k"] }),
|
|
108
|
+
glm: openAi("https://api.z.ai/api/coding/paas/v4", "https://z.ai/manage-apikey/apikey-list", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.z.ai/guides/overview/quick-start", discovery: "static", liveModels: false, models: ["glm-5"] }),
|
|
109
|
+
"glm-cn": openAi("https://open.bigmodel.cn/api/coding/paas/v4", "https://open.bigmodel.cn/usercenter/apikeys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.bigmodel.cn/cn/api/introduction", discovery: "static", liveModels: false, models: ["glm-4.5-flash"] }),
|
|
110
|
+
"kilo-gateway": openAi("https://api.kilo.ai/api/gateway", "https://kilo.ai", { modelsUrl: "https://api.kilo.ai/api/gateway/models" }),
|
|
111
|
+
"opencode-zen": openAi("https://opencode.ai/zen/v1", "https://opencode.ai/auth", { supportLevel: "supported", verification: "official", documentationUrl: "https://opencode.ai/docs/zen/" }),
|
|
112
|
+
requesty: openAi("https://router.requesty.ai/v1", "https://app.requesty.ai", { modelsUrl: "https://router.requesty.ai/v1/models" }),
|
|
113
|
+
routeway: openAi("https://api.routeway.ai/v1", "https://routeway.ai", { modelsUrl: "https://api.routeway.ai/v1/models" }),
|
|
114
|
+
sealion: openAi("https://api.sea-lion.ai/v1", "https://sea-lion.ai", { discovery: "static", liveModels: false, models: ["aisingapore/Llama-SEA-LION-v3.5-70B-R", "aisingapore/Llama-SEA-LION-v3-70B-IT", "aisingapore/Gemma-SEA-LION-v4-27B-IT", "aisingapore/Qwen-SEA-LION-v4.5-27B-IT", "aisingapore/Qwen-SEA-LION-v4-32B-IT"] }),
|
|
115
|
+
siliconflow: openAi("https://api.siliconflow.cn/v1", "https://cloud.siliconflow.cn/account/ak", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.siliconflow.cn/en/api-reference/models/get-model-list" }),
|
|
116
|
+
tencent: openAi("https://api.hunyuan.cloud.tencent.com/v1", "https://console.cloud.tencent.com/hunyuan/api-key", { verification: "official", documentationUrl: "https://cloud.tencent.com/document/product/1729/111007", discovery: "static", liveModels: false, models: ["hunyuan-turbos-latest", "hunyuan-t1-latest", "hunyuan-pro", "hunyuan-lite"] }),
|
|
117
|
+
// Endpoint is live, but the recurring-credit terms could not be confirmed, so this row stays
|
|
118
|
+
// `unverified` and drops the shared verification date rather than borrowing it.
|
|
119
|
+
bytez: openAi("https://api.bytez.com/models/v2/openai/v1", "https://bytez.com", { verification: "unverified", lastVerified: undefined, documentationUrl: "https://docs.bytez.com/", discovery: "static", liveModels: false, models: ["meta-llama/Llama-3.3-70B-Instruct", "mistralai/Mistral-7B-Instruct-v0.3", "Qwen/Qwen2.5-72B-Instruct"], note: "The recurring-credit classification is retained from the requested catalog, but the current reset terms could not be independently verified." }),
|
|
120
|
+
"nous-research": openAi("https://inference-api.nousresearch.com/v1", "https://portal.nousresearch.com", { discovery: "static", liveModels: false, models: ["Hermes-4-405B", "Hermes-4-70B"] }),
|
|
121
|
+
agentrouter: { baseUrl: "https://agentrouter.org", dashboardUrl: "https://agentrouter.org", adapter: "anthropic", authKind: "key", supportLevel: "experimental", verification: "primary", modelsUrl: "https://agentrouter.org/v1/models", lastVerified: LAST_VERIFIED, discovery: "live", liveModels: true, anthropicEofTolerance: true },
|
|
122
|
+
ai21: openAi("https://api.ai21.com/studio/v1", "https://studio.ai21.com/account/api-key", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.ai21.com/reference/models" }),
|
|
123
|
+
baichuan: openAi("https://api.baichuan-ai.com/v1", "https://platform.baichuan-ai.com/console/apikey", { verification: "official" }),
|
|
124
|
+
// Verified end-to-end 2026-07-30: /v1/models returns the OpenAI-shaped live catalog (13 models),
|
|
125
|
+
// and a chat completion against moonshotai/Kimi-K3 returned a standard chat.completion payload.
|
|
126
|
+
baseten: openAi("https://inference.baseten.co/v1", "https://app.baseten.co/settings/api_keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.baseten.co/inference/model-apis/overview", modelsUrl: "https://inference.baseten.co/v1/models", lastVerified: "2026-07-30" }),
|
|
127
|
+
deepinfra: openAi("https://api.deepinfra.com/v1/openai", "https://deepinfra.com/dash/api_keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://deepinfra.com/docs/openai_api" }),
|
|
128
|
+
deepseek: openAi("https://api.deepseek.com", "https://platform.deepseek.com/api_keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://api-docs.deepseek.com/api/list-models" }),
|
|
129
|
+
doubao: openAi("https://ark.cn-beijing.volces.com/api/v3", "https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey", { verification: "official" }),
|
|
130
|
+
fireworks: openAi("https://api.fireworks.ai/inference/v1", "https://fireworks.ai/account/api-keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.fireworks.ai/api-reference/list-models", modelsUrl: "https://api.fireworks.ai/v1/accounts/fireworks/models?filter=supports_serverless=true" }),
|
|
131
|
+
"freemodel-dev": openAi("https://api.freemodel.dev/v1", "https://freemodel.dev", { modelsUrl: "https://api.freemodel.dev/v1/models" }),
|
|
132
|
+
hyperbolic: openAi("https://api.hyperbolic.xyz/v1", "https://app.hyperbolic.xyz/settings", { verification: "official" }),
|
|
133
|
+
longcat: openAi("https://api.longcat.chat/openai/v1", "https://longcat.chat", { verification: "official", discovery: "static", liveModels: false, models: ["LongCat-2.0"] }),
|
|
134
|
+
monsterapi: openAi("https://api.monsterapi.ai/v1", "https://monsterapi.ai", { verification: "official" }),
|
|
135
|
+
nebius: openAi("https://api.tokenfactory.nebius.com/v1", "https://tokenfactory.nebius.com", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.tokenfactory.nebius.com/quickstart", modelsUrl: "https://api.tokenfactory.nebius.com/v1/models?verbose=true", lastVerified: "2026-08-02" }),
|
|
136
|
+
novita: openAi("https://api.novita.ai/openai/v1", "https://novita.ai/settings/key-management", { supportLevel: "supported", verification: "official", modelsUrl: "https://api.novita.ai/openai/v1/models" }),
|
|
137
|
+
nscale: openAi("https://inference.api.nscale.com/v1", "https://console.nscale.com", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.nscale.com/docs/use-cases/chat", modelsUrl: "https://inference.api.nscale.com/v1/models", lastVerified: "2026-08-03" }),
|
|
138
|
+
nvidia: openAi("https://integrate.api.nvidia.com/v1", "https://build.nvidia.com", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.api.nvidia.com/nim/reference/llm-apis" }),
|
|
139
|
+
publicai: openAi("https://api.publicai.co/v1", "https://publicai.co"),
|
|
140
|
+
scaleway: openAi("https://api.scaleway.ai/v1", "https://console.scaleway.com/generative-api", { supportLevel: "supported", verification: "official", documentationUrl: "https://www.scaleway.com/en/docs/generative-apis/api-cli/using-generative-apis/", modelsUrl: "https://api.scaleway.ai/v1/models", lastVerified: "2026-08-01" }),
|
|
141
|
+
sensenova: openAi("https://token.sensenova.cn/v1", "https://console.sensenova.cn", { verification: "official" }),
|
|
142
|
+
stepfun: openAi("https://api.stepfun.com/v1", "https://platform.stepfun.com", { verification: "official" }),
|
|
143
|
+
together: openAi("https://api.together.xyz/v1", "https://api.together.xyz/settings/api-keys", { supportLevel: "supported", verification: "official", documentationUrl: "https://docs.together.ai/reference/models-1" }),
|
|
144
|
+
vertex: { baseUrl: "https://aiplatform.googleapis.com", dashboardUrl: "https://console.cloud.google.com/vertex-ai", adapter: "google", authKind: "key", supportLevel: "experimental", verification: "official", documentationUrl: "https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference", lastVerified: LAST_VERIFIED, discovery: "static", liveModels: false, googleMode: "vertex", models: ["gemini-3.1-pro-preview", "gemini-3.1-flash-lite", "gemini-3-flash-preview"], note: "Vertex accepts an express-mode API key here. ADC users can instead configure project and location through the existing Google Vertex provider." },
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const LABELS: Record<string, string> = {
|
|
148
|
+
agy: "AGY", aihorde: "AI Horde", "api-airforce": "API Airforce", "arcee-ai": "Arcee AI",
|
|
149
|
+
bazaarlink: "BazaarLink", blackbox: "Blackbox", bluesminds: "Bluesminds", "cloudflare-ai": "Cloudflare AI",
|
|
150
|
+
coze: "Coze", "duckduckgo-web": "DuckDuckGo Web", "felo-web": "Felo Web", friendliai: "FriendliAI",
|
|
151
|
+
gemini: "Google Gemini", "github-models": "GitHub Models", huggingchat: "HuggingChat", huggingface: "Hugging Face",
|
|
152
|
+
iflytek: "iFlytek", "inference-net": "Inference.net", llm7: "LLM7", "muse-spark-web": "Muse Spark Web",
|
|
153
|
+
nlpcloud: "NLP Cloud", "ollama-cloud": "Ollama Cloud", ovhcloud: "OVHcloud", "qwen-web": "Qwen Web",
|
|
154
|
+
"t3-web": "T3 Web", uncloseai: "UncloseAI", ainative: "AI Native", baidu: "Baidu Qianfan",
|
|
155
|
+
glm: "Z.AI GLM", "glm-cn": "BigModel GLM (CN)", "kilo-gateway": "Kilo Gateway", "opencode-zen": "OpenCode Zen",
|
|
156
|
+
sealion: "SEA-LION", bytez: "Bytez", "nous-research": "Nous Research", agentrouter: "AgentRouter",
|
|
157
|
+
ai21: "AI21", baichuan: "Baichuan", deepinfra: "DeepInfra", deepseek: "DeepSeek", doubao: "Doubao",
|
|
158
|
+
"freemodel-dev": "FreeModel.dev", sambanova: "SambaNova Cloud", nebius: "Nebius Token Factory",
|
|
159
|
+
novita: "Novita", nscale: "Nscale", nvidia: "NVIDIA NIM",
|
|
160
|
+
publicai: "PublicAI", qoder: "Qoder", sensenova: "SenseNova", stepfun: "StepFun", vertex: "Google Vertex AI",
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const referenceNote = "Reference entry only: no safe documented API integration is enabled. Configure it manually only with provider documentation; consumer-web cookies and anti-bot bypasses are intentionally unsupported.";
|
|
164
|
+
|
|
165
|
+
export const FREE_PROVIDER_DIRECTORY: readonly FreeDirectoryProvider[] = Object.values(FREE_PROVIDER_ACCESS_GROUPS)
|
|
166
|
+
.flat()
|
|
167
|
+
.filter((id, index, ids) => ids.indexOf(id) === index)
|
|
168
|
+
.map(id => {
|
|
169
|
+
const accessGroups = (Object.entries(FREE_PROVIDER_ACCESS_GROUPS) as [ProviderAccessGroup, readonly string[]][])
|
|
170
|
+
.filter(([, ids]) => ids.includes(id))
|
|
171
|
+
.map(([group]) => group);
|
|
172
|
+
const override = CONNECTABLE[id];
|
|
173
|
+
return {
|
|
174
|
+
id,
|
|
175
|
+
label: LABELS[id] ?? id.split("-").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
|
|
176
|
+
adapter: "openai-chat",
|
|
177
|
+
baseUrl: "",
|
|
178
|
+
authKind: "key",
|
|
179
|
+
accessGroups,
|
|
180
|
+
supportLevel: "reference",
|
|
181
|
+
verification: "unverified",
|
|
182
|
+
discovery: "unsupported",
|
|
183
|
+
liveModels: false,
|
|
184
|
+
...(!override ? { note: referenceNote } : {}),
|
|
185
|
+
...override,
|
|
186
|
+
} satisfies FreeDirectoryProvider;
|
|
187
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { OcxProviderConfig } from "../types";
|
|
2
|
+
import {
|
|
3
|
+
GITHUB_COPILOT_DEFAULT_API_BASE,
|
|
4
|
+
GITHUB_COPILOT_EDITOR_HEADERS,
|
|
5
|
+
validateCopilotApiBaseUrl,
|
|
6
|
+
} from "../oauth/github-copilot";
|
|
7
|
+
|
|
8
|
+
export type OcxProviderTransport = OcxProviderConfig & {
|
|
9
|
+
fetch?: typeof globalThis.fetch;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function hasHeaderCaseInsensitive(
|
|
13
|
+
headers: Record<string, string> | undefined,
|
|
14
|
+
name: string,
|
|
15
|
+
): boolean {
|
|
16
|
+
const target = name.toLowerCase();
|
|
17
|
+
return Object.keys(headers ?? {}).some(key => key.toLowerCase() === target);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function withoutUserOverridden(
|
|
21
|
+
defaults: Readonly<Record<string, string>>,
|
|
22
|
+
userHeaders: Record<string, string> | undefined,
|
|
23
|
+
): Record<string, string> {
|
|
24
|
+
return Object.fromEntries(
|
|
25
|
+
Object.entries(defaults).filter(([name]) => !hasHeaderCaseInsensitive(userHeaders, name)),
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Copilot chat requires editor fingerprint headers. Defaults are honest OpenCodex values
|
|
31
|
+
* with Copilot-Integration-Id set to the vscode-chat integration id the public client uses.
|
|
32
|
+
* User-configured headers always win.
|
|
33
|
+
*/
|
|
34
|
+
export function resolveGithubCopilotTransport(
|
|
35
|
+
provider: OcxProviderTransport,
|
|
36
|
+
apiBaseUrl?: string,
|
|
37
|
+
): OcxProviderTransport {
|
|
38
|
+
const stableDefaults = withoutUserOverridden(GITHUB_COPILOT_EDITOR_HEADERS, provider.headers);
|
|
39
|
+
const headers = {
|
|
40
|
+
...stableDefaults,
|
|
41
|
+
...(provider.headers ?? {}),
|
|
42
|
+
};
|
|
43
|
+
// Fail closed: the OAuth bearer only ever goes to an allowlisted *.githubcopilot.com
|
|
44
|
+
// host. A legacy/crafted credential without endpoints.api, or a user-edited baseUrl,
|
|
45
|
+
// must not redirect the token — fall back to the canonical default instead.
|
|
46
|
+
const baseUrl = provider.authMode === "oauth"
|
|
47
|
+
? validateCopilotApiBaseUrl(apiBaseUrl)
|
|
48
|
+
?? validateCopilotApiBaseUrl(provider.baseUrl)
|
|
49
|
+
?? GITHUB_COPILOT_DEFAULT_API_BASE
|
|
50
|
+
: apiBaseUrl?.trim() || provider.baseUrl || GITHUB_COPILOT_DEFAULT_API_BASE;
|
|
51
|
+
return {
|
|
52
|
+
...provider,
|
|
53
|
+
baseUrl,
|
|
54
|
+
headers,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vertex regional hosts are formed as `<location>-aiplatform.googleapis.com`.
|
|
3
|
+
* Restricting the location to one lowercase DNS label keeps user configuration
|
|
4
|
+
* from changing the request authority while remaining forward-compatible with
|
|
5
|
+
* new Google regions and multi-regions.
|
|
6
|
+
*/
|
|
7
|
+
const GOOGLE_VERTEX_LOCATION_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
8
|
+
|
|
9
|
+
export function googleVertexLocationConfigError(location: unknown): string | null {
|
|
10
|
+
if (typeof location !== "string" || !GOOGLE_VERTEX_LOCATION_LABEL.test(location)) {
|
|
11
|
+
return "Vertex AI location must be a single lowercase Google Cloud location label (for example, us-central1 or global)";
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-key 429 failover for non-OpenAI providers.
|
|
3
|
+
*
|
|
4
|
+
* When a provider's upstream returns 429, this module picks the next available key
|
|
5
|
+
* from `apiKeyPool`, puts the exhausted key into cooldown (respecting Retry-After),
|
|
6
|
+
* and returns a fresh provider config with the swapped key. If all keys are in
|
|
7
|
+
* cooldown, returns null so the caller surfaces the 429 to the client.
|
|
8
|
+
*
|
|
9
|
+
* Modelled after src/codex/routing.ts cooldown logic but scoped to plain API-key pools.
|
|
10
|
+
*/
|
|
11
|
+
import { saveConfigPreservingClaudeCode } from "../config";
|
|
12
|
+
import type { OcxConfig, OcxProviderConfig, RateLimitRetryPolicy } from "../types";
|
|
13
|
+
import { resolveProviderTransport, type OcxProviderTransport } from "./xai-transport";
|
|
14
|
+
import { sweepExpiredOnWrite } from "../lib/state-store-sweeper";
|
|
15
|
+
|
|
16
|
+
// ---- cooldown state (in-memory, same as codex/routing.ts) ----
|
|
17
|
+
|
|
18
|
+
interface KeyCooldown {
|
|
19
|
+
cooldownUntil: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DEFAULT_COOLDOWN_MS = 60_000;
|
|
23
|
+
const MAX_COOLDOWN_MS = 10 * 60_000; // cap at 10 min for api-key rotation
|
|
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
|
+
|
|
37
|
+
/** Map<`${providerName}\0${keyId}`, KeyCooldown> */
|
|
38
|
+
const keyCooldowns = new Map<string, KeyCooldown>();
|
|
39
|
+
|
|
40
|
+
function cooldownKey(providerName: string, keyId: string): string {
|
|
41
|
+
return `${providerName}\0${keyId}`;
|
|
42
|
+
}
|
|
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
|
+
*/
|
|
49
|
+
function parseRetryAfterMs(value: string | null | undefined, now = Date.now()): number | undefined {
|
|
50
|
+
const text = value?.trim();
|
|
51
|
+
if (!text) return undefined;
|
|
52
|
+
if (/^\d+(?:\.\d+)?$/.test(text)) {
|
|
53
|
+
const seconds = Number(text);
|
|
54
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
55
|
+
return Math.min(Math.max(Math.ceil(seconds * 1000), 1), MAX_COOLDOWN_MS);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const timestamp = Date.parse(text);
|
|
59
|
+
if (!Number.isFinite(timestamp)) return undefined;
|
|
60
|
+
const delay = timestamp - now;
|
|
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);
|
|
64
|
+
}
|
|
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
|
+
*/
|
|
70
|
+
function isKeyInCooldown(providerName: string, keyId: string, now = Date.now()): boolean {
|
|
71
|
+
const entry = keyCooldowns.get(cooldownKey(providerName, keyId));
|
|
72
|
+
if (!entry) return false;
|
|
73
|
+
if (entry.cooldownUntil <= now) {
|
|
74
|
+
keyCooldowns.delete(cooldownKey(providerName, keyId));
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ---- public API ----
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check whether a provider has multiple keys available for failover.
|
|
84
|
+
* Returns true only for key-auth providers with 2+ pool entries.
|
|
85
|
+
*/
|
|
86
|
+
export function hasKeyPoolFailover(provider: OcxProviderConfig): boolean {
|
|
87
|
+
if (provider.authMode === "oauth" || provider.authMode === "forward") return false;
|
|
88
|
+
return (provider.apiKeyPool?.length ?? 0) >= 2;
|
|
89
|
+
}
|
|
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
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Record a 429 for the current key and attempt to switch to the next available one.
|
|
138
|
+
*
|
|
139
|
+
* @returns A new OcxProviderConfig with the swapped key (and mutated config on disk),
|
|
140
|
+
* or `null` when no alternative key is available (all in cooldown or pool < 2).
|
|
141
|
+
*
|
|
142
|
+
* The returned object is a snapshot of the PERSISTED config — it carries none of the
|
|
143
|
+
* registry backfills `routedProviderConfig` merges in at request time. Request paths must
|
|
144
|
+
* not assign it to an active route wholesale; use `rotateProviderTransportOn429`, which
|
|
145
|
+
* takes only the swapped key and keeps the routed provider intact.
|
|
146
|
+
*/
|
|
147
|
+
export function rotateKeyOn429(
|
|
148
|
+
config: OcxConfig,
|
|
149
|
+
providerName: string,
|
|
150
|
+
retryAfterHeader: string | null | undefined,
|
|
151
|
+
now = Date.now(),
|
|
152
|
+
attemptedKey?: string,
|
|
153
|
+
): OcxProviderConfig | null {
|
|
154
|
+
const provider = config.providers[providerName];
|
|
155
|
+
if (!provider) return null;
|
|
156
|
+
if (provider.authMode === "oauth" || provider.authMode === "forward") return null;
|
|
157
|
+
|
|
158
|
+
const pool = provider.apiKeyPool;
|
|
159
|
+
if (!pool || pool.length < 2) return null;
|
|
160
|
+
|
|
161
|
+
// Cool the key that ACTUALLY failed. Under concurrent 429s another request may already have
|
|
162
|
+
// rotated provider.apiKey — cooling the live key would punish an innocent replacement and can
|
|
163
|
+
// exhaust a 2-key pool from a single bad key. CAS semantics: callers pass the key they used.
|
|
164
|
+
const failedKey = attemptedKey ?? provider.apiKey;
|
|
165
|
+
const currentEntry = pool.find(e => e.key === failedKey);
|
|
166
|
+
if (currentEntry) {
|
|
167
|
+
const cooldownMs = parseRetryAfterMs(retryAfterHeader, now) ?? DEFAULT_COOLDOWN_MS;
|
|
168
|
+
keyCooldowns.set(cooldownKey(providerName, currentEntry.id), {
|
|
169
|
+
cooldownUntil: now + cooldownMs,
|
|
170
|
+
});
|
|
171
|
+
sweepExpiredOnWrite(now);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Lost the race: someone already rotated away from the failed key. If the live key is healthy,
|
|
175
|
+
// retry with it as-is instead of rotating a second time.
|
|
176
|
+
if (attemptedKey !== undefined && provider.apiKey !== attemptedKey) {
|
|
177
|
+
const liveEntry = pool.find(e => e.key === provider.apiKey);
|
|
178
|
+
if (liveEntry && !isKeyInCooldown(providerName, liveEntry.id, now)) {
|
|
179
|
+
return { ...provider };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Pick the next key that is NOT in cooldown
|
|
184
|
+
const currentIndex = currentEntry ? pool.indexOf(currentEntry) : -1;
|
|
185
|
+
for (let i = 1; i < pool.length; i++) {
|
|
186
|
+
const candidate = pool[(currentIndex + i) % pool.length]!;
|
|
187
|
+
if (!isKeyInCooldown(providerName, candidate.id, now)) {
|
|
188
|
+
// Swap active key
|
|
189
|
+
provider.apiKey = candidate.key;
|
|
190
|
+
saveConfigPreservingClaudeCode(config);
|
|
191
|
+
console.warn(
|
|
192
|
+
// Log ids only — labels are user-supplied free text and could carry secret material.
|
|
193
|
+
`[key-failover] ${providerName}: 429 on key ${currentEntry?.id ?? "?"}; rotating to key ${candidate.id}`,
|
|
194
|
+
);
|
|
195
|
+
return { ...provider };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// All keys in cooldown
|
|
200
|
+
console.warn(`[key-failover] ${providerName}: all ${pool.length} keys in cooldown; returning 429 to client`);
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function sweepExpiredApiKeyCooldowns(now = Date.now()): number {
|
|
205
|
+
let removed = 0;
|
|
206
|
+
for (const [key, cooldown] of keyCooldowns) {
|
|
207
|
+
if (cooldown.cooldownUntil > now) continue;
|
|
208
|
+
keyCooldowns.delete(key);
|
|
209
|
+
removed += 1;
|
|
210
|
+
}
|
|
211
|
+
return removed;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
interface RotateProviderTransportOptions {
|
|
215
|
+
retryAfter?: string | null;
|
|
216
|
+
now?: number;
|
|
217
|
+
attemptedKey?: string;
|
|
218
|
+
promptCacheKey?: string;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Rotate a failed key and re-apply provider-specific transport metadata to the replacement.
|
|
223
|
+
*
|
|
224
|
+
* `routedProvider` is the request's active provider (the `routedProviderConfig` output the
|
|
225
|
+
* route was built with). The result inherits it and swaps ONLY the API key: the persisted
|
|
226
|
+
* config that `rotateKeyOn429` snapshots predates registry backfill, so building the retry
|
|
227
|
+
* provider from that snapshot would silently drop every field the registry merged in at
|
|
228
|
+
* routing time (scalar flags like `promptCacheKey`/`parallelToolCalls`, merged model
|
|
229
|
+
* metadata such as `noTemperatureModels`, a pinned baseUrl). Mirrors the OAuth-401 replay
|
|
230
|
+
* path in src/server/responses/core.ts, which spreads `route.provider` for the same reason.
|
|
231
|
+
*/
|
|
232
|
+
export function rotateProviderTransportOn429(
|
|
233
|
+
config: OcxConfig,
|
|
234
|
+
providerName: string,
|
|
235
|
+
routedProvider: OcxProviderTransport,
|
|
236
|
+
options: RotateProviderTransportOptions = {},
|
|
237
|
+
): OcxProviderTransport | null {
|
|
238
|
+
const rotated = rotateKeyOn429(
|
|
239
|
+
config,
|
|
240
|
+
providerName,
|
|
241
|
+
options.retryAfter,
|
|
242
|
+
options.now,
|
|
243
|
+
options.attemptedKey,
|
|
244
|
+
);
|
|
245
|
+
return rotated
|
|
246
|
+
? resolveProviderTransport(
|
|
247
|
+
providerName,
|
|
248
|
+
{ ...routedProvider, apiKey: rotated.apiKey },
|
|
249
|
+
options.promptCacheKey,
|
|
250
|
+
)
|
|
251
|
+
: null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Clear cooldown state for a provider (e.g. after manual key management). */
|
|
255
|
+
export function clearKeyCooldowns(providerName?: string): void {
|
|
256
|
+
if (!providerName) {
|
|
257
|
+
keyCooldowns.clear();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const prefix = `${providerName}\0`;
|
|
261
|
+
for (const key of keyCooldowns.keys()) {
|
|
262
|
+
if (key.startsWith(prefix)) keyCooldowns.delete(key);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Visible-for-testing: get the cooldown-until timestamp for a key. */
|
|
267
|
+
export function getKeyCooldownUntil(providerName: string, keyId: string, now = Date.now()): number | null {
|
|
268
|
+
const entry = keyCooldowns.get(cooldownKey(providerName, keyId));
|
|
269
|
+
if (!entry) return null;
|
|
270
|
+
return entry.cooldownUntil > now ? entry.cooldownUntil : null;
|
|
271
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export const KIRO_MODELS = [
|
|
2
|
+
"kiro-auto",
|
|
3
|
+
// OpenAI GPT-5.6 (Kiro experimental, us-east-1) — added to official catalog 2026-07-13
|
|
4
|
+
"gpt-5.6-sol",
|
|
5
|
+
"gpt-5.6-terra",
|
|
6
|
+
"gpt-5.6-luna",
|
|
7
|
+
"claude-sonnet-5",
|
|
8
|
+
"claude-opus-5",
|
|
9
|
+
"claude-opus-4.8",
|
|
10
|
+
"claude-opus-4.7",
|
|
11
|
+
"claude-opus-4.6",
|
|
12
|
+
"claude-opus-4.5",
|
|
13
|
+
"claude-sonnet-4.6",
|
|
14
|
+
"claude-sonnet-4.5",
|
|
15
|
+
"claude-sonnet-4.0",
|
|
16
|
+
"claude-haiku-4.5",
|
|
17
|
+
"deepseek-3.2",
|
|
18
|
+
"minimax-m2.5",
|
|
19
|
+
"minimax-m2.1",
|
|
20
|
+
"glm-5",
|
|
21
|
+
"qwen3-coder-next",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
// Per-model context windows as documented on Kiro's official model catalog
|
|
25
|
+
// (https://kiro.dev/docs/models/ — "Quick comparison", page updated 2026-07-14).
|
|
26
|
+
// "Auto" is a router with no fixed window on Kiro's table, so it is intentionally omitted.
|
|
27
|
+
export const KIRO_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
|
|
28
|
+
"gpt-5.6-sol": 272_000,
|
|
29
|
+
"gpt-5.6-terra": 272_000,
|
|
30
|
+
"gpt-5.6-luna": 272_000,
|
|
31
|
+
"claude-sonnet-5": 1_000_000,
|
|
32
|
+
"claude-opus-5": 1_000_000,
|
|
33
|
+
"claude-opus-4.8": 1_000_000,
|
|
34
|
+
"claude-opus-4.7": 1_000_000,
|
|
35
|
+
"claude-opus-4.6": 1_000_000,
|
|
36
|
+
"claude-opus-4.5": 200_000,
|
|
37
|
+
"claude-sonnet-4.6": 1_000_000,
|
|
38
|
+
"claude-sonnet-4.5": 200_000,
|
|
39
|
+
"claude-sonnet-4.0": 200_000,
|
|
40
|
+
"claude-haiku-4.5": 200_000,
|
|
41
|
+
"deepseek-3.2": 128_000,
|
|
42
|
+
"minimax-m2.5": 200_000,
|
|
43
|
+
"minimax-m2.1": 200_000,
|
|
44
|
+
"glm-5": 200_000,
|
|
45
|
+
"qwen3-coder-next": 256_000,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const KIRO_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
49
|
+
|
|
50
|
+
// gpt-5.6-sol and claude-opus-5 send these values through Kiro's verified native effort fields
|
|
51
|
+
// (`reasoning.effort` and `output_config.effort` respectively). Other models map them to bounded
|
|
52
|
+
// thinking instructions until their native effort support is verified.
|
|
53
|
+
export const KIRO_MODEL_REASONING_EFFORTS: Record<string, string[]> = Object.fromEntries(
|
|
54
|
+
KIRO_MODELS.map(id => [id, KIRO_REASONING_EFFORTS]),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export function normalizeKiroModelId(id: string): string {
|
|
58
|
+
let model = id.trim().toLowerCase();
|
|
59
|
+
model = model.replace(/^kiro\//, "").replace(/^kiro-/, "");
|
|
60
|
+
if (model === "auto") return "auto";
|
|
61
|
+
|
|
62
|
+
model = model.replace(/-\d{8}$/, "");
|
|
63
|
+
model = model.replace(/-(low|medium|high|xhigh|max)$/, "");
|
|
64
|
+
model = model.replace(/(\d+)-(\d+)/g, "$1.$2");
|
|
65
|
+
model = model.replace(/^claude-([\d.]+)-(sonnet|opus|haiku)$/, "claude-$2-$1");
|
|
66
|
+
return model;
|
|
67
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CODEX_ACCOUNT_LOG_LABEL_RE } from "../codex/account-label";
|
|
2
|
+
|
|
3
|
+
export function canonicalUsageProviderLabel(provider: string): string {
|
|
4
|
+
return provider === "chatgpt" || provider === "openai-multi" ? "openai" : provider;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function baseProviderLabel(provider: string): string {
|
|
8
|
+
const canonical = canonicalUsageProviderLabel(provider);
|
|
9
|
+
if (canonical !== provider) return canonical;
|
|
10
|
+
const cut = provider.lastIndexOf("-");
|
|
11
|
+
if (cut <= 0) return canonicalUsageProviderLabel(provider);
|
|
12
|
+
const suffix = provider.slice(cut + 1);
|
|
13
|
+
// `-main` is the legacy log label for the main Codex account (MAIN_CODEX_ACCOUNT_ID). New entries
|
|
14
|
+
// log under the base provider name, but historical `<provider>-main` entries must still collapse.
|
|
15
|
+
// ChatGPT auth-pool and OpenAI passthrough are the same Codex/OpenAI usage surface, so display
|
|
16
|
+
// summaries normalize them to one `openai` row after recognized main/pool suffixes are removed.
|
|
17
|
+
if (suffix === "main") return canonicalUsageProviderLabel(provider.slice(0, cut));
|
|
18
|
+
return CODEX_ACCOUNT_LOG_LABEL_RE.test(suffix) ? canonicalUsageProviderLabel(provider.slice(0, cut)) : provider;
|
|
19
|
+
}
|