import { type AiGatewayProvider } from '@/lib/ai/router'; // Base URLs mapping for providers const PROVIDER_URLS: Record = { openai: 'https://api.openai.com/v1', deepseek: 'https://api.deepseek.com/v1', openrouter: 'https://openrouter.ai/api/v1', mistral: 'https://api.mistral.ai/v1', zai: 'https://api.zukijourney.com/v1', minimax: 'https://api.minimax.chat/v1', glm: 'https://open.bigmodel.ai/api/paas/v4', }; // Fallback popular models when live fetching fails or for providers without /models endpoint (e.g. Anthropic, Google) export const PROVIDER_MODEL_SUGGESTIONS: Record = { openai: ['gpt-4o-mini', 'gpt-4o', 'gpt-4-turbo', 'gpt-3.5-turbo'], anthropic: ['claude-3-5-sonnet-latest', 'claude-3-5-haiku-latest', 'claude-3-opus-latest'], google: ['gemini-1.5-flash', 'gemini-1.5-pro', 'gemini-2.0-flash-exp'], deepseek: ['deepseek-chat', 'deepseek-coder'], minimax: ['abab6.5-chat', 'abab6.5s-chat'], mistral: ['mistral-small-latest', 'mistral-medium-latest', 'mistral-large-latest'], glm: ['glm-4', 'glm-4-flash'], openrouter: ['openai/gpt-4o-mini', 'anthropic/claude-3.5-sonnet', 'deepseek/deepseek-chat'], custom: [], }; /** * Dynamically queries the provider's /models endpoint using the user's API Key * to fetch their actual available models list instead of relying on hardcoded choices. */ export async function fetchLiveModelsForProvider( provider: AiGatewayProvider, apiKey: string, customBaseUrl?: string ): Promise { try { // Anthropic and Google do not expose a public list via a simple key GET /models (or need specific formats) // We fall back to the popular defaults for those. if (provider === 'anthropic' || provider === 'anthropic_custom' || provider === 'google') { const standardProvider = provider === 'anthropic_custom' ? 'anthropic' : provider; return PROVIDER_MODEL_SUGGESTIONS[standardProvider] ?? []; } const baseUrl = provider === 'custom' ? customBaseUrl?.replace(/\/$/, '') : PROVIDER_URLS[provider]; if (!baseUrl) { return PROVIDER_MODEL_SUGGESTIONS[provider] ?? []; } const headers: Record = { 'Content-Type': 'application/json' }; headers['Authorization'] = `Bearer ${apiKey}`; if (provider === 'openrouter') { headers['HTTP-Referer'] = 'https://localhost:3000'; headers['X-Title'] = 'Memento AI'; } const response = await fetch(`${baseUrl}/models`, { headers, signal: AbortSignal.timeout(6000), }); if (!response.ok) { return PROVIDER_MODEL_SUGGESTIONS[provider] ?? []; } const data = await response.json(); const fetched: string[] = (data.data ?? []) .map((m: any) => m.id || m.name) .filter(Boolean) .sort(); if (fetched.length > 0) { return fetched; } } catch (err) { console.warn(`[fetchLiveModelsForProvider] Failed to fetch live models for ${provider}, using fallbacks:`, err); } return PROVIDER_MODEL_SUGGESTIONS[provider] ?? []; }