Files
OmniRoute/open-sse/config/providerRegistry.ts
Diego Rodrigues de Sa e Souza f59f8daa94 Release v3.8.6 (#2804)
* fix(gemini): preserve structured tool calls for antigravity

* fix(gemini): parse prefixed textual tool calls

* fix(antigravity): preserve textual SSE tool calls

* fix(stream): normalize textual passthrough tool calls

* fix(stream): normalize split textual tool calls

* fix(stream): suppress malformed textual tool calls

* fix(stream): suppress compact malformed tool calls

* fix(stream): emit structured textual tool calls

* fix(stream): suppress unknown textual tool calls

* fix(stream): normalize responses textual tool calls

* chore: ignore .claude/settings.local.json (per-user Claude Code permissions)

* fix(opencode-go): route qwen3.x via claude messages + repair fixMissingToolResponses for Claude-shape upstreams (#2791)

Integrated into release/v3.8.6

* fix: resolve npm install warnings — remove dead deps, relax engine constraint (#2792)

Integrated into release/v3.8.6

* fix: register missing web-cookie validators (claude-web, gemini-web, copilot-web, t3-web) (#2793)

Integrated into release/v3.8.6

* fix: Error: Unable to inspect existing database #2771 (#2795)

Integrated into release/v3.8.6

* fix(oauth): repair Google loopback callback flow (#2796)

Integrated into release/v3.8.6

* feat(logs): add clean history button (#2799)

Integrated into release/v3.8.6

* [codex] home: restore settings-driven home layout and quota auto-refresh (#2800)

Integrated into release/v3.8.6

* fix(gemini): emit signaturelessToolCallMode:text for GEMINI format models (#2801)

Integrated into release/v3.8.6

* feat(modelSpecs): align opencode-go family with upstream provider limits (#2802)

Integrated into release/v3.8.6

* chore: apply unit test fixes, polyfills, and environment precedence fixes

* docs(agents): atualiza fluxos de release e triagem

Expande os workflows de release para incluir auditoria de segurança,
CHANGELOG completo por commits, quality gate obrigatório, homologação em
VPS local, publicação oficial, deploy em Akamai e validação de artefatos.

Reorganiza a triagem de features com arquivos permanentes por bucket,
suporte a itens em andamento, regra de reclaim após 15 dias e novo
tratamento para ideias viáveis catalogadas.

Corrige a orientação de revisão de discussões para usar a ordem
cronológica real dos comentários e respostas ao identificar a última
atividade.

* fix(lockout): classify Gemini Antigravity resource exhaustion as quota_exhausted

* fix(reasoning): gate replay by interleaved field

* docs(rule-16): permit human Co-authored-by, restrict only AI/bot trailers

Rule #16 previously banned all `Co-Authored-By` trailers absolutely.
That blocked the upstream-port workflows (`/port-upstream-features` and
`/port-upstream-issues`), which must credit human upstream PR authors
and issue reporters in OmniRoute commits.

Refine the rule to ban only AI/bot-attributed trailers (Claude, GPT,
Copilot, Bot; anthropic.com / openai.com / bot-owned noreply.github.com
emails) while allowing standard human `Co-authored-by: Name <email>`
attribution.

Sync the rule across the source CLAUDE.md, the E2E shakedown doc note,
and 41 i18n translations.

* fix(gitlawb): add specialty validators for connection test — bypass /models probe

GitLawB OpenGateway API (xiaomi-mimo compatible) does not expose a /models
endpoint, causing validateOpenAILikeProvider to 404 on the initial probe
and report 'Provider validation endpoint not supported'.

Add specialty validators for both gitlawb and gitlawb-gmi that follow the
same pattern as the existing xiaomi-mimo validator: skip GET /models,
validate directly via POST /chat/completions with a minimal test message.
Any 401/403 response means an invalid key; all other responses mean auth
is OK.

Fixes test-connection returning 404 for GitLawB providers.

* test(gitlawb): add 12 unit tests for gitlawb and gitlawb-gmi specialty validators

Covers success, auth failure (401/403), non-auth acceptance (400/422/429),
network errors, and custom baseUrl overrides for both providers.

* feat(gitlawb): serve models from static registry without API-unavailable warning

GitLawB's OpenGateway API does not expose a /models endpoint per
provider-path. Previously the models route fell through to the generic
fallback which returned static catalog models with the misleading
'API unavailable — using local catalog' warning.

Now gitlawb and gitlawb-gmi are handled as static model providers
(same pattern as reka and qwen OAuth) — models are served from the
provider registry without any warning, since all registered models
are functional via POST /chat/completions.

* refactor(gitlawb): extract shared opengateway validator factory, fix docs path in test

- Extract gitlawb/gitlawb-gmi validators into buildOpengatewayValidator factory
- Fix dockerignore-docs-coverage test: update stale docs/AUTO-COMBO.md -> docs/routing/AUTO-COMBO.md

* fix(reasoning): guard interleaved capability lookup

* feat(gitlawb): dynamic model fetch with gmi-cloud fallback

Hybrid approach:
- gitlawb (xiaomi-mimo): dynamic /models endpoint → 356 models
- gitlawb-gmi (gmi-cloud): 404 fallback → local catalog gracefully
Mimics Gitlawb/openclaude's model-routing pattern

* i18n(pt-BR): complete missing translations and sync with en.json

* feat(build): nix multi-OS package manager install (#2806)

Integrated into release/v3.8.6

* fix(i18n): translate 144 new __MISSING__ pt-BR strings (#2816)

Integrated into release/v3.8.6

* chore(docs): set coverage gate to 40/40/40/40 in CLAUDE.md

Aligns the documented coverage gate with the v3.8.6 release decision
(lowered from 75/75/75/70). Matches the threshold already set in
package.json by the large feature PRs (planos 11-22).

* fix(cli): respect PORT env var in serve command (#2845)

Integrated into release/v3.8.6.

* fix(deepseek-web): return 400 when client sends tools[] - chat.deepseek.com has no tool support (#2854)

Integrated into release/v3.8.6.

* fix(qoder): reject invalid/expired PATs returning Cosy 500 error (#2860)

Integrated into release/v3.8.6.

* fix(cli): register openclaw in tool-detector (#2833) (#2850)

Integrated into release/v3.8.6.

* fix(api): include noAuth providers in /v1/models catalog (#2798) (#2814)

Integrated into release/v3.8.6.

* fix(combo): resolve custom provider targets via combo name (#2778) (#2812)

Integrated into release/v3.8.6.

* fix(translator): strip safety_identifier in openai-responses cleanup (#2770) (#2809)

Integrated into release/v3.8.6.

* fix(quota): honor explicit per-connection preflight opt-out (#2831) (#2844)

Integrated into release/v3.8.6.

* fix(usage): un-invert GitHub Copilot Free/limited quota — limited_user_quotas is remaining (#2876) (#2881)

Integrated into release/v3.8.6.

* fix(nous-research): correct baseUrl to include /chat/completions (#2826) (#2835)

Integrated into release/v3.8.6.

* fix(opencode): qwen3.x max/plus models lack vision support (#2822) (#2836)

Integrated into release/v3.8.6.

* fix(translator): pass-through tool_search built-in tool type (#2766) (#2811)

Integrated into release/v3.8.6.

* fix(github): route claude-opus-4.6 via chat completions (#2821)

Integrated into release/v3.8.6.

* docs(oauth): add Windsurf login fix design (Phase 1 hotfix + Phase 2 Firebase OAuth)

Two-phase plan to fix the broken Windsurf OAuth flow:
- Phase 1: drop the dead app.devin.ai/editor/signin PKCE path, promote
  import-token from windsurf.com/show-auth-token as the primary path
- Phase 2: port Firebase OAuth + RegisterUser flow from
  fendoushaonian/WindSurf-gRPC-API for full browser-based automation

Spec only - no code changes yet.

* docs(plan): Phase 1 windsurf login hotfix implementation plan

10 tasks covering:
- TDD assertions for flowType + 410 Gone responses
- Provider switch to import_token
- Route handler retiring authorize/start-callback-server/poll-callback
- OAuthModal UI override
- i18n sync
- Verification + PR steps

* fix(cli): replace cli-table3 with hand-rolled formatter (#2752) (#2813)

Integrated into release/v3.8.6.

* fix(skills): skip interception for unregistered client-native tools (#2815) (#2817)

Integrated into release/v3.8.6.

* feat(sse): add RTK filters for kubectl, docker-build, composer, gh (#2824)

Integrated into release/v3.8.6.

* fix(geminiHelper): support rec.image content shape + warn on dropped remote URLs (refs #2807) (#2855)

Integrated into release/v3.8.6.

* fix(cli): allow nullable/optional apiKey in cliMitmStartSchema (#2857)

Integrated into release/v3.8.6.

* fix(combo): preserve system messages during context handoff summary generation (#2865)

Integrated into release/v3.8.6.

* fix: wire CLIProxyAPI fallback settings into chatCore routing engine (#2866)

Integrated into release/v3.8.6.

* fix(usage): add opencode quota fetcher (#2852) (#2867)

Integrated into release/v3.8.6.

* feat(claude): default xhigh support for newer Opus models (#2874)

Integrated into release/v3.8.6.

* fix(cli): restore omniroute logs command stream (#2756) (#2810)

Integrated into release/v3.8.6.

* fix(combo): normalize upstream Headers for Node 24 undici interop (#2751) (#2823)

Integrated into release/v3.8.6.

* Rename proxy log Public IP to Client IP (#2880)

Integrated into release/v3.8.6.

* fix(claude): preserve max effort for supported models (#2875)

Integrated into release/v3.8.6.

* fix(oauth): switch windsurf provider to import_token flow

The PKCE auth URL targeting app.devin.ai/editor/signin returns 404
post-rebrand. Until Phase 2 ports Firebase OAuth + RegisterUser, the
only supported path is import-token via windsurf.com/show-auth-token.

- windsurf.ts: drop buildAuthUrl, set flowType=import_token
- generateAuthData returns supported:false + helpful error for windsurf/devin-cli
- tests: assert flowType + disabled stub

* fix(oauth): return 410 Gone for retired windsurf/devin-cli PKCE actions

start-callback-server, authorize, and poll-callback (GET + POST) now
return 410 Gone with a pointer to /import-token. The 410 short-circuit
runs before auth so the response is honest about the action being
permanently gone, not gated. Codex PKCE flow unchanged.

Tests: 5 new assertions cover GET + POST 410 paths and a Codex
regression check.

* refactor(oauth): annotate retired PKCE fields in WINDSURF_CONFIG

No behaviour change - comment-only update documenting that authorizeUrl,
codeChallengeMethod, callbackPort, callbackPath, apiServerUrl, and
exchangePath are no longer consumed. Active fields (inferenceUrl,
showAuthTokenUrl, firebaseApiKey, ideName) called out separately.

* fix(cli,docs): use requireCliToolsAuth in logs route + document OPENCODE quota env

Post-merge contract fixes for v3.8.6:
- src/app/api/cli-tools/logs/route.ts (#2810) now uses the shared
  requireCliToolsAuth guard (param renamed req->request) to satisfy the
  cli-tools-auth-hardening contract test.
- Document OMNIROUTE_OPENCODE_QUOTA_URL (#2867) in docs/reference/ENVIRONMENT.md
  to satisfy the env/docs sync contract.

* fix(dashboard): force import-token panel for windsurf/devin-cli

Phase 1 hotfix: hide the 'Browser Login' tab and start in Paste API Key
mode. Removes windsurf/devin-cli from PKCE_CALLBACK_SERVER_PROVIDERS so
no callback server is started for them. Codex still uses the PKCE flow.

The 'Get token' link continues to point at windsurf.com/show-auth-token
via the existing supportsTokenPaste form copy.

* fix(oauth): windsurf import-token mapTokens signature mismatch

The route at `src/app/api/oauth/[provider]/[action]/route.ts` invokes
`providerData.mapTokens({ accessToken: token })` (object), matching the
cursor/kiro signature. The windsurf provider was declared with
`mapTokens(token: string)` instead, so the entire object was stored as
`accessToken`. When the connection record reached the SQLite layer it
crashed with:

  SQLite3 can only bind numbers, strings, bigints, buffers, and null

Fix by aligning windsurf's `mapTokens` signature with the route caller
and the cursor/kiro convention. Also dedupe a copy-pasted second
`if (action === "import-token")` block in the route handler — the
second block was unreachable but identical to the first.

Adds two regression tests asserting that
`provider.mapTokens({ accessToken })` returns a string `accessToken` for
both windsurf and devin-cli, so a future signature drift trips the gate
instead of the SQLite bind error in production.

* feat(compression): expand pt-BR pack with troglodita rules (15 → 49) (#2818)

Integrated into release/v3.8.6

* fix(sse): repair RTK engine defaults so dedup and direct calls work (#2825)

Integrated into release/v3.8.6

* fix(mcp): redirect console.log/warn to stderr in --mcp stdio mode (#2840)

Integrated into release/v3.8.6

* fix(gemini-cli): prefer real project IDs over default-project (#2841)

Integrated into release/v3.8.6

* fix(opencode-go): add provider limits quota fetcher (#2861)

Integrated into release/v3.8.6

* Audit & add web cookie providers: fix 4 missing registry entries + DuckDuckGo (#2862)

Integrated into release/v3.8.6

* fix(antigravity): harden signatureless tool history (#2878)

Integrated into release/v3.8.6

* fix: provider model sync pruning and dynamic antigravity MITM proxy mappings (#2886)

Integrated into release/v3.8.6

* feat(usage): per-API-key token limits scoped to model/provider/global (#2888)

Integrated into release/v3.8.6

* fix(audio): build multipart body manually to preserve Content-Type (#2842)

Integrated into release/v3.8.6

* refactor: remove agent skill documentation files and streamline maintenance workflows

* test(stabilization): resolve unit test failures in blackbox-web, schema-coercion, translator-helper-branches, usage-service-hardening, and audio-transcription

* fix(security): mitigate Socket.dev supply-chain findings + secrets opt-in + minimal build profile (#2863) (#2871)

Two real security gaps closed and four cosmetic Socket.dev fingerprints removed.
See docs/security/SOCKET_DEV_FINDINGS.md for the per-finding maintainer
attestation.

Real bugs fixed:
- cloudSync: HMAC verification of `X-Cloud-Sig` + opt-in
  `OMNIROUTE_CLOUD_SYNC_SECRETS=true` before overwriting `accessToken` /
  `refreshToken` / `providerSpecificData` from a remote response. Closes the
  silent-credential-swap surface (a misconfigured or hostile CLOUD_URL could
  previously replace local tokens unverified).
- Zed import: split into 2-step `/discover` + `/import` flow. `/import` now
  requires `confirmedAccounts: [{ service, account, fingerprint }]` and
  re-reads the keychain server-side to filter by fingerprint, so a tampered
  discover response cannot trick the endpoint into saving an unrelated token.

Cosmetic Socket.dev mitigations:
- runElevatedPowerShell writes the elevated payload to a per-call temp `.ps1`
  file (mode 0o600) and references it via `-File`. Removes the textbook
  `-EncodedCommand <base64utf16le>` pattern flagged as malware by Socket's AI
  classifier.
- Maintainer attestation `SECURITY-AUDITOR-NOTE:` blocks added at every
  flagged call site pointing to `docs/security/SOCKET_DEV_FINDINGS.md`.

Build-time hardening:
- `OMNIROUTE_BUILD_PROFILE=minimal` (`npm run build:secure`) physically
  removes the four sensitive modules from the standalone bundle via webpack
  `NormalModuleReplacementPlugin`. Stubs throw `FeatureDisabledError` at
  runtime. Intended for the `omniroute-secure` artifact.

Tests:
- 24 new unit tests in `tests/unit/security/` covering the wrapper builder,
  HMAC verification (4 cases), credential fingerprint determinism (5 cases),
  confirmedAccounts validation + fingerprint filtering (6 cases), and the
  minimal-build stubs (5 cases).

Docs:
- New `docs/security/SOCKET_DEV_FINDINGS.md` — per-finding attestation.
- New `socket.yml` — Socket.dev v2 config pointing at the attestation.
- Updated `SECURITY.md` — supply-chain scanner section.
- Updated `.env.example` — three new env vars documented.

Backwards compatibility:
- Cloud sync token overwrite is OFF by default. Users who relied on
  it must set `OMNIROUTE_CLOUD_SYNC_SECRETS=true`. Breaking change documented
  in CHANGELOG.
- Zed import 2-step is the new default; legacy 1-step preserved behind
  `OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true` and will be removed in v3.9.

Closes #2863

* fix(security): redact public Firebase Web key from windsurf spec; doc SHA-256 cache-key rationale (#2894)

Two security-scanning findings on release/v3.8.6:

- Secret-scanning alert 7 (google_api_key): the windsurf login-fix design spec
  embedded the literal public Firebase Web API key on two lines. Firebase Web
  API keys are non-sensitive by design (they identify the project; access is
  gated by Firebase Security Rules + key restrictions), but the literal trips
  secret scanning. Redacted to a placeholder; the embedded default still goes
  through resolvePublicCred per rule #11.

- Code-scanning alert 261 (js/insufficient-password-hash): tokenCacheKey() uses
  SHA-256 to derive an in-memory cache key from the session token, not for
  password-at-rest storage. Added a comment documenting why CWE-916 KDFs do not
  apply (false positive).

* fix(ci): resolve release/v3.8.6 gate failures (docs-sync, any-budget, pack-artifact) (#2895)

* fix(ci): resolve release/v3.8.6 gate failures (docs-sync, any-budget, pack-artifact)

Three CI gates failed on release/v3.8.6 (run 26630300877):

- docs-sync: CHANGELOG had a spurious "## [3.8.6-patch]" section above
  "## [3.8.6]", so the latest release no longer matched package.json (3.8.6)
  and the 41 i18n CHANGELOG mirrors were flagged as missing that section.
  Fold the lone #2752 entry into [3.8.6] and drop the patch heading.
- any-budget:t11: open-sse/handlers/chatCore.ts regressed to 1 explicit `any`
  (budget 0). Type the persist callback arg as Record<string, unknown>, which
  matches runWithOnPersist's RefreshPersistFn contract exactly.
- pack-artifact: open-sse/utils/setupPolyfill.ts ships via package.json "files"
  (bin/omniroute.mjs imports it at startup) but was missing from the pack
  policy allowlist. Allow it and add a regression test.

* fix(security): redact public Firebase Web key from windsurf spec

Redact the literal public Firebase Web API key (secret-scanning #7) to a
placeholder, mirroring the redaction on release/v3.8.6 (PR #2894) and the
windsurf fix branch. Non-sensitive public Web key; trips secret scanning.

* feat(combo): Zero-Latency Combos (Hedging, Proactive Compression, Predictive TTFT) (#2868)

* feat(combo): implement zero-latency combo optimizations (hedging, proactive compression, predictive TTFT)

* fix(combo): fix predictive TTFT skip logic and unhandled promise rejections

---------

Co-authored-by: Automation <automation@omniroute>

* feat: implement automated skill workflows and update system configuration and validation schemas

* test: eliminate dynamic cast warnings in cloud-sync unit test

* test: isolate services-branch-hardening database directory to avoid concurrency issues

* feat(providers): add 7 new web-cookie providers + research catalog + discovery tool

New providers:
- huggingchat: free LLM chat via huggingface.co/chat (no subscription)
- phind: free dev-focused AI chat via phind.com/api/agent
- poe-web: multi-model chat via poe.com GraphQL (p-b cookie)
- venice-web: privacy-focused AI chat via venice.ai (session cookie)
- v0-vercel-web: Vercel v0 code gen via v0.dev (session cookie)
- kimi-web: Moonshot Kimi chat via kimi.moonshot.cn (session cookie)
- doubao-web: ByteDance Doubao chat via doubao.com (session cookie)

Additional:
- Research catalog: docs/research/UNLIMITED_LLM_ACCESS.md
- Discovery tool design + stub: src/lib/discovery/ + migration 073
- Unit tests: 33 tests for all 7 providers
- Shared helpers consolidated in error.ts (slop cleanup)
- All registered in WEB_COOKIE_PROVIDERS + providerRegistry + webSessionCredentials

Closes #2885

* fix(typecheck): resolve typecheck errors in combo spec and compression modules

* feat(api,oauth): add `agy` (Antigravity CLI) standalone provider with CLI token import (#2899)

Add a standalone OAuth provider `agy` (Antigravity CLI) next to gemini-cli/antigravity.
It reuses the antigravity inference backend (identical Google client_id +
daily-cloudcode-pa.googleapis.com endpoint, executor and token-refresh) but ships its own
model catalog — including the Claude models the backend exposes (claude-opus-4-6-thinking,
claude-sonnet-4-6) — its own account pool, and four ways to connect:

- token-file import (paste/upload the agy oauth token JSON)
- auto-detect a local CLI login (~/.gemini/antigravity-cli/antigravity-oauth-token)
- browser OAuth (via the shared OAuthModal Google loopback flow)
- bulk / ZIP import

New routes: POST /api/providers/agy-auth/{import,import-bulk,zip-extract,apply-local}.
Catalog pinned from the live :fetchAvailableModels endpoint. Docs (openapi.yaml,
ENVIRONMENT.md, .env.example, CHANGELOG) updated; new unit tests for registration,
the token parser, and route auth-hardening.

* fix(security): redact public Firebase Web key from windsurf spec (#2896)

Redact the literal public Firebase Web API key (secret-scanning #7) to a
placeholder. Firebase Web API keys are non-sensitive by design but the literal
trips GitHub secret scanning. Mirrors the redaction landed on release/v3.8.6
(PR #2894). Embedded default still flows through resolvePublicCred (rule #11).

* Pr 2871 (#2897)

* fix(security): mitigate Socket.dev supply-chain findings + secrets opt-in + minimal build profile (#2863)

Two real security gaps closed and four cosmetic Socket.dev fingerprints removed.
See docs/security/SOCKET_DEV_FINDINGS.md for the per-finding maintainer
attestation.

Real bugs fixed:
- cloudSync: HMAC verification of `X-Cloud-Sig` + opt-in
  `OMNIROUTE_CLOUD_SYNC_SECRETS=true` before overwriting `accessToken` /
  `refreshToken` / `providerSpecificData` from a remote response. Closes the
  silent-credential-swap surface (a misconfigured or hostile CLOUD_URL could
  previously replace local tokens unverified).
- Zed import: split into 2-step `/discover` + `/import` flow. `/import` now
  requires `confirmedAccounts: [{ service, account, fingerprint }]` and
  re-reads the keychain server-side to filter by fingerprint, so a tampered
  discover response cannot trick the endpoint into saving an unrelated token.

Cosmetic Socket.dev mitigations:
- runElevatedPowerShell writes the elevated payload to a per-call temp `.ps1`
  file (mode 0o600) and references it via `-File`. Removes the textbook
  `-EncodedCommand <base64utf16le>` pattern flagged as malware by Socket's AI
  classifier.
- Maintainer attestation `SECURITY-AUDITOR-NOTE:` blocks added at every
  flagged call site pointing to `docs/security/SOCKET_DEV_FINDINGS.md`.

Build-time hardening:
- `OMNIROUTE_BUILD_PROFILE=minimal` (`npm run build:secure`) physically
  removes the four sensitive modules from the standalone bundle via webpack
  `NormalModuleReplacementPlugin`. Stubs throw `FeatureDisabledError` at
  runtime. Intended for the `omniroute-secure` artifact.

Tests:
- 24 new unit tests in `tests/unit/security/` covering the wrapper builder,
  HMAC verification (4 cases), credential fingerprint determinism (5 cases),
  confirmedAccounts validation + fingerprint filtering (6 cases), and the
  minimal-build stubs (5 cases).

Docs:
- New `docs/security/SOCKET_DEV_FINDINGS.md` — per-finding attestation.
- New `socket.yml` — Socket.dev v2 config pointing at the attestation.
- Updated `SECURITY.md` — supply-chain scanner section.
- Updated `.env.example` — three new env vars documented.

Backwards compatibility:
- Cloud sync token overwrite is OFF by default. Users who relied on
  it must set `OMNIROUTE_CLOUD_SYNC_SECRETS=true`. Breaking change documented
  in CHANGELOG.
- Zed import 2-step is the new default; legacy 1-step preserved behind
  `OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true` and will be removed in v3.9.

Closes #2863

* feat: implement automated skill workflows and update system configuration and validation schemas

* test: eliminate dynamic cast warnings in cloud-sync unit test

* test: isolate services-branch-hardening database directory to avoid concurrency issues

* chore(docs): refresh generated docs collection index

Update the generated Fumadocs browser collection mapping to keep
documentation imports in sync with the current docs structure.

* docs: update generated browser docs collection manifest

Refresh the generated Fumadocs browser collection mapping so the docs site can resolve the current documentation files correctly.

---------

Co-authored-by: OpenClaw <openclaw@kuzhomesrv.local>
Co-authored-by: Dmitry Kuznetsov <139351986+dmitry@users.noreply.local>
Co-authored-by: KuzyaBot <kuzya@local>
Co-authored-by: JeferssonLemes <jeferssondev@gmail.com>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: akarray <akarray@users.noreply.github.com>
Co-authored-by: Apostol Apostolov <theapoapostolov@gmail.com>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Dmitry Kuznetsov <dmitry@kuznetsov.me>
Co-authored-by: Nikolay Alafuzov <alafuzov_nn@rusklimat.ru>
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
Co-authored-by: Ronaldo Davi <alltomatos@users.noreply.github.com>
Co-authored-by: levonk <277861+levonk@users.noreply.github.com>
Co-authored-by: Lenine Júnior <lenine@engrene.com.br>
Co-authored-by: Annas Alghoffar <aag.annas@gmail.com>
Co-authored-by: Tushar Agarwal <76201310+Tushar49@users.noreply.github.com>
Co-authored-by: GreatLiu <eurasiaxz@qq.com>
Co-authored-by: yuna amelia <230527278+yunaamelia@users.noreply.github.com>
Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: Container <78986709+disonjer@users.noreply.github.com>
Co-authored-by: nickwizard <35692452+nickwizard@users.noreply.github.com>
Co-authored-by: Rajvardhan Patil <rajvardhanpatil7890@gmail.com>
Co-authored-by: Raxxoor <manker_lol@hotmail.com>
Co-authored-by: Muhammad Mugni Hadi <mugnimaestra3@gmail.com>
Co-authored-by: mi <123757457+soyelmismo@users.noreply.github.com>
Co-authored-by: Automation <automation@omniroute>
2026-05-29 12:44:29 -03:00

4448 lines
154 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Provider Registry — Single source of truth for all provider configuration.
*
* Adding a new provider? Just add an entry here. Everything else
* (PROVIDERS, PROVIDER_MODELS, PROVIDER_ID_TO_ALIAS, executor lookup)
* is auto-generated from this registry.
*/
import { ANTIGRAVITY_BASE_URLS } from "./antigravityUpstream.ts";
import { ANTIGRAVITY_PUBLIC_MODELS } from "./antigravityModelAliases.ts";
import { AGY_PUBLIC_MODELS } from "./agyModels.ts";
import {
ANTHROPIC_BETA_API_KEY,
ANTHROPIC_BETA_CLAUDE_OAUTH,
ANTHROPIC_VERSION_HEADER,
CLAUDE_CLI_STAINLESS_PACKAGE_VERSION,
CLAUDE_CLI_STAINLESS_RUNTIME_VERSION,
CLAUDE_CLI_USER_AGENT,
} from "./anthropicHeaders.ts";
import { getCodexDefaultHeaders } from "./codexClient.ts";
import {
GLM_REQUEST_DEFAULTS,
GLMT_REQUEST_DEFAULTS,
GLM_TIMEOUT_MS,
GLMT_TIMEOUT_MS,
GLM_SHARED_MODELS,
} from "./glmProvider.ts";
import { MARITALK_DEFAULT_BASE_URL } from "./maritalk.ts";
import {
CURSOR_REGISTRY_VERSION,
getAntigravityProviderHeaders,
getCursorRegistryHeaders,
getGitHubCopilotChatHeaders,
getKiroServiceHeaders,
getQoderDefaultHeaders,
getQwenOauthHeaders,
getRuntimePlatform,
getRuntimeArch,
} from "./providerHeaderProfiles.ts";
import type { ProviderRequestDefaults } from "../services/providerRequestDefaults.ts";
import { resolvePublicCred } from "../utils/publicCreds.ts";
import { buildGitLabOAuthEndpoints, GITLAB_DUO_DEFAULT_BASE_URL } from "@/lib/oauth/gitlab";
// ── Types ─────────────────────────────────────────────────────────────────
export interface RegistryModel {
id: string;
name: string;
toolCalling?: boolean;
supportsReasoning?: boolean;
supportsVision?: boolean;
supportsXHighEffort?: boolean;
maxOutputTokens?: number;
targetFormat?: string;
strip?: readonly string[];
unsupportedParams?: readonly string[];
/** Maximum context window in tokens */
contextLength?: number;
}
// Reasoning models reject temperature, top_p, penalties, logprobs, n.
// Frozen to prevent accidental mutation (shared across all model entries).
const REASONING_UNSUPPORTED: readonly string[] = Object.freeze([
"temperature",
"top_p",
"frequency_penalty",
"presence_penalty",
"logprobs",
"top_logprobs",
"n",
]);
export interface RegistryOAuth {
clientIdEnv?: string;
clientIdDefault?: string;
clientSecretEnv?: string;
clientSecretDefault?: string;
tokenUrl?: string;
refreshUrl?: string;
authUrl?: string;
initiateUrl?: string;
pollUrlBase?: string;
}
export interface RegistryEntry {
id: string;
alias?: string;
format: string;
executor: string;
baseUrl?: string;
baseUrls?: string[];
/** Override base URL used only for API key validation (e.g., opencode-go validates on zen/v1) */
testKeyBaseUrl?: string;
responsesBaseUrl?: string;
urlSuffix?: string;
urlBuilder?: (base: string, model: string, stream: boolean) => string;
authType: string;
authHeader: string;
authPrefix?: string;
headers?: Record<string, string>;
extraHeaders?: Record<string, string>;
requestDefaults?: ProviderRequestDefaults;
oauth?: RegistryOAuth;
models: RegistryModel[];
modelsUrl?: string;
/** Prefix to prepend to model IDs before upstream API calls (e.g. "accounts/fireworks/models/") */
modelIdPrefix?: string;
chatPath?: string;
clientVersion?: string;
timeoutMs?: number;
passthroughModels?: boolean;
/** Default context window for all models in this provider (can be overridden per-model) */
defaultContextLength?: number;
}
interface LegacyProvider {
format: string;
baseUrl?: string;
baseUrls?: string[];
responsesBaseUrl?: string;
headers?: Record<string, string>;
requestDefaults?: ProviderRequestDefaults;
clientId?: string;
clientSecret?: string;
tokenUrl?: string;
refreshUrl?: string;
authUrl?: string;
chatPath?: string;
clientVersion?: string;
timeoutMs?: number;
}
const KIMI_CODING_SHARED = {
format: "claude",
executor: "default",
baseUrl: "https://api.kimi.com/coding/v1/messages",
authHeader: "x-api-key",
// Kimi K2.6 native context per Moonshot platform docs and cross-provider
// catalog (openrouter, moonshot, ali, deepinfra, etc. all advertise 262144).
// Without this, contextManager.ts:getTokenLimit falls back to
// DEFAULT_LIMITS.default = 128000 because the Kimi Code OAuth product is
// not synced via models.dev. The under-reported value cascades into
// /v1/models advertised context_length=128000 and downstream client
// assumptions about prompt budget (e.g. Capy computing
// prompt_cap = context_length - request.max_tokens).
defaultContextLength: 262144,
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
},
models: [
{
id: "kimi-k2.6",
name: "Kimi K2.6",
contextLength: 262144,
maxOutputTokens: 262144,
supportsVision: true,
},
{
id: "kimi-k2.6-thinking",
name: "Kimi K2.6 Thinking",
contextLength: 262144,
maxOutputTokens: 262144,
},
] as RegistryModel[],
} as const;
const buildModels = (ids: readonly string[]): RegistryModel[] =>
ids.map((id) => ({ id, name: id }));
const ALIBABA_DASHSCOPE_MODELS: RegistryModel[] = [
{ id: "qwen-max", name: "Qwen Max" },
{ id: "qwen-max-2025-01-25", name: "Qwen Max (2025-01-25)" },
{ id: "qwen-plus", name: "Qwen Plus" },
{ id: "qwen-plus-2025-07-14", name: "Qwen Plus (2025-07-14)" },
{ id: "qwen-turbo", name: "Qwen Turbo" },
{ id: "qwen-turbo-2025-11-01", name: "Qwen Turbo (2025-11-01)" },
{ id: "qwen3-coder-plus", name: "Qwen3 Coder Plus" },
{ id: "qwen3-coder-flash", name: "Qwen3 Coder Flash" },
{ id: "qwq-plus", name: "QwQ Plus (Reasoning)" },
{ id: "qwq-32b", name: "QwQ 32B" },
{ id: "qwen3-32b", name: "Qwen3 32B" },
{ id: "qwen3-235b-a22b", name: "Qwen3 235B A22B" },
];
const GPT_5_5_CONTEXT_LENGTH = 1050000;
const GPT_5_5_CODEX_CAPABILITIES = {
targetFormat: "openai-responses",
toolCalling: true,
supportsReasoning: true,
supportsVision: true,
supportsXHighEffort: true,
contextLength: GPT_5_5_CONTEXT_LENGTH,
} as const;
const CHAT_OPENAI_COMPAT_MODELS: Record<string, RegistryModel[]> = {
deepinfra: buildModels([
"anthropic/claude-4-opus",
"anthropic/claude-4-sonnet",
"openai/gpt-oss-120b",
"openai/gpt-oss-20b",
"google/gemma-4-31B-it",
"google/gemma-4-26B-A4B-it",
"nvidia/NVIDIA-Nemotron-3-Super-120B-A12B",
"nvidia/Nemotron-3-Nano-Omni-30B-A3B-Reasoning",
"meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8",
"meta-llama/Llama-4-Scout-17B-16E-Instruct",
"meta-llama/Llama-3.3-70B-Instruct-Turbo",
"NousResearch/Hermes-3-Llama-3.1-405B",
"deepseek-ai/DeepSeek-V4-Pro",
"deepseek-ai/DeepSeek-V4-Flash",
"zai-org/GLM-5.1",
"moonshotai/Kimi-K2.6",
"MiniMaxAI/MiniMax-M2.5",
"Qwen/Qwen3.6-35B-A3B",
"Qwen/Qwen3.5-397B-A17B",
"Qwen/Qwen3.5-122B-A10B",
"XiaomiMiMo/MiMo-V2.5-Pro",
"XiaomiMiMo/MiMo-V2.5",
]),
"vercel-ai-gateway": buildModels([
"openai/gpt-4.1",
"anthropic/claude-4-sonnet",
"google/gemini-2.5-pro",
"moonshotai/kimi-k2",
"vercel/v0-1.5-md",
]),
"lambda-ai": buildModels([
"deepseek-r1-671b",
"llama3.3-70b-instruct-fp8",
"qwen25-coder-32b-instruct",
]),
sambanova: buildModels([
"MiniMax-M2.7",
"DeepSeek-V3.2",
"Llama-4-Maverick-17B-128E-Instruct",
"Meta-Llama-3.3-70B-Instruct",
"gpt-oss-120b",
]),
nscale: buildModels([
"moonshotai/Kimi-K2.5",
"Qwen/Qwen3-235B-A22B-Instruct-2507",
"openai/gpt-oss-120b",
"openai/gpt-oss-20b",
"meta-llama/Llama-4-Scout-17B-16E-Instruct",
"meta-llama/Llama-3.3-70B-Instruct",
]),
ovhcloud: buildModels([
"Meta-Llama-3_3-70B-Instruct",
"Qwen2.5-Coder-32B-Instruct",
"Mistral-Small-3.2-24B-Instruct-2506",
]),
baseten: buildModels([
"moonshotai/Kimi-K2.6",
"deepseek-ai/DeepSeek-V4-Pro",
"zai-org/GLM-5",
"MiniMaxAI/MiniMax-M2.5",
"nvidia/Nemotron-120B-A12B",
"openai/gpt-oss-120b",
]),
publicai: buildModels([
"swiss-ai/apertus-70b-instruct",
"aisingapore/Qwen-SEA-LION-v4-32B-IT",
"allenai/Olmo-3-32B-Think",
]),
moonshot: buildModels(["kimi-k2.6", "kimi-k2.5"]),
"meta-llama": buildModels([
"Llama-4-Maverick-17B-128E-Instruct-FP8",
"Llama-4-Scout-17B-16E-Instruct-FP8",
"Llama-3.3-70B-Instruct",
]),
"v0-vercel": buildModels(["v0-1.0-md", "v0-1.5-lg", "v0-1.5-md"]),
morph: buildModels(["morph-v3-large", "morph-v3-fast"]),
"featherless-ai": buildModels(["featherless-ai/Qwerky-72B", "featherless-ai/Qwerky-QwQ-32B"]),
friendliai: buildModels(["meta-llama-3.1-70b-instruct", "meta-llama-3.1-8b-instruct"]),
llamagate: buildModels(["qwen2.5-coder-7b", "deepseek-coder-6.7b", "qwen3-vl-8b"]),
heroku: buildModels([
"claude-opus-4-7",
"claude-4-6-sonnet",
"claude-4-5-haiku",
"glm-4-7",
"kimi-k2-5",
"minimax-m2-1",
"deepseek-v3-2",
"qwen3-coder-480b",
"qwen3-235b",
"gpt-oss-120b",
"nova-pro",
"nova-2-lite",
]),
galadriel: buildModels(["galadriel-latest"]),
databricks: buildModels([
"databricks-gpt-5",
"databricks-meta-llama-3-3-70b-instruct",
"databricks-claude-sonnet-4",
"databricks-gemini-2-5-pro",
]),
snowflake: buildModels(["llama3.1-70b", "llama3.3-70b", "deepseek-r1", "claude-3-5-sonnet"]),
wandb: buildModels([
"openai/gpt-oss-120b",
"Qwen/Qwen3-Coder-480B-A35B-Instruct",
"deepseek-ai/DeepSeek-V3.1",
]),
volcengine: buildModels([
"deepseek-v3-2-251201",
"doubao-seed-2-0-code-preview-260215",
"kimi-k2-thinking-251104",
"glm-4-7-251222",
]),
ai21: buildModels(["jamba-large-1.7", "jamba-mini-2"]),
gigachat: buildModels(["GigaChat-2-Max", "GigaChat-2-Pro", "GigaChat-2-Lite"]),
venice: buildModels(["venice-latest"]),
codestral: buildModels(["codestral-2405", "codestral-latest"]),
upstage: buildModels(["solar-pro3", "solar-mini"]),
maritalk: buildModels(["sabia-4", "sabia-3.1", "sabiazinho-4", "sabiazinho-3"]),
"xiaomi-mimo": [
{ id: "mimo-v2.5-pro", name: "MiMo-V2.5-Pro", contextLength: 1048576, maxOutputTokens: 131072 },
{ id: "mimo-v2.5", name: "MiMo-V2.5", contextLength: 1048576, maxOutputTokens: 131072 },
{ id: "mimo-v2-omni", name: "MiMo-V2-Omni", contextLength: 262144, maxOutputTokens: 131072 },
{ id: "mimo-v2-flash", name: "MiMo-V2-Flash", contextLength: 262144, maxOutputTokens: 65536 },
],
gitlawb: [
{ id: "mimo-v2.5-pro", name: "MiMo-V2.5-Pro", contextLength: 1048576, maxOutputTokens: 131072 },
{ id: "mimo-v2.5", name: "MiMo-V2.5", contextLength: 1048576, maxOutputTokens: 131072 },
{ id: "mimo-v2-pro", name: "MiMo-V2-Pro", contextLength: 262144, maxOutputTokens: 131072 },
{ id: "mimo-v2-omni", name: "MiMo-V2-Omni", contextLength: 262144, maxOutputTokens: 131072 },
{ id: "mimo-v2-flash", name: "MiMo-V2-Flash", contextLength: 262144, maxOutputTokens: 65536 },
],
"gitlawb-gmi": [
{
id: "XiaomiMiMo/MiMo-V2.5-Pro",
name: "MiMo-V2.5-Pro (GMI)",
contextLength: 1050000,
maxOutputTokens: 131072,
},
{
id: "XiaomiMiMo/MiMo-V2.5",
name: "MiMo-V2.5 (GMI)",
contextLength: 1050000,
maxOutputTokens: 131072,
},
{ id: "openai/gpt-5.5", name: "GPT-5.5", contextLength: 1050000, maxOutputTokens: 131072 },
{
id: "openai/gpt-5.4-pro",
name: "GPT-5.4 Pro",
contextLength: 409600,
maxOutputTokens: 131072,
},
{ id: "openai/gpt-5.4", name: "GPT-5.4", contextLength: 409600, maxOutputTokens: 131072 },
{
id: "openai/gpt-5.4-mini",
name: "GPT-5.4 Mini",
contextLength: 409600,
maxOutputTokens: 131072,
},
{
id: "openai/gpt-5.4-nano",
name: "GPT-5.4 Nano",
contextLength: 409600,
maxOutputTokens: 131072,
},
{
id: "openai/gpt-5.3-codex",
name: "GPT-5.3 Codex",
contextLength: 409600,
maxOutputTokens: 131072,
},
{
id: "openai/gpt-5.2-codex",
name: "GPT-5.2 Codex",
contextLength: 409600,
maxOutputTokens: 131072,
},
{ id: "openai/gpt-5.2", name: "GPT-5.2", contextLength: 409600, maxOutputTokens: 131072 },
{ id: "openai/gpt-5.1", name: "GPT-5.1", contextLength: 409600, maxOutputTokens: 131072 },
{ id: "openai/gpt-5", name: "GPT-5", contextLength: 409600, maxOutputTokens: 131072 },
{ id: "openai/gpt-4o", name: "GPT-4o", contextLength: 131072, maxOutputTokens: 16384 },
{
id: "openai/gpt-4o-mini",
name: "GPT-4o Mini",
contextLength: 131072,
maxOutputTokens: 16384,
},
{
id: "anthropic/claude-opus-4.7",
name: "Claude Opus 4.7",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-opus-4.6",
name: "Claude Opus 4.6",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-opus-4.5",
name: "Claude Opus 4.5",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-opus-4.1",
name: "Claude Opus 4.1",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-sonnet-4.6",
name: "Claude Sonnet 4.6",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-sonnet-4.5",
name: "Claude Sonnet 4.5",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-sonnet-4",
name: "Claude Sonnet 4",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "anthropic/claude-haiku-4.5",
name: "Claude Haiku 4.5",
contextLength: 409600,
maxOutputTokens: 131072,
targetFormat: "claude",
},
{
id: "deepseek-ai/DeepSeek-V4-Pro",
name: "DeepSeek V4 Pro",
contextLength: 1048576,
maxOutputTokens: 131072,
supportsReasoning: true,
},
{
id: "deepseek-ai/DeepSeek-V4-Flash",
name: "DeepSeek V4 Flash",
contextLength: 1048575,
maxOutputTokens: 131072,
supportsReasoning: true,
},
{
id: "deepseek-ai/DeepSeek-R1-0528",
name: "DeepSeek R1",
contextLength: 163840,
maxOutputTokens: 131072,
supportsReasoning: true,
},
{
id: "deepseek-ai/DeepSeek-V3.2",
name: "DeepSeek V3.2",
contextLength: 163840,
maxOutputTokens: 131072,
},
{
id: "google/gemini-3.1-pro-preview",
name: "Gemini 3.1 Pro",
contextLength: 1048576,
maxOutputTokens: 131072,
},
{
id: "google/gemini-3.1-flash-lite-preview",
name: "Gemini 3.1 Flash Lite",
contextLength: 1048576,
maxOutputTokens: 131072,
},
{
id: "google/gemini-3-flash-preview",
name: "Gemini 3 Flash",
contextLength: 1048576,
maxOutputTokens: 131072,
},
{ id: "zai-org/GLM-5.1-FP8", name: "GLM-5.1", contextLength: 202752, maxOutputTokens: 131072 },
{ id: "zai-org/GLM-5-FP8", name: "GLM-5", contextLength: 202752, maxOutputTokens: 131072 },
{
id: "moonshotai/Kimi-K2.6",
name: "Kimi K2.6",
contextLength: 65536,
maxOutputTokens: 131072,
},
{
id: "moonshotai/Kimi-K2.5",
name: "Kimi K2.5",
contextLength: 262144,
maxOutputTokens: 131072,
},
{
id: "MiniMaxAI/MiniMax-M2.7",
name: "MiniMax M2.7",
contextLength: 196608,
maxOutputTokens: 131072,
},
{
id: "MiniMaxAI/MiniMax-M2.5",
name: "MiniMax M2.5",
contextLength: 196608,
maxOutputTokens: 131072,
},
{
id: "Qwen/Qwen3.6-Max-Preview",
name: "Qwen3.6 Max",
contextLength: 262144,
maxOutputTokens: 131072,
},
{
id: "Qwen/Qwen3.6-Plus",
name: "Qwen3.6 Plus",
contextLength: 262144,
maxOutputTokens: 131072,
},
{
id: "Qwen/Qwen3.5-397B-A17B",
name: "Qwen3.5 397B",
contextLength: 262144,
maxOutputTokens: 131072,
},
{
id: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8",
name: "Qwen3 Coder 480B",
contextLength: 262128,
maxOutputTokens: 131072,
},
{
id: "nvidia/NVIDIA-Nemotron-3-Nano-Omni",
name: "Nemotron 3 Nano",
contextLength: 262144,
maxOutputTokens: 131072,
},
],
"inference-net": buildModels([
"meta-llama/Llama-3.3-70B-Instruct",
"deepseek-ai/DeepSeek-R1",
"Qwen/Qwen2.5-72B-Instruct",
]),
nanogpt: buildModels(["chatgpt-4o-latest", "claude-3.5-sonnet", "gpt-4o-mini"]),
predibase: buildModels(["llama-3.3-70b"]),
bytez: buildModels([
"meta-llama/Llama-3.3-70B-Instruct",
"mistralai/Mistral-7B-Instruct-v0.3",
"Qwen/Qwen2.5-72B-Instruct",
]),
};
function mapStainlessOs() {
switch (getRuntimePlatform()) {
case "darwin":
return "MacOS";
case "win32":
return "Windows";
case "linux":
return "Linux";
default:
return `Other::${getRuntimePlatform()}`;
}
}
function mapStainlessArch() {
switch (getRuntimeArch()) {
case "x64":
return "x64";
case "arm64":
return "arm64";
case "ia32":
return "x86";
default:
return `other::${getRuntimeArch()}`;
}
}
// ── Registry ──────────────────────────────────────────────────────────────
export const REGISTRY: Record<string, RegistryEntry> = {
// ─── OAuth Providers ───────────────────────────────────────────────────
kie: {
id: "kie",
alias: "kie",
format: "openai",
executor: "default",
baseUrl: "https://api.kie.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
{ id: "claude-opus-4-7", name: "Claude 4.7 Opus" },
{ id: "claude-sonnet-4-6", name: "Claude 4.6 Sonnet" },
{ id: "claude-haiku-4-5", name: "Claude 4.5 Haiku" },
{ id: "gpt-5-5", name: "GPT 5.5" },
{ id: "gpt-5-4", name: "GPT 5.4" },
{ id: "gpt-5-2", name: "GPT 5.2" },
{ id: "gemini-3-1-pro", name: "Gemini 3.1 Pro" },
{ id: "gemini-2-5-pro", name: "Gemini 2.5 Pro" },
{ id: "gemini-3-flash", name: "Gemini 3 Flash" },
],
},
claude: {
id: "claude",
alias: "cc",
format: "claude",
executor: "default",
baseUrl: "https://api.anthropic.com/v1/messages",
urlSuffix: "?beta=true",
authType: "oauth",
authHeader: "x-api-key",
defaultContextLength: 200000,
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
"Anthropic-Beta": ANTHROPIC_BETA_CLAUDE_OAUTH,
"Anthropic-Dangerous-Direct-Browser-Access": "true",
"User-Agent": CLAUDE_CLI_USER_AGENT,
"X-App": "cli",
"X-Stainless-Helper-Method": "stream",
"X-Stainless-Retry-Count": "0",
"X-Stainless-Runtime-Version": CLAUDE_CLI_STAINLESS_RUNTIME_VERSION,
"X-Stainless-Package-Version": CLAUDE_CLI_STAINLESS_PACKAGE_VERSION,
"X-Stainless-Runtime": "node",
"X-Stainless-Lang": "js",
"X-Stainless-Arch": mapStainlessArch(),
"X-Stainless-Os": mapStainlessOs(),
"X-Stainless-Timeout": "600",
},
oauth: {
clientIdEnv: "CLAUDE_OAUTH_CLIENT_ID",
clientIdDefault: "9d1c250a-e61b-44d9-88ed-5944d1962f5e",
tokenUrl: "https://console.anthropic.com/v1/oauth/token",
},
models: [
{
id: "claude-opus-4-8",
name: "Claude Opus 4.8",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-opus-4-7",
name: "Claude Opus 4.7",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-opus-4-6",
name: "Claude Opus 4.6",
supportsXHighEffort: false,
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-opus-4-5-20251101",
name: "Claude Opus 4.5",
supportsXHighEffort: false,
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-sonnet-4-6",
name: "Claude 4.6 Sonnet",
supportsXHighEffort: false,
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-sonnet-4-5-20250929",
name: "Claude 4.5 Sonnet",
supportsXHighEffort: false,
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-haiku-4-5-20251001",
name: "Claude 4.5 Haiku",
supportsXHighEffort: false,
contextLength: 200000,
maxOutputTokens: 64000,
},
],
},
gemini: {
id: "gemini",
alias: "gemini",
format: "gemini",
executor: "default",
baseUrl: "https://generativelanguage.googleapis.com/v1beta/models",
urlBuilder: (base, model, stream) => {
const action = stream ? "streamGenerateContent?alt=sse" : "generateContent";
return `${base}/${model}:${action}`;
},
authType: "apikey",
authHeader: "x-goog-api-key",
defaultContextLength: 1048576,
oauth: {
clientIdEnv: "GEMINI_OAUTH_CLIENT_ID",
clientIdDefault: resolvePublicCred("gemini_id"),
clientSecretEnv: "GEMINI_OAUTH_CLIENT_SECRET",
clientSecretDefault: resolvePublicCred("gemini_alt"),
},
models: [
{ id: "gemini-2.0-flash", name: "Gemini 2.0 Flash", toolCalling: true, supportsVision: true },
{
id: "gemini-2.0-flash-thinking-exp-01-21",
name: "Gemini 2.0 Flash Thinking",
supportsReasoning: true,
},
{
id: "gemini-2.0-pro-exp-02-05",
name: "Gemini 2.0 Pro Experimental",
toolCalling: true,
supportsVision: true,
},
{ id: "gemini-1.5-pro", name: "Gemini 1.5 Pro", toolCalling: true, supportsVision: true },
{ id: "gemini-1.5-flash", name: "Gemini 1.5 Flash", toolCalling: true, supportsVision: true },
],
},
"gemini-cli": {
id: "gemini-cli",
alias: "gemini-cli",
format: "gemini-cli",
executor: "gemini-cli",
baseUrl: "https://cloudcode-pa.googleapis.com/v1internal",
urlBuilder: (base, model, stream) => {
const action = stream ? "streamGenerateContent?alt=sse" : "generateContent";
return `${base}:${action}`;
},
authType: "apikey",
authHeader: "x-goog-api-key",
defaultContextLength: 1048576,
oauth: {
clientIdEnv: "GEMINI_CLI_OAUTH_CLIENT_ID",
clientIdDefault: resolvePublicCred("gemini_id"),
clientSecretEnv: "GEMINI_CLI_OAUTH_CLIENT_SECRET",
clientSecretDefault: resolvePublicCred("gemini_alt"),
},
models: [
{ id: "gemini-2.0-flash", name: "Gemini 2.0 Flash" },
{ id: "gemini-2.0-flash-thinking", name: "Gemini 2.0 Flash Thinking" },
{ id: "gemini-2.0-pro-exp-02-05", name: "Gemini 2.0 Pro Experimental" },
{ id: "gemini-1.5-pro", name: "Gemini 1.5 Pro" },
{ id: "gemini-1.5-flash", name: "Gemini 1.5 Flash" },
{ id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro Preview" },
{ id: "gemini-3.1-pro-preview-customtools", name: "Gemini 3.1 Pro Preview Custom Tools" },
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash Preview" },
{ id: "gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite" },
],
},
codex: {
id: "codex",
alias: "cx",
format: "openai-responses",
executor: "codex",
baseUrl: "https://chatgpt.com/backend-api/codex/responses",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 400000,
headers: getCodexDefaultHeaders(),
oauth: {
clientIdEnv: "CODEX_OAUTH_CLIENT_ID",
clientIdDefault: "app_EMoamEEZ73f0CkXaXp7hrann",
clientSecretEnv: "CODEX_OAUTH_CLIENT_SECRET",
clientSecretDefault: "",
tokenUrl: "https://auth.openai.com/oauth/token",
},
models: [
// gpt-5.5 codex OAuth backend caps context at 400K (not the public-API
// 1.05M). Public refs : openai/codex#19208, #19319, #19464 ;
// opencode#24171. max_output_tokens is stripped server-side
// (litellm#21193, codex#4138) so 128K is informational only.
{
id: "gpt-5.5",
name: "GPT 5.5",
...GPT_5_5_CODEX_CAPABILITIES,
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.5-xhigh",
name: "GPT 5.5 (xHigh)",
...GPT_5_5_CODEX_CAPABILITIES,
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.5-high",
name: "GPT 5.5 (High)",
...GPT_5_5_CODEX_CAPABILITIES,
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.5-medium",
name: "GPT 5.5 (Medium)",
...GPT_5_5_CODEX_CAPABILITIES,
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.5-low",
name: "GPT 5.5 (Low)",
...GPT_5_5_CODEX_CAPABILITIES,
contextLength: 400000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.4",
name: "GPT 5.4",
targetFormat: "openai-responses",
supportsReasoning: true,
supportsXHighEffort: true,
},
{ id: "gpt-5.4-mini", name: "GPT 5.4 Mini", targetFormat: "openai-responses" },
{ id: "gpt-5.3-codex-spark", name: "GPT 5.3 Codex Spark" },
{
id: "gpt-5.3-codex",
name: "GPT 5.3 Codex",
targetFormat: "openai-responses",
supportsReasoning: true,
supportsXHighEffort: true,
},
{ id: "gpt-5.2", name: "GPT 5.2" },
],
},
qwen: {
id: "qwen",
alias: "qw",
format: "openai",
executor: "default",
baseUrl: "https://chat.qwen.ai/api/v1/services/aigc/text-generation/generation",
authType: "oauth",
authHeader: "bearer",
headers: getQwenOauthHeaders(),
oauth: {
clientIdEnv: "QWEN_OAUTH_CLIENT_ID",
clientIdDefault: "f0304373b74a44d2b584a3fb70ca9e56",
tokenUrl: "https://chat.qwen.ai/api/v1/oauth2/token",
authUrl: "https://chat.qwen.ai/api/v1/oauth2/device/code",
},
models: [
{ id: "qwen3-coder-plus", name: "Qwen3 Coder Plus" },
{ id: "qwen3-coder-flash", name: "Qwen3 Coder Flash" },
{ id: "vision-model", name: "Qwen3 Vision Model" },
{ id: "coder-model", name: "Qwen3.6 (Coder Model)" },
],
},
qoder: {
id: "qoder",
alias: "if",
format: "openai",
executor: "qoder",
baseUrl: "https://api.qoder.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
headers: getQoderDefaultHeaders(),
oauth: {
clientIdEnv: "QODER_OAUTH_CLIENT_ID",
clientSecretEnv: "QODER_OAUTH_CLIENT_SECRET",
tokenUrl: process.env.QODER_OAUTH_TOKEN_URL || "",
authUrl: process.env.QODER_OAUTH_AUTHORIZE_URL || "",
},
models: [
{ id: "qoder-rome-30ba3b", name: "Qoder ROME" },
{ id: "qwen3-coder-plus", name: "Qwen3 Coder Plus" },
{ id: "qwen3-max", name: "Qwen3 Max" },
{ id: "qwen3-vl-plus", name: "Qwen3 Vision Plus", supportsVision: true },
{ id: "kimi-k2-0905", name: "Kimi K2 0905" },
{ id: "qwen3-max-preview", name: "Qwen3 Max Preview" },
{ id: "kimi-k2", name: "Kimi K2" },
{ id: "deepseek-v3.2", name: "DeepSeek-V3.2-Exp" },
{ id: "deepseek-r1", name: "DeepSeek R1" },
{ id: "deepseek-v3", name: "DeepSeek V3" },
{ id: "qwen3-32b", name: "Qwen3 32B" },
{ id: "qwen3-235b-a22b-thinking-2507", name: "Qwen3 235B A22B Thinking 2507" },
{ id: "qwen3-235b-a22b-instruct", name: "Qwen3 235B A22B Instruct" },
{ id: "qwen3-235b", name: "Qwen3 235B" },
],
},
antigravity: {
id: "antigravity",
alias: undefined,
format: "antigravity",
executor: "antigravity",
baseUrls: [...ANTIGRAVITY_BASE_URLS],
urlBuilder: (base, model, stream) => {
const path = stream
? "/v1internal:streamGenerateContent?alt=sse"
: "/v1internal:generateContent";
return `${base}${path}`;
},
authType: "oauth",
authHeader: "bearer",
headers: getAntigravityProviderHeaders(),
oauth: {
clientIdEnv: "ANTIGRAVITY_OAUTH_CLIENT_ID",
clientIdDefault: resolvePublicCred("antigravity_id"),
clientSecretEnv: "ANTIGRAVITY_OAUTH_CLIENT_SECRET",
clientSecretDefault: resolvePublicCred("antigravity_alt"),
},
models: [...ANTIGRAVITY_PUBLIC_MODELS],
passthroughModels: true,
},
// Antigravity CLI (`agy`): standalone provider that reuses the antigravity executor,
// format and backend (identical client_id + daily-cloudcode-pa endpoint), but ships its
// own model catalog (incl. Claude) and its own account pool / OAuth credential import.
agy: {
id: "agy",
alias: "agy",
format: "antigravity",
executor: "antigravity",
baseUrls: [...ANTIGRAVITY_BASE_URLS],
urlBuilder: (base, model, stream) => {
const path = stream
? "/v1internal:streamGenerateContent?alt=sse"
: "/v1internal:generateContent";
return `${base}${path}`;
},
authType: "oauth",
authHeader: "bearer",
headers: getAntigravityProviderHeaders(),
oauth: {
clientIdEnv: "ANTIGRAVITY_OAUTH_CLIENT_ID",
clientIdDefault: resolvePublicCred("antigravity_id"),
clientSecretEnv: "ANTIGRAVITY_OAUTH_CLIENT_SECRET",
clientSecretDefault: resolvePublicCred("antigravity_alt"),
},
models: [...AGY_PUBLIC_MODELS],
passthroughModels: true,
},
github: {
id: "github",
alias: "gh",
format: "openai",
executor: "github",
baseUrl: "https://api.githubcopilot.com/chat/completions",
responsesBaseUrl: "https://api.githubcopilot.com/responses",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 128000,
headers: getGitHubCopilotChatHeaders(),
models: [
{ id: "gpt-5-mini", name: "GPT-5 Mini", targetFormat: "openai-responses" },
{ id: "gpt-5.3-codex", name: "GPT-5.3 Codex", targetFormat: "openai-responses" },
{ id: "gpt-5.4-mini", name: "GPT-5.4 Mini", targetFormat: "openai-responses" },
{ id: "gpt-5.4", name: "GPT-5.4", targetFormat: "openai-responses" },
{ id: "gpt-5.5", name: "GPT-5.5", ...GPT_5_5_CODEX_CAPABILITIES },
{
id: "claude-haiku-4.5",
name: "Claude Haiku 4.5",
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-sonnet-4.5",
name: "Claude Sonnet 4.5",
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-sonnet-4.6",
name: "Claude Sonnet 4.6",
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-opus-4-5-20251101",
name: "Claude Opus 4.5 (Full ID)",
targetFormat: "openai-responses",
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-opus-4.6",
name: "Claude Opus 4.6",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-opus-4.7",
name: "Claude Opus 4.7",
targetFormat: "openai-responses",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{ id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro", targetFormat: "openai-responses" },
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash", targetFormat: "openai-responses" },
{ id: "oswe-vscode-prime", name: "Raptor Mini", targetFormat: "openai-responses" },
//{ id: "?", name: "Goldeneye" },
],
},
"github-models": {
id: "github-models",
alias: "ghm",
format: "openai",
executor: "default",
baseUrl: "https://models.github.ai/inference/chat/completions",
modelsUrl: "https://models.github.ai/inference/models",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
headers: {
"X-GitHub-Api-Version": "2022-11-28",
Accept: "application/vnd.github+json",
},
defaultContextLength: 128000,
models: [
{ id: "openai/gpt-4.1", name: "GPT-4.1 (Free)", contextLength: 1047576 },
{ id: "openai/gpt-4o", name: "GPT-4o (Free)", contextLength: 128000 },
{ id: "openai/gpt-4o-mini", name: "GPT-4o Mini (Free)", contextLength: 128000 },
{ id: "openai/o1", name: "o1 (Free)", contextLength: 200000 },
{ id: "openai/o3", name: "o3 (Free)", contextLength: 200000 },
{ id: "openai/o4-mini", name: "o4-mini (Free)", contextLength: 200000 },
{ id: "deepseek/DeepSeek-R1", name: "DeepSeek R1 (Free)", contextLength: 131072 },
{
id: "meta/Llama-4-Maverick-17B-128E-Instruct",
name: "Llama 4 Maverick (Free)",
contextLength: 131072,
},
{ id: "xai/grok-3", name: "Grok 3 (Free)", contextLength: 131072 },
{ id: "mistral-ai/Mistral-Medium-3", name: "Mistral Medium 3 (Free)", contextLength: 128000 },
{ id: "cohere/Cohere-command-a", name: "Cohere Command A (Free)", contextLength: 128000 },
{ id: "microsoft/Phi-4", name: "Phi-4 (Free)", contextLength: 16384 },
{ id: "openai/text-embedding-3-large", name: "Text Embedding 3 Large (Free)" },
{ id: "openai/text-embedding-3-small", name: "Text Embedding 3 Small (Free)" },
],
},
kiro: {
id: "kiro",
alias: "kr",
format: "kiro",
executor: "kiro",
baseUrl: "https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 200000,
headers: getKiroServiceHeaders(),
oauth: {
tokenUrl: "https://prod.us-east-1.auth.desktop.kiro.dev/refreshToken",
authUrl: "https://prod.us-east-1.auth.desktop.kiro.dev",
},
models: [
{ id: "auto-kiro", name: "Auto (Kiro picks best model)" },
{
id: "claude-opus-4.7",
name: "Claude Opus 4.7",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-opus-4.6",
name: "Claude Opus 4.6",
contextLength: 1000000,
maxOutputTokens: 128000,
},
{
id: "claude-sonnet-4.6",
name: "Claude Sonnet 4.6",
contextLength: 200000,
maxOutputTokens: 64000,
},
// models for kiro free tier
{
id: "claude-sonnet-4.5",
name: "Claude Sonnet 4.5",
contextLength: 200000,
maxOutputTokens: 64000,
},
{
id: "claude-haiku-4.5",
name: "Claude Haiku 4.5",
contextLength: 200000,
maxOutputTokens: 64000,
},
{ id: "deepseek-3.2", name: "DeepSeek V3.2" },
{ id: "minimax-m2.5", name: "MiniMax M2.5" },
{ id: "minimax-m2.1", name: "MiniMax M2.1" },
{ id: "glm-5", name: "GLM-5" },
{ id: "qwen3-coder-next", name: "Qwen3 Coder Next" },
],
},
"gitlab-duo": {
id: "gitlab-duo",
alias: "gld",
format: "openai",
executor: "gitlab",
// baseUrl is dynamic: resolved at request time from providerSpecificData.baseUrl
// by GitlabExecutor.buildUrl() via buildGitLabOAuthEndpoints().
// The default here keeps the PROVIDERS map non-null so refreshAccessToken()
// can look up this provider.
baseUrl: buildGitLabOAuthEndpoints(GITLAB_DUO_DEFAULT_BASE_URL).publicCompletionsUrl,
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 128000,
oauth: {
clientIdEnv: "GITLAB_DUO_OAUTH_CLIENT_ID",
clientIdDefault: process.env.GITLAB_OAUTH_CLIENT_ID || "",
clientSecretEnv: "GITLAB_DUO_OAUTH_CLIENT_SECRET",
clientSecretDefault: process.env.GITLAB_OAUTH_CLIENT_SECRET || "",
tokenUrl: buildGitLabOAuthEndpoints(GITLAB_DUO_DEFAULT_BASE_URL).tokenUrl,
authUrl: buildGitLabOAuthEndpoints(GITLAB_DUO_DEFAULT_BASE_URL).authorizeUrl,
},
models: [
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6 (GitLab Duo)" },
{ id: "claude-haiku-4-5", name: "Claude Haiku 4.5 (GitLab Duo)" },
],
},
cursor: {
id: "cursor",
alias: "cu",
format: "cursor",
executor: "cursor",
baseUrl: "https://api2.cursor.sh",
chatPath: "/aiserver.v1.ChatService/StreamUnifiedChatWithTools",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 200000,
headers: getCursorRegistryHeaders(),
clientVersion: CURSOR_REGISTRY_VERSION,
models: [
{ id: "auto", name: "Auto (Server Picks)" },
{ id: "composer-2.5-fast", name: "Composer 2.5 Fast" },
{ id: "composer-2.5", name: "Composer 2.5" },
{ id: "composer-2-fast", name: "Composer 2 Fast" },
{ id: "composer-2", name: "Composer 2" },
//
{ id: "gpt-5.5-none", name: "GPT 5.5 None" },
{ id: "gpt-5.5-none-fast", name: "GPT 5.5 None Fast" },
{ id: "gpt-5.5-low", name: "GPT 5.5 Low" },
{ id: "gpt-5.5-low-fast", name: "GPT 5.5 Low Fast" },
{ id: "gpt-5.5-medium", name: "GPT 5.5 Medium" },
{ id: "gpt-5.5-medium-fast", name: "GPT 5.5 Medium Fast" },
{ id: "gpt-5.5-high", name: "GPT 5.5 High" },
{ id: "gpt-5.5-high-fast", name: "GPT 5.5 High Fast" },
{ id: "gpt-5.5-extra-high", name: "GPT 5.5 Extra High" },
{ id: "gpt-5.5-extra-high-fast", name: "GPT 5.5 Extra High Fast" },
//
{ id: "gpt-5.4-low", name: "GPT 5.4 Low" },
{ id: "gpt-5.4-low-fast", name: "GPT 5.4 Low Fast" },
{ id: "gpt-5.4-medium", name: "GPT 5.4 Medium" },
{ id: "gpt-5.4-medium-fast", name: "GPT 5.4 Medium Fast" },
{ id: "gpt-5.4-high", name: "GPT 5.4 High" },
{ id: "gpt-5.4-high-fast", name: "GPT 5.4 High Fast" },
{ id: "gpt-5.4-xhigh", name: "GPT 5.4 XHigh" },
{ id: "gpt-5.4-xhigh-fast", name: "GPT 5.4 XHigh Fast" },
//
{ id: "gpt-5.4-mini-none", name: "GPT 5.4 Mini None" },
{ id: "gpt-5.4-mini-low", name: "GPT 5.4 Mini Low" },
{ id: "gpt-5.4-mini-medium", name: "GPT 5.4 Mini Medium" },
{ id: "gpt-5.4-mini-high", name: "GPT 5.4 Mini High" },
{ id: "gpt-5.4-mini-xhigh", name: "GPT 5.4 Mini XHigh" },
//
{ id: "gpt-5.4-nano-none", name: "GPT 5.4 Nano None" },
{ id: "gpt-5.4-nano-low", name: "GPT 5.4 Nano Low" },
{ id: "gpt-5.4-nano-medium", name: "GPT 5.4 Nano Medium" },
{ id: "gpt-5.4-nano-high", name: "GPT 5.4 Nano High" },
{ id: "gpt-5.4-nano-xhigh", name: "GPT 5.4 Nano XHigh" },
//
{ id: "gpt-5.3-codex-spark-preview-low", name: "GPT 5.3 Codex Spark Preview Low" },
{ id: "gpt-5.3-codex-spark-preview", name: "GPT 5.3 Codex Spark Preview" },
{ id: "gpt-5.3-codex-spark-preview-high", name: "GPT 5.3 Codex Spark Preview High" },
{ id: "gpt-5.3-codex-spark-preview-xhigh", name: "GPT 5.3 Codex Spark Preview XHigh" },
//
{ id: "gpt-5.3-codex-low", name: "GPT 5.3 Codex Low" },
{ id: "gpt-5.3-codex-low-fast", name: "GPT 5.3 Codex Low Fast" },
{ id: "gpt-5.3-codex", name: "GPT 5.3 Codex" },
{ id: "gpt-5.3-codex-fast", name: "GPT 5.3 Codex Fast" },
{ id: "gpt-5.3-codex-high", name: "GPT 5.3 Codex High" },
{ id: "gpt-5.3-codex-high-fast", name: "GPT 5.3 Codex High Fast" },
{ id: "gpt-5.3-codex-xhigh", name: "GPT 5.3 Codex XHigh" },
{ id: "gpt-5.3-codex-xhigh-fast", name: "GPT 5.3 Codex XHigh Fast" },
//
{ id: "gpt-5.2-low", name: "GPT 5.2 Low" },
{ id: "gpt-5.2-low-fast", name: "GPT 5.2 Low Fast" },
{ id: "gpt-5.2", name: "GPT 5.2" },
{ id: "gpt-5.2-fast", name: "GPT 5.2 Fast" },
{ id: "gpt-5.2-high", name: "GPT 5.2 High" },
{ id: "gpt-5.2-high-fast", name: "GPT 5.2 High Fast" },
{ id: "gpt-5.2-xhigh", name: "GPT 5.2 XHigh" },
{ id: "gpt-5.2-xhigh-fast", name: "GPT 5.2 XHigh Fast" },
//
{ id: "claude-opus-4-7-low", name: "Claude Opus 4.7 Low" },
{ id: "claude-opus-4-7-medium", name: "Claude Opus 4.7 Medium" },
{ id: "claude-opus-4-7-high", name: "Claude Opus 4.7 High" },
{ id: "claude-opus-4-7-xhigh", name: "Claude Opus 4.7 XHigh" },
{ id: "claude-opus-4-7-max", name: "Claude Opus 4.7 Max" },
{ id: "claude-opus-4-7-thinking-low", name: "Claude Opus 4.7 Thinking Low" },
{ id: "claude-opus-4-7-thinking-medium", name: "Claude Opus 4.7 Thinking Medium" },
{ id: "claude-opus-4-7-thinking-high", name: "Claude Opus 4.7 Thinking High" },
{ id: "claude-opus-4-7-thinking-xhigh", name: "Claude Opus 4.7 Thinking XHigh" },
{ id: "claude-opus-4-7-thinking-max", name: "Claude Opus 4.7 Thinking Max" },
//
{ id: "claude-4.6-opus-high", name: "Claude 4.6 Opus High" },
{ id: "claude-4.6-opus-high-thinking", name: "Claude 4.6 Opus High Thinking" },
{ id: "claude-4.6-opus-high-thinking-fast", name: "Claude 4.6 Opus High Thinking Fast" },
{ id: "claude-4.6-opus-max", name: "Claude 4.6 Opus Max" },
{ id: "claude-4.6-opus-max-thinking", name: "Claude 4.6 Opus Max Thinking" },
{ id: "claude-4.6-opus-max-thinking-fast", name: "Claude 4.6 Opus Max Thinking Fast" },
//
{ id: "claude-4.6-sonnet-medium", name: "Claude 4.6 Sonnet Medium" },
{ id: "claude-4.6-sonnet-medium-thinking", name: "Claude 4.6 Sonnet Medium Thinking" },
//
{ id: "claude-4.5-sonnet", name: "Claude 4.5 Sonnet" },
{ id: "claude-4.5-sonnet-thinking", name: "Claude 4.5 Sonnet Thinking" },
//
{ id: "gemini-3.1-pro", name: "Gemini 3.1 Pro" },
//
{ id: "gemini-3-flash", name: "Gemini 3 Flash" },
//
{ id: "grok-4.3", name: "Grok 4.3" },
//
{ id: "kimi-k2.5", name: "Kimi K2.5" },
],
},
// ─── API Key Providers ─────────────────────────────────────────────────
openai: {
id: "openai",
alias: "openai",
format: "openai",
executor: "default",
baseUrl: "https://api.openai.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
{ id: "gpt-5.5", name: "GPT-5.5", contextLength: 1050000 },
{ id: "gpt-5.4", name: "GPT-5.4", contextLength: 1050000 },
{ id: "gpt-5.4-mini", name: "GPT-5.4 Mini", contextLength: 400000 },
{ id: "gpt-5.4-nano", name: "GPT-5.4 Nano", contextLength: 400000 },
{ id: "gpt-4.1", name: "GPT-4.1", contextLength: 1047576 },
{ id: "gpt-4o", name: "GPT-4o", contextLength: 128000 },
{ id: "gpt-4o-2024-11-20", name: "GPT-4o (Nov 2024)", contextLength: 128000 },
{ id: "gpt-4o", name: "GPT-4o", contextLength: 128000 },
{ id: "gpt-4o-mini", name: "GPT-4o Mini", contextLength: 128000 },
{ id: "o3", name: "O3", contextLength: 200000, unsupportedParams: REASONING_UNSUPPORTED },
],
},
anthropic: {
id: "anthropic",
alias: "anthropic",
format: "claude",
executor: "default",
baseUrl: "https://api.anthropic.com/v1/messages",
urlSuffix: "?beta=true",
authType: "apikey",
authHeader: "x-api-key",
defaultContextLength: 200000,
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
"Anthropic-Beta": ANTHROPIC_BETA_API_KEY,
},
models: [
{ id: "claude-opus-4.7", name: "Claude Opus 4.7" },
{ id: "claude-opus-4.6", name: "Claude Opus 4.6" },
{ id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
{ id: "claude-sonnet-4.5", name: "Claude Sonnet 4.6" },
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5" },
],
},
opencode: {
id: "opencode",
alias: "oc",
format: "openai",
executor: "opencode",
baseUrl: "https://opencode.ai/zen/v1",
modelsUrl: "https://opencode.ai/zen/v1/models",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
passthroughModels: true,
defaultContextLength: 200000,
models: [
{ id: "big-pickle", name: "Big Pickle" },
{ id: "minimax-m2.5-free", name: "MiniMax M2.5 Free", contextLength: 204800 },
{ id: "ling-2.6-1t-free", name: "Ling 2.6 Free", contextLength: 262000 },
{
id: "trinity-large-preview-free",
name: "Trinity Large Preview Free",
contextLength: 131000,
},
{ id: "nemotron-3-super-free", name: "Nemotron 3 Super Free", contextLength: 1000000 },
],
},
"opencode-go": {
id: "opencode-go",
alias: "opencode-go",
format: "openai",
executor: "opencode",
baseUrl: "https://opencode.ai/zen/go/v1",
// (#532) Key validation must hit the main zen endpoint (same key works for both tiers)
testKeyBaseUrl: "https://opencode.ai/zen/v1",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
defaultContextLength: 200000,
models: [
{ id: "glm-5.1", name: "GLM-5.1" },
{ id: "glm-5", name: "GLM-5" },
{ id: "kimi-k2.6", name: "Kimi K2.6" },
{ id: "kimi-k2.5", name: "Kimi K2.5" },
{ id: "mimo-v2.5-pro", name: "MiMo-V2.5-Pro" },
{ id: "mimo-v2.5", name: "MiMo-V2.5" },
{ id: "mimo-v2-pro", name: "MiMo-V2-Pro" },
{ id: "mimo-v2-omni", name: "MiMo-V2-Omni" },
{ id: "minimax-m2.7", name: "MiniMax M2.7", targetFormat: "claude" },
{ id: "minimax-m2.5", name: "MiniMax M2.5", targetFormat: "claude" },
// Issue #2292: Qwen models on opencode-go reject oa-compat format
// ("Model qwen3.x-* is not supported for format oa-compat") — same
// upstream behavior already declared for opencode-zen. Route them
// through /messages with the Claude translator.
// Issue #2822: These models are text-only — mark supportsVision: false
// so combo routing skips them when the request contains image blocks,
// preventing image content from reaching a vision-incapable upstream.
{ id: "qwen3.7-max", name: "Qwen3.7 Max", targetFormat: "claude", supportsVision: false },
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude", supportsVision: false },
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus", targetFormat: "claude", supportsVision: false },
{ id: "hy3-preview", name: "Hunyuan3 Preview" },
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
],
},
"opencode-zen": {
id: "opencode-zen",
alias: "opencode-zen",
format: "openai",
executor: "opencode",
baseUrl: "https://opencode.ai/zen/v1",
modelsUrl: "https://opencode.ai/zen/v1/models",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
defaultContextLength: 200000,
// Sync with https://opencode.ai/zen/v1/models — this list is regenerated
// from the live API response so new models work without a code deploy.
passthroughModels: true,
models: [
// ── Chat / Coding ──────────────────────────────────────────
{ id: "big-pickle", name: "Big Pickle" },
{ id: "gpt-5-nano", name: "GPT 5 Nano", contextLength: 400000 },
{ id: "gpt-5", name: "GPT 5" },
{ id: "gpt-5-codex", name: "GPT 5 Codex" },
{ id: "gpt-5.1", name: "GPT 5.1" },
{ id: "gpt-5.1-codex", name: "GPT 5.1 Codex" },
{ id: "gpt-5.1-codex-max", name: "GPT 5.1 Codex Max" },
{ id: "gpt-5.1-codex-mini", name: "GPT 5.1 Codex Mini" },
{ id: "gpt-5.2", name: "GPT 5.2" },
{ id: "gpt-5.2-codex", name: "GPT 5.2 Codex" },
{ id: "gpt-5.3-codex", name: "GPT 5.3 Codex" },
{ id: "gpt-5.3-codex-spark", name: "GPT 5.3 Codex Spark" },
{ id: "gpt-5.4", name: "GPT 5.4" },
{ id: "gpt-5.4-mini", name: "GPT 5.4 Mini" },
{ id: "gpt-5.4-nano", name: "GPT 5.4 Nano" },
{ id: "gpt-5.4-pro", name: "GPT 5.4 Pro" },
{ id: "gpt-5.5", name: "GPT 5.5" },
{ id: "gpt-5.5-pro", name: "GPT 5.5 Pro" },
// ── Claude ─────────────────────────────────────────────────
{ id: "claude-haiku-4-5", name: "Claude Haiku 4.5" },
{ id: "claude-sonnet-4", name: "Claude Sonnet 4" },
{ id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5" },
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
{ id: "claude-opus-4-1", name: "Claude Opus 4.1" },
{ id: "claude-opus-4-5", name: "Claude Opus 4.5" },
{ id: "claude-opus-4-6", name: "Claude Opus 4.6" },
{ id: "claude-opus-4-7", name: "Claude Opus 4.7" },
// ── Gemini ─────────────────────────────────────────────────
{ id: "gemini-3-flash", name: "Gemini 3 Flash" },
{ id: "gemini-3.1-pro", name: "Gemini 3.1 Pro" },
{ id: "gemini-3.5-flash", name: "Gemini 3.5 Flash" },
// ── Grok ───────────────────────────────────────────────────
{ id: "grok-build-0.1", name: "Grok Build 0.1" },
// ── GLM / Z.AI ─────────────────────────────────────────────
{ id: "glm-5", name: "GLM-5" },
{ id: "glm-5.1", name: "GLM-5.1" },
// ── MiniMax ────────────────────────────────────────────────
{ id: "minimax-m2.5", name: "MiniMax M2.5" },
{ id: "minimax-m2.7", name: "MiniMax M2.7" },
// ── Kimi / Moonshot ────────────────────────────────────────
{ id: "kimi-k2.5", name: "Kimi K2.5" },
{ id: "kimi-k2.6", name: "Kimi K2.6" },
// ── Qwen ───────────────────────────────────────────────────
// Issue #2292: Qwen models return Claude-format SSE bodies even
// when hitting /chat/completions. targetFormat: "claude" routes
// through /messages and the Claude translator.
// Issue #2822: These models are text-only — supportsVision: false
// ensures combo routing skips them on image-bearing requests.
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus", targetFormat: "claude", supportsVision: false },
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude", supportsVision: false },
// ── Free Tier ──────────────────────────────────────────────
{ id: "deepseek-v4-flash-free", name: "DeepSeek V4 Flash Free", supportsReasoning: true },
{ id: "minimax-m2.5-free", name: "MiniMax M2.5 Free", contextLength: 204800 },
{ id: "nemotron-3-super-free", name: "Nemotron 3 Super Free", contextLength: 1000000 },
{
id: "qwen3.6-plus-free",
name: "Qwen3.6 Plus Free",
targetFormat: "claude",
contextLength: 200000,
},
],
},
agentrouter: {
id: "agentrouter",
alias: "agentrouter",
format: "claude",
executor: "default",
baseUrl: "https://agentrouter.org/v1/messages",
authType: "apikey",
authHeader: "x-api-key",
defaultContextLength: 128000,
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
"Anthropic-Beta": ANTHROPIC_BETA_CLAUDE_OAUTH,
"Anthropic-Dangerous-Direct-Browser-Access": "true",
"User-Agent": CLAUDE_CLI_USER_AGENT,
"X-App": "cli",
"X-Stainless-Helper-Method": "stream",
"X-Stainless-Retry-Count": "0",
"X-Stainless-Runtime-Version": CLAUDE_CLI_STAINLESS_RUNTIME_VERSION,
"X-Stainless-Package-Version": CLAUDE_CLI_STAINLESS_PACKAGE_VERSION,
"X-Stainless-Runtime": "node",
"X-Stainless-Lang": "js",
"X-Stainless-Arch": mapStainlessArch(),
"X-Stainless-Os": mapStainlessOs(),
"X-Stainless-Timeout": "600",
},
models: [
{ id: "claude-opus-4-6", name: "Claude 4.6 Opus" },
{ id: "claude-haiku-4-5-20251001", name: "Claude 4.5 Haiku" },
{ id: "glm-5.1", name: "GLM 5.1" },
{ id: "deepseek-v3.2", name: "DeepSeek V3.2" },
],
passthroughModels: true,
},
"command-code": {
id: "command-code",
alias: "cmd",
format: "openai",
executor: "command-code",
baseUrl: "https://api.commandcode.ai",
chatPath: "/alpha/generate",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer ",
defaultContextLength: 200000,
models: [
{
id: "claude-opus-4-7",
name: "Claude Opus 4.7 (CC)",
supportsReasoning: true,
contextLength: 200000,
maxOutputTokens: 32000,
},
{
id: "claude-opus-4-6",
name: "Claude Opus 4.6 (CC)",
supportsReasoning: true,
contextLength: 200000,
maxOutputTokens: 32000,
},
{
id: "claude-sonnet-4-6",
name: "Claude Sonnet 4.6 (CC)",
supportsReasoning: true,
contextLength: 200000,
maxOutputTokens: 16384,
},
{
id: "claude-haiku-4-5-20251001",
name: "Claude Haiku 4.5 (CC)",
supportsReasoning: true,
contextLength: 200000,
maxOutputTokens: 8192,
},
{
id: "gpt-5.5",
name: "GPT-5.5 (CC)",
supportsReasoning: true,
contextLength: 256000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.4",
name: "GPT-5.4 (CC)",
supportsReasoning: true,
contextLength: 256000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.3-codex",
name: "GPT-5.3 Codex (CC)",
supportsReasoning: true,
contextLength: 256000,
maxOutputTokens: 128000,
},
{
id: "gpt-5.4-mini",
name: "GPT-5.4 Mini (CC)",
supportsReasoning: false,
contextLength: 256000,
maxOutputTokens: 128000,
},
{
id: "deepseek/deepseek-v4-pro",
name: "DeepSeek V4 Pro (CC)",
supportsReasoning: true,
contextLength: 1000000,
maxOutputTokens: 384000,
},
{
id: "deepseek/deepseek-v4-flash",
name: "DeepSeek V4 Flash (CC)",
supportsReasoning: true,
contextLength: 1000000,
maxOutputTokens: 384000,
},
{
id: "moonshotai/Kimi-K2.6",
name: "Kimi K2.6 (CC)",
supportsReasoning: true,
contextLength: 262144,
maxOutputTokens: 131072,
},
{
id: "moonshotai/Kimi-K2.5",
name: "Kimi K2.5 (CC)",
supportsReasoning: true,
contextLength: 262144,
maxOutputTokens: 131072,
},
{
id: "zai-org/GLM-5.1",
name: "GLM-5.1 (CC)",
supportsReasoning: true,
contextLength: 200000,
maxOutputTokens: 131072,
},
{
id: "zai-org/GLM-5",
name: "GLM-5 (CC)",
supportsReasoning: true,
contextLength: 200000,
maxOutputTokens: 131072,
},
{
id: "MiniMaxAI/MiniMax-M2.7",
name: "MiniMax M2.7 (CC)",
supportsReasoning: true,
contextLength: 1048576,
maxOutputTokens: 131072,
},
{
id: "MiniMaxAI/MiniMax-M2.5",
name: "MiniMax M2.5 (CC)",
supportsReasoning: true,
contextLength: 1048576,
maxOutputTokens: 131072,
},
{
id: "Qwen/Qwen3.6-Max-Preview",
name: "Qwen 3.6 Max (CC)",
supportsReasoning: true,
contextLength: 1000000,
maxOutputTokens: 131072,
},
{
id: "Qwen/Qwen3.6-Plus",
name: "Qwen 3.6 Plus (CC)",
supportsReasoning: true,
contextLength: 1000000,
maxOutputTokens: 131072,
},
],
},
openrouter: {
id: "openrouter",
alias: "openrouter",
format: "openai",
executor: "default",
baseUrl: "https://openrouter.ai/api/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
headers: {
"HTTP-Referer": "https://endpoint-proxy.local",
"X-Title": "Endpoint Proxy",
},
models: [{ id: "auto", name: "Auto (Best Available)" }],
},
"api-airforce": {
id: "api-airforce",
alias: "af",
format: "openai",
executor: "default",
baseUrl: "https://api.airforce/v1/chat/completions",
modelsUrl: "https://api.airforce/v1/models",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
headers: {
"HTTP-Referer": "https://endpoint-proxy.local",
"X-Title": "Endpoint Proxy",
},
models: [
// Free tier models (55 available)
{ id: "x-ai/grok-3", name: "Grok-3 (Free)", contextLength: 131072, maxOutputTokens: 65536 },
{
id: "x-ai/grok-2-1212",
name: "Grok-2 1212 (Free)",
contextLength: 131072,
maxOutputTokens: 65536,
},
{
id: "anthropic/claude-3.7-sonnet",
name: "Claude 3.7 Sonnet (Free)",
contextLength: 200000,
maxOutputTokens: 8192,
},
{
id: "qwen/qwen3-32b",
name: "Qwen3 32B (Free)",
contextLength: 128000,
maxOutputTokens: 8192,
},
{
id: "moonshot/kimi-k2.6",
name: "Kimi K2.6 (Free)",
contextLength: 262144,
maxOutputTokens: 65536,
},
{
id: "google/gemini-2.5-flash",
name: "Gemini 2.5 Flash (Free)",
contextLength: 1048576,
maxOutputTokens: 65536,
},
{
id: "deepseek/deepseek-v3",
name: "DeepSeek V3 (Free)",
contextLength: 262144,
maxOutputTokens: 16384,
},
],
},
qianfan: {
id: "qianfan",
alias: "qianfan",
format: "openai",
executor: "default",
baseUrl: "https://qianfan.baidubce.com/v2/chat/completions",
modelsUrl: "https://qianfan.baidubce.com/v2/models",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
{ id: "ernie-5.1", name: "ERNIE 5.1" },
{ id: "ernie-5.0-thinking-latest", name: "ERNIE 5.0 Thinking Latest" },
{ id: "ernie-x1.1", name: "ERNIE X1.1", contextLength: 64000 },
],
},
glm: {
id: "glm",
alias: "glm",
format: "openai",
executor: "glm",
baseUrl: "https://api.z.ai/api/coding/paas/v4/chat/completions",
defaultContextLength: 200000,
authType: "apikey",
authHeader: "bearer",
requestDefaults: GLM_REQUEST_DEFAULTS,
timeoutMs: GLM_TIMEOUT_MS,
models: [...GLM_SHARED_MODELS],
},
"glm-cn": {
id: "glm-cn",
alias: "glmcn",
format: "openai",
executor: "glm",
baseUrl: "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 200000,
requestDefaults: GLM_REQUEST_DEFAULTS,
timeoutMs: GLM_TIMEOUT_MS,
models: [...GLM_SHARED_MODELS],
passthroughModels: true,
},
glmt: {
id: "glmt",
alias: "glmt",
format: "openai",
executor: "glm",
baseUrl: "https://api.z.ai/api/coding/paas/v4/chat/completions",
defaultContextLength: 200000,
authType: "apikey",
authHeader: "bearer",
requestDefaults: GLMT_REQUEST_DEFAULTS,
timeoutMs: GLMT_TIMEOUT_MS,
models: [...GLM_SHARED_MODELS],
},
"bailian-coding-plan": {
id: "bailian-coding-plan",
alias: "bcp",
format: "claude",
executor: "default",
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1",
chatPath: "/messages",
authType: "apikey",
authHeader: "x-api-key",
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
},
models: [
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus(vision)" },
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus(vision)" },
{ id: "qwen3-max-2026-01-23", name: "Qwen3 Max" },
{ id: "kimi-k2.5", name: "Kimi K2.5(vision)" },
{ id: "glm-5", name: "GLM 5" },
{ id: "MiniMax-M2.5", name: "MiniMax M2.5" },
],
},
zai: {
id: "zai",
alias: "zai",
format: "claude",
executor: "default",
baseUrl: "https://api.z.ai/api/anthropic/v1/messages",
urlSuffix: "?beta=true",
authType: "apikey",
authHeader: "x-api-key",
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
},
models: [
{ id: "glm-5.1", name: "GLM 5.1" },
{ id: "glm-5", name: "GLM 5" },
{ id: "glm-5-turbo", name: "GLM 5 Turbo" },
],
},
kimi: {
id: "kimi",
alias: "kimi",
format: "openai",
executor: "default",
baseUrl: "https://api.moonshot.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "kimi-k2.6", name: "Kimi K2.6" },
{ id: "kimi-k2.5", name: "Kimi K2.5" },
],
},
"kimi-coding": {
id: "kimi-coding",
alias: "kmc",
...KIMI_CODING_SHARED,
urlSuffix: "?beta=true",
authType: "oauth",
oauth: {
clientIdEnv: "KIMI_CODING_OAUTH_CLIENT_ID",
clientIdDefault: "17e5f671-d194-4dfb-9706-5516cb48c098",
tokenUrl: "https://auth.kimi.com/api/oauth/token",
refreshUrl: "https://auth.kimi.com/api/oauth/token",
authUrl: "https://auth.kimi.com/api/oauth/device_authorization",
},
},
"kimi-coding-apikey": {
id: "kimi-coding-apikey",
alias: "kmca",
...KIMI_CODING_SHARED,
authType: "apikey",
},
kilocode: {
id: "kilocode",
alias: "kc",
format: "openrouter",
executor: "openrouter",
baseUrl: "https://api.kilo.ai/api/openrouter/chat/completions",
modelsUrl: "https://api.kilo.ai/api/openrouter/models",
authType: "oauth",
authHeader: "Authorization",
authPrefix: "Bearer ",
oauth: {
initiateUrl: "https://api.kilo.ai/api/device-auth/codes",
pollUrlBase: "https://api.kilo.ai/api/device-auth/codes",
},
models: [
{ id: "openrouter/free", name: "Free Models Router" },
{ id: "qwen/qwen3.6-plus", name: "Qwen3.6 Plus" },
{ id: "qwen/qwen3.5-397b-a17b", name: "Qwen3.5 397B A17B" },
{ id: "openai/gpt-5.5", name: "GPT-5.5" },
{ id: "openai/gpt-5.4-mini", name: "GPT-5.4 Mini" },
{ id: "anthropic/claude-opus-4.7", name: "Claude Opus 4.7" },
{ id: "anthropic/claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
{ id: "anthropic/claude-haiku-4.5", name: "Claude Haiku 4.5" },
{ id: "google/gemini-3.1-pro-preview", name: "Gemini 3.1 Pro" },
{ id: "google/gemini-3-flash-preview", name: "Gemini 3 Flash" },
{ id: "google/gemini-3.1-flash-lite", name: "Gemini 3.1 Flash Lite" },
{ id: "deepseek/deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
{ id: "deepseek/deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
{ id: "moonshotai/kimi-k2.6", name: "Kimi K2.6" },
],
passthroughModels: true,
},
cline: {
id: "cline",
alias: "cl",
format: "openai",
executor: "openai",
baseUrl: "https://api.cline.bot/api/v1/chat/completions",
authType: "oauth",
authHeader: "Authorization",
authPrefix: "Bearer ",
oauth: {
tokenUrl: "https://api.cline.bot/api/v1/auth/token",
refreshUrl: "https://api.cline.bot/api/v1/auth/refresh",
authUrl: "https://api.cline.bot/api/v1/auth/authorize",
},
extraHeaders: {
"HTTP-Referer": "https://cline.bot",
"X-Title": "Cline",
},
models: [
{ id: "moonshotai/kimi-k2.6", name: "Kimi K2.6 (Free)" },
{ id: "anthropic/claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
{ id: "anthropic/claude-opus-4.7", name: "Claude Opus 4.7" },
{ id: "google/gemini-3.1-pro-preview", name: "Gemini 3.1 Pro" },
{ id: "google/gemini-3-flash-preview", name: "Gemini 3 Flash" },
{ id: "openai/gpt-5.5", name: "GPT-5.5" },
{ id: "deepseek/deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
{ id: "deepseek/deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
],
passthroughModels: true,
},
windsurf: {
id: "windsurf",
alias: "ws",
format: "windsurf",
executor: "windsurf",
// gRPC-web endpoint — handled entirely inside WindsurfExecutor.
// Model IDs are the canonical Windsurf catalog names (with dots), auto-synced
// from the Windsurf cloud via GetCascadeModelConfigs. Source: guanxiaol/WindsurfPoolAPI.
baseUrl: "https://server.self-serve.windsurf.com",
authType: "oauth",
authHeader: "Authorization",
authPrefix: "Bearer ",
defaultContextLength: 200000,
// Model IDs verified against model_configs_v2.bin from Devin CLI binary (2026.5.x).
// dot-notation = OmniRoute ID; executor MODEL_ALIAS_MAP maps it to Windsurf modelUid.
models: [
// ── Cognition / SWE ──────────────────────────────────────────────────
{ id: "swe-1.6-fast", name: "SWE-1.6 Fast" },
{ id: "swe-1.6", name: "SWE-1.6" },
{ id: "swe-1.5-fast", name: "SWE-1.5 Fast" },
{ id: "swe-1.5", name: "SWE-1.5" },
// ── Claude Opus 4.7 — effort-tiered ─────────────────────────────────
{ id: "claude-opus-4.7-max", name: "Claude Opus 4.7 Max", contextLength: 200000 },
{ id: "claude-opus-4.7-xhigh", name: "Claude Opus 4.7 XHigh", contextLength: 200000 },
{ id: "claude-opus-4.7-high", name: "Claude Opus 4.7 High", contextLength: 200000 },
{ id: "claude-opus-4.7-medium", name: "Claude Opus 4.7 Medium", contextLength: 200000 },
{ id: "claude-opus-4.7-low", name: "Claude Opus 4.7 Low", contextLength: 200000 },
{ id: "claude-opus-4.7-review", name: "Claude Opus 4.7 Review", contextLength: 200000 },
// ── Claude Sonnet/Opus 4.6 ──────────────────────────────────────────
{
id: "claude-sonnet-4.6-thinking-1m",
name: "Claude Sonnet 4.6 Thinking 1M",
contextLength: 1000000,
},
{ id: "claude-sonnet-4.6-1m", name: "Claude Sonnet 4.6 1M", contextLength: 1000000 },
{
id: "claude-sonnet-4.6-thinking",
name: "Claude Sonnet 4.6 Thinking",
contextLength: 200000,
},
{ id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6", contextLength: 200000 },
{ id: "claude-opus-4.6-thinking", name: "Claude Opus 4.6 Thinking", contextLength: 200000 },
{ id: "claude-opus-4.6", name: "Claude Opus 4.6", contextLength: 200000 },
// ── Claude 4.5 ──────────────────────────────────────────────────────
{ id: "claude-opus-4.5-thinking", name: "Claude Opus 4.5 Thinking", contextLength: 200000 },
{ id: "claude-opus-4.5", name: "Claude Opus 4.5", contextLength: 200000 },
{
id: "claude-sonnet-4.5-thinking",
name: "Claude Sonnet 4.5 Thinking",
contextLength: 200000,
},
{ id: "claude-sonnet-4.5", name: "Claude Sonnet 4.5", contextLength: 200000 },
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5", contextLength: 200000 },
// ── GPT-5.5 — effort-tiered (+ fast/priority variants) ──────────────
{ id: "gpt-5.5-xhigh-fast", name: "GPT-5.5 XHigh Fast", contextLength: 200000 },
{ id: "gpt-5.5-xhigh", name: "GPT-5.5 XHigh", contextLength: 200000 },
{ id: "gpt-5.5-high-fast", name: "GPT-5.5 High Fast", contextLength: 200000 },
{ id: "gpt-5.5-high", name: "GPT-5.5 High", contextLength: 200000 },
{ id: "gpt-5.5-medium-fast", name: "GPT-5.5 Medium Fast", contextLength: 200000 },
{ id: "gpt-5.5-medium", name: "GPT-5.5 Medium", contextLength: 200000 },
{ id: "gpt-5.5-low-fast", name: "GPT-5.5 Low Fast", contextLength: 200000 },
{ id: "gpt-5.5-low", name: "GPT-5.5 Low", contextLength: 200000 },
{ id: "gpt-5.5-none-fast", name: "GPT-5.5 None Fast", contextLength: 200000 },
{ id: "gpt-5.5-none", name: "GPT-5.5 None", contextLength: 200000 },
// ── GPT-5.4 — effort-tiered (+ mini + fast variants) ────────────────
{ id: "gpt-5.4-xhigh-fast", name: "GPT-5.4 XHigh Fast", contextLength: 200000 },
{ id: "gpt-5.4-xhigh", name: "GPT-5.4 XHigh", contextLength: 200000 },
{ id: "gpt-5.4-high-fast", name: "GPT-5.4 High Fast", contextLength: 200000 },
{ id: "gpt-5.4-high", name: "GPT-5.4 High", contextLength: 200000 },
{ id: "gpt-5.4-medium-fast", name: "GPT-5.4 Medium Fast", contextLength: 200000 },
{ id: "gpt-5.4-medium", name: "GPT-5.4 Medium", contextLength: 200000 },
{ id: "gpt-5.4-low-fast", name: "GPT-5.4 Low Fast", contextLength: 200000 },
{ id: "gpt-5.4-low", name: "GPT-5.4 Low", contextLength: 200000 },
{ id: "gpt-5.4-none-fast", name: "GPT-5.4 None Fast", contextLength: 200000 },
{ id: "gpt-5.4-none", name: "GPT-5.4 None", contextLength: 200000 },
{ id: "gpt-5.4-mini-xhigh", name: "GPT-5.4 Mini XHigh", contextLength: 128000 },
{ id: "gpt-5.4-mini-high", name: "GPT-5.4 Mini High", contextLength: 128000 },
{ id: "gpt-5.4-mini-medium", name: "GPT-5.4 Mini Medium", contextLength: 128000 },
{ id: "gpt-5.4-mini-low", name: "GPT-5.4 Mini Low", contextLength: 128000 },
// ── GPT-5.3 Codex — effort-tiered (+ fast variants) ─────────────────
{ id: "gpt-5.3-codex-xhigh-fast", name: "GPT-5.3 Codex XHigh Fast", contextLength: 200000 },
{ id: "gpt-5.3-codex-xhigh", name: "GPT-5.3 Codex XHigh", contextLength: 200000 },
{ id: "gpt-5.3-codex-high-fast", name: "GPT-5.3 Codex High Fast", contextLength: 200000 },
{ id: "gpt-5.3-codex-high", name: "GPT-5.3 Codex High", contextLength: 200000 },
{ id: "gpt-5.3-codex-medium-fast", name: "GPT-5.3 Codex Medium Fast", contextLength: 200000 },
{ id: "gpt-5.3-codex-medium", name: "GPT-5.3 Codex Medium", contextLength: 200000 },
{ id: "gpt-5.3-codex-low-fast", name: "GPT-5.3 Codex Low Fast", contextLength: 200000 },
{ id: "gpt-5.3-codex-low", name: "GPT-5.3 Codex Low", contextLength: 200000 },
// ── GPT-5.2 ─────────────────────────────────────────────────────────
{ id: "gpt-5.2-xhigh", name: "GPT-5.2 XHigh", contextLength: 200000 },
{ id: "gpt-5.2-high", name: "GPT-5.2 High", contextLength: 200000 },
{ id: "gpt-5.2-medium", name: "GPT-5.2 Medium", contextLength: 200000 },
{ id: "gpt-5.2-low", name: "GPT-5.2 Low", contextLength: 200000 },
{ id: "gpt-5.2-none", name: "GPT-5.2 None", contextLength: 200000 },
// ── GPT-5 ────────────────────────────────────────────────────────────
{ id: "gpt-5", name: "GPT-5", contextLength: 200000 },
// ── GPT-4.1 / 4o ────────────────────────────────────────────────────
{ id: "gpt-4.1", name: "GPT-4.1", contextLength: 200000 },
{ id: "gpt-4.1-mini", name: "GPT-4.1 Mini", contextLength: 128000 },
{ id: "gpt-4.1-nano", name: "GPT-4.1 Nano", contextLength: 32000 },
{ id: "gpt-4o", name: "GPT-4o", contextLength: 128000 },
{ id: "gpt-4o-mini", name: "GPT-4o Mini", contextLength: 128000 },
// ── Gemini ───────────────────────────────────────────────────────────
{ id: "gemini-3.1-pro-high", name: "Gemini 3.1 Pro High", contextLength: 1000000 },
{ id: "gemini-3.1-pro-low", name: "Gemini 3.1 Pro Low", contextLength: 1000000 },
{ id: "gemini-3.0-flash-high", name: "Gemini 3 Flash High", contextLength: 1000000 },
{ id: "gemini-3.0-flash-medium", name: "Gemini 3 Flash Medium", contextLength: 1000000 },
{ id: "gemini-3.0-flash-low", name: "Gemini 3 Flash Low", contextLength: 1000000 },
{ id: "gemini-3.0-flash-minimal", name: "Gemini 3 Flash Minimal", contextLength: 1000000 },
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", contextLength: 1000000 },
// ── Others ───────────────────────────────────────────────────────────
{ id: "deepseek-v4", name: "DeepSeek V4", contextLength: 64000 },
{ id: "kimi-k2.6", name: "Kimi K2.6", contextLength: 131000 },
{ id: "kimi-k2.5", name: "Kimi K2.5", contextLength: 131000 },
{ id: "glm-5.1", name: "GLM-5.1", contextLength: 128000 },
],
},
// ── Devin CLI (Official — ACP JSON-RPC over stdio) ──────────────────────────
// Uses the official `devin` binary via `devin acp --agent-type summarizer`.
// Requires devin CLI installed (https://cli.devin.ai) and authenticated
// via `devin auth login` or WINDSURF_API_KEY env var.
// Model IDs are passed directly to the ACP session/new `model` param.
"devin-cli": {
id: "devin-cli",
alias: "dv",
format: "openai",
executor: "devin-cli",
baseUrl: "devin://acp/stdio",
authType: "oauth",
authHeader: "Authorization",
authPrefix: "Bearer ",
defaultContextLength: 200000,
models: [
// Cognition / SWE — default model family recommended for coding tasks
{ id: "swe-1.6-fast", name: "SWE-1.6 Fast" },
{ id: "swe-1.6", name: "SWE-1.6" },
{ id: "swe-1.5-fast", name: "SWE-1.5 Fast" },
{ id: "swe-1.5", name: "SWE-1.5" },
// Claude Opus 4.7
{ id: "claude-opus-4.7-max", name: "Claude Opus 4.7 Max", contextLength: 200000 },
{ id: "claude-opus-4.7-high", name: "Claude Opus 4.7 High", contextLength: 200000 },
{ id: "claude-opus-4.7-medium", name: "Claude Opus 4.7 Medium", contextLength: 200000 },
{ id: "claude-opus-4.7-low", name: "Claude Opus 4.7 Low", contextLength: 200000 },
// Claude Sonnet/Opus 4.6
{
id: "claude-sonnet-4.6-thinking-1m",
name: "Claude Sonnet 4.6 Thinking 1M",
contextLength: 1000000,
},
{
id: "claude-sonnet-4.6-thinking",
name: "Claude Sonnet 4.6 Thinking",
contextLength: 200000,
},
{ id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6", contextLength: 200000 },
{ id: "claude-opus-4.6-thinking", name: "Claude Opus 4.6 Thinking", contextLength: 200000 },
{ id: "claude-opus-4.6", name: "Claude Opus 4.6", contextLength: 200000 },
// Claude 4.5
{ id: "claude-sonnet-4.5", name: "Claude Sonnet 4.5", contextLength: 200000 },
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5", contextLength: 200000 },
// GPT-5.5
{ id: "gpt-5.5-xhigh", name: "GPT-5.5 XHigh", contextLength: 200000 },
{ id: "gpt-5.5-high", name: "GPT-5.5 High", contextLength: 200000 },
{ id: "gpt-5.5-medium", name: "GPT-5.5 Medium", contextLength: 200000 },
{ id: "gpt-5.5-low", name: "GPT-5.5 Low", contextLength: 200000 },
// GPT-5.4
{ id: "gpt-5.4-high", name: "GPT-5.4 High", contextLength: 200000 },
{ id: "gpt-5.4-medium", name: "GPT-5.4 Medium", contextLength: 200000 },
{ id: "gpt-5.4-low", name: "GPT-5.4 Low", contextLength: 200000 },
// GPT-5.3 Codex
{ id: "gpt-5.3-codex-high", name: "GPT-5.3 Codex High", contextLength: 200000 },
{ id: "gpt-5.3-codex-medium", name: "GPT-5.3 Codex Medium", contextLength: 200000 },
{ id: "gpt-5.3-codex-low", name: "GPT-5.3 Codex Low", contextLength: 200000 },
// GPT-5.2
{ id: "gpt-5.2-high", name: "GPT-5.2 High", contextLength: 200000 },
{ id: "gpt-5.2-medium", name: "GPT-5.2 Medium", contextLength: 200000 },
{ id: "gpt-5.2-low", name: "GPT-5.2 Low", contextLength: 200000 },
// Gemini
{ id: "gemini-3.1-pro-high", name: "Gemini 3.1 Pro High", contextLength: 1000000 },
{ id: "gemini-3.1-pro-low", name: "Gemini 3.1 Pro Low", contextLength: 1000000 },
{ id: "gemini-3.0-flash-high", name: "Gemini 3 Flash High", contextLength: 1000000 },
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", contextLength: 1000000 },
// Others
{ id: "deepseek-v4", name: "DeepSeek V4", contextLength: 64000 },
{ id: "kimi-k2.6", name: "Kimi K2.6", contextLength: 131000 },
{ id: "glm-5.1", name: "GLM-5.1", contextLength: 128000 },
],
},
minimax: {
id: "minimax",
alias: "minimax",
format: "claude",
executor: "default",
baseUrl: "https://api.minimax.io/anthropic/v1/messages",
urlSuffix: "?beta=true",
authType: "apikey",
authHeader: "bearer",
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
},
models: [
// T12/T28: MiniMax default upgraded from M2.5 to M2.7
{ id: "MiniMax-M2.7", name: "MiniMax M2.7" },
{ id: "MiniMax-M2.7-highspeed", name: "MiniMax M2.7 Highspeed" },
{ id: "MiniMax-M2.5", name: "MiniMax M2.5" },
{ id: "MiniMax-M2.5-highspeed", name: "MiniMax M2.5 Highspeed" },
],
},
"minimax-cn": {
id: "minimax-cn",
alias: "minimax-cn", // unique alias (was colliding with minimax)
format: "claude",
executor: "default",
baseUrl: "https://api.minimaxi.com/anthropic/v1/messages",
urlSuffix: "?beta=true",
authType: "apikey",
authHeader: "bearer",
headers: {
"Anthropic-Version": ANTHROPIC_VERSION_HEADER,
},
models: [
// Keep parity with minimax to ensure model discovery works for minimax-cn connections.
{ id: "MiniMax-M2.7", name: "MiniMax M2.7" },
{ id: "MiniMax-M2.7-highspeed", name: "MiniMax M2.7 Highspeed" },
{ id: "MiniMax-M2.5", name: "MiniMax M2.5" },
{ id: "MiniMax-M2.5-highspeed", name: "MiniMax M2.5 Highspeed" },
],
},
crof: {
id: "crof",
alias: "crof",
format: "openai",
executor: "default",
baseUrl: "https://crof.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
// Seed list — runtime /v1/models discovery keeps this fresh.
// Source: GET https://crof.ai/v1/models (2026-05-17).
models: [
{
id: "deepseek-v4-pro-precision",
name: "DeepSeek V4 Pro (Precision)",
supportsReasoning: true,
},
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
{ id: "deepseek-v3.2", name: "DeepSeek V3.2" },
{ id: "kimi-k2.6-precision", name: "Kimi K2.6 (Precision)", supportsReasoning: true },
{ id: "kimi-k2.6", name: "Kimi K2.6", supportsReasoning: true },
{ id: "kimi-k2.5-lightning", name: "Kimi K2.5 (Lightning)", supportsReasoning: true },
{ id: "kimi-k2.5", name: "Kimi K2.5", supportsReasoning: true },
{ id: "glm-5.1-precision", name: "GLM 5.1 (Precision)", supportsReasoning: true },
{ id: "glm-5.1", name: "GLM 5.1", supportsReasoning: true },
{ id: "glm-4.7", name: "GLM 4.7" },
{ id: "glm-4.7-flash", name: "GLM 4.7 Flash" },
{ id: "mimo-v2.5-pro-precision", name: "Mimo 2.5 Pro (Precision)", supportsReasoning: true },
{ id: "mimo-v2.5-pro", name: "Mimo 2.5 Pro", supportsReasoning: true },
{ id: "gemma-4-31b-it", name: "Gemma 4 31B", supportsReasoning: true },
{ id: "minimax-m2.5", name: "MiniMax M2.5" },
{ id: "qwen3.6-27b", name: "Qwen3.6 27B", supportsReasoning: true },
{ id: "qwen3.5-397b-a17b", name: "Qwen3.5 397B A17B", supportsReasoning: true },
{ id: "qwen3.5-9b", name: "Qwen3.5 9B", supportsReasoning: true },
],
},
deepseek: {
id: "deepseek",
alias: "ds",
format: "openai",
executor: "default",
baseUrl: "https://api.deepseek.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
],
},
haiper: {
id: "haiper",
alias: "hp",
format: "openai",
executor: "default",
baseUrl: "https://api.haiper.ai/v1",
authType: "apikey",
authHeader: "HAIPER_KEY",
models: [
{ id: "gen2", name: "Gen 2 Video" },
{ id: "gen2-image", name: "Gen 2 Image" },
],
},
leonardo: {
id: "leonardo",
alias: "leo",
format: "openai",
executor: "default",
baseUrl: "https://cloud.leonardo.ai/api/rest/v1",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "phoenix", name: "Phoenix" },
{ id: "sdxl", name: "SDXL" },
],
},
ideogram: {
id: "ideogram",
alias: "ideo",
format: "openai",
executor: "default",
baseUrl: "https://api.ideogram.ai",
authType: "apikey",
authHeader: "Api-Key",
models: [
{ id: "V_3", name: "Ideogram V3" },
{ id: "V_2A", name: "Ideogram V2A" },
],
},
suno: {
id: "suno",
alias: "suno",
format: "openai",
executor: "default",
baseUrl: "https://studio-api.suno.ai/api/generate/v2/",
authType: "cookie",
authHeader: "cookie",
models: [
{ id: "chirp-v3-5", name: "Chirp V3.5" },
{ id: "chirp-v4", name: "Chirp V4" },
],
},
udio: {
id: "udio",
alias: "udio",
format: "openai",
executor: "default",
baseUrl: "https://www.udio.com/api/generate-proxy",
authType: "apikey",
authHeader: "cookie",
models: [{ id: "udio-default", name: "Udio Default" }],
},
groq: {
id: "groq",
alias: "groq",
format: "openai",
executor: "default",
baseUrl: "https://api.groq.com/openai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "meta-llama/llama-4-scout-17b-16e-instruct", name: "Llama 4 Scout" },
{ id: "llama-3.3-70b-versatile", name: "Llama 3.3 70B" },
{ id: "openai/gpt-oss-120b", name: "GPT-OSS 120B" },
{ id: "openai/gpt-oss-20b", name: "GPT-OSS 20B" },
{ id: "qwen/qwen3-32b", name: "Qwen3 32B" },
],
},
novita: {
id: "novita",
alias: "novita",
format: "openai",
executor: "default",
baseUrl: "https://api.novita.ai/v3/chat/completions",
modelsUrl: "https://api.novita.ai/v3/models",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "ai-ai/llama-3.1-8b-instruct", name: "Llama 3.1 8B" }],
},
baidu: {
id: "baidu",
alias: "baidu",
format: "openai",
executor: "default",
baseUrl: "https://qianfan.baidubce.com/v2/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "ernie-4.0-8k", name: "ERNIE 4.0 8K" }],
},
baichuan: {
id: "baichuan",
alias: "baichuan",
format: "openai",
executor: "default",
baseUrl: "https://api.baichuan-ai.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "Baichuan4", name: "Baichuan 4" }],
},
coze: {
id: "coze",
alias: "coze",
format: "openai",
executor: "default",
baseUrl: "https://api.coze.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "claude-3-7-sonnet-20250514", name: "Claude 3.7 Sonnet" }],
},
dify: {
id: "dify",
alias: "dify",
format: "openai",
executor: "default",
baseUrl: "https://api.dify.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "auto", name: "Auto" }],
},
lepton: {
id: "lepton",
alias: "lepton",
format: "openai",
executor: "default",
baseUrl: "https://api.lepton.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "llama-3.1-8b", name: "Llama 3.1 8B" }],
},
kluster: {
id: "kluster",
alias: "kluster",
format: "openai",
executor: "default",
baseUrl: "https://api.kluster.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "auto", name: "Auto" }],
},
krutrim: {
id: "krutrim",
alias: "krutrim",
format: "openai",
executor: "default",
baseUrl: "https://api.krutrim.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "krutrim-2-7b-instruct", name: "Krutrim 2 7B" }],
},
liquid: {
id: "liquid",
alias: "liquid",
format: "openai",
executor: "default",
baseUrl: "https://api.liquid.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "liquid-lfm-40b", name: "Liquid LFM 40B" }],
},
nomic: {
id: "nomic",
alias: "nomic",
format: "openai",
executor: "default",
baseUrl: "https://api.nomic.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "nomic-embed-text-v1.5", name: "Nomic Embed Text" }],
},
monsterapi: {
id: "monsterapi",
alias: "monster",
format: "openai",
executor: "default",
baseUrl: "https://api.monsterapi.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "llama-3-8b-fuse", name: "Llama 3 8B Fuse" }],
},
nlpcloud: {
id: "nlpcloud",
alias: "nlpc",
format: "openai",
executor: "default",
baseUrl: "https://api.nlpcloud.io/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "llama-3-8b-instruct", name: "Llama 3 8B" }],
},
phind: {
id: "phind",
alias: "ph",
format: "openai",
executor: "phind",
baseUrl: "https://www.phind.com/api/chat",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "phind-model", name: "Phind Model (Auto)" },
{ id: "gpt-4o", name: "GPT-4o (via Phind)" },
{ id: "claude-3.5-sonnet", name: "Claude 3.5 Sonnet (via Phind)" },
],
},
poolside: {
id: "poolside",
alias: "poolside",
format: "openai",
executor: "default",
baseUrl: "https://api.poolside.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "poolside-model", name: "Poolside Model" }],
},
chutes: {
id: "chutes",
alias: "chutes",
format: "openai",
executor: "default",
baseUrl: "https://api.chutesai.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "Qwen2.5-72B-Instruct", name: "Qwen2.5 72B" }],
},
glhf: {
id: "glhf",
alias: "glhf",
format: "openai",
executor: "default",
baseUrl: "https://api.laf.run/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "deepseek-7b-chat", name: "DeepSeek 7B Chat" }],
},
huggingchat: {
id: "huggingchat",
alias: "hc",
format: "openai",
executor: "huggingchat",
baseUrl: "https://huggingface.co/chat/conversation",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "meta-llama/Llama-3.3-70B-Instruct", name: "Llama 3.3 70B" },
{ id: "Qwen/Qwen2.5-72B-Instruct", name: "Qwen 2.5 72B" },
{ id: "mistralai/Mistral-Small-24B-Instruct-2501", name: "Mistral Small 24B" },
{ id: "deepseek-ai/DeepSeek-R1", name: "DeepSeek R1" },
],
},
iflytek: {
id: "iflytek",
alias: "iflytek",
format: "openai",
executor: "default",
baseUrl: "https://spark-api.xf-yun.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "generalv3.5", name: "General V3.5" }],
},
inclusionai: {
id: "inclusionai",
alias: "inclusionai",
format: "openai",
executor: "default",
baseUrl: "https://api.inclusionai.tech/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "inclusion-model", name: "Inclusion Model" }],
},
sensenova: {
id: "sensenova",
alias: "sensenova",
format: "openai",
executor: "default",
baseUrl: "https://api.sensenova.cn/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "sensechat", name: "SenseChat" }],
},
sparkdesk: {
id: "sparkdesk",
alias: "sparkdesk",
format: "openai",
executor: "default",
baseUrl: "https://spark-api.xf-yun.com/v3.1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "general", name: "General" }],
},
stepfun: {
id: "stepfun",
alias: "stepfun",
format: "openai",
executor: "default",
baseUrl: "https://api.stepfun.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "step-1v", name: "Step 1V" }],
},
tencent: {
id: "tencent",
alias: "tencent",
format: "openai",
executor: "default",
baseUrl: "https://api.hunyuan.cloud.tencent.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "hunyuan-pro", name: "Hunyuan Pro" }],
},
doubao: {
id: "doubao",
alias: "doubao",
format: "openai",
executor: "default",
baseUrl: "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "doubao-pro-32k", name: "Doubao Pro 32K" }],
},
yi: {
id: "yi",
alias: "yi",
format: "openai",
executor: "default",
baseUrl: "https://api.lingyiwanwu.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "yi-large", name: "Yi Large" }],
},
modal: {
id: "modal",
alias: "modal",
format: "openai",
executor: "default",
baseUrl: "https://api.modal.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "google/gemini-2.0-flash", name: "Gemini 2.0 Flash" }],
},
blackbox: {
id: "blackbox",
alias: "bb",
format: "openai",
executor: "default",
baseUrl: "https://api.blackbox.ai/v1/chat/completions",
modelsUrl: "https://api.blackbox.ai/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "gpt-4o", name: "GPT-4o" },
{ id: "gemini-2.5-flash", name: "Gemini 2.5 Flash" },
{ id: "claude-sonnet-4", name: "Claude Sonnet 4" },
{ id: "deepseek-v3", name: "DeepSeek V3" },
{ id: "blackboxai", name: "Blackbox AI" },
{ id: "blackboxai-pro", name: "Blackbox AI Pro" },
],
},
bazaarlink: {
id: "bazaarlink",
alias: "bzl",
format: "openai",
executor: "default",
baseUrl: "https://bazaarlink.ai/api/v1/chat/completions",
modelsUrl: "https://bazaarlink.ai/api/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "auto:free", name: "Auto Free (Zero Cost)" },
{ id: "claude-opus-4.7", name: "Claude Opus 4.7" },
{ id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5" },
{ id: "gpt-5.5", name: "GPT-5.5" },
{ id: "gpt-5.4", name: "GPT-5.4" },
{ id: "gpt-5.4-mini", name: "GPT-5.4 Mini" },
{ id: "gpt-5.4-nano", name: "GPT-5.4 Nano" },
{ id: "grok-4.3", name: "Grok 4.3" },
{ id: "grok-4.20", name: "Grok 4.20" },
{ id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro" },
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash" },
{ id: "gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite" },
{ id: "gemma-4-31b-it", name: "Gemma 4 31B" },
{ id: "gemma-4-26b-a4b-it", name: "Gemma 4 26B A4B" },
{ id: "deepseek-v3.2", name: "DeepSeek V3.2" },
{ id: "kimi-k2.6", name: "Kimi K2.6" },
{ id: "kimi-k2.5", name: "Kimi K2.5" },
{ id: "glm-5.1", name: "GLM 5.1" },
{ id: "glm-5", name: "GLM 5" },
{ id: "mimo-v2.5-pro", name: "MiMo-V2.5-Pro" },
{ id: "mimo-v2.5", name: "MiMo-V2.5" },
{ id: "minimax-m2.7", name: "MiniMax M2.7" },
{ id: "minimax-m2.5", name: "MiniMax M2.5" },
{ id: "llama-4-maverick", name: "Llama 4 Maverick" },
{ id: "llama-4-scout", name: "Llama 4 Scout" },
{ id: "llama-3.3-70b-instruct", name: "Llama 3.3 70B" },
{ id: "qwen3.6-plus", name: "Qwen 3.6 Plus" },
{ id: "mistral-large-2512", name: "Mistral Large 3" },
{ id: "mistral-medium-3.1", name: "Mistral Medium 3.1" },
{ id: "mistral-small-2603", name: "Mistral Small 4" },
{ id: "nemotron-3-super-120b-a12b", name: "Nemotron 3 Super" },
],
},
completions: {
id: "completions",
alias: "cpl",
format: "openai",
executor: "default",
baseUrl: "https://completions.me/api/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "claude-opus-4.6", name: "Claude Opus 4.6" },
{ id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5" },
{ id: "gpt-5.2", name: "GPT-5.2" },
{ id: "gpt-5-mini", name: "GPT-5 Mini" },
{ id: "gpt-4.1", name: "GPT-4.1" },
{ id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro" },
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash" },
],
},
enally: {
id: "enally",
alias: "enly",
format: "openai",
executor: "default",
baseUrl: "https://ai.enally.in",
authType: "apikey",
authHeader: "X-API-Key",
models: [
{ id: "default", name: "Default Model" },
{ id: "chat", name: "Chat Model" },
{ id: "reasoning", name: "Reasoning Model" },
{ id: "multimodal", name: "Multimodal Model" },
],
},
freetheai: {
id: "freetheai",
alias: "fta",
format: "openai",
executor: "default",
baseUrl: "https://api.freetheai.xyz/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "free-fast", name: "Free Fast (Low Latency)" },
{ id: "free-smart", name: "Free Smart (Reasoning)" },
{ id: "free", name: "Free (Max Uptime)" },
],
},
xai: {
id: "xai",
alias: "xai",
format: "openai",
executor: "default",
baseUrl: "https://api.x.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "grok-4.3", name: "Grok 4.3" },
{ id: "grok-4.20-multi-agent-0309", name: "Grok 4.20 Multi Agent" },
{ id: "grok-4.20-0309-reasoning", name: "Grok 4.20 Reasoning" },
{ id: "grok-4.20-0309-non-reasoning", name: "Grok 4.20" },
],
},
"chatgpt-web": {
id: "chatgpt-web",
alias: "cgpt-web",
format: "openai",
executor: "chatgpt-web",
baseUrl: "https://chatgpt.com/backend-api/conversation",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "gpt-5.5-pro", name: "GPT-5.5 Pro" }, //pro tier only
{ id: "gpt-5.5-thinking", name: "GPT-5.5 Thinking" }, //plus, pro tier
{ id: "gpt-5.5", name: "GPT-5.5 Instant" }, //free, plus, pro tier
{ id: "gpt-5.4-pro", name: "GPT-5.4 Pro" }, //pro tier only
{ id: "gpt-5.4-thinking", name: "GPT-5.4 Thinking" }, //plus, pro tier
{ id: "gpt-5.4-thinking-mini", name: "GPT-5.4 Thinking Mini" }, //free-login only
{ id: "gpt-5.3", name: "GPT-5.3 Instant" }, //free, free-login, plus, pro tier
{ id: "gpt-5.3-mini", name: "GPT-5.3 Mini" }, //limit fallback
{ id: "gpt-5.2-pro", name: "GPT-5.2 Pro" }, //pro tier only
{ id: "gpt-5.2-thinking", name: "GPT-5.2 Thinking" }, //plus ~ tier
{ id: "gpt-5.2-instant", name: "GPT-5.2 Instant" }, //plus ~ tier
{ id: "o3", name: "o3" }, //plus ~ tier
{ id: "gpt-4-5", name: "GPT-4.5" }, //pro tier only
],
},
"deepseek-web": {
id: "deepseek-web",
alias: "ds-web",
format: "openai",
executor: "deepseek-web",
baseUrl: "https://chat.deepseek.com/api/v0/chat/completion",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro" },
{ id: "deepseek-v4-pro-think", name: "DeepSeek V4 Pro Think", supportsReasoning: true },
{ id: "deepseek-v4-pro-search", name: "DeepSeek V4 Pro Search" },
{
id: "deepseek-v4-pro-think-search",
name: "DeepSeek V4 Pro Think+Search",
supportsReasoning: true,
},
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" },
{ id: "deepseek-v4-flash-think", name: "DeepSeek V4 Flash Think", supportsReasoning: true },
{ id: "deepseek-v4-flash-search", name: "DeepSeek V4 Flash Search" },
{
id: "deepseek-v4-flash-think-search",
name: "DeepSeek V4 Flash Think+Search",
supportsReasoning: true,
},
{ id: "deepseek-chat", name: "DeepSeek Chat" },
{ id: "deepseek-reasoner", name: "DeepSeek Reasoner", supportsReasoning: true },
{ id: "DeepSeek-R1", name: "DeepSeek R1", supportsReasoning: true },
{ id: "DeepSeek-R1-Search", name: "DeepSeek R1 Search", supportsReasoning: true },
{ id: "DeepSeek-V3.2", name: "DeepSeek V3.2" },
{ id: "DeepSeek-Search", name: "DeepSeek Search" },
],
},
"grok-web": {
id: "grok-web",
alias: "gw",
format: "openai",
executor: "grok-web",
baseUrl: "https://grok.com/rest/app-chat/conversations/new",
authType: "apikey",
authHeader: "cookie",
passthroughModels: true,
models: [
{ id: "fast", name: "Grok 4.20", toolCalling: true },
{ id: "expert", name: "Grok 4.20 Thinking", toolCalling: true },
{ id: "heavy", name: "Grok 4.20 Multi Agent", toolCalling: true },
{ id: "grok-420-computer-use-sa", name: "Grok 4.3 (Beta)", toolCalling: true },
],
},
"gemini-web": {
id: "gemini-web",
alias: "gweb",
format: "openai",
executor: "gemini-web",
baseUrl: "https://gemini.google.com/app",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro" },
{ id: "gemini-2.5-flash", name: "Gemini 2.5 Flash" },
{ id: "gemini-2.0-pro", name: "Gemini 2.0 Pro" },
{ id: "gemini-2.0-flash", name: "Gemini 2.0 Flash" },
{ id: "gemini-1.5-pro", name: "Gemini 1.5 Pro" },
{ id: "gemini-1.5-flash", name: "Gemini 1.5 Flash" },
],
},
mistral: {
id: "mistral",
alias: "mistral",
format: "openai",
executor: "default",
baseUrl: "https://api.mistral.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "mistral-large-latest", name: "Mistral Large 3" },
{ id: "mistral-medium-3-5", name: "Mistral Medium 3.5" },
{ id: "mistral-small-latest", name: "Mistral Small 4" },
{ id: "devstral-latest", name: "Devstral 2" },
{ id: "codestral-latest", name: "Codestral" },
],
},
perplexity: {
id: "perplexity",
alias: "pplx",
format: "openai",
executor: "default",
baseUrl: "https://api.perplexity.ai/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "sonar-deep-research", name: "Sonar Deep Research" },
{ id: "sonar-reasoning-pro", name: "Sonar Reasoning Pro" },
{ id: "sonar-pro", name: "Sonar Pro" },
{ id: "sonar", name: "Sonar" },
],
},
"perplexity-web": {
id: "perplexity-web",
alias: "pplx-web",
format: "openai",
executor: "perplexity-web",
baseUrl: "https://www.perplexity.ai/rest/sse/perplexity_ask",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "pplx-auto", name: "Perplexity Auto (Free)" },
{ id: "pplx-sonar", name: "Perplexity Sonar" },
{ id: "pplx-gpt", name: "GPT-5.5 (via Perplexity)" },
{ id: "pplx-gemini", name: "Gemini 3.1 Pro (via Perplexity)" },
{ id: "pplx-sonnet", name: "Claude Sonnet 4.6 (via Perplexity)" },
{ id: "pplx-opus", name: "Claude Opus 4.7 (via Perplexity)" },
{ id: "pplx-kimi", name: "Kimi K2.6 (via Perplexity)" },
{ id: "pplx-nemotron", name: "Nemotron 3 Super (via Perplexity)" },
],
},
"muse-spark-web": {
id: "muse-spark-web",
alias: "ms-web",
format: "openai",
executor: "muse-spark-web",
baseUrl: "https://www.meta.ai/api/graphql",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "muse-spark", name: "Muse Spark" },
{
id: "muse-spark-thinking",
name: "Muse Spark Thinking",
supportsReasoning: true,
},
{
id: "muse-spark-contemplating",
name: "Muse Spark Contemplating",
supportsReasoning: true,
},
],
},
"inner-ai": {
id: "inner-ai",
alias: "in-ai",
format: "openai",
executor: "inner-ai",
baseUrl: "https://chatapi.innerai.com/chat",
authType: "apikey",
authHeader: "bearer",
models: [
// OpenAI
{ id: "gpt-4o", name: "GPT-4o (via Inner.ai)" },
{ id: "gpt-4.1", name: "GPT-4.1 (via Inner.ai)" },
{ id: "gpt-4.1-mini", name: "GPT-4.1 Mini (via Inner.ai)" },
{ id: "o3", name: "o3 (via Inner.ai)", supportsReasoning: true },
{ id: "o4-mini", name: "o4-mini (via Inner.ai)", supportsReasoning: true },
// Anthropic
{ id: "claude-opus-4-5", name: "Claude Opus 4.5 (via Inner.ai)" },
{ id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5 (via Inner.ai)" },
{ id: "claude-3-7-sonnet-20250219", name: "Claude 3.7 Sonnet (via Inner.ai)" },
{ id: "claude-3-5-sonnet-20241022", name: "Claude 3.5 Sonnet (via Inner.ai)" },
// Google
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (via Inner.ai)" },
{ id: "gemini-2.5-flash", name: "Gemini 2.5 Flash (via Inner.ai)" },
{ id: "gemini-2.0-flash", name: "Gemini 2.0 Flash (via Inner.ai)" },
// DeepSeek
{
id: "deepseek-r1",
name: "DeepSeek R1 (via Inner.ai)",
supportsReasoning: true,
},
{ id: "deepseek-v3", name: "DeepSeek V3 (via Inner.ai)" },
// xAI
{ id: "grok-3", name: "Grok 3 (via Inner.ai)" },
{ id: "grok-3-mini", name: "Grok 3 Mini (via Inner.ai)", supportsReasoning: true },
// Meta
{ id: "llama-4-maverick", name: "Llama 4 Maverick (via Inner.ai)" },
{ id: "llama-3.3-70b-instruct", name: "Llama 3.3 70B (via Inner.ai)" },
// Mistral
{ id: "mistral-large-2411", name: "Mistral Large (via Inner.ai)" },
],
},
"adapta-web": {
id: "adapta-web",
alias: "adp-web",
format: "openai",
executor: "adapta-web",
baseUrl: "https://agent.adapta.one/api/chat/stream/v1",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "adapta-one", name: "Adapta ONE (Auto)" },
{ id: "adapta-gpt", name: "GPT-5 (via Adapta)" },
{ id: "adapta-claude", name: "Claude Sonnet 4.6 (via Adapta)" },
{ id: "adapta-gemini", name: "Gemini 2.5 Pro (via Adapta)" },
{ id: "adapta-grok", name: "Grok 4 (via Adapta)" },
{ id: "adapta-deepseek", name: "DeepSeek R2 (via Adapta)" },
{ id: "adapta-llama", name: "Llama 4 (via Adapta)" },
],
},
// t3.chat — Convex-based chat app. Cookie session auth via T3ChatWebExecutor.
// Base URL confirmed: POST https://t3.chat/api/chat (Convex HTTP action endpoint).
"t3-web": {
id: "t3-web",
alias: "t3chat",
format: "openai",
executor: "t3-web",
baseUrl: "https://t3.chat/api/chat",
authType: "apikey",
authHeader: "cookie",
models: [
// Claude
{ id: "claude-opus-4", name: "Claude Opus 4 (via t3.chat)" },
{ id: "claude-sonnet-4", name: "Claude Sonnet 4 (via t3.chat)" },
{ id: "claude-haiku-4", name: "Claude Haiku 4 (via t3.chat)" },
{ id: "claude-3.7", name: "Claude 3.7 Sonnet (via t3.chat)" },
// GPT / OpenAI
{ id: "gpt-5", name: "GPT-5 (via t3.chat)" },
{ id: "gpt-4o", name: "GPT-4o (via t3.chat)" },
{ id: "gpt-4.1", name: "GPT-4.1 (via t3.chat)" },
{ id: "o3", name: "o3 (via t3.chat)" },
{ id: "o4-mini", name: "o4-mini (via t3.chat)" },
// Gemini
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (via t3.chat)" },
{ id: "gemini-2.5-flash", name: "Gemini 2.5 Flash (via t3.chat)" },
// DeepSeek
{ id: "deepseek-r1", name: "DeepSeek R1 (via t3.chat)", supportsReasoning: true },
{ id: "deepseek-v3", name: "DeepSeek V3 (via t3.chat)" },
// Grok
{ id: "grok-3", name: "Grok 3 (via t3.chat)" },
{ id: "grok-3-mini", name: "Grok 3 Mini (via t3.chat)" },
// Llama / Meta
{ id: "llama-4-maverick", name: "Llama 4 Maverick (via t3.chat)" },
{ id: "llama-4-scout", name: "Llama 4 Scout (via t3.chat)" },
{ id: "llama-3.3-70b", name: "Llama 3.3 70B (via t3.chat)" },
// Mistral
{ id: "devstral", name: "Devstral (via t3.chat)" },
{ id: "mistral-large", name: "Mistral Large (via t3.chat)" },
// Qwen
{ id: "qwen3-235b", name: "Qwen3 235B (via t3.chat)", supportsReasoning: true },
{ id: "qwen3-32b", name: "Qwen3 32B (via t3.chat)", supportsReasoning: true },
// Kimi
{ id: "kimi-k2", name: "Kimi K2 (via t3.chat)" },
],
},
"blackbox-web": {
id: "blackbox-web",
alias: "bb-web",
format: "openai",
executor: "blackbox-web",
baseUrl: "https://app.blackbox.ai/api/chat",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "gpt-4-turbo", name: "GPT-4 Turbo" },
{ id: "gpt-4", name: "GPT-4" },
{ id: "gpt-3.5-turbo", name: "GPT-3.5 Turbo" },
{ id: "claude-3-opus", name: "Claude 3 Opus" },
{ id: "claude-3-sonnet", name: "Claude 3 Sonnet" },
{ id: "gemini-pro", name: "Gemini Pro" },
],
},
"claude-web": {
id: "claude-web",
alias: "claude-web",
format: "openai",
executor: "claude-web",
baseUrl: "https://claude.ai/api/organizations",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "claude-3-opus-20250219", name: "Claude 3 Opus (web)" },
{ id: "claude-3-5-sonnet-20241022", name: "Claude 3.5 Sonnet (web)" },
{ id: "claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku (web)" },
],
},
"copilot-web": {
id: "copilot-web",
alias: "copilot-web",
format: "openai",
executor: "copilot-web",
baseUrl: "wss://copilot.microsoft.com/c/api/chat?api-version=2",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "copilot-pro", name: "Copilot Pro (web)" },
{ id: "gpt-4-turbo", name: "GPT-4 Turbo (via Copilot)" },
{ id: "gpt-4", name: "GPT-4 (via Copilot)" },
],
},
"veoaifree-web": {
id: "veoaifree-web",
alias: "veo-free",
format: "openai",
executor: "veoaifree-web",
baseUrl: "https://veoaifree.com/wp-admin/admin-ajax.php",
authType: "none",
authHeader: "none",
models: [
{ id: "veo", name: "VEO 3.1" },
{ id: "seedance", name: "Seedance" },
],
},
"duckduckgo-web": {
id: "duckduckgo-web",
alias: "ddgw",
format: "openai",
executor: "duckduckgo-web",
baseUrl: "https://duckduckgo.com/duckchat/v1/chat",
authType: "none",
authHeader: "none",
models: [
{ id: "gpt-4o-mini", name: "GPT-4o Mini" },
{ id: "gpt-5-mini", name: "GPT-5 Mini" },
{ id: "claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku" },
{ id: "llama-4-scout", name: "Llama 4 Scout" },
{ id: "mistral-small-2501", name: "Mistral Small" },
{ id: "o3-mini", name: "O3 Mini" },
],
},
together: {
id: "together",
alias: "together",
format: "openai",
executor: "default",
baseUrl: "https://api.together.xyz/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "meta-llama/Llama-3.3-70B-Instruct-Turbo-Free", name: "Llama 3.3 70B Turbo (🆓 Free)" },
{ id: "meta-llama/Llama-Vision-Free", name: "Llama Vision (🆓 Free)" },
{
id: "deepseek-ai/DeepSeek-R1-Distill-Llama-70B-Free",
name: "DeepSeek R1 Distill 70B (🆓 Free)",
},
{ id: "meta-llama/Llama-3.3-70B-Instruct-Turbo", name: "Llama 3.3 70B Turbo" },
{ id: "deepseek-ai/DeepSeek-R1", name: "DeepSeek R1" },
{ id: "Qwen/Qwen3-235B-A22B", name: "Qwen3 235B" },
{ id: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", name: "Llama 4 Maverick" },
],
},
fireworks: {
id: "fireworks",
alias: "fireworks",
format: "openai",
executor: "default",
baseUrl: "https://api.fireworks.ai/inference/v1/chat/completions",
modelsUrl:
"https://api.fireworks.ai/v1/accounts/fireworks/models?filter=supports_serverless=true",
modelIdPrefix: "accounts/fireworks/models/",
authType: "apikey",
authHeader: "bearer",
models: [
{
id: "deepseek-v4-flash",
name: "DeepSeek V4 Flash",
supportsReasoning: true,
},
{
id: "deepseek-v4-pro",
name: "DeepSeek V4 Pro",
supportsReasoning: true,
},
{ id: "glm-5p1", name: "GLM 5.1" },
{ id: "gpt-oss-120b", name: "OpenAI gpt-oss-120b" },
{ id: "gpt-oss-20b", name: "OpenAI gpt-oss-20b" },
{ id: "kimi-k2p5", name: "Kimi K2.5" },
{ id: "kimi-k2p6", name: "Kimi K2.6" },
{ id: "minimax-m2p5", name: "MiniMax M2.5" },
{ id: "minimax-m2p7", name: "MiniMax M2.7" },
{ id: "qwen3p6-plus", name: "Qwen3.6 Plus" },
],
},
cerebras: {
id: "cerebras",
alias: "cerebras",
format: "openai",
executor: "default",
baseUrl: "https://api.cerebras.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "zai-glm-4.7", name: "GLM 4.7" },
{ id: "gpt-oss-120b", name: "GPT OSS 120B" },
],
},
"ollama-cloud": {
id: "ollama-cloud",
alias: "ollamacloud",
format: "openai",
executor: "default",
baseUrl: "https://ollama.com/v1/chat/completions",
modelsUrl: "https://ollama.com/api/tags",
authType: "apikey",
authHeader: "bearer",
// Note: rate limits vary by plan (free = "Light usage", Pro = more, Max = 5x Pro).
// Users can generate API keys at https://ollama.com/settings/api-keys
models: [
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
{ id: "kimi-k2.6", name: "Kimi K2.6" },
{ id: "glm-5.1", name: "GLM 5.1" },
{ id: "minimax-m2.7", name: "MiniMax M2.7" },
{ id: "gemma4:31b", name: "Gemma 4 31B" },
{ id: "nemotron-3-super", name: "NVIDIA Nemotron 3 Super" },
{ id: "qwen3.5:397b", name: "Qwen 3.5 397B" },
],
passthroughModels: true,
},
cohere: {
id: "cohere",
alias: "cohere",
format: "openai",
executor: "default",
// Issue #2360: Cohere's native /v2/chat endpoint returns the upstream
// proprietary shape ({ message: { content: [{type:"text", text:...}] } })
// which the combo test validator (extractComboTestResponseText) does not
// know how to read, surfacing as "Provider returned HTTP 200 but no text
// content." Cohere also publishes an OpenAI-compatible compatibility
// layer at /compatibility/v1 that returns the canonical
// { choices: [{ message: { content: "..." } }] } shape, so we route
// through it instead of needing a Cohere-specific response translator.
baseUrl: "https://api.cohere.com/compatibility/v1/chat/completions",
modelsUrl: "https://api.cohere.com/compatibility/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "command-a-reasoning-08-2025", name: "Command A Reasoning (Aug 2025)" },
{ id: "command-a-vision-07-2025", name: "Command A Vision (Jul 2025)" },
{ id: "command-a-03-2025", name: "Command A (Mar 2025)" },
{ id: "command-r7b-12-2024", name: "Command R7B (Dec 2024)" },
{ id: "command-r-plus-08-2024", name: "Command R Plus (Aug 2024)" },
{ id: "command-r-08-2024", name: "Command R (Aug 2024)" },
],
},
nvidia: {
id: "nvidia",
alias: "nvidia",
format: "openai",
executor: "default",
baseUrl: "https://integrate.api.nvidia.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "z-ai/glm-5.1", name: "GLM 5.1" },
{ id: "minimaxai/minimax-m2.7", name: "MiniMax M2.7" },
{ id: "google/gemma-4-31b-it", name: "Gemma 4 31B" },
{ id: "mistralai/mistral-small-4-119b-2603", name: "Mistral Small 4 2603" },
{ id: "mistralai/mistral-large-3-675b-instruct-2512", name: "Mistral Large 3 675B" },
{ id: "mistralai/devstral-2-123b-instruct-2512", name: "Devstral 2 123B" },
{ id: "qwen/qwen3.5-397b-a17b", name: "Qwen3.5-397B-A17B" },
{ id: "qwen/qwen3.5-122b-a10b", name: "Qwen3.5-122B-A10B" },
{ id: "stepfun-ai/step-3.5-flash", name: "Step 3.5 Flash" },
{ id: "deepseek-ai/deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
{ id: "openai/gpt-oss-120b", name: "GPT OSS 120B", toolCalling: false },
{ id: "openai/gpt-oss-20b", name: "GPT OSS 20B", toolCalling: false },
{ id: "nvidia/nemotron-3-super-120b-a12b", name: "Nemotron 3 Super 120B A12B" },
],
},
nebius: {
id: "nebius",
alias: "nebius",
format: "openai",
executor: "default",
baseUrl: "https://api.tokenfactory.nebius.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [{ id: "meta-llama/Llama-3.3-70B-Instruct", name: "Llama 3.3 70B Instruct" }],
},
siliconflow: {
id: "siliconflow",
alias: "siliconflow",
format: "openai",
executor: "default",
baseUrl: "https://api.siliconflow.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "deepseek-ai/DeepSeek-V3.2", name: "DeepSeek V3.2" },
{ id: "deepseek-ai/DeepSeek-V3.1", name: "DeepSeek V3.1" },
{ id: "deepseek-ai/DeepSeek-R1", name: "DeepSeek R1" },
{ id: "Qwen/Qwen3-235B-A22B-Instruct-2507", name: "Qwen3 235B" },
{ id: "Qwen/Qwen3-Coder-480B-A35B-Instruct", name: "Qwen3 Coder 480B" },
{ id: "Qwen/Qwen3-32B", name: "Qwen3 32B" },
{ id: "moonshotai/Kimi-K2.5", name: "Kimi K2.5" },
{ id: "zai-org/GLM-4.7", name: "GLM 4.7" },
{ id: "openai/gpt-oss-120b", name: "GPT OSS 120B" },
{ id: "baidu/ERNIE-4.5-300B-A47B", name: "ERNIE 4.5 300B" },
],
},
hyperbolic: {
id: "hyperbolic",
alias: "hyp",
format: "openai",
executor: "default",
baseUrl: "https://api.hyperbolic.xyz/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "Qwen/QwQ-32B", name: "QwQ 32B" },
{ id: "deepseek-ai/DeepSeek-R1", name: "DeepSeek R1" },
{ id: "deepseek-ai/DeepSeek-V3", name: "DeepSeek V3" },
{ id: "meta-llama/Llama-3.3-70B-Instruct", name: "Llama 3.3 70B" },
{ id: "meta-llama/Llama-3.2-3B-Instruct", name: "Llama 3.2 3B" },
{ id: "Qwen/Qwen2.5-72B-Instruct", name: "Qwen 2.5 72B" },
{ id: "Qwen/Qwen2.5-Coder-32B-Instruct", name: "Qwen 2.5 Coder 32B" },
{ id: "NousResearch/Hermes-3-Llama-3.1-70B", name: "Hermes 3 70B" },
],
},
huggingface: {
id: "huggingface",
alias: "hf",
format: "openai",
executor: "default",
baseUrl: "https://router.huggingface.co/v1/chat/completions",
modelsUrl: "https://router.huggingface.co/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "meta-llama/llama-3.1-8b-instruct", name: "Llama 3.1 8B" },
{ id: "meta-llama/llama-3.2-11b-instruct", name: "Llama 3.2 11B" },
{ id: "mistralai/mistral-7b-instruct", name: "Mistral 7B" },
{ id: "google/gemma-2-9b-it", name: "Gemma 2 9B" },
{ id: "Qwen/Qwen2.5-7B-Instruct", name: "Qwen 2.5 7B" },
{ id: "deepseek-ai/DeepSeek-V3", name: "DeepSeek V3" },
],
},
synthetic: {
id: "synthetic",
alias: "synthetic",
format: "openai",
executor: "default",
baseUrl: "https://api.synthetic.new/openai/v1/chat/completions",
modelsUrl: "https://api.synthetic.new/openai/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "hf:nvidia/Kimi-K2.5-NVFP4", name: "Kimi K2.5 (NVFP4)" },
{ id: "hf:MiniMaxAI/MiniMax-M2.5", name: "MiniMax M2.5" },
{ id: "hf:zai-org/GLM-4.7-Flash", name: "GLM 4.7 Flash" },
{ id: "hf:zai-org/GLM-4.7", name: "GLM 4.7" },
{ id: "hf:moonshotai/Kimi-K2.5", name: "Kimi K2.5" },
{ id: "hf:deepseek-ai/DeepSeek-V3.2", name: "DeepSeek V3.2" },
],
passthroughModels: true,
},
"kilo-gateway": {
id: "kilo-gateway",
alias: "kg",
format: "openai",
executor: "default",
baseUrl: "https://api.kilo.ai/api/gateway/chat/completions",
modelsUrl: "https://api.kilo.ai/api/gateway/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "kilo-auto/frontier", name: "Kilo Auto Frontier" },
{ id: "kilo-auto/balanced", name: "Kilo Auto Balanced" },
{ id: "kilo-auto/free", name: "Kilo Auto Free" },
{ id: "nvidia/nemotron-3-super-120b-a12b:free", name: "Nemotron 3 Super 120B (Free)" },
{ id: "minimax/minimax-m2.5:free", name: "MiniMax M2.5 (Free)" },
{ id: "arcee-ai/trinity-large-preview:free", name: "Trinity Large Preview (Free)" },
],
passthroughModels: true,
},
bedrock: {
id: "bedrock",
alias: "bedrock",
format: "openai",
executor: "bedrock",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 200000,
models: [
{
id: "anthropic.claude-sonnet-4-6",
name: "Claude Sonnet 4.6 (Bedrock)",
toolCalling: true,
supportsVision: true,
contextLength: 1000000,
},
{
id: "anthropic.claude-sonnet-4-5",
name: "Claude Sonnet 4.5 (Bedrock)",
toolCalling: true,
supportsVision: true,
contextLength: 200000,
},
{
id: "anthropic.claude-opus-4-6",
name: "Claude Opus 4.6 (Bedrock)",
toolCalling: true,
supportsVision: true,
contextLength: 1000000,
},
{
id: "anthropic.claude-opus-4-7",
name: "Claude Opus 4.7 (Bedrock)",
toolCalling: true,
supportsVision: true,
contextLength: 1000000,
},
{
id: "anthropic.claude-haiku-4-5",
name: "Claude Haiku 4.5 (Bedrock)",
toolCalling: true,
supportsVision: true,
},
{ id: "openai.gpt-oss-120b-1:0", name: "GPT-OSS 120B (Bedrock)" },
],
passthroughModels: true,
},
vertex: {
id: "vertex",
alias: "vertex",
// Vertex AI uses Google's generateContent format (same as Gemini)
format: "gemini",
executor: "vertex",
// URL uses {project_id} and {region} from providerSpecificData — handled by custom executor or fallback
// Default to us-central1 / generic endpoint; users configure project via providerSpecificData
baseUrl: "https://us-central1-aiplatform.googleapis.com/v1/projects",
urlBuilder: (base, model, stream) => {
// Full URL: {base}/{project}/locations/{region}/publishers/google/models/{model}:{action}
// For a generic fallback, we build a Gemini-compatible URL
// The actual project/region are configured via providerSpecificData in the DB connection
const action = stream ? "streamGenerateContent?alt=sse" : "generateContent";
return `https://generativelanguage.googleapis.com/v1beta/models/${model}:${action}`;
},
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro Preview (Vertex)" },
{ id: "gemini-3.1-flash-lite", name: "Gemini 3.1 Flash Lite (Vertex)" },
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash Preview (Vertex)" },
{ id: "gemma-4-31b-it", name: "Gemma 4 31B (Vertex)" },
{ id: "DeepSeek-V4-Flash", name: "DeepSeek V4 Flash (Vertex Partner)" },
{ id: "DeepSeek-V4-Pro", name: "DeepSeek V4 Pro (Vertex Partner)" },
{ id: "Qwen3.6-35B-A3B", name: "Qwen3.6 35B A3B (Vertex Partner)" },
{ id: "GLM-5.1-FP8", name: "GLM-5.1 (Vertex Partner)" },
{ id: "claude-opus-4-7", name: "Claude Opus 4.7 (Vertex)" },
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6 (Vertex)" },
],
},
"vertex-partner": {
id: "vertex-partner",
alias: "vp",
format: "gemini",
executor: "vertex",
baseUrl: "https://us-central1-aiplatform.googleapis.com/v1/projects",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "DeepSeek-V4-Flash", name: "DeepSeek V4 Flash" },
{ id: "DeepSeek-V4-Pro", name: "DeepSeek V4 Pro" },
{ id: "Qwen3.6-35B-A3B", name: "Qwen 3.6 35B A3B" },
{ id: "GLM-5.1-FP8", name: "GLM 5.1" },
{ id: "claude-opus-4-7", name: "Claude Opus 4.7" },
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
],
},
alibaba: {
id: "alibaba",
alias: "ali",
format: "openai",
executor: "default",
baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
modelsUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/models",
authType: "apikey",
authHeader: "bearer",
models: ALIBABA_DASHSCOPE_MODELS,
passthroughModels: true,
},
"alibaba-cn": {
id: "alibaba-cn",
alias: "ali-cn",
format: "openai",
executor: "default",
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
modelsUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1/models",
authType: "apikey",
authHeader: "bearer",
models: ALIBABA_DASHSCOPE_MODELS,
passthroughModels: true,
},
// ── New Free Providers (2026) ─────────────────────────────────────────────
longcat: {
id: "longcat",
alias: "lc",
format: "openai",
executor: "default",
baseUrl: "https://api.longcat.chat/openai/v1/chat/completions",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
// Free tier: 50M tokens/day (Flash-Lite) + 500K/day (Chat/Thinking) — 100% free while public beta
models: [
{ id: "LongCat-Flash-Lite", name: "LongCat Flash-Lite (50M tok/day 🆓)" },
{ id: "LongCat-Flash-Chat", name: "LongCat Flash-Chat (500K tok/day 🆓)" },
{ id: "LongCat-Flash-Thinking", name: "LongCat Flash-Thinking (500K tok/day 🆓)" },
{ id: "LongCat-Flash-Omni-2603", name: "LongCat Flash-Omni-2603 (500K tok/day 🆓)" },
//{ id: "LongCat-2.0-Preview", name: "LongCat 2.0 Preview (10M tok/day 🆓)" },
],
},
pollinations: {
id: "pollinations",
alias: "pol",
format: "openai",
executor: "pollinations",
// Primary endpoint is text.pollinations.ai. gen.pollinations.ai is the current
// OpenAI-compatible fallback used when the primary edge is rate-limited or unavailable.
baseUrl: "https://text.pollinations.ai/openai/chat/completions",
baseUrls: [
"https://text.pollinations.ai/openai/chat/completions",
"https://gen.pollinations.ai/v1/chat/completions",
],
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "openai", name: "OpenAI (Pollinations)" },
{ id: "openai-fast", name: "OpenAI Fast (Pollinations)" },
{ id: "openai-large", name: "OpenAI Large (Pollinations)" },
{ id: "qwen-coder", name: "Qwen Coder (Pollinations)" },
{ id: "mistral", name: "Mistral (Pollinations)" },
{ id: "gemini", name: "Gemini (Pollinations)" },
{ id: "gemini-flash-lite-3.1", name: "Gemini Flash Lite 3.1 (Pollinations)" },
{ id: "gemini-fast", name: "Gemini Fast (Pollinations)" },
{ id: "deepseek", name: "DeepSeek (Pollinations)" },
{ id: "grok", name: "Grok (Pollinations)" },
{ id: "grok-large", name: "Grok Large (Pollinations)" },
{ id: "gemini-search", name: "Gemini Search (Pollinations)" },
{ id: "midijourney", name: "Midijourney (Pollinations)" },
{ id: "midijourney-large", name: "Midijourney Large (Pollinations)" },
{ id: "claude-fast", name: "Claude Fast (Pollinations)" },
{ id: "claude", name: "Claude (Pollinations)" },
{ id: "claude-large", name: "Claude Large (Pollinations)" },
{ id: "perplexity-fast", name: "Perplexity Fast (Pollinations)" },
{ id: "perplexity-reasoning", name: "Perplexity Reasoning (Pollinations)" },
{ id: "kimi", name: "Kimi (Pollinations)" },
{ id: "gemini-large", name: "Gemini Large (Pollinations)" },
{ id: "nova-fast", name: "Nova Fast (Pollinations)" },
{ id: "nova", name: "Nova (Pollinations)" },
{ id: "glm", name: "GLM (Pollinations)" },
{ id: "minimax", name: "MiniMax (Pollinations)" },
{ id: "mistral-large", name: "Mistral Large (Pollinations)" },
{ id: "polly", name: "Polly (Pollinations)" },
{ id: "qwen-coder-large", name: "Qwen Coder Large (Pollinations)" },
{ id: "qwen-large", name: "Qwen Large (Pollinations)" },
{ id: "qwen-vision", name: "Qwen Vision (Pollinations)" },
{ id: "qwen-safety", name: "Qwen Safety (Pollinations)" },
],
},
puter: {
id: "puter",
alias: "pu",
format: "openai",
executor: "puter",
// OpenAI-compatible gateway with 500+ models (GPT, Claude, Gemini, Grok, DeepSeek, Qwen…)
// Auth: Bearer <puter_auth_token> from puter.com/dashboard → Copy Auth Token
// Model IDs use provider/model-name format for non-OpenAI models.
// Only chat completions (incl. streaming) are available via REST.
// Image gen, TTS, STT, video are puter.js SDK-only (browser).
baseUrl: "https://api.puter.com/puterai/openai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
// OpenAI — use bare IDs
{ id: "gpt-5.5", name: "GPT-5.5 (Puter)" },
{ id: "gpt-5.4", name: "GPT-5.4 (Puter)" },
{ id: "gpt-5.4-mini", name: "GPT-5.4 Mini (Puter)" },
{ id: "gpt-5.4-nano", name: "GPT-5.4 Nano (Puter)" },
{ id: "gpt-4o", name: "GPT-4o (Puter)" },
{ id: "gpt-4o-mini", name: "GPT-4o Mini (🆓 Puter)" },
{ id: "o3", name: "OpenAI o3 (Puter)" },
// Anthropic Claude — use bare IDs (confirmed working)
{ id: "claude-haiku-4-5", name: "Claude Haiku 4.5 (Puter)" },
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6 (Puter)" },
{ id: "claude-opus-4-7", name: "Claude Opus 4.7 (Puter)" },
// Google Gemini — use google/ prefix (confirmed working)
{ id: "google/gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite (Puter)" },
{ id: "google/gemini-3-flash", name: "Gemini 3 Flash (Puter)" },
{ id: "google/gemini-3.1-pro-preview", name: "Gemini 3.1 Pro (Puter)" },
// DeepSeek — use deepseek/ prefix (confirmed working)
{
id: "deepseek/deepseek-v4-pro",
name: "DeepSeek V4 Pro (Puter)",
supportsReasoning: true,
},
{
id: "deepseek/deepseek-v4-flash",
name: "DeepSeek V4 Flash (Puter)",
supportsReasoning: true,
},
// xAI Grok — use x-ai/ prefix
{ id: "x-ai/grok-4.3", name: "Grok 4.3 (Puter)" },
{ id: "x-ai/grok-4.20", name: "Grok 4.20 (Puter)" },
// Meta Llama — bare IDs (confirmed ✅)
{ id: "llama-4-scout", name: "Llama 4 Scout (Puter)" },
{ id: "llama-4-maverick", name: "Llama 4 Maverick (Puter)" },
{ id: "llama-3.3-70b-instruct", name: "Llama 3.3 70B (Puter)" },
// Mistral — bare IDs (confirmed ✅)
{ id: "mistral-small-2603", name: "Mistral Small 4 (Puter)" },
{ id: "mistral-medium-3-5", name: "Mistral Medium 3.5 (Puter)" },
{ id: "mistral-large-2512", name: "Mistral Large (Puter)" },
{ id: "devstral-2512", name: "Devstral 2 (Puter)" },
{ id: "codestral-2508", name: "Codestral (Puter)" },
{ id: "mistral-nemo", name: "Mistral Nemo (Puter)" },
// Qwen — use qwen/ prefix (confirmed ✅)
{ id: "qwen/qwen3.6-plus", name: "Qwen 3.6 Plus (Puter)" },
{ id: "qwen/qwen3.5-397b-a17b", name: "Qwen 3.5 397B (Puter)" },
// Perplexity Sonar via OpenRouter aliases exposed by Puter
{ id: "perplexity/sonar-deep-research", name: "Perplexity Sonar Deep Research (Puter)" },
{ id: "perplexity/sonar-pro-search", name: "Perplexity Sonar Pro Search (Puter)" },
{ id: "perplexity/sonar-pro", name: "Perplexity Sonar Pro (Puter)" },
{ id: "perplexity/sonar-reasoning-pro", name: "Perplexity Sonar Reasoning Pro (Puter)" },
{ id: "perplexity/sonar", name: "Perplexity Sonar (Puter)" },
],
passthroughModels: true, // 500+ models available — users can type arbitrary Puter model IDs
},
"cloudflare-ai": {
id: "cloudflare-ai",
alias: "cf",
format: "openai",
executor: "cloudflare-ai",
// URL is dynamic: uses accountId from credentials. The executor builds it.
baseUrl: "https://api.cloudflare.com/client/v4/accounts",
authType: "apikey",
authHeader: "bearer",
// 10K Neurons/day free: ~150 LLM responses or 500s Whisper audio — global edge
models: [
{ id: "@cf/meta/llama-3.3-70b-instruct", name: "Llama 3.3 70B (🆓 ~150 resp/day)" },
{ id: "@cf/meta/llama-3.1-8b-instruct", name: "Llama 3.1 8B (🆓)" },
{ id: "@cf/google/gemma-3-12b-it", name: "Gemma 3 12B (🆓)" },
{ id: "@cf/mistral/mistral-7b-instruct-v0.2-lora", name: "Mistral 7B (🆓)" },
{ id: "@cf/qwen/qwen2.5-coder-15b-instruct", name: "Qwen 2.5 Coder 15B (🆓)" },
{ id: "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", name: "DeepSeek R1 Distill 32B (🆓)" },
],
},
scaleway: {
id: "scaleway",
alias: "scw",
format: "openai",
executor: "default",
baseUrl: "https://api.scaleway.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
// 1M tokens free for new accounts — EU/GDPR (Paris), no credit card needed under limit
models: [
{ id: "qwen3-235b-a22b-instruct-2507", name: "Qwen3 235B A22B (1M free tok 🆓)" },
{ id: "llama-3.1-70b-instruct", name: "Llama 3.1 70B (🆓 EU)" },
{ id: "llama-3.1-8b-instruct", name: "Llama 3.1 8B (🆓 EU)" },
{ id: "mistral-small-3.2-24b-instruct-2506", name: "Mistral Small 3.2 (🆓 EU)" },
{ id: "deepseek-v3-0324", name: "DeepSeek V3 (🆓 EU)" },
{ id: "gpt-oss-120b", name: "GPT-OSS 120B (🆓 EU)" },
],
},
uncloseai: {
id: "uncloseai",
alias: "unc",
format: "openai",
executor: "default",
baseUrl: "https://hermes.ai.unturf.com/v1/chat/completions",
authType: "optional",
authHeader: "bearer",
models: [
{
id: "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic",
name: "Hermes 3 Llama 3.1 8B (🆓 Free)",
},
{ id: "qwen3.6:27b", name: "Qwen3 Coder 27B (🆓 Free)" },
{ id: "gemma4:31b", name: "Gemma 4 31B (🆓 Free)" },
],
},
replicate: {
id: "replicate",
alias: "rep",
format: "openai",
executor: "default",
baseUrl: "https://openai-proxy.replicate.com/v1/chat/completions",
modelsUrl: "https://openai-proxy.replicate.com/v1/models",
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
passthroughModels: true,
defaultContextLength: 128000,
models: [
{
id: "meta/meta-llama-3.1-405b-instruct",
name: "Llama 3.1 405B Instruct (Free)",
contextLength: 128000,
},
{
id: "meta/meta-llama-3.1-70b-instruct",
name: "Llama 3.1 70B Instruct (Free)",
contextLength: 128000,
},
{
id: "mistralai/mixtral-8x7b-instruct-v0.1",
name: "Mixtral 8x7B Instruct (Free)",
contextLength: 32768,
},
{
id: "deepseek-ai/deepseek-r1",
name: "DeepSeek R1 (Free)",
contextLength: 65536,
supportsReasoning: true,
},
],
},
hackclub: {
id: "hackclub",
alias: "hc",
format: "openai",
executor: "default",
baseUrl: "https://ai.hackclub.com/proxy/v1/chat/completions",
modelsUrl: "https://ai.hackclub.com/proxy/v1/models",
authType: "optional",
authHeader: "bearer",
passthroughModels: true,
defaultContextLength: 128000,
models: [
{ id: "meta-llama/llama-3.3-70b-instruct", name: "Llama 3.3 70B" },
{ id: "mistralai/mistral-7b-instruct", name: "Mistral 7B" },
{ id: "deepseek-ai/deepseek-coder-33b", name: "DeepSeek Coder 33B" },
],
},
deepinfra: {
id: "deepinfra",
alias: "deepinfra",
format: "openai",
executor: "default",
baseUrl: "https://api.deepinfra.com/v1/openai/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.deepinfra,
},
"vercel-ai-gateway": {
id: "vercel-ai-gateway",
alias: "vag",
format: "openai",
executor: "default",
baseUrl: "https://ai-gateway.vercel.sh/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["vercel-ai-gateway"],
},
"lambda-ai": {
id: "lambda-ai",
alias: "lambda",
format: "openai",
executor: "default",
baseUrl: "https://api.lambda.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["lambda-ai"],
},
sambanova: {
id: "sambanova",
alias: "samba",
format: "openai",
executor: "default",
baseUrl: "https://api.sambanova.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.sambanova,
},
nscale: {
id: "nscale",
alias: "nscale",
format: "openai",
executor: "default",
baseUrl: "https://inference.api.nscale.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.nscale,
},
ovhcloud: {
id: "ovhcloud",
alias: "ovh",
format: "openai",
executor: "default",
baseUrl: "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.ovhcloud,
},
baseten: {
id: "baseten",
alias: "baseten",
format: "openai",
executor: "default",
baseUrl: "https://inference.baseten.co/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.baseten,
},
publicai: {
id: "publicai",
alias: "publicai",
format: "openai",
executor: "default",
baseUrl: "https://api.publicai.co/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.publicai,
},
moonshot: {
id: "moonshot",
alias: "moonshot",
format: "openai",
executor: "default",
baseUrl: "https://api.moonshot.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.moonshot,
},
"meta-llama": {
id: "meta-llama",
alias: "meta",
format: "openai",
executor: "default",
baseUrl: "https://api.llama.com/compat/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["meta-llama"],
},
"v0-vercel": {
id: "v0-vercel",
alias: "v0",
format: "openai",
executor: "default",
baseUrl: "https://api.v0.dev/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["v0-vercel"],
},
morph: {
id: "morph",
alias: "morph",
format: "openai",
executor: "default",
baseUrl: "https://api.morphllm.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.morph,
},
"featherless-ai": {
id: "featherless-ai",
alias: "featherless",
format: "openai",
executor: "default",
baseUrl: "https://api.featherless.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["featherless-ai"],
},
friendliai: {
id: "friendliai",
alias: "friendli",
format: "openai",
executor: "default",
baseUrl: "https://api.friendli.ai/dedicated/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.friendliai,
},
llamagate: {
id: "llamagate",
alias: "llamagate",
format: "openai",
executor: "default",
baseUrl: "https://llamagate.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.llamagate,
},
heroku: {
id: "heroku",
alias: "heroku",
format: "openai",
executor: "default",
baseUrl: "https://us.inference.heroku.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.heroku,
},
galadriel: {
id: "galadriel",
alias: "galadriel",
format: "openai",
executor: "default",
baseUrl: "https://api.galadriel.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.galadriel,
},
databricks: {
id: "databricks",
alias: "databricks",
format: "openai",
executor: "default",
baseUrl: "https://adb-0000000000000000.0.azuredatabricks.net/serving-endpoints",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.databricks,
},
snowflake: {
id: "snowflake",
alias: "snowflake",
format: "openai",
executor: "default",
baseUrl: "https://{account}.snowflakecomputing.com/api/v2",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.snowflake,
},
wandb: {
id: "wandb",
alias: "wandb",
format: "openai",
executor: "default",
baseUrl: "https://api.inference.wandb.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.wandb,
},
volcengine: {
id: "volcengine",
alias: "volcengine",
format: "openai",
executor: "default",
baseUrl: "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.volcengine,
},
ai21: {
id: "ai21",
alias: "ai21",
format: "openai",
executor: "default",
baseUrl: "https://api.ai21.com/studio/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.ai21,
},
gigachat: {
id: "gigachat",
alias: "gigachat",
format: "openai",
executor: "default",
baseUrl: "https://gigachat.devices.sberbank.ru/api/v1",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.gigachat,
},
venice: {
id: "venice",
alias: "venice",
format: "openai",
executor: "default",
baseUrl: "https://api.venice.ai/api/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.venice,
},
"kimi-web": {
id: "kimi-web",
alias: "kimi",
format: "openai",
executor: "kimi-web",
baseUrl: "https://kimi.moonshot.cn/api/chat",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "kimi-default", name: "Kimi Default" },
{ id: "kimi-128k", name: "Kimi 128K (Long Context)" },
],
},
"doubao-web": {
id: "doubao-web",
alias: "db",
format: "openai",
executor: "doubao-web",
baseUrl: "https://www.doubao.com/api/chat",
authType: "apikey",
authHeader: "cookie",
models: [
{ id: "doubao-default", name: "Doubao Default" },
{ id: "doubao-pro", name: "Doubao Pro" },
],
},
codestral: {
id: "codestral",
alias: "codestral",
format: "openai",
executor: "default",
baseUrl: "https://codestral.mistral.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.codestral,
},
upstage: {
id: "upstage",
alias: "upstage",
format: "openai",
executor: "default",
baseUrl: "https://api.upstage.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.upstage,
},
maritalk: {
id: "maritalk",
alias: "maritalk",
format: "openai",
executor: "default",
baseUrl: MARITALK_DEFAULT_BASE_URL,
authType: "apikey",
authHeader: "key",
models: CHAT_OPENAI_COMPAT_MODELS.maritalk,
},
"xiaomi-mimo": {
id: "xiaomi-mimo",
alias: "mimo",
format: "openai",
executor: "default",
baseUrl: "https://api.xiaomimimo.com/v1",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["xiaomi-mimo"],
},
gitlawb: {
id: "gitlawb",
alias: "glb",
format: "openai",
executor: "default",
baseUrl: "https://opengateway.gitlawb.com/v1/xiaomi-mimo",
authType: "apikey",
authHeader: "bearer",
headers: {
"User-Agent": "OpenClaude/1.0 (linux; x86_64)",
"X-Title": "OpenClaude CLI",
"HTTP-Referer": "https://github.com/Gitlawb/openclaude",
},
models: CHAT_OPENAI_COMPAT_MODELS["gitlawb"],
},
"gitlawb-gmi": {
id: "gitlawb-gmi",
alias: "glb-gmi",
format: "openai",
executor: "default",
baseUrl: "https://opengateway.gitlawb.com/v1/gmi-cloud",
authType: "apikey",
authHeader: "bearer",
headers: {
"User-Agent": "OpenClaude/1.0 (linux; x86_64)",
"X-Title": "OpenClaude CLI",
"HTTP-Referer": "https://github.com/Gitlawb/openclaude",
},
passthroughModels: true,
models: CHAT_OPENAI_COMPAT_MODELS["gitlawb-gmi"],
},
"inference-net": {
id: "inference-net",
alias: "inet",
format: "openai",
executor: "default",
baseUrl: "https://api.inference.net/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS["inference-net"],
},
nanogpt: {
id: "nanogpt",
alias: "nanogpt",
format: "openai",
executor: "default",
baseUrl: "https://nano-gpt.com/api/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.nanogpt,
},
predibase: {
id: "predibase",
alias: "predibase",
format: "openai",
executor: "default",
baseUrl: "https://serving.app.predibase.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.predibase,
},
bytez: {
id: "bytez",
alias: "bytez",
format: "openai",
executor: "default",
baseUrl: "https://api.bytez.com/models/v2",
authType: "apikey",
authHeader: "bearer",
models: CHAT_OPENAI_COMPAT_MODELS.bytez,
},
// Issue #2361: LLM7.io was visible in the dashboard provider list
// (entry in `src/shared/constants/providers.ts`) but missing from the
// executor registry, so test-connection and chat requests had no
// baseUrl / authType to route to and returned a credential error.
// The provider exposes a standard OpenAI-compatible v1 endpoint with
// an optional bearer token (set the literal string "unused" when no
// key is configured, per upstream docs).
llm7: {
id: "llm7",
alias: "llm7",
format: "openai",
executor: "default",
baseUrl: "https://api.llm7.io/v1/chat/completions",
modelsUrl: "https://api.llm7.io/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "gpt-4o-mini-2024-07-18", name: "GPT-4o mini (LLM7)" },
{ id: "gpt-4.1-nano-2025-04-14", name: "GPT-4.1 nano (LLM7)" },
{ id: "deepseek-r1-0528", name: "DeepSeek R1 (LLM7)" },
{ id: "qwen2.5-coder-32b-instruct", name: "Qwen2.5 Coder 32B (LLM7)" },
],
},
aimlapi: {
id: "aimlapi",
alias: "aiml",
format: "openai",
executor: "default",
baseUrl: "https://api.aimlapi.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
// $0.025/day free credits — 200+ models via single aggregator endpoint
models: [
{ id: "gpt-4o", name: "GPT-4o (via AI/ML API)" },
{ id: "claude-3-5-sonnet-20241022", name: "Claude 3.5 Sonnet (via AI/ML API)" },
{ id: "gemini-1.5-pro", name: "Gemini 1.5 Pro (via AI/ML API)" },
{ id: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo", name: "Llama 3.1 70B (via AI/ML API)" },
{ id: "deepseek-chat", name: "DeepSeek Chat (via AI/ML API)" },
{ id: "mistral-large-latest", name: "Mistral Large (via AI/ML API)" },
],
passthroughModels: true,
},
// Free tier: 50 RPM, 500,000 TPM
"nous-research": {
id: "nous-research",
alias: "nous",
format: "openai",
executor: "default",
baseUrl: "https://inference-api.nousresearch.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "Hermes-4-405B", name: "Hermes 4 7B (Nous Research)" },
{ id: "Hermes-4-70B", name: "Hermes 4 70B (Nous Research)" },
],
},
reka: {
id: "reka",
alias: "reka",
format: "openai",
executor: "default",
baseUrl: "https://api.reka.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
models: [
{ id: "reka-flash-3", name: "Reka Flash 3" },
{ id: "reka-edge-2603", name: "Reka Edge 2603" },
],
},
bluesminds: {
id: "bluesminds",
alias: "bm",
format: "openai",
executor: "default",
baseUrl: "https://api.bluesminds.com/v1/chat/completions",
modelsUrl: "https://api.bluesminds.com/v1/models",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
// Default free models
{ id: "gpt-4o", name: "GPT-4o" },
{ id: "gpt-4o-mini", name: "GPT-4o Mini" },
{ id: "gpt-4.1", name: "GPT-4.1" },
{ id: "gpt-4.1-mini", name: "GPT-4.1 Mini" },
{ id: "gpt-4.1-nano", name: "GPT-4.1 Nano" },
{ id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5" },
{ id: "claude-haiku-4-5", name: "Claude Haiku 4.5" },
{ id: "gemini-2.0-flash", name: "Gemini 2.0 Flash" },
{ id: "gemini-2.0-flash-exp", name: "Gemini 2.0 Flash (Exp)" },
{ id: "deepseek-reasoner", name: "DeepSeek Reasoner", supportsReasoning: true },
{ id: "deepseek-chat", name: "DeepSeek Chat" },
{ id: "qwen-plus", name: "Qwen Plus" },
{ id: "qwen-turbo", name: "Qwen Turbo" },
{ id: "kimi-k2", name: "Kimi K2" },
{ id: "kimi-k2-thinking", name: "Kimi K2 Thinking" },
{ id: "glm-4.7", name: "GLM 4.7" },
{ id: "glm-4-flash", name: "GLM 4 Flash" },
{ id: "minimax-m2.5", name: "MiniMax M2.5" },
// VIP models (cost pi credits)
{ id: "claude-opus-4-5", name: "Claude Opus 4.5 (VIP)", contextLength: 200000 },
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (VIP)", contextLength: 1048576 },
{ id: "grok-3", name: "Grok-3 (VIP)", contextLength: 131072 },
{ id: "qwen-max", name: "Qwen Max (VIP)" },
],
},
"freemodel-dev": {
id: "freemodel-dev",
alias: "fmd",
format: "openai",
executor: "default",
baseUrl: "https://api.freemodel.dev/v1/chat/completions",
modelsUrl: "https://api.freemodel.dev/v1/models",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
{ id: "gpt-5.5", name: "GPT-5.5", contextLength: 400000 },
{ id: "gpt-5.4", name: "GPT-5.4", contextLength: 400000 },
{ id: "gpt-5.4-mini", name: "GPT-5.4 Mini" },
{ id: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
],
},
freeaiapikey: {
id: "freeaiapikey",
alias: "faik",
format: "openai",
executor: "default",
baseUrl: "https://freeaiapikey.com/v1/chat/completions",
modelsUrl: "https://freeaiapikey.com/v1/models",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
{ id: "openai/gpt-5", name: "GPT-5 (via FreeAIAPIKey)", contextLength: 400000 },
{ id: "openai/gpt-4o", name: "GPT-4o (via FreeAIAPIKey)" },
{ id: "openai/gpt-5.2-codex", name: "GPT-5.2 Codex (via FreeAIAPIKey)" },
{
id: "anthropic/claude-opus-4.6",
name: "Claude Opus 4.6 (via FreeAIAPIKey)",
contextLength: 1000000,
},
{
id: "anthropic/claude-sonnet-4.6",
name: "Claude Sonnet 4.6 (via FreeAIAPIKey)",
contextLength: 1000000,
},
{
id: "Alibaba/qwen3.5",
name: "Qwen 3.5 (via FreeAIAPIKey)",
contextLength: 128000,
},
{
id: "Alibaba/qwen3-vl:235b",
name: "Qwen 3 VL 235B (via FreeAIAPIKey)",
contextLength: 128000,
},
],
},
};
// ── Generator Functions ───────────────────────────────────────────────────
/** Generate legacy PROVIDERS object shape for constants.js backward compatibility */
export function generateLegacyProviders(): Record<string, LegacyProvider> {
const providers: Record<string, LegacyProvider> = {};
for (const [id, entry] of Object.entries(REGISTRY)) {
const p: LegacyProvider = { format: entry.format };
// URL(s)
if (entry.baseUrls) {
p.baseUrls = entry.baseUrls;
} else if (entry.baseUrl) {
p.baseUrl = entry.baseUrl;
}
if (entry.responsesBaseUrl) {
p.responsesBaseUrl = entry.responsesBaseUrl;
}
if (entry.requestDefaults) {
p.requestDefaults = entry.requestDefaults;
}
if (typeof entry.timeoutMs === "number") {
p.timeoutMs = entry.timeoutMs;
}
// Headers
const mergedHeaders = {
...(entry.headers || {}),
...(entry.extraHeaders || {}),
};
if (Object.keys(mergedHeaders).length > 0) {
p.headers = mergedHeaders;
}
// OAuth
if (entry.oauth) {
if (entry.oauth.clientIdEnv) {
p.clientId = process.env[entry.oauth.clientIdEnv] || entry.oauth.clientIdDefault;
}
if (entry.oauth.clientSecretEnv) {
p.clientSecret =
process.env[entry.oauth.clientSecretEnv] || entry.oauth.clientSecretDefault;
}
if (entry.oauth.tokenUrl) p.tokenUrl = entry.oauth.tokenUrl;
if (entry.oauth.refreshUrl) p.refreshUrl = entry.oauth.refreshUrl;
if (entry.oauth.authUrl) p.authUrl = entry.oauth.authUrl;
}
// Cursor-specific
if (entry.chatPath) p.chatPath = entry.chatPath;
if (entry.clientVersion) p.clientVersion = entry.clientVersion;
providers[id] = p;
}
return providers;
}
/** Generate PROVIDER_MODELS map (alias → model list) */
export function generateModels(): Record<string, RegistryModel[]> {
const models: Record<string, RegistryModel[]> = {};
for (const entry of Object.values(REGISTRY)) {
if (entry.models && entry.models.length > 0) {
const key = entry.alias || entry.id;
// If alias already exists, don't overwrite (first wins)
if (!models[key]) {
models[key] = entry.models;
}
}
}
return models;
}
/** Generate PROVIDER_ID_TO_ALIAS map */
export function generateAliasMap(): Record<string, string> {
const map: Record<string, string> = {};
for (const entry of Object.values(REGISTRY)) {
map[entry.id] = entry.alias || entry.id;
}
return map;
}
// ── Local Provider Detection ──────────────────────────────────────────────
// Evaluated once at module load time — process restart required for env var changes.
const LOCAL_HOSTNAMES = new Set([
"localhost",
"127.0.0.1",
...(typeof process !== "undefined" && process.env.LOCAL_HOSTNAMES
? process.env.LOCAL_HOSTNAMES.split(",")
.map((h) => h.trim())
.filter(Boolean)
: []),
]);
/**
* Detect if a base URL points to a local inference backend.
* Used for shorter 404 cooldowns (model-only, not connection) and health check targets.
*
* Operators can extend via LOCAL_HOSTNAMES env var (comma-separated) for Docker
* hostnames (e.g., LOCAL_HOSTNAMES=omlx,mlx-audio).
*/
export function isLocalProvider(baseUrl?: string | null): boolean {
if (!baseUrl) return false;
try {
const url = new URL(baseUrl);
const hostname = url.hostname;
// Strictly matching 172.16.0.0/12 (Docker/local) and explicitly blocking ::1 per SSRF hardening
return (
LOCAL_HOSTNAMES.has(hostname) ||
/^172\.(1[6-9]|2[0-9]|3[0-1])\.\d{1,3}\.\d{1,3}$/.test(hostname)
);
} catch {
return false;
}
}
/** Set of provider IDs with passthroughModels enabled — 404s are model-specific, not account-level. */
const _passthroughProviderIds: Set<string> | null = (() => {
try {
const ids = new Set<string>();
for (const entry of Object.values(REGISTRY)) {
if (entry.passthroughModels) ids.add(entry.id);
}
return ids;
} catch {
return null;
}
})();
export function getPassthroughProviders(): Set<string> {
return _passthroughProviderIds ?? new Set<string>();
}
// ── Registry Lookup Helpers ───────────────────────────────────────────────
const _byAlias = new Map<string, RegistryEntry>();
for (const entry of Object.values(REGISTRY)) {
if (entry.alias && entry.alias !== entry.id) {
_byAlias.set(entry.alias, entry);
}
}
/** Get registry entry by provider ID or alias */
export function getRegistryEntry(provider: string): RegistryEntry | null {
return REGISTRY[provider] || _byAlias.get(provider) || null;
}
/** Get all registered provider IDs */
export function getRegisteredProviders(): string[] {
return Object.keys(REGISTRY);
}
// Precomputed map: modelId → unsupportedParams (O(1) lookup instead of O(N×M) scan).
// Built once at module load from all registry entries.
const _unsupportedParamsMap = new Map<string, readonly string[]>();
for (const entry of Object.values(REGISTRY)) {
for (const model of entry.models) {
if (model.unsupportedParams && !_unsupportedParamsMap.has(model.id)) {
_unsupportedParamsMap.set(model.id, model.unsupportedParams);
}
}
}
/**
* Get unsupported parameters for a specific model.
* Uses O(1) precomputed lookup. Also handles prefixed model IDs
* (e.g., "openai/o3" → strips prefix and looks up "o3").
* Returns empty array if no restrictions are defined.
*/
export function getUnsupportedParams(provider: string, modelId: string): readonly string[] {
// 1. Check current provider's registry (exact match)
const entry = getRegistryEntry(provider);
const modelEntry = entry?.models.find((m) => m.id === modelId);
if (modelEntry?.unsupportedParams) return modelEntry.unsupportedParams;
// 2. O(1) lookup in precomputed map (handles cross-provider routing)
const cached = _unsupportedParamsMap.get(modelId);
if (cached) return cached;
// 3. Handle prefixed model IDs (e.g., "openai/o3" → "o3")
if (modelId.includes("/")) {
const bareId = modelId.split("/").pop() || "";
const bare = _unsupportedParamsMap.get(bareId);
if (bare) return bare;
}
return [];
}
/**
* Get provider category: "oauth" or "apikey"
* Used by the resilience layer to apply different cooldown/backoff profiles.
* @param {string} provider - Provider ID or alias
* @returns {"oauth"|"apikey"}
*/
export function getProviderCategory(provider: string): "oauth" | "apikey" {
const entry = getRegistryEntry(provider);
if (!entry) return "apikey"; // Safe default for unknown providers
return entry.authType === "apikey" ? "apikey" : "oauth";
}
/**
* Derive the latest opus/sonnet/haiku model IDs from the `claude` registry entry.
* Picks the first model whose ID matches each family pattern — registry order
* determines precedence, so newer models should be listed first.
*/
export function getClaudeCodeDefaultModels(): {
opus: string;
sonnet: string;
haiku: string;
} {
const models = REGISTRY.claude?.models ?? [];
const find = (pattern: RegExp) => models.find((m) => pattern.test(m.id))?.id ?? "";
return {
opus: find(/opus/i),
sonnet: find(/sonnet/i),
haiku: find(/haiku/i),
};
}