""" Cloud LLM provider registry. Select provider via CLOUD_LLM_PROVIDER env var. Each provider reads its own env vars for auth/config. CLOUD_LLM_PROVIDER=groq → GROQ_API_KEY, GROQ_MODEL, GROQ_BASE_URL CLOUD_LLM_PROVIDER=gemini → GEMINI_API_KEY, GEMINI_MODEL CLOUD_LLM_PROVIDER=openai → OPENAI_API_KEY, OPENAI_MODEL, OPENAI_BASE_URL CLOUD_LLM_PROVIDER=claude → ANTHROPIC_API_KEY, CLAUDE_MODEL """ from __future__ import annotations import os from .base import CloudProvider, ProviderResponse from .groq import GroqProvider from .gemini import GeminiProvider from .openai_compat import OpenAICompatProvider from .claude import ClaudeProvider PROVIDERS: dict[str, type] = { "groq": GroqProvider, "gemini": GeminiProvider, "openai": OpenAICompatProvider, "claude": ClaudeProvider, } _cached: CloudProvider | None = None def get_provider() -> CloudProvider: """Get the configured cloud provider (cached after first call).""" global _cached if _cached is not None: return _cached name = os.environ.get("CLOUD_LLM_PROVIDER", "groq") cls = PROVIDERS.get(name) if cls is None: raise ValueError(f"Unknown provider: {name!r}. Options: {list(PROVIDERS)}") _cached = cls() return _cached def has_api_key() -> bool: """Check if the configured provider has an API key set.""" name = os.environ.get("CLOUD_LLM_PROVIDER", "groq") key_map = { "groq": "GROQ_API_KEY", "gemini": "GEMINI_API_KEY", "openai": "OPENAI_API_KEY", "claude": "ANTHROPIC_API_KEY", } env_var = key_map.get(name, "") return bool(os.environ.get(env_var, ""))