research-agent / src /config.py
abhid1234's picture
upload research agent app
056cefb verified
Raw
History Blame Contribute Delete
2.37 kB
"""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)}."
)