2026-01-04 21:58:59 -05:00
// Provider definitions
2026-03-30 00:28:07 -04:00
// Free Providers (kiro first, iflow last)
2026-02-06 23:17:06 -05:00
export const FREE _PROVIDERS = {
2026-03-30 00:28:07 -04:00
kiro : { id : "kiro" , alias : "kr" , name : "Kiro AI" , icon : "psychology_alt" , color : "#FF6B35" } ,
2026-04-29 00:34:39 -04:00
qwen : { id : "qwen" , alias : "qw" , name : "Qwen Code" , icon : "psychology" , color : "#10B981" , deprecated : true , deprecationNotice : "Qwen OAuth free tier was discontinued by Alibaba on 2026-04-15. New connections will not work." , serviceKinds : [ "llm" , "tts" , "stt" ] , ttsConfig : { baseUrl : "http://localhost:8000/v1/audio/speech" , authType : "none" , authHeader : "none" , format : "openai" , models : [ { id : "qwen3-tts" , name : "Qwen3 TTS" } ] } } ,
2026-04-13 01:04:57 -04:00
"gemini-cli" : { id : "gemini-cli" , alias : "gc" , name : "Gemini CLI" , icon : "terminal" , color : "#4285F4" , deprecated : true , deprecationNotice : "Gemini CLI is designed exclusively for Gemini CLI. Using it with other tools (OpenClaw, Claude, Codex...) may result in account restrictions or bans." } ,
2026-03-30 00:28:07 -04:00
// gitlab: { id: "gitlab", alias: "gl", name: "GitLab Duo", icon: "code", color: "#FC6D26" },
// codebuddy: { id: "codebuddy", alias: "cb", name: "CodeBuddy", icon: "smart_toy", color: "#006EFF" },
2026-03-31 04:41:52 -04:00
// qoder: { id: "qoder", alias: "qd", name: "Qoder AI", icon: "water_drop", color: "#EC4899" },
2026-03-30 00:28:07 -04:00
iflow : { id : "iflow" , alias : "if" , name : "iFlow AI" , icon : "water_drop" , color : "#6366F1" } ,
2026-04-22 03:16:21 -04:00
opencode : { id : "opencode" , alias : "oc" , name : "OpenCode Free" , icon : "terminal" , color : "#E87040" , textIcon : "OC" , noAuth : true , passthroughModels : true , modelsFetcher : { url : "https://opencode.ai/zen/v1/models" , type : "opencode-free" } } ,
2026-03-30 00:28:07 -04:00
} ;
// Free Tier Providers (has free access but may require account/API key)
export const FREE _TIER _PROVIDERS = {
2026-04-29 00:34:39 -04:00
openrouter : { id : "openrouter" , alias : "openrouter" , name : "OpenRouter" , icon : "router" , color : "#F97316" , textIcon : "OR" , website : "https://openrouter.ai" , notice : { text : "Free tier: 27+ free models, no credit card needed, 200 req/day. After $10 credit: 1,000 req/day." , apiKeyUrl : "https://openrouter.ai/settings/keys" } , modelsFetcher : { url : "https://openrouter.ai/api/v1/models" , type : "openrouter-free" } , passthroughModels : true , serviceKinds : [ "llm" , "embedding" , "tts" , "imageToText" ] , embeddingConfig : { baseUrl : "https://openrouter.ai/api/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "openai/text-embedding-3-small" , name : "Text Embedding 3 Small (OpenRouter)" , dimensions : 1536 } , { id : "openai/text-embedding-3-large" , name : "Text Embedding 3 Large (OpenRouter)" , dimensions : 3072 } , { id : "openai/text-embedding-ada-002" , name : "Text Embedding Ada 002 (OpenRouter)" , dimensions : 1536 } ] } } ,
nvidia : { id : "nvidia" , alias : "nvidia" , name : "NVIDIA NIM" , icon : "developer_board" , color : "#76B900" , textIcon : "NV" , website : "https://developer.nvidia.com/nim" , notice : { text : "Free access for NVIDIA Developer Program members (prototyping & testing)." , apiKeyUrl : "https://build.nvidia.com/settings/api-keys" } , serviceKinds : [ "llm" , "tts" , "embedding" , "stt" ] , ttsConfig : { baseUrl : "https://integrate.api.nvidia.com/v1/audio/speech" , authType : "apikey" , authHeader : "bearer" , format : "nvidia-tts" , models : [ { id : "fastpitch" , name : "FastPitch" } , { id : "tacotron2" , name : "Tacotron2" } ] } , embeddingConfig : { baseUrl : "https://integrate.api.nvidia.com/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "nvidia/nv-embedqa-e5-v5" , name : "NV EmbedQA E5 v5" , dimensions : 1024 } ] } } ,
2026-03-31 04:41:52 -04:00
ollama : { id : "ollama" , alias : "ollama" , name : "Ollama Cloud" , icon : "cloud" , color : "#ffffffff" , textIcon : "OL" , website : "https://ollama.com" , notice : { text : "Free tier: light usage, 1 cloud model at a time (limits reset every 5h & 7d). Pro $20/mo · Max $100/mo." , apiKeyUrl : "https://ollama.com/settings/keys" } } ,
2026-03-30 00:28:07 -04:00
vertex : { id : "vertex" , alias : "vx" , name : "Vertex AI" , icon : "cloud" , color : "#4285F4" , textIcon : "VX" , website : "https://cloud.google.com/vertex-ai" , notice : { text : "New Google Cloud accounts get $300 free credits. Requires GCP project + Service Account with Vertex AI API enabled." , apiKeyUrl : "https://console.cloud.google.com/iam-admin/serviceaccounts" } } ,
2026-04-29 00:34:39 -04:00
gemini : { id : "gemini" , alias : "gemini" , name : "Gemini" , icon : "diamond" , color : "#4285F4" , textIcon : "GE" , website : "https://ai.google.dev" , serviceKinds : [ "llm" , "embedding" , "image" , "imageToText" , "webSearch" ] , searchViaChat : { defaultModel : "gemini-2.5-flash" , pricingUrl : "https://ai.google.dev/pricing" , freeTier : "Free tier: 15 RPM, 1M tokens/day on gemini-2.5-flash via AI Studio." } , embeddingConfig : { baseUrl : "https://generativelanguage.googleapis.com/v1beta/models" , authType : "apikey" , authHeader : "key" , models : [ { id : "text-embedding-004" , name : "Text Embedding 004" , dimensions : 768 } , { id : "embedding-001" , name : "Embedding 001" , dimensions : 768 } ] } } ,
2026-04-25 06:04:48 -04:00
byteplus : { id : "byteplus" , alias : "bpm" , name : "BytePlus ModelArk" , icon : "cloud" , color : "#2563EB" , textIcon : "BP" , website : "https://console.byteplus.com/ark" , notice : { text : "Free credits for new accounts. Access to Seed 2.0, Kimi K2 Thinking, GLM 4.7, GPT-OSS-120B models." , apiKeyUrl : "https://console.byteplus.com/ark/region:ark+ap-southeast-1/apiKey" } , serviceKinds : [ "llm" ] } ,
2026-02-06 23:17:06 -05:00
} ;
2026-04-13 01:04:57 -04:00
// Thinking config definitions
// options: list of selectable modes ("auto" = no override from server)
// defaultMode: fallback when user hasn't configured
// extended: claude-style thinking (thinking.type + budget_tokens) — used by most providers
// effort: openai-style reasoning_effort — only openai + codex
export const THINKING _CONFIG = {
extended : {
options : [ "auto" , "on" , "off" ] ,
defaultMode : "auto" ,
defaultBudgetTokens : 10000
} ,
effort : {
options : [ "auto" , "none" , "low" , "medium" , "high" ] ,
defaultMode : "auto"
}
} ;
2026-01-04 21:58:59 -05:00
// OAuth Providers
export const OAUTH _PROVIDERS = {
claude : { id : "claude" , alias : "cc" , name : "Claude Code" , icon : "smart_toy" , color : "#D97757" } ,
2026-04-13 01:04:57 -04:00
antigravity : { id : "antigravity" , alias : "ag" , name : "Antigravity" , icon : "rocket_launch" , color : "#F59E0B" , deprecated : true , deprecationNotice : "AG is designed exclusively for Antigravity IDE. Using it with other tools (OpenClaw, Claude, Codex...) may result in account restrictions or bans." } ,
2026-04-25 05:22:30 -04:00
codex : { id : "codex" , alias : "cx" , name : "OpenAI Codex" , icon : "code" , color : "#3B82F6" , thinkingConfig : THINKING _CONFIG . effort , serviceKinds : [ "llm" , "image" ] , kindNotice : { image : "Requires a ChatGPT Plus (or higher) account. Free accounts are not supported for image generation." } } ,
2026-04-29 00:34:39 -04:00
github : { id : "github" , alias : "gh" , name : "GitHub Copilot" , icon : "code" , color : "#333333" , serviceKinds : [ "llm" , "embedding" ] , embeddingConfig : { baseUrl : "https://models.github.ai/inference/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "text-embedding-3-small" , name : "Text Embedding 3 Small (GitHub)" , dimensions : 1536 } , { id : "text-embedding-3-large" , name : "Text Embedding 3 Large (GitHub)" , dimensions : 3072 } ] } } ,
2026-02-04 00:07:29 -05:00
cursor : { id : "cursor" , alias : "cu" , name : "Cursor IDE" , icon : "edit_note" , color : "#00D4AA" } ,
2026-03-11 23:48:11 -04:00
// "kimi-coding": { id: "kimi-coding", alias: "kmc", name: "Kimi Coding", icon: "psychology", color: "#1E40AF", textIcon: "KC" },
2026-03-01 06:40:55 -05:00
kilocode : { id : "kilocode" , alias : "kc" , name : "Kilo Code" , icon : "code" , color : "#FF6B35" , textIcon : "KC" } ,
cline : { id : "cline" , alias : "cl" , name : "Cline" , icon : "smart_toy" , color : "#5B9BD5" , textIcon : "CL" } ,
2026-03-30 00:28:07 -04:00
// opencode: { id: "opencode", alias: "oc", name: "OpenCode", icon: "terminal", color: "#E87040", textIcon: "OC" },
2026-01-04 21:58:59 -05:00
} ;
export const APIKEY _PROVIDERS = {
2026-02-20 05:05:46 -05:00
glm : { id : "glm" , alias : "glm" , name : "GLM Coding" , icon : "code" , color : "#2563EB" , textIcon : "GL" , website : "https://open.bigmodel.cn" } ,
2026-02-24 22:34:52 -05:00
"glm-cn" : { id : "glm-cn" , alias : "glm-cn" , name : "GLM (China)" , icon : "code" , color : "#DC2626" , textIcon : "GC" , website : "https://open.bigmodel.cn" } ,
2026-04-29 00:34:39 -04:00
kimi : { id : "kimi" , alias : "kimi" , name : "Kimi" , icon : "psychology" , color : "#1E3A8A" , textIcon : "KM" , website : "https://kimi.moonshot.cn" , serviceKinds : [ "llm" , "webSearch" ] , searchViaChat : { defaultModel : "kimi-k2.5" , pricingUrl : "https://platform.moonshot.ai/docs/pricing/chat" } } ,
minimax : { id : "minimax" , alias : "minimax" , name : "Minimax Coding" , icon : "memory" , color : "#7C3AED" , textIcon : "MM" , website : "https://www.minimaxi.com" , serviceKinds : [ "llm" , "image" , "imageToText" , "webSearch" ] , searchViaChat : { defaultModel : "MiniMax-M2.7" , pricingUrl : "https://www.minimaxi.com/document/price" } } ,
2026-02-20 05:05:46 -05:00
"minimax-cn" : { id : "minimax-cn" , alias : "minimax-cn" , name : "Minimax (China)" , icon : "memory" , color : "#DC2626" , textIcon : "MC" , website : "https://www.minimaxi.com" } ,
2026-03-01 21:31:16 -05:00
alicode : { id : "alicode" , alias : "alicode" , name : "Alibaba" , icon : "cloud" , color : "#FF6A00" , textIcon : "ALi" } ,
2026-03-06 22:08:55 -05:00
"alicode-intl" : { id : "alicode-intl" , alias : "alicode-intl" , name : "Alibaba Intl" , icon : "cloud" , color : "#FF6A00" , textIcon : "ALi" } ,
2026-05-01 05:32:25 -04:00
"xiaomi-mimo" : { id : "xiaomi-mimo" , alias : "mimo" , name : "Xiaomi MiMo" , icon : "smart_toy" , color : "#FF6900" , textIcon : "XM" , website : "https://xiaomimimo.com" } ,
2026-04-23 22:28:50 -04:00
"volcengine-ark" : { id : "volcengine-ark" , alias : "ark" , name : "Volcengine Ark" , icon : "cloud" , color : "#1677FF" , textIcon : "ARK" , website : "https://ark.cn-beijing.volces.com" } ,
2026-04-29 00:34:39 -04:00
openai : { id : "openai" , alias : "openai" , name : "OpenAI" , icon : "auto_awesome" , color : "#10A37F" , textIcon : "OA" , website : "https://platform.openai.com" , serviceKinds : [ "llm" , "embedding" , "tts" , "image" , "imageToText" , "webSearch" ] , thinkingConfig : THINKING _CONFIG . effort , searchViaChat : { defaultModel : "gpt-4o-mini" , pricingUrl : "https://openai.com/api/pricing" } , ttsConfig : { baseUrl : "https://api.openai.com/v1/audio/speech" , authType : "apikey" , authHeader : "bearer" , format : "openai" , models : [ { id : "tts-1" , name : "TTS-1" } , { id : "tts-1-hd" , name : "TTS-1 HD" } , { id : "gpt-4o-mini-tts" , name : "GPT-4o Mini TTS" } ] } , embeddingConfig : { baseUrl : "https://api.openai.com/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "text-embedding-3-small" , name : "Text Embedding 3 Small" , dimensions : 1536 } , { id : "text-embedding-3-large" , name : "Text Embedding 3 Large" , dimensions : 3072 } , { id : "text-embedding-ada-002" , name : "Text Embedding Ada 002" , dimensions : 1536 } ] } } ,
2026-04-14 23:45:46 -04:00
anthropic : { id : "anthropic" , alias : "anthropic" , name : "Anthropic" , icon : "smart_toy" , color : "#D97757" , textIcon : "AN" , website : "https://console.anthropic.com" , serviceKinds : [ "llm" , "imageToText" ] } ,
2026-04-22 03:16:21 -04:00
"opencode-go" : { id : "opencode-go" , alias : "ocg" , name : "OpenCode Go" , icon : "terminal" , color : "#E87040" , textIcon : "OC" , website : "https://opencode.ai/auth" , notice : { text : "OpenCode Go subscription: $5/mo (then $10/mo). Access to Kimi, GLM, Qwen, MiMo, MiniMax models." , apiKeyUrl : "https://opencode.ai/auth" } } ,
2026-04-23 23:04:59 -04:00
azure : { id : "azure" , alias : "azure" , name : "Azure OpenAI" , icon : "cloud" , color : "#0078D4" , textIcon : "AZ" , website : "https://azure.microsoft.com/en-us/products/ai-services/openai-service" , hasProviderSpecificData : true } ,
2026-04-07 00:35:25 -04:00
2026-02-20 05:05:46 -05:00
deepseek : { id : "deepseek" , alias : "ds" , name : "DeepSeek" , icon : "bolt" , color : "#4D6BFE" , textIcon : "DS" , website : "https://deepseek.com" } ,
2026-04-14 23:45:46 -04:00
groq : { id : "groq" , alias : "groq" , name : "Groq" , icon : "speed" , color : "#F55036" , textIcon : "GQ" , website : "https://groq.com" , serviceKinds : [ "llm" , "imageToText" ] } ,
2026-04-29 00:34:39 -04:00
xai : { id : "xai" , alias : "xai" , name : "xAI (Grok)" , icon : "auto_awesome" , color : "#1DA1F2" , textIcon : "XA" , website : "https://x.ai" , serviceKinds : [ "llm" , "imageToText" , "webSearch" ] , searchViaChat : { defaultModel : "grok-4.20-reasoning" , pricingUrl : "https://x.ai/api#pricing" } } ,
mistral : { id : "mistral" , alias : "mistral" , name : "Mistral" , icon : "air" , color : "#FF7000" , textIcon : "MI" , website : "https://mistral.ai" , serviceKinds : [ "llm" , "imageToText" , "embedding" ] , embeddingConfig : { baseUrl : "https://api.mistral.ai/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "mistral-embed" , name : "Mistral Embed" , dimensions : 1024 } ] } } ,
2026-04-28 00:07:39 -04:00
perplexity : { id : "perplexity" , alias : "pplx" , name : "Perplexity" , icon : "search" , color : "#20808D" , textIcon : "PP" , website : "https://www.perplexity.ai" , serviceKinds : [ "llm" , "webSearch" ] , searchConfig : { baseUrl : "https://api.perplexity.ai/search" , method : "POST" , authType : "apikey" , authHeader : "bearer" , costPerQuery : 0.005 , freeMonthlyQuota : 0 , searchTypes : [ "web" ] , defaultMaxResults : 5 , maxMaxResults : 20 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
2026-04-29 00:34:39 -04:00
together : { id : "together" , alias : "together" , name : "Together AI" , icon : "group_work" , color : "#0F6FFF" , textIcon : "TG" , website : "https://www.together.ai" , serviceKinds : [ "llm" , "embedding" ] , embeddingConfig : { baseUrl : "https://api.together.xyz/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "BAAI/bge-large-en-v1.5" , name : "BGE Large EN v1.5" , dimensions : 1024 } , { id : "togethercomputer/m2-bert-80M-8k-retrieval" , name : "M2 BERT 80M 8K" , dimensions : 768 } ] } } ,
fireworks : { id : "fireworks" , alias : "fireworks" , name : "Fireworks AI" , icon : "local_fire_department" , color : "#7B2EF2" , textIcon : "FW" , website : "https://fireworks.ai" , serviceKinds : [ "llm" , "embedding" ] , embeddingConfig : { baseUrl : "https://api.fireworks.ai/inference/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "nomic-ai/nomic-embed-text-v1.5" , name : "Nomic Embed Text v1.5" , dimensions : 768 } ] } } ,
2026-02-20 05:05:46 -05:00
cerebras : { id : "cerebras" , alias : "cerebras" , name : "Cerebras" , icon : "memory" , color : "#FF4F00" , textIcon : "CB" , website : "https://www.cerebras.ai" } ,
cohere : { id : "cohere" , alias : "cohere" , name : "Cohere" , icon : "hub" , color : "#39594D" , textIcon : "CO" , website : "https://cohere.com" } ,
2026-04-29 00:34:39 -04:00
nebius : { id : "nebius" , alias : "nebius" , name : "Nebius AI" , icon : "cloud" , color : "#6C5CE7" , textIcon : "NB" , website : "https://nebius.com" , serviceKinds : [ "llm" , "embedding" ] , embeddingConfig : { baseUrl : "https://api.tokenfactory.nebius.com/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "Qwen/Qwen3-Embedding-8B" , name : "Qwen3 Embedding 8B" , dimensions : 4096 } ] } } ,
2026-02-20 05:05:46 -05:00
siliconflow : { id : "siliconflow" , alias : "siliconflow" , name : "SiliconFlow" , icon : "cloud_queue" , color : "#5B6EF5" , textIcon : "SF" , website : "https://cloud.siliconflow.com" } ,
2026-04-29 00:34:39 -04:00
hyperbolic : { id : "hyperbolic" , alias : "hyp" , name : "Hyperbolic" , icon : "bolt" , color : "#00D4FF" , textIcon : "HY" , website : "https://hyperbolic.xyz" , serviceKinds : [ "llm" , "tts" ] , ttsConfig : { baseUrl : "https://api.hyperbolic.xyz/v1/audio/generation" , authType : "apikey" , authHeader : "bearer" , format : "hyperbolic" , models : [ { id : "melo-tts" , name : "Melo TTS" } ] } } ,
deepgram : { id : "deepgram" , alias : "dg" , name : "Deepgram" , icon : "mic" , color : "#13EF93" , textIcon : "DG" , website : "https://deepgram.com" , notice : { text : "$200 free credit on signup (no card required). Aura-1: $0.015/1k chars, Aura-2: $0.030/1k chars (Pay-As-You-Go)." , apiKeyUrl : "https://console.deepgram.com/api-keys" } , serviceKinds : [ "stt" , "imageToText" , "tts" ] , ttsConfig : { baseUrl : "https://api.deepgram.com/v1/speak" , authType : "apikey" , authHeader : "token" , format : "deepgram" , models : [ ] } } ,
2026-04-04 04:07:07 -04:00
assemblyai : { id : "assemblyai" , alias : "aai" , name : "AssemblyAI" , icon : "record_voice_over" , color : "#0062FF" , textIcon : "AA" , website : "https://assemblyai.com" , serviceKinds : [ "stt" ] } ,
nanobanana : { id : "nanobanana" , alias : "nb" , name : "NanoBanana" , icon : "image" , color : "#FFD700" , textIcon : "NB" , website : "https://nanobananaapi.ai" , serviceKinds : [ "image" ] } ,
2026-04-29 00:34:39 -04:00
elevenlabs : { id : "elevenlabs" , alias : "el" , name : "ElevenLabs" , icon : "record_voice_over" , color : "#6C47FF" , textIcon : "EL" , website : "https://elevenlabs.io" , serviceKinds : [ "tts" ] , ttsConfig : { baseUrl : "https://api.elevenlabs.io/v1/text-to-speech" , authType : "apikey" , authHeader : "xi-api-key" , format : "elevenlabs" , models : [ { id : "eleven_multilingual_v2" , name : "Eleven Multilingual v2" } , { id : "eleven_turbo_v2_5" , name : "Eleven Turbo v2.5" } ] } } ,
cartesia : { id : "cartesia" , alias : "cartesia" , name : "Cartesia" , icon : "spatial_audio" , color : "#FF4F8B" , textIcon : "CA" , website : "https://cartesia.ai" , serviceKinds : [ "tts" ] , hidden : true , ttsConfig : { baseUrl : "https://api.cartesia.ai/tts/bytes" , authType : "apikey" , authHeader : "x-api-key" , format : "cartesia" , models : [ { id : "sonic-2" , name : "Sonic 2" } , { id : "sonic-3" , name : "Sonic 3" } ] } } ,
playht : { id : "playht" , alias : "playht" , name : "PlayHT" , icon : "play_circle" , color : "#00B4D8" , textIcon : "PH" , website : "https://play.ht" , serviceKinds : [ "tts" ] , hidden : true , ttsConfig : { baseUrl : "https://api.play.ht/api/v2/tts/stream" , authType : "apikey" , authHeader : "playht" , format : "playht" , models : [ { id : "PlayDialog" , name : "PlayDialog" } , { id : "Play3.0-mini" , name : "Play 3.0 Mini" } ] } } ,
"local-device" : { id : "local-device" , alias : "local-device" , name : "Local Device" , icon : "speaker" , color : "#64748B" , textIcon : "LD" , serviceKinds : [ "tts" ] , noAuth : true , ttsConfig : { baseUrl : "local-device" , authType : "none" , authHeader : "none" , format : "local-device" , models : [ ] } } ,
"google-tts" : { id : "google-tts" , alias : "google-tts" , name : "Google TTS" , icon : "record_voice_over" , color : "#4285F4" , textIcon : "GT" , serviceKinds : [ "tts" ] , noAuth : true , ttsConfig : { baseUrl : "google-tts" , authType : "none" , authHeader : "none" , format : "google-tts" , models : [ ] } } ,
"edge-tts" : { id : "edge-tts" , alias : "edge-tts" , name : "Edge TTS" , icon : "record_voice_over" , color : "#0078D4" , textIcon : "ET" , serviceKinds : [ "tts" ] , noAuth : true , ttsConfig : { baseUrl : "edge-tts" , authType : "none" , authHeader : "none" , format : "edge-tts" , models : [ ] } } ,
coqui : { id : "coqui" , alias : "coqui" , name : "Coqui TTS" , icon : "record_voice_over" , color : "#10B981" , textIcon : "CQ" , website : "https://github.com/coqui-ai/TTS" , serviceKinds : [ "tts" ] , hidden : true , noAuth : true , ttsConfig : { baseUrl : "http://localhost:5002/api/tts" , authType : "none" , authHeader : "none" , format : "coqui" , models : [ { id : "tts_models/en/ljspeech/tacotron2-DDC" , name : "Tacotron2 DDC (LJSpeech)" } ] } } ,
tortoise : { id : "tortoise" , alias : "tortoise" , name : "Tortoise TTS" , icon : "record_voice_over" , color : "#7C3AED" , textIcon : "TT" , website : "https://github.com/neonbjb/tortoise-tts" , serviceKinds : [ "tts" ] , hidden : true , noAuth : true , ttsConfig : { baseUrl : "http://localhost:5000/api/tts" , authType : "none" , authHeader : "none" , format : "tortoise" , models : [ { id : "tortoise-v2" , name : "Tortoise v2" } ] } } ,
inworld : { id : "inworld" , alias : "inworld" , name : "Inworld TTS" , icon : "record_voice_over" , color : "#FF6B6B" , textIcon : "IW" , website : "https://inworld.ai" , notice : { text : "Free tier: 40 minutes/month TTS. Paid: TTS-1.5 Mini $0.01/min ($15/1M chars), TTS-1.5 Max $0.025/min ($30/1M chars). 270+ voices, 15 languages." , apiKeyUrl : "https://platform.inworld.ai/api-keys" } , serviceKinds : [ "tts" ] , ttsConfig : { baseUrl : "https://api.inworld.ai/tts/v1/voice" , authType : "apikey" , authHeader : "basic" , format : "inworld" , models : [ { id : "inworld-tts-1.5-mini" , name : "Inworld TTS 1.5 Mini ($0.01/min)" } , { id : "inworld-tts-1.5-max" , name : "Inworld TTS 1.5 Max ($0.025/min)" } ] } } ,
"voyage-ai" : { id : "voyage-ai" , alias : "voyage" , name : "Voyage AI" , icon : "data_array" , color : "#0EA5E9" , textIcon : "VG" , website : "https://www.voyageai.com" , notice : { apiKeyUrl : "https://dash.voyageai.com/api-keys" } , serviceKinds : [ "embedding" ] , embeddingConfig : { baseUrl : "https://api.voyageai.com/v1/embeddings" , authType : "apikey" , authHeader : "bearer" , models : [ { id : "voyage-3-large" , name : "Voyage 3 Large" , dimensions : 1024 } , { id : "voyage-3.5" , name : "Voyage 3.5" , dimensions : 1024 } , { id : "voyage-3.5-lite" , name : "Voyage 3.5 Lite" , dimensions : 1024 } , { id : "voyage-code-3" , name : "Voyage Code 3" , dimensions : 1024 } , { id : "voyage-finance-2" , name : "Voyage Finance 2" , dimensions : 1024 } , { id : "voyage-law-2" , name : "Voyage Law 2" , dimensions : 1024 } , { id : "voyage-multilingual-2" , name : "Voyage Multilingual 2" , dimensions : 1024 } ] } } ,
2026-04-04 04:07:07 -04:00
sdwebui : { id : "sdwebui" , alias : "sdwebui" , name : "SD WebUI" , icon : "brush" , color : "#FF7043" , textIcon : "SD" , website : "https://github.com/AUTOMATIC1111/stable-diffusion-webui" , serviceKinds : [ "image" ] } ,
comfyui : { id : "comfyui" , alias : "comfyui" , name : "ComfyUI" , icon : "account_tree" , color : "#4CAF50" , textIcon : "CF" , website : "https://github.com/comfyanonymous/ComfyUI" , serviceKinds : [ "image" ] } ,
2026-04-29 00:34:39 -04:00
huggingface : { id : "huggingface" , alias : "hf" , name : "HuggingFace" , icon : "face" , color : "#FFD21E" , textIcon : "HF" , website : "https://huggingface.co" , serviceKinds : [ "image" , "imageToText" , "tts" ] , hiddenKinds : [ "tts" ] , ttsConfig : { baseUrl : "https://api-inference.huggingface.co/models" , authType : "apikey" , authHeader : "bearer" , format : "huggingface-tts" , models : [ { id : "facebook/mms-tts-eng" , name : "MMS TTS English" } , { id : "microsoft/speecht5_tts" , name : "SpeechT5 TTS" } ] } } ,
2026-04-17 01:06:00 -04:00
blackbox : { id : "blackbox" , alias : "bb" , name : "Blackbox AI" , icon : "smart_toy" , color : "#5B5FEF" , textIcon : "BB" , website : "https://blackbox.ai" , serviceKinds : [ "llm" ] } ,
2026-03-12 04:24:02 -04:00
chutes : { id : "chutes" , alias : "ch" , name : "Chutes AI" , icon : "water_drop" , color : "#ffffffff" , textIcon : "CH" , website : "https://chutes.ai" } ,
2026-03-12 23:22:59 -04:00
"ollama-local" : { id : "ollama-local" , alias : "ollama-local" , name : "Ollama Local" , icon : "cloud" , color : "#ffffffff" , textIcon : "OL" , website : "https://ollama.com" } ,
feat: Add Google Cloud Vertex AI provider support (vertex, vertex-partner)
Co-authored-by: Quan <quanle96@outlook.com>
PR: https://github.com/decolua/9router/pull/298
Thanks to @kwanLeeFrmVi for the original implementation. Here is a summary
of changes made during review integration:
- Replaced google-auth-library with jose (already a project dependency)
for SA JSON -> OAuth2 Bearer token minting (RS256 JWT assertion flow)
- Moved auth logic (parseSaJson, refreshVertexToken, token cache) from
executor into open-sse/services/tokenRefresh.js to match project pattern
- Fixed executor to use proxyAwareFetch instead of raw fetch (proxy support)
- Simplified buildUrl: use global aiplatform.googleapis.com endpoint for
both vertex (Gemini) and vertex-partner; removed region/modelFamily fields
- Added auto-detection of GCP project_id from raw API key via probe request
(vertex-partner only, cached per key)
- Added vertex/vertex-partner cases to /api/providers/validate/route.js
- Updated model lists based on live testing:
- vertex: gemini-3.1-pro-preview, gemini-3.1-flash-lite-preview,
gemini-3-flash-preview, gemini-2.5-flash (removed gemini-2.5-pro: 404)
- vertex-partner: deepseek-v3.2, qwen3-next-80b (instruct+thinking),
glm-5 (removed Mistral/Llama: not enabled in test project)
- gemini provider: added gemini-3.1-pro-preview, gemini-3.1-flash-lite-preview
- Removed bun.lock (project uses npm/package-lock.json)
- Removed region and modelFamily UI fields (global endpoint, auto-detect)
- Kiro token auto-refresh on AccessDeniedException (from commit 2)
Made-with: Cursor
2026-03-14 00:37:23 -04:00
"vertex-partner" : { id : "vertex-partner" , alias : "vxp" , name : "Vertex Partner" , icon : "cloud" , color : "#34A853" , textIcon : "VP" , website : "https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-partner-models" } ,
2026-04-28 06:28:57 -04:00
tavily : { id : "tavily" , alias : "tavily" , name : "Tavily" , icon : "search" , color : "#5B21B6" , textIcon : "TV" , website : "https://tavily.com" , notice : { apiKeyUrl : "https://app.tavily.com/home" } , serviceKinds : [ "webSearch" , "webFetch" ] , searchConfig : { baseUrl : "https://api.tavily.com/search" , method : "POST" , authType : "apikey" , authHeader : "bearer" , costPerQuery : 0.008 , freeMonthlyQuota : 1000 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 20 , timeoutMs : 10000 , cacheTTLMs : 300000 } , fetchConfig : { baseUrl : "https://api.tavily.com/extract" , method : "POST" , authType : "apikey" , authHeader : "bearer" , costPerQuery : 0.008 , freeMonthlyQuota : 1000 , formats : [ "markdown" , "text" ] , maxCharacters : 100000 , timeoutMs : 15000 } } ,
"brave-search" : { id : "brave-search" , alias : "brave" , name : "Brave Search" , icon : "travel_explore" , color : "#FB542B" , textIcon : "BR" , website : "https://brave.com/search/api" , notice : { apiKeyUrl : "https://api-dashboard.search.brave.com/app/keys" } , serviceKinds : [ "webSearch" ] , searchConfig : { baseUrl : "https://api.search.brave.com/res/v1" , method : "GET" , authType : "apikey" , authHeader : "x-subscription-token" , costPerQuery : 0.005 , freeMonthlyQuota : 1000 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 20 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
serper : { id : "serper" , alias : "serper" , name : "Serper" , icon : "search" , color : "#4F46E5" , textIcon : "SP" , website : "https://serper.dev" , notice : { apiKeyUrl : "https://serper.dev/api-key" } , serviceKinds : [ "webSearch" ] , searchConfig : { baseUrl : "https://google.serper.dev" , method : "POST" , authType : "apikey" , authHeader : "x-api-key" , costPerQuery : 0.001 , freeMonthlyQuota : 2500 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 100 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
exa : { id : "exa" , alias : "exa" , name : "Exa" , icon : "manage_search" , color : "#2563EB" , textIcon : "EX" , website : "https://exa.ai" , notice : { apiKeyUrl : "https://dashboard.exa.ai/api-keys" } , serviceKinds : [ "webSearch" , "webFetch" ] , searchConfig : { baseUrl : "https://api.exa.ai/search" , method : "POST" , authType : "apikey" , authHeader : "x-api-key" , costPerQuery : 0.007 , freeMonthlyQuota : 1000 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 100 , timeoutMs : 10000 , cacheTTLMs : 300000 } , fetchConfig : { baseUrl : "https://api.exa.ai/contents" , method : "POST" , authType : "apikey" , authHeader : "x-api-key" , costPerQuery : 0.001 , freeMonthlyQuota : 1000 , formats : [ "text" , "markdown" ] , maxCharacters : 100000 , timeoutMs : 15000 } } ,
2026-04-28 00:07:39 -04:00
searxng : { id : "searxng" , alias : "searxng" , name : "SearXNG" , icon : "saved_search" , color : "#3B82F6" , textIcon : "SX" , website : "https://docs.searxng.org" , serviceKinds : [ "webSearch" ] , noAuth : true , searchConfig : { baseUrl : "http://localhost:8888/search" , method : "GET" , authType : "none" , authHeader : "none" , costPerQuery : 0 , freeMonthlyQuota : 999999 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 50 , timeoutMs : 10000 , cacheTTLMs : 180000 } } ,
2026-04-28 06:28:57 -04:00
"google-pse" : { id : "google-pse" , alias : "gpse" , name : "Google PSE" , icon : "search" , color : "#4285F4" , textIcon : "GP" , website : "https://programmablesearchengine.google.com" , notice : { apiKeyUrl : "https://programmablesearchengine.google.com/controlpanel/create" } , serviceKinds : [ "webSearch" ] , searchConfig : { baseUrl : "https://www.googleapis.com/customsearch/v1" , method : "GET" , authType : "apikey" , authHeader : "key" , costPerQuery : 0.005 , freeMonthlyQuota : 3000 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 10 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
linkup : { id : "linkup" , alias : "linkup" , name : "Linkup" , icon : "link" , color : "#0EA5E9" , textIcon : "LK" , website : "https://linkup.so" , notice : { apiKeyUrl : "https://app.linkup.so/api-keys" } , serviceKinds : [ "webSearch" ] , searchConfig : { baseUrl : "https://api.linkup.so/v1/search" , method : "POST" , authType : "apikey" , authHeader : "bearer" , costPerQuery : 0.005 , freeMonthlyQuota : 1000 , searchTypes : [ "web" ] , defaultMaxResults : 5 , maxMaxResults : 50 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
searchapi : { id : "searchapi" , alias : "searchapi" , name : "SearchAPI" , icon : "search" , color : "#0EA5A4" , textIcon : "SA" , website : "https://www.searchapi.io" , notice : { apiKeyUrl : "https://www.searchapi.io/dashboard" } , serviceKinds : [ "webSearch" ] , searchConfig : { baseUrl : "https://www.searchapi.io/api/v1/search" , method : "GET" , authType : "apikey" , authHeader : "api_key" , costPerQuery : 0.004 , freeMonthlyQuota : 100 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 100 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
youcom : { id : "youcom" , alias : "youcom" , name : "You.com Search" , icon : "search" , color : "#7C3AED" , textIcon : "YC" , website : "https://you.com" , notice : { apiKeyUrl : "https://api.you.com" } , serviceKinds : [ "webSearch" ] , searchConfig : { baseUrl : "https://ydc-index.io/v1/search" , method : "GET" , authType : "apikey" , authHeader : "x-api-key" , costPerQuery : 0.005 , freeMonthlyQuota : 0 , searchTypes : [ "web" , "news" ] , defaultMaxResults : 5 , maxMaxResults : 100 , timeoutMs : 10000 , cacheTTLMs : 300000 } } ,
firecrawl : { id : "firecrawl" , alias : "firecrawl" , name : "Firecrawl" , icon : "local_fire_department" , color : "#F59E0B" , textIcon : "FC" , website : "https://firecrawl.dev" , notice : { apiKeyUrl : "https://www.firecrawl.dev/app/api-keys" } , serviceKinds : [ "webFetch" ] , fetchConfig : { baseUrl : "https://api.firecrawl.dev/v1/scrape" , method : "POST" , authType : "apikey" , authHeader : "bearer" , costPerQuery : 0.002 , freeMonthlyQuota : 500 , formats : [ "markdown" , "html" , "text" ] , maxCharacters : 200000 , timeoutMs : 30000 } } ,
"jina-reader" : { id : "jina-reader" , alias : "jina" , name : "Jina Reader" , icon : "menu_book" , color : "#000000" , textIcon : "JR" , website : "https://jina.ai/reader" , notice : { apiKeyUrl : "https://jina.ai/?sui=apikey" } , serviceKinds : [ "webFetch" ] , fetchConfig : { baseUrl : "https://r.jina.ai" , method : "GET" , authType : "apikey" , authHeader : "bearer" , costPerQuery : 0 , freeMonthlyQuota : 1000000 , formats : [ "markdown" , "text" , "html" ] , maxCharacters : 200000 , timeoutMs : 30000 } } ,
2026-01-04 21:58:59 -05:00
} ;
2026-04-22 00:58:53 -04:00
// Web Cookie Providers (use browser session cookie instead of API key)
export const WEB _COOKIE _PROVIDERS = {
"grok-web" : { id : "grok-web" , alias : "gw" , name : "Grok Web (Subscription)" , icon : "auto_awesome" , color : "#1DA1F2" , textIcon : "GW" , website : "https://grok.com" , authType : "cookie" , authHint : "Paste your sso= cookie value from grok.com" , passthroughModels : true , serviceKinds : [ "llm" ] } ,
"perplexity-web" : { id : "perplexity-web" , alias : "pw" , name : "Perplexity Web (Pro/Max)" , icon : "search" , color : "#20808D" , textIcon : "PW" , website : "https://www.perplexity.ai" , authType : "cookie" , authHint : "Paste your __Secure-next-auth.session-token cookie value from perplexity.ai" , serviceKinds : [ "llm" ] } ,
} ;
2026-04-04 04:07:07 -04:00
// Media provider kinds — each kind maps to a route and endpoint config
export const MEDIA _PROVIDER _KINDS = [
2026-04-14 23:45:46 -04:00
{ id : "embedding" , label : "Embedding" , icon : "data_array" , endpoint : { method : "POST" , path : "/v1/embeddings" } } ,
{ id : "image" , label : "Text to Image" , icon : "brush" , endpoint : { method : "POST" , path : "/v1/images/generations" } } ,
{ id : "imageToText" , label : "Image to Text" , icon : "image_search" , endpoint : { method : "POST" , path : "/v1/images/understanding" } } ,
{ id : "tts" , label : "Text To Speech" , icon : "record_voice_over" , endpoint : { method : "POST" , path : "/v1/audio/speech" } } ,
{ id : "stt" , label : "STT" , icon : "mic" , endpoint : { method : "POST" , path : "/v1/audio/transcriptions" } } ,
{ id : "webSearch" , label : "Web Search" , icon : "travel_explore" , endpoint : { method : "POST" , path : "/v1/search" } } ,
{ id : "webFetch" , label : "Web Fetch" , icon : "language" , endpoint : { method : "POST" , path : "/v1/web/fetch" } } ,
{ id : "video" , label : "Video" , icon : "movie" , endpoint : { method : "POST" , path : "/v1/video/generations" } } ,
{ id : "music" , label : "Music" , icon : "music_note" , endpoint : { method : "POST" , path : "/v1/audio/music" } } ,
2026-04-04 04:07:07 -04:00
] ;
2026-02-02 07:45:12 -05:00
export const OPENAI _COMPATIBLE _PREFIX = "openai-compatible-" ;
2026-02-03 03:11:41 -05:00
export const ANTHROPIC _COMPATIBLE _PREFIX = "anthropic-compatible-" ;
2026-04-25 05:22:30 -04:00
export const CUSTOM _EMBEDDING _PREFIX = "custom-embedding-" ;
2026-02-02 07:45:12 -05:00
export function isOpenAICompatibleProvider ( providerId ) {
return typeof providerId === "string" && providerId . startsWith ( OPENAI _COMPATIBLE _PREFIX ) ;
}
2026-02-03 03:11:41 -05:00
export function isAnthropicCompatibleProvider ( providerId ) {
return typeof providerId === "string" && providerId . startsWith ( ANTHROPIC _COMPATIBLE _PREFIX ) ;
}
2026-04-25 05:22:30 -04:00
export function isCustomEmbeddingProvider ( providerId ) {
return typeof providerId === "string" && providerId . startsWith ( CUSTOM _EMBEDDING _PREFIX ) ;
}
2026-01-04 21:58:59 -05:00
// All providers (combined)
2026-04-22 00:58:53 -04:00
export const AI _PROVIDERS = { ... FREE _PROVIDERS , ... FREE _TIER _PROVIDERS , ... OAUTH _PROVIDERS , ... APIKEY _PROVIDERS , ... WEB _COOKIE _PROVIDERS } ;
2026-01-04 21:58:59 -05:00
// Auth methods
export const AUTH _METHODS = {
oauth : { id : "oauth" , name : "OAuth" , icon : "lock" } ,
apikey : { id : "apikey" , name : "API Key" , icon : "key" } ,
2026-04-22 00:58:53 -04:00
cookie : { id : "cookie" , name : "Browser Cookie" , icon : "cookie" } ,
2026-01-04 21:58:59 -05:00
} ;
// Helper: Get provider by alias
export function getProviderByAlias ( alias ) {
for ( const provider of Object . values ( AI _PROVIDERS ) ) {
if ( provider . alias === alias || provider . id === alias ) {
return provider ;
}
}
return null ;
}
// Helper: Get provider ID from alias
export function resolveProviderId ( aliasOrId ) {
const provider = getProviderByAlias ( aliasOrId ) ;
return provider ? . id || aliasOrId ;
}
// Helper: Get alias from provider ID
export function getProviderAlias ( providerId ) {
const provider = AI _PROVIDERS [ providerId ] ;
return provider ? . alias || providerId ;
}
// Alias to ID mapping (for quick lookup)
export const ALIAS _TO _ID = Object . values ( AI _PROVIDERS ) . reduce ( ( acc , p ) => {
acc [ p . alias ] = p . id ;
return acc ;
} , { } ) ;
// ID to Alias mapping
export const ID _TO _ALIAS = Object . values ( AI _PROVIDERS ) . reduce ( ( acc , p ) => {
acc [ p . id ] = p . alias ;
return acc ;
} , { } ) ;
2026-02-05 06:38:50 -05:00
2026-04-04 04:07:07 -04:00
// Helper: Get providers by service kind (e.g. "tts", "embedding", "image")
// Providers without serviceKinds default to ["llm"]
export function getProvidersByKind ( kind ) {
return Object . values ( AI _PROVIDERS ) . filter ( ( p ) => {
const kinds = p . serviceKinds ? ? [ "llm" ] ;
2026-04-09 23:17:53 -04:00
if ( ! kinds . includes ( kind ) ) return false ;
if ( p . hidden ) return false ; // globally hidden
if ( p . hiddenKinds ? . includes ( kind ) ) return false ; // hidden for specific kind
return true ;
2026-04-04 04:07:07 -04:00
} ) ;
}
2026-02-05 06:38:50 -05:00
// Providers that support usage/quota API
2026-03-11 23:48:11 -04:00
export const USAGE _SUPPORTED _PROVIDERS = [
"claude" ,
"antigravity" ,
"kiro" ,
"github" ,
"codex" ,
"kimi-coding" ,
2026-04-21 23:32:28 -04:00
"ollama" ,
2026-03-11 23:48:11 -04:00
] ;