"""Minimal provider HTTP adapters for Groq, DeepSeek, and OpenAI-compatible endpoints using httpx.""" from __future__ import annotations import os from pathlib import Path from typing import Any, Dict, List, Optional import httpx def _load_env_file() -> None: """Loads environment variables from .env if present.""" for parent in [Path.cwd(), Path(__file__).resolve().parent.parent.parent.parent]: env_file = parent / ".env" if env_file.is_file(): try: for line in env_file.read_text(encoding="utf-8").splitlines(): line = line.strip() if line and not line.startswith("#") and "=" in line: key, val = line.split("=", 1) key = key.strip() val = val.strip().strip("'\"") if key and key not in os.environ: os.environ[key] = val except Exception: pass break _load_env_file() class ProviderAdapter: def __init__(self, provider_name: str, base_url: Optional[str] = None): self.provider_name = provider_name self.base_url = base_url async def execute_call( self, model: str, messages: List[Dict[str, str]], temperature: float = 0.0, timeout_seconds: int = 30, response_format: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: raise NotImplementedError class GroqAdapter(ProviderAdapter): def __init__(self, base_url: str = "https://api.groq.com/openai/v1"): super().__init__("groq", base_url) self.api_key = os.environ.get("GROQ_API_KEY", "") async def execute_call( self, model: str, messages: List[Dict[str, str]], temperature: float = 0.0, timeout_seconds: int = 30, response_format: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: headers = { "Authorization": f"Bearer {self.api_key or os.environ.get('GROQ_API_KEY', '')}", "Content-Type": "application/json", } payload: Dict[str, Any] = { "model": model, "messages": messages, "temperature": temperature, } if response_format: payload["response_format"] = response_format async with httpx.AsyncClient(timeout=float(timeout_seconds)) as client: resp = await client.post( f"{self.base_url}/chat/completions", headers=headers, json=payload ) resp.raise_for_status() return resp.json() class DeepSeekAdapter(ProviderAdapter): def __init__(self, base_url: str = "https://api.deepseek.com/v1"): super().__init__("deepseek", base_url) self.api_key = os.environ.get("DEEPSEEK_API_KEY", "") async def execute_call( self, model: str, messages: List[Dict[str, str]], temperature: float = 0.0, timeout_seconds: int = 30, response_format: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: headers = { "Authorization": f"Bearer {self.api_key or os.environ.get('DEEPSEEK_API_KEY', '')}", "Content-Type": "application/json", } payload: Dict[str, Any] = { "model": model, "messages": messages, "temperature": temperature, } if response_format: payload["response_format"] = response_format async with httpx.AsyncClient(timeout=float(timeout_seconds)) as client: resp = await client.post( f"{self.base_url}/chat/completions", headers=headers, json=payload ) resp.raise_for_status() return resp.json() class OpenAIAdapter(ProviderAdapter): def __init__(self, base_url: Optional[str] = None): url = base_url or os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1") super().__init__("openai", url) self.api_key = os.environ.get("OPENAI_API_KEY", "") async def execute_call( self, model: str, messages: List[Dict[str, str]], temperature: float = 0.0, timeout_seconds: int = 30, response_format: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: key = self.api_key or os.environ.get("OPENAI_API_KEY", "") headers = { "Authorization": f"Bearer {key}", "Content-Type": "application/json", } payload: Dict[str, Any] = { "model": model, "messages": messages, "temperature": temperature, } if response_format: payload["response_format"] = response_format async with httpx.AsyncClient(timeout=float(timeout_seconds)) as client: resp = await client.post( f"{self.base_url}/chat/completions", headers=headers, json=payload ) resp.raise_for_status() return resp.json()