Files
OmniRoute/src/shared/constants/providers.ts
Diego Rodrigues de Sa e Souza de60b4b171 Release v3.8.23
* chore(release): open v3.8.23 development cycle

* fix(anthropic): strip top_p when temperature is set to avoid 400 (#3691)

Integrated into release/v3.8.23

* fix(vertex): support Vertex AI Express-mode API keys (#3690)

Integrated into release/v3.8.23

* fix(stream): error on empty Claude SSE instead of synthetic success (#3689)

Integrated into release/v3.8.23

* fix(oauth): stop token-refresh invalidation loop + harden proxy resolution (#3692)

Integrated into release/v3.8.23

* docs: add FUNDING.yml and Support section to README (#3698)

Integrated into release/v3.8.23

* feat: gemini - handle known ratelimits (#3686)

Integrated into release/v3.8.23

* fix: stream combo fails over on empty content-filtered response (#3685) (#3702)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(antigravity): preserve gemini-3.1-pro high/low budget tiers (#3696) (#3703)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(auto-combo): add auto-updating model intelligence scoring (#3660)

Integrated into release/v3.8.23

* fix(gemini): context-mode fallback for signatureless tool calls (#3688) (#3704)

* chore(quality-gate): reconcile file-size baseline (27 files + providerLimits.ts) (#3705)

* feat(vertex): dynamic model discovery via Generative Language models API (#3712)

Integrated into release/v3.8.23. Vertex dynamic model discovery — surfaces image models (imagen-*, gemini-*-image), embeddings and audio from the live Generative Language catalog, with cached→static fallback and the shared parseGeminiModelsList helper. Validated: parser test 5/5, typecheck:core clean.

* fix(combo): gate reasoning token buffer (#3700)

Integrated into release/v3.8.23. Makes the #3588 reasoning token buffer safe and configurable: only inflates max_tokens when the model has a known, non-default output cap and the buffered value fits inside it; otherwise preserves/clamps the client limit. Adds the reasoningTokenBufferEnabled kill switch (default ON). Validated: combo-routing-engine 81/81, combo-config 25/25, combo-quality-validator-reasoning 12/12, phase1f 10/10, typecheck:core clean.

* refactor(#3501): god-component Phase 1g-1j — client 4062→3408 LOC (-654) (#3717)

Phase 1g-1j of #3501: client 4062→3408 LOC. Pure extraction (ProviderPlaygroundPanel, useCommandCodeAuth, useExternalLinkFlow+ExternalLinkModal, useAuthFileHandlers) + loadConnProxies ReferenceError fix + phase1f test path fix.

Co-authored-by: oyi77 <14921983+oyi77@users.noreply.github.com>

* refactor(#3501): god-component Phase 1k-1m — client 3408→2553 LOC (-855) (#3721)

Phase 1k-1m of #3501: client 3408→2553 LOC. Pure extraction (useModelImportHandlers+ImportProgressModal, useModelVisibilityHandlers, ProviderModelsSection).

Co-authored-by: oyi77 <14921983+oyi77@users.noreply.github.com>

* docs(changelog): restore #3590 bullet lost on the v3.8.20 release branch

The fix itself reached main pre-tag via cherry-pick #3591, but its changelog
bullet (commit e33fdd4ab) only ever existed on release/v3.8.20 after the
squash-merge. Restored under [3.8.20] per the 2026-06-12 release-branch
leftover audit (_tasks/release-audit/release-leftovers-audit-2026-06-12.md).

* fix(kiro): resolve quota for IAM Identity Center accounts missing a profileArn (#3722)

Integrated into release/v3.8.23

* refactor(#3501): god-component Phase 1n-1s — client 2553→1376 LOC (-1177) (#3725)

Phase 1n-1s of #3501: client 2553→1376 LOC. Pure extraction (ConnectionsListPanel, ConnectionsHeaderToolbar, ZedImportCard, BatchTestResultsModal, AdaptaTutorialModal, useApiKeySave + helpers).

Co-authored-by: oyi77 <14921983+oyi77@users.noreply.github.com>

* feat(model-lockout): settings UI, backend integration, error classification, and success-decay recovery (#3629)

Integrated into release/v3.8.23

* refactor(#3501): god-component Phase 1t — client 1376→781 LOC (≤800 TARGET REACHED ) (#3727)

Phase 1t of #3501: client 1376→781 LOC (≤800 reached). Original god-component 12,882→781 (−94%).

Co-authored-by: oyi77 <14921983+oyi77@users.noreply.github.com>

* fix: bundle @omniroute/opencode-plugin inside omniroute + add 'setup opencode' CLI command (#3726)

Integrated into release/v3.8.23

* feat(vertex): self-tracked USD spend since account added (#3724)

Integrated into release/v3.8.23

* fix(qwen-web): migrate to v2 chat API with full cookie-jar replay (#3288) (#3723)

Integrated into release/v3.8.23

* fix(sse): make safeLogEvents async — 'await' in a sync function broke every chatHelpers import

#3692 added a lazy 'await import(proxyEgress)' for egress-IP visibility inside
safeLogEvents, which is a sync function — an ES syntax error. It went unnoticed
because typecheck:core does not cover src/sse and no test in the merge gates
loaded chatHelpers via tsx; any consumer that did (chat-context-relay and
chat-route-coverage suites, integration harnesses) failed at module load with
'await can only be used inside an async function'.

safeLogEvents is fire-and-forget logging with an outer try/catch, so making it
async (and 'void'-ing the single chat.ts call site) preserves behavior exactly.

Validation: tests/unit/chat-context-relay.test.ts + chat-route-coverage.test.ts
went from failing-at-load to green (+14 tests destravados).

* fix(sse): remove cross-provider credential leak in emergency fallback + combo/proxy audit fixes (#3699)

Integrated into release/v3.8.23

* fix(executors): inject MiMoCode anti-abuse marker so free endpoint stops 403ing (#3728)

Integrated into release/v3.8.23

* fix(dashboard): repair "Test all models" — toast crash, status icons, auto-hide (#3729)

Integrated into release/v3.8.23

* chore(deps): bump actions/upload-artifact from 4 to 7 (#3735)

Integrated into release/v3.8.23 — aligns upload-artifact to v7 (already used across ci.yml).

* chore(deps): bump actions/cache from 4 to 5 (#3734)

Integrated into release/v3.8.23 — actions/cache v4→v5.

* chore(deps): bump actions/download-artifact from 4 to 8 (#3733)

Integrated into release/v3.8.23 — download-artifact v4→v8.

* feat(fallback): add OMNIROUTE_EMERGENCY_FALLBACK env switch (#3741)

Adds an OMNIROUTE_EMERGENCY_FALLBACK env switch to disable the emergency budget-exhaustion fallback (reroute to free nvidia/gpt-oss-120b). Default unchanged (enabled). Closes #3739, related #2879.

Integrated into release/v3.8.23.

* i18n: comprehensive zh-CN translation improvements (#3736)

Aligns zh-CN to en (hundreds of entries), translates batch-action labels + settings sidebar menu, adds categoryConfig/endpointTokenSaver keys, resolves __MISSING__ stubs. Sidebar/SidebarTab hardcoded strings replaced with t(). en.json purely additive (8 new sidebar.* keys, 0 removed); cli-i18n gate green.

Integrated into release/v3.8.23.

* chore(release): v3.8.23 — 2026-06-12

- CHANGELOG: complete v3.8.23 section (28 bullets, 27 commits)
- fix(webdav): resolve promise on writeStream finish, not req end — eliminates
  intermittent 500 on PUT update (writeStream may not have flushed at rename time)
- test(autoCombo): stub DB calls from PR #3660 in tieredRotation.test.ts to prevent
  5s timeout in vitest (getModelIntelligenceBySource DB init path)
- chore(env-sync): add XDG_DATA_HOME + OMNIROUTE_OPENCODE_PLUGIN_DIR to IGNORE_FROM_CODE
  allowlist (introduced by PR #3726 setup-open-code.mjs, not OmniRoute config vars)
- chore(cli): regenerated bin/cli/api-commands/*.mjs (7 new, 27 updated)

* fix(model-family): fallback lookup also tries bare model name with dots

getNextFamilyFallback normalized dots-to-hyphens ("gemini-3.1-pro-high" →
"gemini-3-1-pro-high") but MODEL_FAMILIES keys use the literal dot form. The
lookup always missed, returning null for any model whose dots are part of the
name rather than a version separator.

Fallback: try MODEL_FAMILIES[lookupKey] ?? MODEL_FAMILIES[bareModel] so both
naming conventions are covered. Fixes T30 test (pre-existing since v3.8.22).

* feat: expose API key cost drilldown + quota % used (#3742)

Adds all-time USD cost per API key in the API Key Manager, a per-key deep-link into the Cost Explorer (filtered + grouped by model), URL-param hydration of range/groupBy/apiKeyIds, and a '% used' quota display. Review adjustments: extracted URL-param parsers to a tested module (Rule #18), i18n'd the new strings (en + zh-CN), dropped the redundant webdav-handler entry already on release.

Integrated into release/v3.8.23.

* feat: add provider display modes — All / Configured / Compact (#3743)

Replaces the Providers page configured-only toggle with All/Configured/Compact display modes (Compact = flat deduped grid, no-auth last). Persists the preference and migrates the legacy localStorage key. Rebased onto release/v3.8.23.

Integrated into release/v3.8.23.

* fix(cache): scope semantic-cache signature to API key (#3740)

Adds the api_key_id dimension to generateSignature's SHA-256 hash so two callers with different API keys never receive each other's cached responses. Threads apiKeyId through checkSemanticCache + both write sites; migration 098 clears pre-existing key-less entries; unauthenticated requests stay isolated from keyed ones. 3 TDD tests.

Integrated into release/v3.8.23.

* fix(responses): apply OpenAI Responses API stream=false spec default (#3708)

resolveStreamFlag now applies the stream=false-when-omitted default for sourceFormat=openai-responses (same as the existing claude path), so spec-compliant /v1/responses upstreams that return JSON no longer fall through to the wildcard-Accept heuristic and trigger STREAM_EARLY_EOF / 502. Codex CLI (stream:true) and explicit text/event-stream clients unaffected.

Integrated into release/v3.8.23.

* chore(release): reconcile CI gates for v3.8.23

- file-size baseline: re-freeze 8 files grown by PRs #3742/#3743/#3740
  (cost drilldown, provider display modes, cache key isolation)
- ARCHITECTURE.md: update executor count 55→60 (check:docs-counts drift)
- .env.example: add OMNIROUTE_EMERGENCY_FALLBACK (#3741, env-doc-sync)
- CHANGELOG: add formatted bullets for #3742, #3743, #3708, #3740,
  model-family-fallback fix; remove duplicate raw ### Fixed section

* test: restore assert count to satisfy check:test-masking gate

Three test files had net assertion removals after behavior-changing PRs:
- chatcore-translation-paths: emergency fallback moved to routing layer
  (#3699) — add body error assertion + model-name guard
- executor-vertex-extended: non-JSON is now Express API key (#3690) —
  add projects/-path guard to the express-key URL test
- stream-utils: empty streams now emit error (#3685) — add code/message/
  status/completePayload guards to both passthrough and translate variants

All new assertions are meaningful (code enum value, 5xx range, non-empty
message, onComplete must-not-fire contract).

* fix(ci): move rtl-logical-classes test to ui/ so vitest:ui runner collects it

---------

Co-authored-by: Felipe Almeman <4226997+zhiru@users.noreply.github.com>
Co-authored-by: NOXX - Commiter <artur1992123@mail.ru>
Co-authored-by: Nick Sullivan <142708+TechNickAI@users.noreply.github.com>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com>
Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: oyi77 <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Chewji <126886556+Chewji9875@users.noreply.github.com>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Felipe Sartori <felipesartori.ti@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Zois Pagoulatos <zpagoulatos@hotmail.com>
Co-authored-by: sdfsdfw2 <167810361+sdfsdfw2@users.noreply.github.com>
Co-authored-by: Witroch4 <witalo_rocha@hotmail.com>
2026-06-12 23:49:22 -03:00

3146 lines
89 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 definitions
/**
* Service kind — declarative tag for what a provider can do beyond basic LLM chat.
* Affects UI filtering and playground routing; does not influence request routing.
*/
export type ServiceKind =
| "llm"
| "embedding"
| "image"
| "imageToText"
| "tts"
| "stt"
| "webSearch"
| "webFetch"
| "video"
| "music";
export type RiskNoticeVariant = "oauth" | "webCookie" | "deprecated" | "embedded-service";
export interface ProviderRiskNoticeFields {
subscriptionRisk?: boolean;
riskNoticeVariant?: RiskNoticeVariant;
isEmbeddedService?: boolean;
}
export const FREE_PROVIDERS = {};
// No-auth Providers
export const NOAUTH_PROVIDERS = {
opencode: {
id: "opencode",
alias: "oc",
name: "OpenCode Free",
icon: "terminal",
color: "#E87040",
textIcon: "OC",
website: "https://opencode.ai",
noAuth: true,
hasFree: true,
serviceKinds: ["llm"],
authHint: "No API key required — uses OpenCode's public free endpoint.",
freeNote:
"No API key required — public OpenCode endpoint with Kimi, GLM, Qwen, MiMo, MiniMax models.",
notice: {
text: "OpenCode Free uses the public OpenCode endpoint (https://opencode.ai/zen/v1). No signup or API key needed. Rate limits apply.",
},
},
"duckduckgo-web": {
id: "duckduckgo-web",
alias: "ddgw",
name: "DuckDuckGo AI Chat",
icon: "auto_awesome",
color: "#DE5833",
textIcon: "DDG",
website: "https://duckduckgo.com/duckchat",
noAuth: true,
hasFree: true,
serviceKinds: ["llm"],
freeNote: "Free — anonymous access to multiple AI models via DuckDuckGo.",
authHint: "No credentials required — DuckDuckGo AI Chat is anonymous and free.",
},
theoldllm: {
id: "theoldllm",
alias: "tllm",
name: "The Old LLM (Free)",
icon: "auto_awesome",
color: "#8B5CF6",
textIcon: "TL",
website: "https://theoldllm.vercel.app",
noAuth: true,
hasFree: true,
serviceKinds: ["llm"],
freeNote:
"Free — GPT-5.4, Claude 4.6 Opus/Sonnet/Haiku, + more. No API key — tokens auto-generated via browser.",
authHint:
"No credentials required. The executor auto-generates access tokens via an embedded Playwright browser instance.",
},
chipotle: {
id: "chipotle",
alias: "pepper",
name: "Chipotle Pepper AI (Free)",
icon: "restaurant",
color: "#C41230",
textIcon: "🌯",
website: "https://amelia.chipotle.com",
noAuth: true,
hasFree: true,
serviceKinds: ["llm"],
freeNote:
"Free — Chipotle's Pepper AI (IPsoft Amelia). Anonymous sessions, no API key. Rate-limited.",
authHint:
"No credentials required. Uses Chipotle's public support chatbot via reverse-engineered SockJS/STOMP protocol.",
},
"veoaifree-web": {
id: "veoaifree-web",
alias: "veo-free",
name: "Veo AI Free",
icon: "videocam",
color: "#8B5CF6",
textIcon: "VF",
website: "https://veoaifree.com",
noAuth: true,
hasFree: true,
serviceKinds: ["video"],
freeNote: "Free video generation — VEO 3.1, Seedance. 6 requests/hour.",
authHint: "No auth required. Rate limited to 6 requests/hour per IP.",
},
mimocode: {
id: "mimocode",
alias: "mcode",
name: "MiMoCode (Free)",
icon: "devices",
color: "#FF6B35",
textIcon: "MC",
website: "https://mimo.mi.com",
noAuth: true,
hasFree: true,
serviceKinds: ["llm"],
freeNote:
"Free — Xiaomi MiMo models via bootstrap JWT auth. No API key required. Supports streaming.",
authHint:
"No API key required. The executor auto-generates JWT tokens via device fingerprint bootstrap.",
notice: {
text: "MiMoCode uses Xiaomi's public free AI endpoint with bootstrap-based JWT authentication. No signup needed. Rate limits apply.",
},
},
};
export const FREE_APIKEY_PROVIDER_IDS = new Set(["qoder", "mimocode", "opencode"]);
export function supportsApiKeyOnFreeProvider(providerId: unknown): boolean {
return typeof providerId === "string" && FREE_APIKEY_PROVIDER_IDS.has(providerId);
}
// OAuth Providers
export const OAUTH_PROVIDERS = {
qoder: {
id: "qoder",
alias: "if",
name: "Qoder AI",
icon: "water_drop",
color: "#6366F1",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
hasFree: true,
},
qwen: {
id: "qwen",
alias: "qw",
name: "Qwen Code",
icon: "psychology",
color: "#10B981",
subscriptionRisk: true,
riskNoticeVariant: "deprecated",
deprecated: true,
deprecationReason:
"Qwen OAuth free tier was discontinued on 2026-04-15. Use 'bailian-coding-plan', 'alibaba', 'alibaba-cn', or 'openrouter' provider with API key instead.",
},
"gemini-cli": {
id: "gemini-cli",
alias: "gemini-cli",
name: "Gemini CLI",
icon: "terminal",
color: "#4285F4",
subscriptionRisk: true,
riskNoticeVariant: "deprecated",
hasFree: true,
authHint:
"Uses Gemini CLI OAuth / Cloud Code credentials. Pro models require an eligible Google account or paid plan.",
},
agy: {
id: "agy",
alias: "agy",
name: "Antigravity CLI",
icon: "terminal",
color: "#F59E0B",
textIcon: "AGY",
website: "https://antigravity.google",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
hasFree: true,
authHint:
"Import your Antigravity CLI (`agy`) login (paste/upload its token file), auto-detect a local CLI login, or sign in with Google. Shares the Antigravity backend (incl. Claude models).",
},
kiro: {
id: "kiro",
alias: "kr",
name: "Kiro AI",
icon: "psychology_alt",
color: "#FF6B35",
subscriptionRisk: true,
riskNoticeVariant: "deprecated",
hasFree: true,
freeNote:
"Free tier: 50 credits/month (~25K100K tokens). ⚠️ Kiro ToS prohibits third-party proxy/harness use.",
},
"amazon-q": {
id: "amazon-q",
alias: "aq",
name: "Amazon Q",
icon: "cloud",
color: "#FF9900",
textIcon: "AQ",
website: "https://aws.amazon.com/q/developer/",
hasFree: true,
authHint:
"Uses the same AWS Builder ID or imported refresh-token flow as Kiro, but keeps Amazon Q connections separate.",
},
claude: {
id: "claude",
alias: "cc",
name: "Claude Code",
icon: "smart_toy",
color: "#D97757",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
antigravity: {
id: "antigravity",
alias: undefined,
name: "Antigravity",
icon: "rocket_launch",
color: "#F59E0B",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
codex: {
id: "codex",
alias: "cx",
name: "OpenAI Codex",
icon: "code",
color: "#3B82F6",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
github: { id: "github", alias: "gh", name: "GitHub Copilot", icon: "code", color: "#333333" },
"gitlab-duo": {
id: "gitlab-duo",
alias: "gitlab-duo",
name: "GitLab Duo",
icon: "hub",
color: "#FC6D26",
textIcon: "GL",
website: "https://docs.gitlab.com/user/duo_agent_platform/code_suggestions/",
authHint:
"OAuth application with ai_features + read_user scopes. Configure GITLAB_DUO_OAUTH_CLIENT_ID and optionally GITLAB_DUO_OAUTH_CLIENT_SECRET on this OmniRoute instance.",
},
cursor: {
id: "cursor",
alias: "cu",
name: "Cursor IDE",
icon: "edit_note",
color: "#00D4AA",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
zed: {
id: "zed",
alias: "zd",
name: "Zed IDE",
icon: "code",
color: "#084CCF",
textIcon: "ZD",
website: "https://zed.dev",
authHint:
"Zed stores LLM provider credentials (OpenAI, Anthropic, Google, Mistral, xAI) in the OS keychain. Use the Import button below to discover and import them automatically.",
},
trae: {
id: "trae",
alias: "tr",
name: "Trae",
icon: "edit_square",
color: "#FF7849",
textIcon: "TR",
website: "https://trae.ai",
authHint:
"Trae is an AI-native IDE by ByteDance (SOLO remote agent). Authorize via trae.ai in the popup, or sign in at solo.trae.ai and paste the Cloud-IDE-JWT (sent as 'Authorization: Cloud-IDE-JWT <token>', ~14-day lifetime) as the access token; web_id/biz_user_id/user_unique_id/scope/tenant/region propagate via providerSpecificData. No headless refresh for pasted tokens — re-paste on expiry.",
},
"kimi-coding": {
id: "kimi-coding",
alias: "kmc",
name: "Kimi Coding",
icon: "psychology",
color: "#1E40AF",
textIcon: "KC",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
kilocode: {
id: "kilocode",
alias: "kc",
name: "Kilo Code",
icon: "code",
color: "#FF6B35",
textIcon: "KC",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
cline: {
id: "cline",
alias: "cl",
name: "Cline",
icon: "smart_toy",
color: "#5B9BD5",
textIcon: "CL",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
},
windsurf: {
id: "windsurf",
alias: "ws",
name: "Windsurf (Devin CLI)",
icon: "air",
color: "#00C5A0",
textIcon: "WS",
subscriptionRisk: true,
riskNoticeVariant: "oauth",
authHint:
"Sign in at windsurf.com to get your token. Visit windsurf.com/show-auth-token after logging in and paste it here, or use the device-code login flow.",
website: "https://windsurf.com",
},
"devin-cli": {
id: "devin-cli",
alias: "dv",
name: "Devin CLI (Official)",
icon: "terminal",
color: "#6366F1",
textIcon: "DV",
authHint:
"Requires the Devin CLI binary. Run `devin auth login` to authenticate, or provide your WINDSURF_API_KEY. Install: https://cli.devin.ai",
website: "https://cli.devin.ai",
},
};
// Web / Cookie Providers
export const WEB_COOKIE_PROVIDERS = {
"chatgpt-web": {
id: "chatgpt-web",
alias: "cgpt-web",
name: "ChatGPT Web (Plus/Pro)",
icon: "auto_awesome",
color: "#10A37F",
textIcon: "CG",
website: "https://chatgpt.com",
authHint: "Paste your __Secure-next-auth.session-token cookie value from chatgpt.com",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"grok-web": {
id: "grok-web",
alias: "gw",
name: "Grok Web (Subscription)",
icon: "auto_awesome",
color: "#1DA1F2",
textIcon: "GW",
website: "https://grok.com",
authHint:
"Paste the full grok.com cookie line from DevTools → Application → Cookies. Include both `sso` and `sso-rw` (e.g. `sso=...; sso-rw=...`) — Grok's anti-bot rejects `sso` on its own.",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"gemini-web": {
id: "gemini-web",
alias: "gweb",
name: "Gemini Web (Free)",
icon: "auto_awesome",
color: "#4285F4",
textIcon: "GWeb",
website: "https://gemini.google.com",
authHint:
"Paste your __Secure-1PSID cookie value from gemini.google.com. Optionally add __Secure-1PSIDTS separated by semicolon.",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"perplexity-web": {
id: "perplexity-web",
alias: "pplx-web",
name: "Perplexity Web (Pro/Max)",
icon: "search",
color: "#20808D",
textIcon: "PW",
website: "https://www.perplexity.ai",
authHint: "Paste your __Secure-next-auth.session-token cookie value from perplexity.ai",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"blackbox-web": {
id: "blackbox-web",
alias: "bb-web",
name: "Blackbox Web (Subscription)",
icon: "view_in_ar",
color: "#1A1A2E",
textIcon: "BW",
website: "https://app.blackbox.ai",
authHint:
"Paste your __Secure-authjs.session-token value or full cookie header from app.blackbox.ai",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"muse-spark-web": {
id: "muse-spark-web",
alias: "ms-web",
name: "Muse Spark Web (Meta AI)",
icon: "auto_awesome",
color: "#0866FF",
textIcon: "MS",
website: "https://www.meta.ai",
hasFree: true,
freeNote: "Free with login — Meta AI platform with Llama models.",
authHint: "Paste your abra_sess value or full cookie header from meta.ai",
},
"claude-web": {
id: "claude-web",
alias: "cw",
name: "Claude Web",
icon: "auto_awesome",
color: "#D97757",
textIcon: "CW",
website: "https://claude.ai",
authHint: "Paste your session cookie from claude.ai",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"deepseek-web": {
id: "deepseek-web",
alias: "ds-web",
name: "DeepSeek Web",
icon: "auto_awesome",
color: "#4D6BFE",
textIcon: "DS",
website: "https://chat.deepseek.com",
authHint:
"Paste your userToken from chat.deepseek.com — DevTools → Application → Local Storage → userToken",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"copilot-web": {
id: "copilot-web",
alias: "copilot",
name: "Microsoft Copilot Web",
icon: "auto_awesome",
color: "#0078D4",
textIcon: "CP",
website: "https://copilot.microsoft.com",
authHint:
"Paste your access_token from copilot.microsoft.com (or export a .har file from DevTools while logged in)",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"t3-web": {
id: "t3-web",
alias: "t3chat",
name: "t3.chat (Pro/Free)",
icon: "auto_awesome",
color: "#7C3AED",
textIcon: "T3",
website: "https://t3.chat",
hasFree: true,
freeNote: "Free tier gives limited model access. Pro ($8/month) unlocks 50+ models.",
authHint:
"Open t3.chat in your browser, log in, then open DevTools → Application → Local Storage → https://t3.chat. " +
"Copy the value of 'convex-session-id'. Also open DevTools → Network, copy the Cookie header from any request. " +
"Paste both values here. See provider setup docs for a step-by-step guide.",
},
"inner-ai": {
id: "inner-ai",
alias: "in-ai",
name: "Inner.ai (Subscription)",
icon: "auto_awesome",
color: "#1A56DB",
textIcon: "IA",
website: "https://app.innerai.com",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
authHint:
"Paste your token cookie and email separated by a space: open DevTools → Application → Cookies → .innerai.com, copy the token value, then append a space and your Inner.ai login email. Example: eyJhbG... user@example.com",
},
"adapta-web": {
id: "adapta-web",
alias: "adp-web",
name: "Adapta.org (Adapta One Web)",
icon: "auto_awesome",
color: "#6E3AD3",
textIcon: "AW",
website: "https://agent.adapta.one",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
authHint:
"Paste your __client cookie value from .clerk.agent.adapta.one (DevTools → Application → Cookies)",
},
lmarena: {
id: "lmarena",
alias: "lma",
name: "LMArena (Free)",
icon: "auto_awesome",
color: "#FF6B6B",
textIcon: "LMA",
website: "https://lmarena.ai",
hasFree: true,
freeNote: "Free model comparison platform — 40+ models (GPT, Claude, Gemini, Llama). No subscription required.",
authHint:
"Paste your session cookie from lmarena.ai (DevTools → Application → Cookies). Optional — works with free tier for basic comparisons.",
riskNoticeVariant: "webCookie",
},
huggingchat: {
id: "huggingchat",
// "hc" belongs to the hackclub provider; huggingchat uses its own id as alias.
alias: "huggingchat",
name: "HuggingChat (Free)",
icon: "auto_awesome",
color: "#FFD21E",
textIcon: "HC",
website: "https://huggingface.co/chat",
hasFree: true,
freeNote: "Free LLM chat — no subscription required. Rate limits apply.",
authHint:
"Paste your hf-chat cookie value from huggingface.co/chat (DevTools → Application → Cookies → hf-chat). Optional — works without auth for basic use.",
riskNoticeVariant: "webCookie",
},
phind: {
id: "phind",
alias: "ph",
name: "Phind (Free)",
icon: "auto_awesome",
color: "#000000",
textIcon: "PH",
website: "https://www.phind.com",
hasFree: true,
freeNote: "Free dev-focused AI chat with code search. Rate limits apply.",
authHint:
"Paste your session cookie from phind.com (DevTools → Application → Cookies). Optional — works with free tier.",
riskNoticeVariant: "webCookie",
},
"poe-web": {
id: "poe-web",
alias: "poe",
name: "Poe Web (Subscription)",
icon: "auto_awesome",
color: "#6C3AED",
textIcon: "PW",
website: "https://poe.com",
authHint: "Paste your p-b cookie value from poe.com (DevTools → Application → Cookies → p-b)",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"venice-web": {
id: "venice-web",
alias: "ven",
name: "Venice Web (Privacy)",
icon: "auto_awesome",
color: "#22C55E",
textIcon: "VW",
website: "https://venice.ai",
authHint: "Paste your session cookie from venice.ai (DevTools → Application → Cookies)",
riskNoticeVariant: "webCookie",
},
"v0-vercel-web": {
id: "v0-vercel-web",
alias: "v0",
name: "v0 Vercel Web (Code Gen)",
icon: "auto_awesome",
color: "#000000",
textIcon: "V0",
website: "https://v0.dev",
authHint: "Paste your session cookie from v0.dev (DevTools → Application → Cookies)",
riskNoticeVariant: "webCookie",
},
"kimi-web": {
id: "kimi-web",
// Primary "kimi" provider keeps the short alias; web variant uses its own id.
alias: "kimi-web",
name: "Kimi Web (Moonshot AI)",
icon: "auto_awesome",
color: "#2563EB",
textIcon: "KW",
website: "https://kimi.moonshot.cn",
authHint: "Paste your session cookie from kimi.moonshot.cn (DevTools → Application → Cookies)",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"doubao-web": {
id: "doubao-web",
alias: "db",
name: "Doubao Web (ByteDance)",
icon: "auto_awesome",
color: "#3B82F6",
textIcon: "DW",
website: "https://www.doubao.com",
authHint: "Paste your session cookie from doubao.com (DevTools → Application → Cookies)",
subscriptionRisk: true,
riskNoticeVariant: "webCookie",
},
"qwen-web": {
id: "qwen-web",
// Primary "qwen" provider keeps the short alias; web variant uses its own id.
alias: "qwen-web",
name: "Qwen Web (Free)",
icon: "auto_awesome",
color: "#10B981",
textIcon: "QW",
website: "https://chat.qwen.ai",
hasFree: true,
freeNote: "Free — Qwen models via chat.qwen.ai with login token. No subscription required.",
authHint:
"Open chat.qwen.ai, log in, then open DevTools → Application → Local Storage → " +
'copy the "token" value (or use tongyi_sso_ticket cookie as Bearer token).',
},
"gemini-business": {
id: "gemini-business",
alias: "gembiz",
name: "Gemini Business (Enterprise)",
icon: "business_center",
color: "#4285F4",
textIcon: "GB",
website: "https://business.gemini.google",
hasFree: true,
freeNote:
"Free for Google Workspace enterprise accounts — enterprise Gemini models (Pro, Flash, image, video) via direct StreamGenerate HTTP API. No subscription required, just enterprise SSO.",
authHint:
"From your enterprise account: open business.gemini.google/home/cid/{your-cid}, then copy __Secure-1PSID and __Secure-1PSIDTS cookies from DevTools → Application → Cookies. Paste as a cookie header below.",
},
};
// API Key Providers
export const APIKEY_PROVIDERS = {
agentrouter: {
id: "agentrouter",
alias: "agentrouter",
name: "AgentRouter",
icon: "router",
color: "#10B981",
textIcon: "AR",
passthroughModels: true,
website: "https://agentrouter.org",
hasFree: true,
freeNote: "$200 free credits on signup - multi-model routing gateway",
apiHint: "Get $200 free credits at https://agentrouter.org/register — no credit card required.",
},
"command-code": {
id: "command-code",
alias: "cmd",
name: "Command Code",
icon: "terminal",
color: "#111827",
textIcon: "CC",
website: "https://commandcode.ai/",
authHint:
"Use a Command Code API key. Requests are sent to Command Code's /alpha/generate endpoint.",
apiHint: "Create or copy an API key from Command Code, then paste it here as a Bearer token.",
},
openrouter: {
id: "openrouter",
alias: "openrouter",
name: "OpenRouter",
icon: "router",
color: "#F97316",
textIcon: "OR",
passthroughModels: true,
website: "https://openrouter.ai",
hasFree: true,
freeNote: "Free models at $0/token with :free suffix - 20 RPM / 200 RPD",
},
"api-airforce": {
id: "api-airforce",
alias: "af",
name: "Api.airforce",
icon: "flight",
color: "#1E3A5F",
textIcon: "AF",
website: "https://api.airforce",
hasFree: true,
freeNote:
"55 free tier models including Grok-3, Claude 3.7, Qwen3, Kimi-K2, Gemini 2.5 Flash, DeepSeek-V3",
apiHint:
"Get your API key from https://panel.api.airforce — OpenAI-compatible endpoint at https://api.airforce/v1",
},
qianfan: {
id: "qianfan",
alias: "qianfan",
name: "Baidu Qianfan",
icon: "cloud",
color: "#2468F2",
textIcon: "BD",
website: "https://cloud.baidu.com/product/wenxinworkshop",
apiHint:
"Use a Qianfan API key from Baidu AI Cloud. The default endpoint is OpenAI-compatible v2.",
},
glm: {
id: "glm",
alias: "glm",
name: "GLM Coding",
icon: "code",
color: "#2563EB",
textIcon: "GL",
website: "https://z.ai/subscribe",
},
"glm-cn": {
id: "glm-cn",
alias: "glmcn",
name: "GLM Coding (China)",
icon: "code",
color: "#DC2626",
textIcon: "GC",
website: "https://open.bigmodel.cn",
},
glmt: {
id: "glmt",
alias: "glmt",
name: "GLM Thinking",
icon: "psychology",
color: "#1D4ED8",
textIcon: "GT",
website: "https://open.bigmodel.cn",
apiHint: "Preset GLM profile with higher token budget, thinking enabled, and longer timeout.",
},
"bailian-coding-plan": {
id: "bailian-coding-plan",
alias: "bcp",
name: "Alibaba Coding Plan",
icon: "code",
color: "#FF6A00",
textIcon: "BCP",
website: "https://www.alibabacloud.com/help/en/model-studio/coding-plan",
},
kimi: {
id: "kimi",
alias: "kimi",
name: "Kimi",
icon: "psychology",
color: "#1E3A8A",
textIcon: "KM",
website: "https://platform.moonshot.ai",
},
"kimi-coding-apikey": {
id: "kimi-coding-apikey",
alias: "kmca",
name: "Kimi Coding (API Key)",
icon: "psychology",
color: "#1E40AF",
textIcon: "KC",
website: "https://www.kimi.com/code",
},
minimax: {
id: "minimax",
alias: "minimax",
name: "Minimax Coding",
icon: "memory",
color: "#7C3AED",
textIcon: "MM",
website: "https://www.minimax.io",
},
"minimax-cn": {
id: "minimax-cn",
alias: "minimax-cn",
name: "Minimax (China)",
icon: "memory",
color: "#DC2626",
textIcon: "MC",
website: "https://www.minimaxi.com",
},
crof: {
id: "crof",
alias: "crof",
name: "CrofAI",
icon: "auto_awesome",
color: "#0EA5E9",
textIcon: "CR",
website: "https://crof.ai",
},
openai: {
id: "openai",
alias: "openai",
name: "OpenAI",
icon: "auto_awesome",
color: "#10A37F",
textIcon: "OA",
website: "https://platform.openai.com",
},
"azure-openai": {
id: "azure-openai",
alias: "azure",
name: "Azure OpenAI",
icon: "cloud",
color: "#0078D4",
textIcon: "AZ",
website: "https://azure.microsoft.com/products/ai-services/openai-service",
authHint:
"Use your Azure OpenAI API key. Base URL should be your resource endpoint, for example https://my-resource.openai.azure.com.",
passthroughModels: true,
},
"azure-ai": {
id: "azure-ai",
alias: "azure-ai",
name: "Azure AI Foundry",
icon: "cloud",
color: "#2563EB",
textIcon: "AF",
website: "https://learn.microsoft.com/azure/ai-foundry",
authHint:
"Use your Azure AI Foundry key. Base URL can be https://<resource>.services.ai.azure.com/openai/v1/ or https://<resource>.openai.azure.com/openai/v1/.",
apiHint:
"Foundry uses the OpenAI v1 surface with deployment names as models. OmniRoute normalizes root resource URLs to the v1 chat and /models endpoints.",
passthroughModels: true,
},
bedrock: {
id: "bedrock",
alias: "bedrock",
name: "Amazon Bedrock",
icon: "cloud",
color: "#FF9900",
textIcon: "BR",
website: "https://aws.amazon.com/bedrock",
authHint:
"Use your Amazon Bedrock API key and configure the AWS region where your models are enabled (for example eu-west-2). OmniRoute calls Bedrock's native Converse API directly.",
apiHint:
"Native Bedrock integration: model discovery uses Bedrock foundation models and inference profiles, while chat uses the regional Bedrock Runtime Converse/ConverseStream APIs.",
passthroughModels: true,
},
watsonx: {
id: "watsonx",
alias: "watsonx",
name: "IBM watsonx.ai Gateway",
icon: "hub",
color: "#0F62FE",
textIcon: "WX",
website: "https://www.ibm.com/products/watsonx-ai",
authHint:
"Use your watsonx bearer token. Base URL can be https://<region>.ml.cloud.ibm.com/ml/gateway/v1/ or a self-managed /ml/gateway/v1 endpoint.",
apiHint:
"The watsonx model gateway exposes OpenAI-compatible /chat/completions and /models under /ml/gateway/v1.",
passthroughModels: true,
},
oci: {
id: "oci",
alias: "oci",
name: "OCI Generative AI",
icon: "cloud",
color: "#C74634",
textIcon: "OCI",
website: "https://www.oracle.com/artificial-intelligence/generative-ai",
authHint:
"Use your OCI Generative AI API key or IAM bearer token. Base URL can be https://inference.generativeai.<region>.oci.oraclecloud.com/openai/v1/.",
apiHint:
"OCI exposes OpenAI-compatible chat and responses endpoints. Project ID is optional in OmniRoute but may be required for Responses and agentic workflows.",
passthroughModels: true,
},
sap: {
id: "sap",
alias: "sap",
name: "SAP Generative AI Hub",
icon: "business",
color: "#0FAAFF",
textIcon: "SAP",
website:
"https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/generative-ai-hub-in-sap-ai-core",
authHint:
"Use your SAP AI Core bearer token. Base URL can be your AI_API_URL root or a deploymentUrl from Generative AI Hub.",
apiHint:
"Model discovery uses /v2/lm/scenarios/foundation-models/models on AI_API_URL. Chat requests use deploymentUrl/chat/completions and require AI-Resource-Group.",
passthroughModels: true,
},
modal: {
id: "modal",
alias: "mdl",
name: "Modal",
icon: "cloud_queue",
color: "#7C3AED",
textIcon: "MDL",
website: "https://modal.com/docs",
authHint:
"Use the bearer token that protects your Modal deployment, if enabled. Base URL should point to your OpenAI-compatible Modal app, for example https://<workspace>--<app>.modal.run/v1.",
apiHint:
"Modal commonly serves user-hosted OpenAI-compatible apps on /v1. OmniRoute will probe /v1/models and route chat traffic to /v1/chat/completions.",
hasFree: true,
freeNote: "$30/month free credits for new accounts",
passthroughModels: true,
},
reka: {
id: "reka",
alias: "reka",
name: "Reka",
icon: "auto_awesome",
color: "#111827",
textIcon: "RK",
website: "https://docs.reka.ai/chat/overview",
authHint:
"Use your Reka API key. OmniRoute supports the OpenAI-compatible base URL https://api.reka.ai/v1 and sends both Authorization and X-Api-Key headers for compatibility.",
apiHint:
"Reka Chat is OpenAI-compatible on /v1. OmniRoute probes /v1/models and routes chat traffic to /v1/chat/completions.",
hasFree: true,
freeNote: "$10/month recurring free API credits",
},
nlpcloud: {
id: "nlpcloud",
alias: "nlpc",
name: "NLP Cloud",
icon: "psychology",
color: "#2196F3",
textIcon: "NLPC",
website: "https://docs.nlpcloud.com",
authHint:
"Use your NLP Cloud API key in Authorization: Token <key>. OmniRoute targets the chatbot endpoint on https://api.nlpcloud.io/v1/gpu/<model>/chatbot by default.",
apiHint:
"NLP Cloud uses a proprietary chatbot API instead of OpenAI chat/completions. OmniRoute adapts OpenAI messages to input/context/history and exposes a local catalog of supported chatbot models.",
hasFree: true,
freeNote: "Trial credits for new accounts",
},
runwayml: {
id: "runwayml",
alias: "runway",
name: "Runway",
icon: "movie",
color: "#111827",
textIcon: "RW",
website: "https://docs.dev.runwayml.com",
authHint:
"Use your Runway API key in Authorization: Bearer <key>. OmniRoute targets the current Runway API at https://api.dev.runwayml.com/v1 and sends the required X-Runway-Version header automatically.",
apiHint:
"Runway video generation is task-based. OmniRoute submits text-to-video or image-to-video jobs, polls /v1/tasks/{id}, and normalizes the finished video outputs back into the OpenAI-like /v1/videos/generations response.",
},
anthropic: {
id: "anthropic",
alias: "anthropic",
name: "Anthropic",
icon: "smart_toy",
color: "#D97757",
textIcon: "AN",
website: "https://platform.claude.com",
},
gemini: {
id: "gemini",
alias: "gemini",
name: "Gemini (Google AI Studio)",
icon: "diamond",
color: "#4285F4",
textIcon: "GE",
website: "https://aistudio.google.com",
hasFree: true,
freeNote:
"Free forever: 1,500 req/day for Gemini 2.5 Flash — no credit card, get key at aistudio.google.com",
},
deepseek: {
id: "deepseek",
alias: "ds",
name: "DeepSeek",
icon: "bolt",
color: "#4D6BFE",
textIcon: "DS",
website: "https://platform.deepseek.com",
hasFree: true,
freeNote: "5M free tokens on signup - no credit card required",
},
groq: {
id: "groq",
alias: "groq",
name: "Groq",
icon: "speed",
color: "#F55036",
textIcon: "GQ",
website: "https://groq.com",
hasFree: true,
freeNote: "Free tier: 30 RPM / 14.4K RPD — no credit card",
},
blackbox: {
id: "blackbox",
alias: "bb",
name: "Blackbox AI",
icon: "view_in_ar",
color: "#1A1A2E",
textIcon: "BB",
website: "https://blackbox.ai",
hasFree: true,
freeNote: "Free tier: unlimited basic chat plus Minimax-M2.5, no credit card required",
},
bazaarlink: {
id: "bazaarlink",
alias: "bzl",
name: "BazaarLink",
icon: "storefront",
color: "#6366F1",
textIcon: "BZ",
website: "https://bazaarlink.ai",
hasFree: true,
freeNote: "Free tier with auto:free routing — zero-cost inference, no credit card required",
apiHint:
"Get free API key at https://bazaarlink.ai — use model 'auto:free' for zero-cost inference. OpenAI-compatible.",
},
xai: {
id: "xai",
alias: "xai",
name: "xAI (Grok)",
icon: "auto_awesome",
color: "#1DA1F2",
textIcon: "XA",
website: "https://x.ai",
},
mistral: {
id: "mistral",
alias: "mistral",
name: "Mistral",
icon: "air",
color: "#FF7000",
textIcon: "MI",
website: "https://mistral.ai",
hasFree: true,
freeNote: "Free Experiment tier: rate-limited access to all models, no credit card required",
},
perplexity: {
id: "perplexity",
alias: "pplx",
name: "Perplexity",
icon: "search",
color: "#20808D",
textIcon: "PP",
website: "https://www.perplexity.ai",
},
together: {
id: "together",
alias: "together",
name: "Together AI",
icon: "group_work",
color: "#0F6FFF",
textIcon: "TG",
website: "https://www.together.ai",
hasFree: true,
freeNote:
"$25 signup credits + 3 permanently free models: Llama 3.3 70B, Vision, DeepSeek-R1 distill",
},
fireworks: {
id: "fireworks",
alias: "fireworks",
name: "Fireworks AI",
icon: "local_fire_department",
color: "#7B2EF2",
textIcon: "FW",
website: "https://fireworks.ai",
hasFree: true,
freeNote: "$1 free starter credits on signup for API testing",
},
cerebras: {
id: "cerebras",
alias: "cerebras",
name: "Cerebras",
icon: "memory",
color: "#FF4F00",
textIcon: "CB",
website: "https://inference.cerebras.ai",
hasFree: true,
freeNote: "Free Trial: 1M tokens/day, 30K TPM, 5 RPM — no credit card.",
},
cohere: {
id: "cohere",
alias: "cohere",
name: "Cohere",
icon: "hub",
color: "#39594D",
textIcon: "CO",
website: "https://cohere.com",
hasFree: true,
freeNote: "Free Trial: 1,000 API calls/month for testing, no credit card required",
},
nvidia: {
id: "nvidia",
alias: "nvidia",
name: "NVIDIA NIM",
icon: "developer_board",
color: "#76B900",
textIcon: "NV",
website: "https://build.nvidia.com",
hasFree: true,
freeNote: "Free dev access: ~40 RPM, 70+ models (Kimi K2.5, GLM 4.7, DeepSeek V3.2...)",
},
nebius: {
id: "nebius",
alias: "nebius",
name: "Nebius AI",
icon: "cloud",
color: "#6C5CE7",
textIcon: "NB",
website: "https://nebius.com",
hasFree: true,
freeNote: "~$1 trial credits on signup for API testing",
},
siliconflow: {
id: "siliconflow",
alias: "siliconflow",
name: "SiliconFlow",
icon: "cloud_queue",
color: "#5B6EF5",
textIcon: "SF",
website: "https://cloud.siliconflow.com",
hasFree: true,
freeNote: "$1 free credits plus permanently free models after identity verification",
},
hyperbolic: {
id: "hyperbolic",
alias: "hyp",
name: "Hyperbolic",
icon: "bolt",
color: "#00D4FF",
textIcon: "HY",
website: "https://hyperbolic.xyz",
hasFree: true,
freeNote: "$1-5 trial credits on signup for serverless inference",
},
kie: {
id: "kie",
alias: "kie",
name: "KIE.AI",
icon: "hub",
color: "#2563EB",
textIcon: "KIE",
website: "https://kie.ai",
},
"ollama-cloud": {
id: "ollama-cloud",
alias: "ollamacloud",
name: "Ollama Cloud",
icon: "cloud",
color: "#58A6FF",
textIcon: "OC",
website: "https://ollama.com/settings/api-keys",
hasFree: true,
},
huggingface: {
id: "huggingface",
alias: "hf",
name: "HuggingFace",
icon: "face",
color: "#FFD21E",
textIcon: "HF",
website: "https://huggingface.co",
hasFree: true,
freeNote: "Free Inference API for thousands of models (Whisper, VITS, SDXL…)",
},
synthetic: {
id: "synthetic",
alias: "synthetic",
name: "Synthetic",
icon: "verified_user",
color: "#6366F1",
textIcon: "SY",
website: "https://synthetic.new",
passthroughModels: true,
},
"kilo-gateway": {
id: "kilo-gateway",
alias: "kg",
name: "Kilo Gateway",
icon: "hub",
color: "#617A91",
textIcon: "KG",
website: "https://kilo.ai",
passthroughModels: true,
},
vertex: {
id: "vertex",
alias: "vertex",
name: "Vertex AI",
icon: "cloud",
color: "#4285F4",
textIcon: "VA",
website: "https://cloud.google.com/vertex-ai",
hasFree: true,
authHint: "Provide Service Account JSON or OAuth access_token",
},
"vertex-partner": {
id: "vertex-partner",
alias: "vp",
name: "Vertex AI Partners",
icon: "cloud",
color: "#34A853",
textIcon: "VP",
website: "https://cloud.google.com/vertex-ai",
authHint: "Provide the same Service Account JSON used for Vertex AI partner models.",
},
zai: {
id: "zai",
alias: "zai",
name: "Z.AI",
icon: "psychology",
color: "#2563EB",
textIcon: "ZA",
website: "https://open.bigmodel.cn",
apiHint: "API key from https://open.bigmodel.cn/usercenter/apikeys",
},
"opencode-zen": {
id: "opencode-zen",
alias: "opencode-zen",
name: "OpenCode Zen",
icon: "opencode",
color: "#6366f1",
website: "https://opencode.ai/zen",
anonymousFallback: true,
},
"opencode-go": {
id: "opencode-go",
alias: "opencode-go",
name: "OpenCode Go",
icon: "opencode",
color: "#6366f1",
website: "https://opencode.ai/go",
anonymousFallback: true,
},
alibaba: {
id: "alibaba",
alias: "ali",
name: "Alibaba",
icon: "cloud_queue",
color: "#FF6600",
textIcon: "AL",
website: "https://dashscope-intl.aliyuncs.com",
hasFree: false,
},
"alibaba-cn": {
id: "alibaba-cn",
alias: "ali-cn",
name: "Alibaba (China)",
icon: "cloud_queue",
color: "#FF6600",
textIcon: "AL",
website: "https://dashscope.aliyuncs.com",
hasFree: false,
},
longcat: {
id: "longcat",
alias: "lc",
name: "LongCat AI",
icon: "auto_awesome",
color: "#FF6B9D",
textIcon: "LC",
website: "https://longcat.chat/platform/docs",
hasFree: true,
freeNote:
"Free: 5M tokens/day on LongCat-2.0-Preview (Flash models retired 2026-05-29); up to 120M/day via feedback.",
},
pollinations: {
id: "pollinations",
alias: "pol",
name: "Pollinations AI",
icon: "local_florist",
color: "#4CAF50",
textIcon: "PO",
website: "https://pollinations.ai",
hasFree: true,
anonymousFallback: true,
freeNote:
"No API key required for free public endpoint. Optional Spore tier: ~0.01 pollen/hour.",
},
puter: {
id: "puter",
alias: "pu",
name: "Puter AI",
icon: "cloud_circle",
color: "#6366F1",
textIcon: "PU",
website: "https://puter.com",
hasFree: true,
freeNote:
"500+ models (GPT-5, Claude Opus 4, Gemini 3 Pro, Grok 4, DeepSeek V3...) — Users pay via free Puter account",
passthroughModels: true,
authHint: "Get token at puter.com/dashboard → Copy Auth Token",
},
uncloseai: {
id: "uncloseai",
alias: "unc",
name: "UncloseAI",
icon: "auto_awesome",
color: "#8B5CF6",
textIcon: "UN",
website: "https://uncloseai.com",
hasFree: true,
freeNote: "Free forever — no signup, no credit card. OpenAI-compatible endpoints.",
passthroughModels: true,
authHint: "No auth required. API accepts any non-empty string as key for identification.",
},
hackclub: {
id: "hackclub",
alias: "hc",
name: "Hackclub AI",
icon: "auto_awesome",
color: "#FF6B00",
textIcon: "HC",
website: "https://ai.hackclub.com",
hasFree: true,
freeNote: "Free AI for Hack Club members — 30+ models, no credit card.",
passthroughModels: true,
authHint: "Sign in with your Hack Club account at ai.hackclub.com.",
},
"github-models": {
id: "github-models",
alias: "ghm",
name: "GitHub Models",
icon: "code",
color: "#238636",
textIcon: "GH",
website: "https://github.com/marketplace/models",
hasFree: true,
freeNote: "Free GPT-5, o-series, DeepSeek-R1, Llama 4, Grok 3 — GitHub account only.",
authHint: "Create a GitHub PAT with 'models: read' scope at github.com/settings/tokens",
},
haiper: {
id: "haiper",
alias: "hp",
name: "Haiper",
icon: "videocam",
color: "#6366F1",
textIcon: "HP",
website: "https://haiper.ai",
authHint: "Get API key at haiper.ai/haiper-api",
},
leonardo: {
id: "leonardo",
alias: "leo",
name: "Leonardo AI",
icon: "palette",
color: "#8B5CF6",
textIcon: "LE",
website: "https://leonardo.ai",
authHint: "Get API key at leonardo.ai/developer",
},
ideogram: {
id: "ideogram",
alias: "ideo",
name: "Ideogram",
icon: "image",
color: "#EC4899",
textIcon: "ID",
website: "https://ideogram.ai",
authHint: "Get API key at ideogram.ai/docs/api",
},
suno: {
id: "suno",
alias: "suno",
name: "Suno",
icon: "music_note",
color: "#F59E0B",
textIcon: "SU",
website: "https://suno.ai",
authHint: "Paste session cookie from suno.ai (Clerk auth)",
},
udio: {
id: "udio",
alias: "udio",
name: "Udio",
icon: "music_note",
color: "#10B981",
textIcon: "UD",
website: "https://udio.com",
authHint: "Paste session cookie from udio.com (Supabase auth)",
},
"cloudflare-ai": {
id: "cloudflare-ai",
alias: "cf",
name: "Cloudflare Workers AI",
icon: "cloud",
color: "#F48120",
textIcon: "CF",
website: "https://developers.cloudflare.com/workers-ai",
hasFree: true,
freeNote:
"Free 10K Neurons/day: ~150 LLM responses or 500s Whisper audio — edge inference globally",
authHint: "Requires API Token AND Account ID (found at dash.cloudflare.com)",
},
scaleway: {
id: "scaleway",
alias: "scw",
name: "Scaleway AI",
icon: "cloud",
color: "#4F0599",
textIcon: "SCW",
website: "https://www.scaleway.com/en/ai/generative-apis",
hasFree: true,
freeNote: "1M free tokens for new accounts — EU/GDPR compliant (Paris), Qwen3 235B & Llama 70B",
},
deepinfra: {
id: "deepinfra",
alias: "deepinfra",
name: "DeepInfra",
icon: "hub",
color: "#2563EB",
textIcon: "DI",
website: "https://deepinfra.com",
hasFree: true,
freeNote: "Free signup credits for API testing and model exploration",
},
"vercel-ai-gateway": {
id: "vercel-ai-gateway",
alias: "vag",
name: "Vercel AI Gateway",
icon: "route",
color: "#111827",
textIcon: "VAI",
website: "https://vercel.com/docs/ai-gateway",
},
"lambda-ai": {
id: "lambda-ai",
alias: "lambda",
name: "Lambda AI",
icon: "bolt",
color: "#7C3AED",
textIcon: "LA",
website: "https://lambda.ai",
},
sambanova: {
id: "sambanova",
alias: "samba",
name: "SambaNova",
icon: "memory",
color: "#DC2626",
textIcon: "SN",
website: "https://sambanova.ai",
hasFree: true,
freeNote: "$5 free credits on signup (30-day validity), no credit card required",
},
nscale: {
id: "nscale",
alias: "nscale",
name: "nScale",
icon: "token",
color: "#0891B2",
textIcon: "NS",
website: "https://nscale.com",
hasFree: true,
freeNote: "$5 free credits on signup for inference testing",
},
ovhcloud: {
id: "ovhcloud",
alias: "ovh",
name: "OVHcloud AI",
icon: "cloud",
color: "#2563EB",
textIcon: "OVH",
website: "https://www.ovhcloud.com",
},
baseten: {
id: "baseten",
alias: "baseten",
name: "Baseten",
icon: "deployed_code",
color: "#111827",
textIcon: "BT",
website: "https://baseten.co",
hasFree: true,
freeNote: "$30 free trial credits for GPU inference",
},
publicai: {
id: "publicai",
alias: "publicai",
name: "PublicAI",
icon: "public",
color: "#059669",
textIcon: "PA",
website: "https://publicai.co",
// #3558: PublicAI requires an API key (registry authType:"apikey"); signup grants a
// one-time credit, then it bills per-model. It is NOT a keyless/free tier.
hasFree: false,
freeNote: "Requires an API key — one-time signup credit, then paid",
},
moonshot: {
id: "moonshot",
alias: "moonshot",
name: "Moonshot AI",
icon: "rocket_launch",
color: "#1E40AF",
textIcon: "MS",
website: "https://platform.moonshot.ai",
},
"meta-llama": {
id: "meta-llama",
alias: "meta",
name: "Meta Llama API",
icon: "smart_toy",
color: "#0F766E",
textIcon: "ML",
website: "https://llama.developer.meta.com",
},
"v0-vercel": {
id: "v0-vercel",
alias: "v0",
name: "v0 (Vercel)",
icon: "code_blocks",
color: "#111827",
textIcon: "V0",
website: "https://v0.dev",
},
morph: {
id: "morph",
alias: "morph",
name: "Morph",
icon: "auto_fix_high",
color: "#2563EB",
textIcon: "MP",
website: "https://morphllm.com",
hasFree: true,
freeNote: "Free tier: 250K credits/month, $0",
},
"featherless-ai": {
id: "featherless-ai",
alias: "featherless",
name: "Featherless AI",
icon: "flutter_dash",
color: "#EA580C",
textIcon: "FL",
website: "https://featherless.ai",
hasFree: true,
freeNote: "Free tier available — no credit card required",
},
llm7: {
id: "llm7",
alias: "llm7",
name: "LLM7.io",
icon: "hub",
color: "#6366F1",
textIcon: "LM",
website: "https://llm7.io",
hasFree: true,
freeNote: "No signup required - 2 req/s, 20 RPM, 100 req/hr free tier",
apiHint:
"Works without API key (use 'unused' as key). Get free token at token.llm7.io for higher limits.",
},
kluster: {
id: "kluster",
alias: "kluster",
name: "Kluster AI",
icon: "hub",
color: "#8B5CF6",
textIcon: "KL",
website: "https://kluster.ai",
hasFree: true,
freeNote: "$5 free credits on signup - DeepSeek R1, Llama 4 Maverick/Scout, Qwen3 235B",
apiHint: "Get API key at https://kluster.ai/dashboard/api-keys",
},
friendliai: {
id: "friendliai",
alias: "friendli",
name: "FriendliAI",
icon: "handshake",
color: "#EC4899",
textIcon: "FR",
website: "https://friendli.ai",
hasFree: true,
freeNote: "Free tier for serverless inference — no credit card required",
},
llamagate: {
id: "llamagate",
alias: "llamagate",
name: "LlamaGate",
icon: "gate",
color: "#16A34A",
textIcon: "LG",
website: "https://llamagate.ai",
},
heroku: {
id: "heroku",
alias: "heroku",
name: "Heroku AI",
icon: "cloud_upload",
color: "#7C3AED",
textIcon: "HK",
website: "https://www.heroku.com",
},
galadriel: {
id: "galadriel",
alias: "galadriel",
name: "Galadriel",
icon: "auto_awesome",
color: "#F59E0B",
textIcon: "GA",
website: "https://galadriel.com",
},
databricks: {
id: "databricks",
alias: "databricks",
name: "Databricks",
icon: "table_chart",
color: "#F97316",
textIcon: "DB",
website: "https://www.databricks.com",
},
datarobot: {
id: "datarobot",
alias: "datarobot",
name: "DataRobot",
icon: "precision_manufacturing",
color: "#6D28D9",
textIcon: "DR",
website: "https://docs.datarobot.com",
authHint:
"Use your DataRobot API token. Optional Base URL can be the account root (for LLM Gateway) or a deployment URL under /api/v2/deployments/<id>.",
apiHint:
"The default gateway catalogs active models from /genai/llmgw/catalog/. Deployment URLs are also supported for direct OpenAI-compatible chat requests.",
passthroughModels: true,
},
clarifai: {
id: "clarifai",
alias: "clarifai",
name: "Clarifai",
icon: "hub",
color: "#7C3AED",
textIcon: "CF",
website: "https://docs.clarifai.com",
authHint:
"Use your Clarifai PAT or app-specific API key. OmniRoute targets the OpenAI-compatible endpoint at https://api.clarifai.com/v2/ext/openai/v1 and authenticates with Authorization: Key <token>.",
apiHint:
"Clarifai exposes OpenAI-compatible chat, responses and /models on /v2/ext/openai/v1. Public/community models typically require a PAT; app-scoped keys only work for resources inside that app.",
passthroughModels: true,
},
snowflake: {
id: "snowflake",
alias: "snowflake",
name: "Snowflake Cortex",
icon: "ac_unit",
color: "#29B5E8",
textIcon: "SF",
website: "https://www.snowflake.com",
},
wandb: {
id: "wandb",
alias: "wandb",
name: "Weights & Biases Inference",
icon: "monitoring",
color: "#FFBE0B",
textIcon: "WB",
website: "https://wandb.ai",
},
volcengine: {
id: "volcengine",
alias: "volcengine",
name: "Volcengine",
icon: "local_fire_department",
color: "#DC2626",
textIcon: "VE",
website: "https://www.volcengine.com",
},
ai21: {
id: "ai21",
alias: "ai21",
name: "AI21 Labs",
icon: "psychology_alt",
color: "#0284C7",
textIcon: "AI21",
website: "https://www.ai21.com",
hasFree: true,
freeNote: "$10 trial credits on signup (valid 3 months), no credit card required",
},
gigachat: {
id: "gigachat",
alias: "gigachat",
name: "GigaChat (Sber)",
icon: "lock_person",
color: "#10B981",
textIcon: "GC",
website: "https://developers.sber.ru",
},
venice: {
id: "venice",
alias: "venice",
name: "Venice.ai",
icon: "travel_explore",
color: "#0EA5E9",
textIcon: "VN",
website: "https://venice.ai",
},
codestral: {
id: "codestral",
alias: "codestral",
name: "Codestral",
icon: "terminal",
color: "#FF7000",
textIcon: "CS",
website: "https://mistral.ai",
},
upstage: {
id: "upstage",
alias: "upstage",
name: "Upstage",
icon: "trending_up",
color: "#0F766E",
textIcon: "UP",
website: "https://www.upstage.ai",
},
maritalk: {
id: "maritalk",
alias: "maritalk",
name: "Maritalk",
icon: "translate",
color: "#1D4ED8",
textIcon: "MT",
website: "https://www.maritaca.ai",
},
"xiaomi-mimo": {
id: "xiaomi-mimo",
alias: "mimo",
name: "Xiaomi MiMo",
icon: "devices",
color: "#EA580C",
textIcon: "MM",
website: "https://mimo.mi.com",
},
gitlawb: {
id: "gitlawb",
alias: "glb",
name: "Gitlawb Opengateway (MiMo)",
icon: "hub",
color: "#10B981",
textIcon: "GLB",
website: "https://opengateway.gitlawb.com",
hasFree: true,
freeNote: "Free tier available — no credit card required",
apiHint: "Get your API key from Gitlawb Opengateway dashboard.",
},
"gitlawb-gmi": {
id: "gitlawb-gmi",
alias: "glb-gmi",
name: "Gitlawb Opengateway (GMI Cloud)",
icon: "hub",
color: "#10B981",
textIcon: "GMI",
website: "https://opengateway.gitlawb.com",
hasFree: true,
freeNote: "Free tier available — no credit card required",
apiHint: "Get your API key from Gitlawb Opengateway dashboard.",
},
"inference-net": {
id: "inference-net",
alias: "inet",
name: "Inference.net",
icon: "dns",
color: "#2563EB",
textIcon: "IN",
website: "https://inference.net",
hasFree: true,
freeNote: "$25 free credits on signup plus research grants available",
},
nanogpt: {
id: "nanogpt",
alias: "nanogpt",
name: "NanoGPT",
icon: "chat",
color: "#4F46E5",
textIcon: "NG",
website: "https://nano-gpt.com",
},
predibase: {
id: "predibase",
alias: "predibase",
name: "Predibase",
icon: "deployed_code_history",
color: "#0F766E",
textIcon: "PB",
website: "https://predibase.com",
hasFree: true,
freeNote: "$25 free trial credits (30-day validity)",
},
bytez: {
id: "bytez",
alias: "bytez",
name: "Bytez",
icon: "api",
color: "#6366F1",
textIcon: "BZ",
website: "https://bytez.com",
hasFree: true,
freeNote: "$1 free credits, refreshes every 4 weeks",
},
aimlapi: {
id: "aimlapi",
alias: "aiml",
name: "AI/ML API",
icon: "hub",
color: "#6366F1",
textIcon: "AI",
website: "https://aimlapi.com",
hasFree: true,
freeNote:
"$0.025/day free credits — 200+ models (GPT-4o, Claude, Gemini, Llama) via single endpoint",
passthroughModels: true,
},
novita: {
id: "novita",
alias: "novita",
name: "Novita AI",
icon: "auto_awesome",
color: "#FF4081",
textIcon: "NV",
website: "https://novita.ai",
hasFree: true,
freeNote: "$0.50 trial credits on signup (valid about 1 year)",
passthroughModels: true,
},
piapi: {
id: "piapi",
alias: "pi",
name: "PiAPI",
icon: "api",
color: "#7C4DFF",
textIcon: "PI",
website: "https://piapi.ai",
passthroughModels: true,
},
getgoapi: {
id: "getgoapi",
alias: "ggo",
name: "GoAPI",
icon: "rocket_launch",
color: "#FF6D00",
textIcon: "GO",
website: "https://api.getgoapi.com",
passthroughModels: true,
},
laozhang: {
id: "laozhang",
alias: "lz",
name: "LaoZhang AI",
icon: "hub",
color: "#FF1744",
textIcon: "LZ",
website: "https://api.laozhang.ai",
passthroughModels: true,
},
glhf: {
id: "glhf",
alias: "glhf",
name: "GLHF Chat",
icon: "hub",
color: "#10B981",
textIcon: "GH",
website: "https://glhf.chat",
authHint: "Bearer API key for the GLHF OpenAI-compatible gateway.",
hasFree: true,
freeNote: "Free tier for open-source model inference",
passthroughModels: true,
},
cablyai: {
id: "cablyai",
alias: "cablyai",
name: "CablyAI",
icon: "hub",
color: "#FF4081",
textIcon: "CA",
website: "https://cablyai.com",
authHint: "Bearer API key for the CablyAI OpenAI-compatible gateway.",
passthroughModels: true,
},
thebai: {
id: "thebai",
alias: "thebai",
name: "TheB.AI",
icon: "hub",
color: "#3B82F6",
textIcon: "TB",
website: "https://theb.ai",
authHint: "Bearer API key for the TheB.AI OpenAI-compatible gateway.",
passthroughModels: true,
},
fenayai: {
id: "fenayai",
alias: "fenayai",
name: "FenayAI",
icon: "hub",
color: "#FF9800",
textIcon: "FN",
website: "https://fenayai.com",
authHint: "Bearer API key for the FenayAI OpenAI-compatible gateway.",
passthroughModels: true,
},
empower: {
id: "empower",
alias: "empower",
name: "Empower",
icon: "hub",
color: "#14B8A6",
textIcon: "EM",
website: "https://docs.empower.dev",
authHint: "Bearer API key for the Empower OpenAI-compatible endpoint.",
apiHint:
"Empower exposes OpenAI-compatible chat on https://app.empower.dev/api/v1 with tool-calling support on empower-functions.",
passthroughModels: true,
},
"nous-research": {
id: "nous-research",
alias: "nous",
name: "Nous Research",
icon: "hub",
color: "#2563EB",
textIcon: "NO",
website: "https://portal.nousresearch.com/help",
authHint:
"Use your Nous Portal API key. OmniRoute targets the official OpenAI-compatible inference endpoint at https://inference-api.nousresearch.com/v1.",
apiHint:
"Nous exposes an OpenAI-compatible /v1 surface with a large remote /models catalog. The /chat/completions endpoint requires a valid API key for programmatic inference.",
hasFree: true,
freeNote: "Free tier: 50 RPM, 500,000 TPM — no credit card",
},
poe: {
id: "poe",
alias: "poe",
name: "Poe",
icon: "hub",
color: "#F97316",
textIcon: "PO",
website: "https://creator.poe.com/api-reference",
authHint: "Bearer API key for the Poe OpenAI-compatible API.",
apiHint:
"Poe exposes OpenAI-compatible chat and responses on https://api.poe.com/v1, with authenticated balance checks on /usage/current_balance.",
passthroughModels: true,
},
gitlab: {
id: "gitlab",
alias: "gitlab",
name: "GitLab Duo PAT",
icon: "hub",
color: "#FC6D26",
textIcon: "GL",
website: "https://docs.gitlab.com/user/duo_agent_platform/code_suggestions/",
authHint:
"GitLab personal access token for the public Code Suggestions API. Configure a self-hosted base URL when not using gitlab.com.",
},
chutes: {
id: "chutes",
alias: "chutes",
name: "Chutes.ai",
icon: "hub",
color: "#06B6D4",
textIcon: "CH",
website: "https://chutes.ai",
hasFree: true,
freeNote: "Free tier available — no credit card required",
authHint: "Bearer API key for the Chutes OpenAI-compatible gateway.",
passthroughModels: true,
},
"voyage-ai": {
id: "voyage-ai",
alias: "voyage",
name: "Voyage AI",
icon: "blur_on",
color: "#0F766E",
textIcon: "VA",
website: "https://www.voyageai.com",
authHint: "Bearer API key for Voyage AI embeddings and rerank APIs.",
hasFree: true,
freeNote: "200M free tokens for embeddings and reranking",
},
"jina-ai": {
id: "jina-ai",
alias: "jina",
name: "Jina AI",
icon: "sort",
color: "#2563EB",
textIcon: "JA",
website: "https://jina.ai",
authHint: "Bearer API key for the Jina AI rerank API.",
hasFree: true,
freeNote: "10M free tokens on signup (non-commercial), no credit card required",
},
"fal-ai": {
id: "fal-ai",
alias: "fal",
name: "Fal.ai",
icon: "image",
color: "#2563EB",
textIcon: "FL",
website: "https://fal.ai",
},
"stability-ai": {
id: "stability-ai",
alias: "stability",
name: "Stability AI",
icon: "image",
color: "#8B5CF6",
textIcon: "SA",
website: "https://stability.ai",
},
"black-forest-labs": {
id: "black-forest-labs",
alias: "bfl",
name: "Black Forest Labs",
icon: "image",
color: "#111827",
textIcon: "BF",
website: "https://blackforestlabs.ai",
},
recraft: {
id: "recraft",
alias: "recraft",
name: "Recraft",
icon: "image",
color: "#EC4899",
textIcon: "RC",
website: "https://recraft.ai",
},
topaz: {
id: "topaz",
alias: "topaz",
name: "Topaz",
icon: "image",
color: "#059669",
textIcon: "TP",
website: "https://topazlabs.com",
},
baidu: {
id: "baidu",
alias: "baidu",
name: "Baidu (ERNIE)",
icon: "auto_awesome",
color: "#2932E1",
textIcon: "BD",
website: "https://yiyan.baidu.com",
hasFree: true,
freeNote: "Free ERNIE Speed/Lite models. China's #2 LLM.",
passthroughModels: true,
authHint: "Get API key at console.bce.baidu.com",
},
tencent: {
id: "tencent",
alias: "tencent",
name: "Tencent Hunyuan",
icon: "auto_awesome",
color: "#07C160",
textIcon: "TC",
website: "https://hunyuan.tencent.com",
hasFree: true,
freeNote: "Free Hunyuan Lite models. WeChat ecosystem.",
passthroughModels: true,
authHint: "Get API key at console.cloud.tencent.com",
},
iflytek: {
id: "iflytek",
alias: "iflytek",
name: "iFlytek Spark",
icon: "auto_awesome",
color: "#0066FF",
textIcon: "IF",
website: "https://xinghuo.xfyun.cn",
hasFree: true,
freeNote: "Free Spark Lite models. China's voice AI leader.",
passthroughModels: true,
authHint: "Get API key at console.xfyun.cn",
},
baichuan: {
id: "baichuan",
alias: "baichuan",
name: "Baichuan",
icon: "auto_awesome",
color: "#6366F1",
textIcon: "BC",
website: "https://baichuan.com",
hasFree: true,
freeNote: "Free Baichuan models. Popular Chinese LLM startup.",
passthroughModels: true,
authHint: "Get API key at platform.baichuan-ai.com",
},
yi: {
id: "yi",
alias: "yi",
name: "Yi (01.AI)",
icon: "auto_awesome",
color: "#10B981",
textIcon: "YI",
website: "https://01.ai",
hasFree: true,
freeNote: "Free Yi-Light models. Kai-Fu Lee's company.",
passthroughModels: true,
authHint: "Get API key at platform.lingyiwanwu.com",
},
stepfun: {
id: "stepfun",
alias: "stepfun",
name: "StepFun",
icon: "auto_awesome",
color: "#8B5CF6",
textIcon: "SF",
website: "https://stepfun.com",
hasFree: true,
freeNote: "Free Step-2 models. Chinese AI company.",
passthroughModels: true,
authHint: "Get API key at platform.stepfun.com",
},
coze: {
id: "coze",
alias: "coze",
name: "Coze",
icon: "smart_toy",
color: "#3B82F6",
textIcon: "CZ",
website: "https://coze.com",
hasFree: true,
freeNote: "Free ByteDance agent platform. Bot building + LLM access.",
passthroughModels: true,
authHint: "Get API key at coze.com/open/api",
},
"360ai": {
id: "360ai",
alias: "360ai",
name: "360 AI",
icon: "auto_awesome",
color: "#00B96B",
textIcon: "360",
website: "https://ai.360.cn",
hasFree: true,
freeNote: "Free 360 AI Brain models. Major Chinese security company.",
passthroughModels: true,
authHint: "Get API key at ai.360.cn",
},
doubao: {
id: "doubao",
alias: "doubao",
name: "Doubao",
icon: "auto_awesome",
color: "#FE2C55",
textIcon: "DB",
website: "https://doubao.com",
hasFree: true,
freeNote: "Free Doubao models. ByteDance's chatbot.",
passthroughModels: true,
authHint: "Get API key at console.volcengine.com",
},
sensenova: {
id: "sensenova",
alias: "sensenova",
name: "SenseNova",
icon: "auto_awesome",
color: "#0066FF",
textIcon: "SN",
website: "https://platform.sensenova.cn",
hasFree: true,
freeNote: "Free SenseTime models. Computer vision leader.",
passthroughModels: true,
authHint: "Get API key at platform.sensenova.cn",
},
sparkdesk: {
id: "sparkdesk",
alias: "sparkdesk",
name: "SparkDesk",
icon: "auto_awesome",
color: "#0066FF",
textIcon: "SD",
website: "https://xinghuo.xfyun.cn",
hasFree: true,
freeNote: "Free iFlytek Spark models (alias for iflytek).",
passthroughModels: true,
authHint: "Get API key at console.xfyun.cn",
},
phind: {
id: "phind",
alias: "phind",
name: "Phind",
icon: "search",
color: "#EC4899",
textIcon: "PH",
website: "https://phind.com",
hasFree: true,
freeNote: "Free code search + AI. Developer-focused.",
passthroughModels: true,
authHint: "Get API key at phind.com",
},
huggingchat: {
id: "huggingchat",
alias: "huggingchat",
name: "HuggingChat",
icon: "chat",
color: "#FFD21E",
textIcon: "HC",
website: "https://huggingface.co/chat",
hasFree: true,
freeNote: "Free chat with open models (Llama, Mistral, etc.).",
passthroughModels: true,
authHint: "No API key required for basic access.",
},
dify: {
id: "dify",
alias: "dify",
name: "Dify",
icon: "smart_toy",
color: "#6366F1",
textIcon: "DF",
website: "https://dify.ai",
hasFree: true,
freeNote: "Free open-source AI app builder + RAG platform.",
passthroughModels: true,
authHint: "Get API key from your Dify instance.",
},
"arcee-ai": {
id: "arcee-ai",
alias: "arcee",
name: "Arcee AI",
icon: "auto_awesome",
color: "#8B5CF6",
textIcon: "AR",
website: "https://arcee.ai",
hasFree: true,
freeNote: "Free Trinity Large Thinking model (262K context). No credit card required.",
passthroughModels: true,
authHint: "Get API key at arcee.ai",
},
inclusionai: {
id: "inclusionai",
alias: "inclusion",
name: "InclusionAI",
icon: "psychology",
color: "#10B981",
textIcon: "IA",
website: "https://inclusionai.com",
hasFree: true,
freeNote: "Free Ling-2.6-flash model (1T-param MoE, 262K context). No credit card required.",
passthroughModels: true,
authHint: "Get API key at inclusionai.com",
},
liquid: {
id: "liquid",
alias: "liquid",
name: "Liquid AI",
icon: "water_drop",
color: "#06B6D4",
textIcon: "LQ",
website: "https://liquid.ai",
hasFree: true,
freeNote:
"Free LFM2.5-1.2B-Thinking and LFM2.5-1.2B-Instruct models. MIT spinoff, hybrid architecture.",
passthroughModels: true,
authHint: "Get API key at liquid.ai",
},
nomic: {
id: "nomic",
alias: "nomic",
name: "Nomic",
icon: "hub",
color: "#7C3AED",
textIcon: "NM",
website: "https://nomic.ai",
hasFree: true,
freeNote: "Free Nomic Embed API. Open-source embeddings, no credit card required.",
passthroughModels: true,
authHint: "Get API key at atlas.nomic.ai",
},
monsterapi: {
id: "monsterapi",
alias: "monster",
name: "MonsterAPI",
icon: "cloud",
color: "#EF4444",
textIcon: "MA",
website: "https://monsterapi.ai",
hasFree: true,
freeNote: "Free credits for decentralized GPU inference. No credit card required.",
passthroughModels: true,
authHint: "Get API key at monsterapi.ai",
},
// ── Web Fetch Providers ─────────────────────────────────────────────────────
firecrawl: {
id: "firecrawl",
alias: "fc",
name: "Firecrawl",
icon: "language",
color: "#FB923C",
textIcon: "FC",
website: "https://firecrawl.dev",
hasFree: true,
notice: {
text: "Free tier: 500 fetches/month, no credit card needed.",
apiKeyUrl: "https://firecrawl.dev/app/api-keys",
},
serviceKinds: ["webFetch"],
},
"jina-reader": {
id: "jina-reader",
alias: "jr",
name: "Jina Reader",
icon: "menu_book",
color: "#0EA5E9",
textIcon: "JR",
website: "https://jina.ai/reader",
hasFree: true,
notice: {
text: "Free tier: 1M fetches/month.",
apiKeyUrl: "https://jina.ai/api-dashboard",
},
serviceKinds: ["webFetch"],
},
byteplus: {
id: "byteplus",
alias: "bpm",
name: "BytePlus ModelArk",
icon: "cloud",
color: "#2563EB",
textIcon: "BP",
website: "https://console.byteplus.com/ark",
hasFree: true,
notice: {
text: "Free credits for new accounts. Seed 2.0, Kimi K2 Thinking, GLM 4.7, GPT-OSS-120B available.",
apiKeyUrl: "https://console.byteplus.com/ark/region:ark+ap-southeast-1/apiKey",
},
serviceKinds: ["llm"],
},
bluesminds: {
id: "bluesminds",
alias: "bm",
name: "BluesMinds",
icon: "psychology",
color: "#3B82F6",
textIcon: "BM",
website: "https://www.bluesminds.com",
hasFree: true,
freeNote:
"Free daily pi credits — supports 200+ models including GPT-4o, GPT-4.1, Claude Sonnet 4.5, Gemini 2.0 Flash, DeepSeek V4, Qwen, Kimi K2",
apiHint:
"Get your API key at https://www.bluesminds.com — OpenAI-compatible endpoint at https://api.bluesminds.com/v1 with free daily credits. VIP models (Claude Opus 4.5, Gemini 2.5 Pro) consume pi credits.",
},
"freemodel-dev": {
id: "freemodel-dev",
alias: "fmd",
name: "FreeModel.dev",
icon: "auto_awesome",
color: "#8B5CF6",
textIcon: "FM",
website: "https://freemodel.dev",
hasFree: true,
freeNote:
"$300 free credits on signup — no credit card required. Access GPT-5.4 and GPT-5.5 (OpenAI's latest flagship models) through an OpenAI-compatible API.",
apiHint:
"Get $300 free API credits at https://freemodel.dev — no payment info required. OpenAI-compatible endpoint. GPT-5.4 and GPT-5.5 models available.",
},
freeaiapikey: {
id: "freeaiapikey",
alias: "faik",
name: "FreeAIAPIKey",
icon: "vpn_key",
color: "#F59E0B",
textIcon: "FK",
website: "https://freeaiapikey.com",
apiHint:
"Discounted API proxy for 40+ models including GPT-5, Claude Opus 4.6, Claude Sonnet 4.6, Qwen 3.5. Get your API key at https://freeaiapikey.com/dashboard. Base URL: https://freeaiapikey.com/v1.",
},
zenmux: {
id: "zenmux",
alias: "zm",
name: "ZenMux",
icon: "neurology",
color: "#7C3AED",
textIcon: "ZM",
website: "https://zenmux.ai",
hasFree: true,
freeNote:
"Free tier includes access to Gemini 3 Flash, DeepSeek V3.2, Grok 4.1 Fast, Mistral Large, and more. Get your API key at https://zenmux.ai.",
authHint:
"Use your ZenMux API key in Authorization: Bearer <key>. ZenMux is fully OpenAI-compatible. Base URL: https://zenmux.ai/api/v1.",
apiHint:
"ZenMux exposes an OpenAI-compatible chat completions endpoint at /api/v1/chat/completions, plus Anthropic Messages (/api/anthropic/v1/messages) and Google Gemini (/api/vertex-ai) protocol surfaces. OmniRoute uses the OpenAI protocol.",
},
};
// Sub-categories within APIKEY_PROVIDERS (used by dashboard and catalog views).
export const IMAGE_ONLY_PROVIDER_IDS = new Set([
"nanobanana",
"fal-ai",
"stability-ai",
"black-forest-labs",
"recraft",
"topaz",
]);
export const AGGREGATOR_PROVIDER_IDS = new Set([
"openrouter",
"synthetic",
"kilo-gateway",
"aimlapi",
"novita",
"piapi",
"getgoapi",
"laozhang",
"vercel-ai-gateway",
"agentrouter",
"glhf",
"cablyai",
"thebai",
"fenayai",
"empower",
"poe",
"chutes",
"hackclub",
]);
export const ENTERPRISE_CLOUD_PROVIDER_IDS = new Set([
"azure-openai",
"azure-ai",
"bedrock",
"watsonx",
"oci",
"sap",
"vertex",
"vertex-partner",
"databricks",
"datarobot",
"clarifai",
"snowflake",
"heroku",
"modal",
]);
export const VIDEO_PROVIDER_IDS = new Set([
"runwayml",
"veoaifree-web",
"pollinations",
"minimax",
"together",
"replicate",
"haiper",
"leonardo",
]);
// IDE Providers: editors with built-in AI subscription (separate section in UI).
// These providers live in OAUTH_PROVIDERS but render under "IDE Providers"
// instead of "OAuth Providers" to avoid visual duplication.
export const IDE_PROVIDER_IDS = new Set(["cursor", "zed", "trae"]);
export const EMBEDDING_RERANK_PROVIDER_IDS = new Set(["voyage-ai", "jina-ai"]);
// Local / Self-Hosted Providers
export const LOCAL_PROVIDERS = {
"lm-studio": {
id: "lm-studio",
alias: "lmstudio",
name: "LM Studio",
icon: "server",
color: "#4A148C",
textIcon: "LM",
website: "https://lmstudio.ai",
authHint:
"API key optional. Configure the local LM Studio OpenAI-compatible base URL (default: http://localhost:1234/v1).",
localDefault: "http://localhost:1234/v1",
passthroughModels: true,
},
vllm: {
id: "vllm",
alias: "vllm",
name: "vLLM",
icon: "memory",
color: "#0F766E",
textIcon: "VL",
website: "https://github.com/vllm-project/vllm",
authHint:
"API key optional. Configure the local vLLM OpenAI-compatible base URL (default: http://localhost:8000/v1).",
localDefault: "http://localhost:8000/v1",
passthroughModels: true,
},
lemonade: {
id: "lemonade",
alias: "lemonade",
name: "Lemonade Server",
icon: "bolt",
color: "#F59E0B",
textIcon: "LM",
website: "https://lemonade-server.ai",
authHint:
"API key optional. Configure the local Lemonade OpenAI-compatible base URL (default: http://localhost:13305/api/v1).",
localDefault: "http://localhost:13305/api/v1",
passthroughModels: true,
},
llamafile: {
id: "llamafile",
alias: "llamafile",
name: "Llamafile",
icon: "article",
color: "#EA580C",
textIcon: "LF",
website: "https://github.com/Mozilla-Ocho/llamafile",
authHint:
"API key optional. Configure the local Llamafile OpenAI-compatible base URL (default: http://127.0.0.1:8080/v1).",
localDefault: "http://127.0.0.1:8080/v1",
passthroughModels: true,
},
"llama-cpp": {
id: "llama-cpp",
alias: "llamacpp",
name: "llama.cpp",
icon: "memory",
color: "#795548",
textIcon: "LC",
website: "https://github.com/ggml-org/llama.cpp",
authHint:
"API key optional (use any value, e.g. sk-no-key-required). Configure the llama-server OpenAI-compatible base URL (default: http://127.0.0.1:8080/v1). Note: if Llamafile is also installed, both default to port 8080 — run only one at a time or override the port.",
localDefault: "http://127.0.0.1:8080/v1",
passthroughModels: true,
},
triton: {
id: "triton",
alias: "triton",
name: "NVIDIA Triton",
icon: "developer_board",
color: "#76B900",
textIcon: "TR",
website: "https://developer.nvidia.com/triton-inference-server",
authHint:
"API key optional. Configure the Triton OpenAI-compatible base URL (default: http://localhost:8000/v1).",
localDefault: "http://localhost:8000/v1",
passthroughModels: true,
},
"docker-model-runner": {
id: "docker-model-runner",
alias: "dmr",
name: "Docker Model Runner",
icon: "inventory_2",
color: "#2496ED",
textIcon: "DM",
website: "https://docs.docker.com/ai/model-runner/",
authHint:
"API key optional. Configure the local Docker Model Runner OpenAI-compatible base URL (default: http://localhost:12434/v1).",
localDefault: "http://localhost:12434/v1",
passthroughModels: true,
},
xinference: {
id: "xinference",
alias: "xinference",
name: "XInference",
icon: "hub",
color: "#DC2626",
textIcon: "XI",
website: "https://inference.readthedocs.io",
authHint:
"API key optional. Configure the local XInference OpenAI-compatible base URL (default: http://localhost:9997/v1).",
localDefault: "http://localhost:9997/v1",
passthroughModels: true,
},
oobabooga: {
id: "oobabooga",
alias: "ooba",
name: "oobabooga",
icon: "dns",
color: "#8B5CF6",
textIcon: "OO",
website: "https://github.com/oobabooga/text-generation-webui",
authHint:
"API key optional. Configure the local oobabooga OpenAI-compatible base URL (default: http://localhost:5000/v1).",
localDefault: "http://localhost:5000/v1",
passthroughModels: true,
},
sdwebui: {
id: "sdwebui",
alias: "sdwebui",
name: "SD WebUI",
icon: "brush",
color: "#FF7043",
textIcon: "SD",
website: "https://github.com/AUTOMATIC1111/stable-diffusion-webui",
hasFree: true,
authHint:
"No API key required. Configure the local WebUI base URL (default: http://localhost:7860).",
localDefault: "http://localhost:7860",
},
comfyui: {
id: "comfyui",
alias: "comfyui",
name: "ComfyUI",
icon: "account_tree",
color: "#4CAF50",
textIcon: "CF",
website: "https://github.com/comfyanonymous/ComfyUI",
hasFree: true,
authHint:
"No API key required. Configure the local ComfyUI base URL (default: http://localhost:8188).",
localDefault: "http://localhost:8188",
},
};
// Search Providers
export const SEARCH_PROVIDERS = {
"perplexity-search": {
id: "perplexity-search",
alias: "pplx-search",
name: "Perplexity Search",
icon: "search",
color: "#20808D",
textIcon: "PS",
website: "https://docs.perplexity.ai/guides/search-quickstart",
authHint: "Same API key as Perplexity (pplx-...)",
},
"serper-search": {
id: "serper-search",
alias: "serper-search",
name: "Serper Search",
icon: "search",
color: "#4285F4",
textIcon: "SP",
website: "https://serper.dev",
hasFree: true,
authHint: "API key from serper.dev dashboard",
serviceKinds: ["webSearch"],
},
"brave-search": {
id: "brave-search",
alias: "brave-search",
name: "Brave Search",
icon: "travel_explore",
color: "#FB542B",
textIcon: "BR",
website: "https://brave.com/search/api",
hasFree: true,
authHint: "Subscription token from Brave Search API dashboard",
},
"exa-search": {
id: "exa-search",
alias: "exa-search",
name: "Exa Search",
icon: "neurology",
color: "#1E40AF",
textIcon: "EX",
website: "https://exa.ai",
hasFree: true,
authHint: "API key from dashboard.exa.ai",
serviceKinds: ["webSearch", "webFetch"],
},
"tavily-search": {
id: "tavily-search",
alias: "tavily-search",
name: "Tavily Search",
icon: "manage_search",
color: "#5B4FDB",
textIcon: "TV",
website: "https://tavily.com",
hasFree: true,
authHint: "API key from app.tavily.com (format: tvly-...)",
serviceKinds: ["webSearch", "webFetch"],
},
"google-pse-search": {
id: "google-pse-search",
alias: "google-pse",
name: "Google Programmable Search",
icon: "travel_explore",
color: "#4285F4",
textIcon: "GP",
website: "https://developers.google.com/custom-search/v1/overview",
authHint: "Requires a Google API key and your Programmable Search Engine ID (cx)",
},
"linkup-search": {
id: "linkup-search",
alias: "linkup",
name: "Linkup Search",
icon: "public",
color: "#0F766E",
textIcon: "LU",
website: "https://docs.linkup.so",
authHint: "Bearer API key from the Linkup dashboard",
},
"searchapi-search": {
id: "searchapi-search",
alias: "searchapi",
name: "SearchAPI",
icon: "manage_search",
color: "#2563EB",
textIcon: "SA",
website: "https://www.searchapi.io/docs",
authHint: "API key from SearchAPI (query param or Bearer auth)",
},
"youcom-search": {
id: "youcom-search",
alias: "youcom-search",
name: "You.com Search",
icon: "travel_explore",
color: "#2563EB",
textIcon: "YOU",
website: "https://you.com/docs/search/overview",
authHint: "X-API-Key from the You.com platform dashboard",
},
"searxng-search": {
id: "searxng-search",
alias: "searxng",
name: "SearXNG Search",
icon: "search",
color: "#1A237E",
textIcon: "SX",
website: "https://docs.searxng.org",
hasFree: true,
authHint:
"API key is optional. Set your SearXNG base URL. Some instances may require a bearer token for access.",
},
"ollama-search": {
id: "ollama-search",
alias: "ollama-search",
name: "Ollama Search",
icon: "search",
color: "#58A6FF",
textIcon: "OS",
website: "https://ollama.com/settings/api-keys",
authHint: "Same API key as Ollama Cloud (from ollama.com/settings/api-keys)",
},
};
// Audio Only Providers
export const AUDIO_ONLY_PROVIDERS = {
deepgram: {
id: "deepgram",
alias: "dg",
name: "Deepgram",
icon: "mic",
color: "#13EF93",
textIcon: "DG",
website: "https://deepgram.com",
},
assemblyai: {
id: "assemblyai",
alias: "aai",
name: "AssemblyAI",
icon: "record_voice_over",
color: "#0062FF",
textIcon: "AA",
website: "https://assemblyai.com",
},
elevenlabs: {
id: "elevenlabs",
alias: "el",
name: "ElevenLabs",
icon: "record_voice_over",
color: "#6C47FF",
textIcon: "EL",
website: "https://elevenlabs.io",
},
cartesia: {
id: "cartesia",
alias: "cartesia",
name: "Cartesia",
icon: "spatial_audio",
color: "#FF4F8B",
textIcon: "CA",
website: "https://cartesia.ai",
},
playht: {
id: "playht",
alias: "playht",
name: "PlayHT",
icon: "play_circle",
color: "#00B4D8",
textIcon: "PH",
website: "https://play.ht",
},
inworld: {
id: "inworld",
alias: "inworld",
name: "Inworld",
icon: "voice_chat",
color: "#7B2EF2",
textIcon: "IW",
website: "https://inworld.ai",
},
"aws-polly": {
id: "aws-polly",
alias: "polly",
name: "AWS Polly",
icon: "record_voice_over",
color: "#FF9900",
textIcon: "PL",
website: "https://aws.amazon.com/polly/",
authHint:
"Use AWS Secret Access Key as API key; set providerSpecificData.accessKeyId and optional region.",
},
};
export const OPENAI_COMPATIBLE_PREFIX = "openai-compatible-";
export const ANTHROPIC_COMPATIBLE_PREFIX = "anthropic-compatible-";
export const CLAUDE_CODE_COMPATIBLE_PREFIX = "anthropic-compatible-cc-";
export function isOpenAICompatibleProvider(providerId: unknown): providerId is string {
return typeof providerId === "string" && providerId.startsWith(OPENAI_COMPATIBLE_PREFIX);
}
export function isAnthropicCompatibleProvider(providerId: unknown): providerId is string {
return typeof providerId === "string" && providerId.startsWith(ANTHROPIC_COMPATIBLE_PREFIX);
}
export const UPSTREAM_PROXY_PROVIDERS = {
cliproxyapi: {
id: "cliproxyapi",
alias: "cpa",
name: "CLIProxyAPI",
icon: "proxy",
color: "#6366F1",
textIcon: "CPA",
website: "https://github.com/router-for-me/CLIProxyAPI",
defaultPort: 8317,
healthEndpoint: "/v1/models",
managementPrefix: "/v0/management",
configDir: "~/.cli-proxy-api",
binaryName: "cli-proxy-api",
githubRepo: "router-for-me/CLIProxyAPI",
},
"9router": {
id: "9router",
alias: "nr",
name: "9router",
icon: "router",
color: "#0EA5E9",
textIcon: "9R",
website: "https://www.npmjs.com/package/9router",
defaultPort: 20130,
healthEndpoint: "/api/health",
npmPackage: "9router",
embedded: true,
isEmbeddedService: true,
riskNoticeVariant: "embedded-service" as const,
},
};
export const CLOUD_AGENT_PROVIDERS = {
jules: {
id: "jules",
alias: "jules",
name: "Google Jules",
icon: "engineering",
color: "#4285F4",
textIcon: "JL",
website: "https://jules.google",
authHint: "Jules API key for creating and managing cloud coding tasks.",
},
devin: {
id: "devin",
alias: "devin",
name: "Devin",
icon: "smart_toy",
color: "#111827",
textIcon: "DV",
website: "https://devin.ai",
authHint: "Devin API key for cloud agent sessions.",
},
"codex-cloud": {
id: "codex-cloud",
alias: "codex-cloud",
name: "Codex Cloud",
icon: "cloud",
color: "#10A37F",
textIcon: "CC",
website: "https://openai.com/codex",
authHint: "OpenAI API key with Codex Cloud task access.",
},
};
export function isClaudeCodeCompatibleProvider(providerId: unknown): providerId is string {
return typeof providerId === "string" && providerId.startsWith(CLAUDE_CODE_COMPATIBLE_PREFIX);
}
export function isLocalProvider(providerId: unknown): boolean {
return (
typeof providerId === "string" &&
Object.prototype.hasOwnProperty.call(LOCAL_PROVIDERS, providerId)
);
}
export const SELF_HOSTED_CHAT_PROVIDER_IDS = new Set([
"lm-studio",
"vllm",
"lemonade",
"llamafile",
"llama-cpp",
"triton",
"docker-model-runner",
"xinference",
"oobabooga",
]);
export function isSelfHostedChatProvider(providerId: unknown): boolean {
return typeof providerId === "string" && SELF_HOSTED_CHAT_PROVIDER_IDS.has(providerId);
}
export function providerAllowsOptionalApiKey(providerId: unknown): boolean {
return (
providerId === "searxng-search" ||
providerId === "pollinations" ||
providerId === "copilot-web" ||
providerId === "duckduckgo-web" ||
providerId === "veoaifree-web" ||
providerId === "hackclub" ||
providerId === "huggingchat" ||
providerId === "gitlawb" ||
providerId === "gitlawb-gmi" ||
providerId === "mimocode" ||
providerId === "opencode" ||
isLocalProvider(providerId) ||
isSelfHostedChatProvider(providerId) ||
isOpenAICompatibleProvider(providerId) ||
isAnthropicCompatibleProvider(providerId)
);
}
/**
* Providers explicitly excluded from bulk API key add — auth is heterogeneous,
* OAuth-based, multi-field, or requires manual setup per connection.
*/
const BULK_API_KEY_EXCLUDED = new Set([
"vertex",
"vertex-partner",
"ollama-local",
"grok-web",
"perplexity-web",
"blackbox-web",
"muse-spark-web",
"deepseek-web",
"inner-ai",
"qoder",
"google-pse-search",
"command-code",
"azure",
"cloudflare-ai",
]);
export function supportsBulkApiKey(providerId: unknown): boolean {
if (typeof providerId !== "string" || !providerId) return false;
if (BULK_API_KEY_EXCLUDED.has(providerId)) return false;
if (isLocalProvider(providerId)) return false;
if (isSelfHostedChatProvider(providerId)) return false;
if (isClaudeCodeCompatibleProvider(providerId)) return false;
return true;
}
// ── System Providers (virtual, not user-connectable) ──────────────────────────
export const SYSTEM_PROVIDERS = {
auto: {
id: "auto",
alias: "auto",
name: "Auto (Zero-Config)",
icon: "auto_awesome",
color: "#6366F1",
textIcon: "Auto",
systemOnly: true,
description: "Zero-config auto-routing with LKGP across all connected providers",
},
};
const _PROVIDER_SECTIONS = [
NOAUTH_PROVIDERS,
OAUTH_PROVIDERS,
APIKEY_PROVIDERS,
WEB_COOKIE_PROVIDERS,
LOCAL_PROVIDERS,
SEARCH_PROVIDERS,
AUDIO_ONLY_PROVIDERS,
UPSTREAM_PROXY_PROVIDERS,
CLOUD_AGENT_PROVIDERS,
SYSTEM_PROVIDERS,
] as const;
let _aiProviders: Record<string, any> | null = null;
function getOrCreateAiProviders(): Record<string, any> {
if (!_aiProviders) {
_aiProviders = {};
for (const section of _PROVIDER_SECTIONS) {
Object.assign(_aiProviders, section);
}
}
return _aiProviders;
}
let _ALIAS_TO_ID: Record<string, string> | null = null;
function getOrCreateAliasToId(): Record<string, string> {
if (!_ALIAS_TO_ID) {
_ALIAS_TO_ID = {};
for (const section of _PROVIDER_SECTIONS) {
for (const p of Object.values(section)) {
if ((p as any).alias) _ALIAS_TO_ID[(p as any).alias] = (p as any).id;
}
}
}
return _ALIAS_TO_ID;
}
let _ID_TO_ALIAS: Record<string, string> | null = null;
function getOrCreateIdToAlias(): Record<string, string> {
if (!_ID_TO_ALIAS) {
_ID_TO_ALIAS = {};
for (const section of _PROVIDER_SECTIONS) {
for (const p of Object.values(section)) {
_ID_TO_ALIAS[(p as any).id] = (p as any).alias || (p as any).id;
}
}
}
return _ID_TO_ALIAS;
}
export function getProviderById(id: string) {
return (
(NOAUTH_PROVIDERS as Record<string, any>)[id] ??
(OAUTH_PROVIDERS as Record<string, any>)[id] ??
(APIKEY_PROVIDERS as Record<string, any>)[id] ??
(WEB_COOKIE_PROVIDERS as Record<string, any>)[id] ??
(LOCAL_PROVIDERS as Record<string, any>)[id] ??
(SEARCH_PROVIDERS as Record<string, any>)[id] ??
(AUDIO_ONLY_PROVIDERS as Record<string, any>)[id] ??
(UPSTREAM_PROXY_PROVIDERS as Record<string, any>)[id] ??
(CLOUD_AGENT_PROVIDERS as Record<string, any>)[id] ??
(SYSTEM_PROVIDERS as Record<string, any>)[id] ??
undefined
);
}
export const AI_PROVIDERS = new Proxy({} as Record<string, any>, {
get(_, key) {
if (key === "then") return undefined;
return typeof key === "string" ? getOrCreateAiProviders()[key] : undefined;
},
ownKeys() {
return Reflect.ownKeys(getOrCreateAiProviders());
},
has(_, key) {
return key in getOrCreateAiProviders();
},
getOwnPropertyDescriptor(_, key) {
const obj = getOrCreateAiProviders();
if (typeof key === "string" && key in obj) {
return { configurable: true, enumerable: true, value: obj[key] };
}
return undefined;
},
});
export type AiProviderId =
| keyof typeof NOAUTH_PROVIDERS
| keyof typeof OAUTH_PROVIDERS
| keyof typeof APIKEY_PROVIDERS
| keyof typeof WEB_COOKIE_PROVIDERS
| keyof typeof LOCAL_PROVIDERS
| keyof typeof SEARCH_PROVIDERS
| keyof typeof AUDIO_ONLY_PROVIDERS
| keyof typeof UPSTREAM_PROXY_PROVIDERS
| keyof typeof CLOUD_AGENT_PROVIDERS
| keyof typeof SYSTEM_PROVIDERS;
export type AiProviderDefinition =
| (typeof NOAUTH_PROVIDERS)[keyof typeof NOAUTH_PROVIDERS]
| (typeof OAUTH_PROVIDERS)[keyof typeof OAUTH_PROVIDERS]
| (typeof APIKEY_PROVIDERS)[keyof typeof APIKEY_PROVIDERS]
| (typeof WEB_COOKIE_PROVIDERS)[keyof typeof WEB_COOKIE_PROVIDERS]
| (typeof LOCAL_PROVIDERS)[keyof typeof LOCAL_PROVIDERS]
| (typeof SEARCH_PROVIDERS)[keyof typeof SEARCH_PROVIDERS]
| (typeof AUDIO_ONLY_PROVIDERS)[keyof typeof AUDIO_ONLY_PROVIDERS]
| (typeof UPSTREAM_PROXY_PROVIDERS)[keyof typeof UPSTREAM_PROXY_PROVIDERS]
| (typeof CLOUD_AGENT_PROVIDERS)[keyof typeof CLOUD_AGENT_PROVIDERS]
| (typeof SYSTEM_PROVIDERS)[keyof typeof SYSTEM_PROVIDERS];
// Auth methods
export const AUTH_METHODS = {
oauth: { id: "oauth", name: "OAuth", icon: "lock" },
apikey: { id: "apikey", name: "API Key", icon: "key" },
};
export function getProviderByAlias(alias: string): AiProviderDefinition | null {
for (const section of _PROVIDER_SECTIONS) {
for (const provider of Object.values(section)) {
if (provider.alias === alias || provider.id === alias) {
return provider as AiProviderDefinition;
}
}
}
return null;
}
// Helper: Get provider ID from alias
export function resolveProviderId(aliasOrId: string): string {
const provider = getProviderByAlias(aliasOrId);
return provider?.id || aliasOrId;
}
export function getProviderAlias(providerId: string): string {
const provider = getProviderById(providerId);
return provider?.alias || providerId;
}
export const ALIAS_TO_ID = new Proxy({} as Record<string, string>, {
get(_, key) {
return typeof key === "string" ? getOrCreateAliasToId()[key] : undefined;
},
ownKeys() {
return Reflect.ownKeys(getOrCreateAliasToId());
},
has(_, key) {
return key in getOrCreateAliasToId();
},
getOwnPropertyDescriptor(_, key) {
const obj = getOrCreateAliasToId();
if (typeof key === "string" && key in obj) {
return { configurable: true, enumerable: true, value: obj[key] };
}
return undefined;
},
});
export const ID_TO_ALIAS = new Proxy({} as Record<string, string>, {
get(_, key) {
return typeof key === "string" ? getOrCreateIdToAlias()[key] : undefined;
},
ownKeys() {
return Reflect.ownKeys(getOrCreateIdToAlias());
},
has(_, key) {
return key in getOrCreateIdToAlias();
},
getOwnPropertyDescriptor(_, key) {
const obj = getOrCreateIdToAlias();
if (typeof key === "string" && key in obj) {
return { configurable: true, enumerable: true, value: obj[key] };
}
return undefined;
},
});
// Providers that support usage/quota API
export const USAGE_SUPPORTED_PROVIDERS = [
"antigravity",
"agy",
"gemini-cli",
"kiro",
"amazon-q",
"github",
"codex",
"claude",
"cursor",
"kimi-coding",
"glm",
"glm-cn",
"zai",
"glmt",
"opencode-go",
"minimax",
"minimax-cn",
"crof",
"nanogpt",
"deepseek",
"xiaomi-mimo",
"vertex",
"vertex-partner",
];
// ── Zod validation at module load (Phase 7.2) ──
import { validateProviders } from "../validation/providerSchema";
validateProviders(NOAUTH_PROVIDERS, "NOAUTH_PROVIDERS");
validateProviders(OAUTH_PROVIDERS, "OAUTH_PROVIDERS");
validateProviders(APIKEY_PROVIDERS, "APIKEY_PROVIDERS");
validateProviders(WEB_COOKIE_PROVIDERS, "WEB_COOKIE_PROVIDERS");
validateProviders(LOCAL_PROVIDERS, "LOCAL_PROVIDERS");
validateProviders(SEARCH_PROVIDERS, "SEARCH_PROVIDERS");
validateProviders(AUDIO_ONLY_PROVIDERS, "AUDIO_ONLY_PROVIDERS");
validateProviders(UPSTREAM_PROXY_PROVIDERS, "UPSTREAM_PROXY_PROVIDERS");
validateProviders(CLOUD_AGENT_PROVIDERS, "CLOUD_AGENT_PROVIDERS");