Spaces:
Sleeping
Sleeping
| """OpenRouter chat-completions client.""" | |
| from __future__ import annotations | |
| import httpx | |
| from app.config import get_settings | |
| def complete_text( | |
| prompt: str, | |
| *, | |
| system_prompt: str | None = None, | |
| temperature: float = 0.2, | |
| max_tokens: int = 2048, | |
| ) -> str: | |
| """Send a prompt to OpenRouter and return the assistant text.""" | |
| settings = get_settings() | |
| if not settings.openrouter_api_key: | |
| raise RuntimeError("OPENROUTER_API_KEY is not configured.") | |
| messages = [] | |
| if system_prompt: | |
| messages.append({"role": "system", "content": system_prompt}) | |
| messages.append({"role": "user", "content": prompt}) | |
| response = httpx.post( | |
| "https://openrouter.ai/api/v1/chat/completions", | |
| headers={ | |
| "Authorization": f"Bearer {settings.openrouter_api_key}", | |
| "Content-Type": "application/json", | |
| "HTTP-Referer": settings.openrouter_site_url, | |
| "X-Title": settings.openrouter_app_name, | |
| }, | |
| json={ | |
| "model": settings.openrouter_model, | |
| "messages": messages, | |
| "temperature": temperature, | |
| "max_tokens": max_tokens, | |
| }, | |
| timeout=settings.openrouter_timeout_seconds, | |
| ) | |
| try: | |
| response.raise_for_status() | |
| except httpx.HTTPStatusError as exc: | |
| detail = response.text[:500] | |
| raise RuntimeError( | |
| f"OpenRouter request failed with HTTP {response.status_code}: {detail}" | |
| ) from exc | |
| data = response.json() | |
| choices = data.get("choices") or [] | |
| if not choices: | |
| raise RuntimeError("OpenRouter returned no choices.") | |
| content = choices[0].get("message", {}).get("content", "") | |
| if not content: | |
| raise RuntimeError("OpenRouter returned an empty response.") | |
| return content | |