52 lines
1.5 KiB
Python
52 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
from .config import settings
|
|
|
|
|
|
class OpenRouterClient:
|
|
def __init__(self) -> None:
|
|
self.base_url = settings.openrouter_base_url.rstrip("/")
|
|
self.api_key = settings.openrouter_api_key
|
|
self.model = settings.openrouter_model
|
|
self.timeout = settings.request_timeout
|
|
|
|
async def chat_completion(
|
|
self,
|
|
messages: list[dict[str, Any]],
|
|
tools: list[dict[str, Any]] | None = None,
|
|
tool_choice: str | dict[str, Any] | None = None,
|
|
temperature: float = 0.2,
|
|
) -> dict[str, Any]:
|
|
if not self.api_key:
|
|
raise RuntimeError("OPENROUTER_API_KEY is not configured")
|
|
|
|
payload: dict[str, Any] = {
|
|
"model": self.model,
|
|
"messages": messages,
|
|
"temperature": temperature,
|
|
}
|
|
if tools:
|
|
payload["tools"] = tools
|
|
payload["tool_choice"] = tool_choice or "auto"
|
|
|
|
headers = {
|
|
"Authorization": f"Bearer {self.api_key}",
|
|
"Content-Type": "application/json",
|
|
"HTTP-Referer": settings.public_app_url,
|
|
"X-Title": settings.public_app_name,
|
|
}
|
|
|
|
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
|
response = await client.post(
|
|
f"{self.base_url}/chat/completions",
|
|
headers=headers,
|
|
json=payload,
|
|
)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
|