mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 12:22:14 +03:00
* 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>
3146 lines
89 KiB
TypeScript
3146 lines
89 KiB
TypeScript
// 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 (~25K–100K 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");
|