// Provider alias to ID mapping const ALIAS_TO_PROVIDER_ID = { cc: "claude", cx: "codex", gc: "gemini-cli", qw: "qwen", if: "iflow", ag: "antigravity", gh: "github", kr: "kiro", cu: "cursor", kc: "kilocode", kmc: "kimi-coding", cl: "cline", oc: "opencode", ocg: "opencode-go", // TTS providers el: "elevenlabs", // API Key providers openai: "openai", anthropic: "anthropic", gemini: "gemini", openrouter: "openrouter", glm: "glm", kimi: "kimi", minimax: "minimax", "minimax-cn": "minimax-cn", ds: "deepseek", deepseek: "deepseek", cmc: "commandcode", commandcode: "commandcode", groq: "groq", xai: "xai", mistral: "mistral", pplx: "perplexity", perplexity: "perplexity", together: "together", fireworks: "fireworks", cerebras: "cerebras", cohere: "cohere", nvidia: "nvidia", nebius: "nebius", siliconflow: "siliconflow", hyp: "hyperbolic", hyperbolic: "hyperbolic", dg: "deepgram", deepgram: "deepgram", aai: "assemblyai", assemblyai: "assemblyai", nb: "nanobanana", nanobanana: "nanobanana", ch: "chutes", chutes: "chutes", ark: "volcengine-ark", "volcengine-ark": "volcengine-ark", byteplus: "byteplus", bpm: "byteplus", cursor: "cursor", vx: "vertex", vertex: "vertex", vxp: "vertex-partner", "vertex-partner": "vertex-partner", // Web cookie providers gw: "grok-web", "grok-web": "grok-web", pw: "perplexity-web", "perplexity-web": "perplexity-web", mimo: "xiaomi-mimo", "xiaomi-mimo": "xiaomi-mimo", cf: "cloudflare-ai", "cloudflare-ai": "cloudflare-ai", // Image/video providers fal: "fal-ai", "fal-ai": "fal-ai", stability: "stability-ai", "stability-ai": "stability-ai", bfl: "black-forest-labs", "black-forest-labs": "black-forest-labs", recraft: "recraft", topaz: "topaz", runway: "runwayml", runwayml: "runwayml", // Embedding/rerank jina: "jina-ai", "jina-ai": "jina-ai", // TTS polly: "aws-polly", "aws-polly": "aws-polly", }; /** * Resolve provider alias to provider ID */ export function resolveProviderAlias(aliasOrId) { return ALIAS_TO_PROVIDER_ID[aliasOrId] || aliasOrId; } /** * Parse model string: "alias/model" or "provider/model" or just alias */ export function parseModel(modelStr) { if (!modelStr) { return { provider: null, model: null, isAlias: false, providerAlias: null }; } // Check if standard format: provider/model or alias/model if (modelStr.includes("/")) { const firstSlash = modelStr.indexOf("/"); const providerOrAlias = modelStr.slice(0, firstSlash); const model = modelStr.slice(firstSlash + 1); const provider = resolveProviderAlias(providerOrAlias); return { provider, model, isAlias: false, providerAlias: providerOrAlias }; } // Alias format (model alias, not provider alias) return { provider: null, model: modelStr, isAlias: true, providerAlias: null, }; } /** * Resolve model alias from aliases object * Format: { "alias": "provider/model" } */ export function resolveModelAliasFromMap(alias, aliases) { if (!aliases) return null; // Check if alias exists const resolved = aliases[alias]; if (!resolved) return null; // Resolved value is "provider/model" format if (typeof resolved === "string" && resolved.includes("/")) { const firstSlash = resolved.indexOf("/"); const providerOrAlias = resolved.slice(0, firstSlash); return { provider: resolveProviderAlias(providerOrAlias), model: resolved.slice(firstSlash + 1), }; } // Or object { provider, model } if (typeof resolved === "object" && resolved.provider && resolved.model) { return { provider: resolveProviderAlias(resolved.provider), model: resolved.model, }; } return null; } /** * Get full model info (parse or resolve) * @param {string} modelStr - Model string * @param {object|function} aliasesOrGetter - Aliases object or async function to get aliases */ export async function getModelInfoCore(modelStr, aliasesOrGetter) { const parsed = parseModel(modelStr); if (!parsed.isAlias) { return { provider: parsed.provider, model: parsed.model, }; } // Get aliases (from object or function) const aliases = typeof aliasesOrGetter === "function" ? await aliasesOrGetter() : aliasesOrGetter; // Resolve alias const resolved = resolveModelAliasFromMap(parsed.model, aliases); if (resolved) { return resolved; } // Fallback: infer provider from model name prefix return { provider: inferProviderFromModelName(parsed.model), model: parsed.model, }; } /** * Infer provider from model name prefix * Used as fallback when no provider prefix or alias is given */ function inferProviderFromModelName(modelName) { if (!modelName) return "openai"; const m = modelName.toLowerCase(); if (m.startsWith("claude-")) return "anthropic"; if (m.startsWith("gemini-")) return "gemini"; if (m.startsWith("gpt-")) return "openai"; if (m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4")) return "openai"; if (m.startsWith("deepseek-")) return "openrouter"; // Default fallback return "openai"; }