Spaces:
Running
Running
| """Environment + provider configuration. | |
| Single source of truth for which LLM provider/model to use and for | |
| constructing the underlying SDK client. Fails fast with a clear message | |
| when the required API key is missing. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| PROVIDER = os.getenv("LLM_PROVIDER", "anthropic").strip().lower() | |
| _SUPPORTED = {"anthropic", "openai", "gemini"} | |
| _DEFAULT_MODELS = { | |
| "anthropic": "claude-sonnet-4-6", | |
| "openai": "gpt-4o", | |
| "gemini": "gemini-2.5-flash", | |
| } | |
| # Gemini's OpenAI-compatible surface — lets us reuse the OpenAI client/code path. | |
| _GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/" | |
| # Use the explicit MODEL if set, else a sensible per-provider default. | |
| MODEL = (os.getenv("MODEL") or _DEFAULT_MODELS.get(PROVIDER, "claude-sonnet-4-6")).strip() | |
| class ConfigError(RuntimeError): | |
| """Raised when configuration is incomplete or invalid.""" | |
| def _require_key(name: str) -> str: | |
| key = os.getenv(name, "").strip() | |
| if not key: | |
| raise ConfigError( | |
| f"{name} is not set. Copy .env.example to .env and add your key " | |
| f"(LLM_PROVIDER={PROVIDER})." | |
| ) | |
| return key | |
| def get_llm_client(): | |
| """Return an SDK client for the configured provider. | |
| The returned object is the raw provider SDK client. Callers should use | |
| ``src.utils.complete`` rather than calling the client directly so that | |
| provider differences stay in one place. | |
| """ | |
| if PROVIDER == "anthropic": | |
| import anthropic | |
| return anthropic.Anthropic(api_key=_require_key("ANTHROPIC_API_KEY")) | |
| if PROVIDER == "openai": | |
| from openai import OpenAI | |
| return OpenAI(api_key=_require_key("OPENAI_API_KEY")) | |
| if PROVIDER == "gemini": | |
| from openai import OpenAI | |
| # GEMINI_API_KEY preferred; GOOGLE_API_KEY accepted as a fallback. | |
| key = os.getenv("GEMINI_API_KEY", "").strip() or os.getenv( | |
| "GOOGLE_API_KEY", "" | |
| ).strip() | |
| if not key: | |
| raise ConfigError( | |
| "GEMINI_API_KEY is not set. Add it to .env (LLM_PROVIDER=gemini)." | |
| ) | |
| return OpenAI(api_key=key, base_url=_GEMINI_BASE_URL) | |
| raise ConfigError( | |
| f"Unsupported LLM_PROVIDER={PROVIDER!r}. Supported: {sorted(_SUPPORTED)}." | |
| ) | |