/** Auto-detect available LLM providers from environment variables */ import type { DetectedProvider } from './types.js'; const PROVIDER_ENV_MAP: Record = { openai: { keys: ['OPENAI_API_KEY'], label: 'OpenAI GPT-5.4', model: 'gpt-5.4' }, anthropic: { keys: ['ANTHROPIC_API_KEY'], label: 'Claude Sonnet 4.6', model: 'claude-sonnet-4-6' }, xai: { keys: ['XAI_API_KEY', 'GROK_API_KEY'], label: 'xAI Grok 4', model: 'grok-4' }, mistral: { keys: ['MISTRAL_API_KEY'], label: 'Mistral Large', model: 'mistral-large-latest' }, cohere: { keys: ['COHERE_API_KEY'], label: 'Cohere Command R+', model: 'command-r-plus-08-2024' }, gemini: { keys: ['GEMINI_API_KEY'], label: 'Google Gemini 2.5', model: 'gemini-2.5-flash' }, perplexity: { keys: ['PERPLEXITY_API_KEY'], label: 'Perplexity Sonar Pro', model: 'sonar-pro' }, groq: { keys: ['GROQ_API_KEY'], label: 'Groq', model: 'llama-3.3-70b-versatile' }, huggingface: { keys: ['HF_API_KEY', 'HUGGINGFACE_API_KEY'], label: 'HuggingFace Qwen 3.5', model: 'Qwen/Qwen3.5-9B' }, }; /** * Scan process.env for provider API keys and return detected providers. * Also checks for Ollama at localhost:11434 if reachable. */ export function detectProviders(): DetectedProvider[] { const found: DetectedProvider[] = []; for (const [name, config] of Object.entries(PROVIDER_ENV_MAP)) { for (const envKey of config.keys) { if (process.env[envKey]) { found.push({ name, label: config.label, model: config.model, envKey, }); break; // Only need one key per provider } } } return found; } /** * Check if Ollama is reachable. Call separately since it's async. */ export async function checkOllama(host = 'http://localhost:11434'): Promise { try { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 1500); const res = await fetch(`${host}/api/tags`, { signal: controller.signal }); clearTimeout(timeout); if (res.ok) { return { name: 'ollama', label: 'Ollama (Local)', model: 'llama3.2:3b', envKey: '' }; } } catch { // Not reachable } return null; } /** Resolve the API key for a provider from env */ export function resolveApiKey(provider: string): string { const config = PROVIDER_ENV_MAP[provider]; if (!config) return ''; for (const envKey of config.keys) { if (process.env[envKey]) return process.env[envKey]!; } return ''; }