| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- from __future__ import annotations
- from typing import Any
- import httpx
- DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1"
- def normalize_base_url(base_url: str | None) -> str:
- return (base_url or DEFAULT_OPENAI_BASE_URL).rstrip("/")
- def chat(provider: dict[str, Any], model: dict[str, Any], prompt: str, temperature: float) -> dict[str, Any]:
- base_url = normalize_base_url(provider.get("base_url"))
- headers = {"Content-Type": "application/json"}
- api_key = provider.get("api_key")
- if api_key:
- headers["Authorization"] = f"Bearer {api_key}"
- payload = {
- "model": model["name"],
- "messages": [{"role": "user", "content": prompt}],
- "temperature": temperature,
- }
- with httpx.Client(timeout=120) as client:
- response = client.post(f"{base_url}/chat/completions", json=payload, headers=headers)
- response.raise_for_status()
- data = response.json()
- content = data.get("choices", [{}])[0].get("message", {}).get("content")
- if content is None:
- content = ""
- return {"content": content, "raw_response": data}
- def chat_with_images(
- provider: dict[str, Any],
- model: dict[str, Any],
- prompt: str,
- images: list[dict[str, str]],
- temperature: float,
- ) -> dict[str, Any]:
- base_url = normalize_base_url(provider.get("base_url"))
- headers = {"Content-Type": "application/json"}
- api_key = provider.get("api_key")
- if api_key:
- headers["Authorization"] = f"Bearer {api_key}"
- content: list[dict[str, Any]] = [{"type": "text", "text": prompt}]
- for image in images:
- content.append(
- {
- "type": "image_url",
- "image_url": {"url": f"data:{image['mime_type']};base64,{image['base64']}"},
- }
- )
- payload = {
- "model": model["name"],
- "messages": [{"role": "user", "content": content}],
- "temperature": temperature,
- }
- with httpx.Client(timeout=180) as client:
- response = client.post(f"{base_url}/chat/completions", json=payload, headers=headers)
- response.raise_for_status()
- data = response.json()
- result = data.get("choices", [{}])[0].get("message", {}).get("content") or ""
- return {"content": result, "raw_response": data}
|