- Apply migration 0008_audio_source_import (additive schema for source import) - Apply migration 0009_translation_import_runs (ledger table for import runs) - Wire PostgresAudioImportStore into HTTP commit path with org from node credential - Commit path uses PG store with org from node, no payload org - Bundle hash 21ce5687… remains frozen until v2; no authority transferred
41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
"""OpenAI-compatible LLM client for Ollama and other backends."""
|
|
import os
|
|
import json
|
|
import time
|
|
from typing import Dict, Any, Optional, List
|
|
import urllib.request
|
|
import urllib.error
|
|
|
|
|
|
class LLMClient:
|
|
def __init__(self, base_url: str = "http://localhost:11434/v1", api_key: str = "ollama"):
|
|
self.base_url = base_url.rstrip('/')
|
|
self.api_key = api_key
|
|
|
|
def chat(self, model: str, messages: List[Dict[str, str]],
|
|
temperature: float = 0.2, max_tokens: int = 2000,
|
|
response_format: Optional[Dict] = None) -> Dict[str, Any]:
|
|
url = f"{self.base_url}/chat/completions"
|
|
headers = {
|
|
"Authorization": f"Bearer {self.api_key}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
payload = {
|
|
"model": model,
|
|
"messages": messages,
|
|
"temperature": temperature,
|
|
"stream": False,
|
|
}
|
|
if response_format:
|
|
payload["response_format"] = response_format
|
|
|
|
data = json.dumps(payload).encode('utf-8')
|
|
req = urllib.request.Request(url, data=data, headers=headers)
|
|
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=300) as response:
|
|
body = response.read()
|
|
return json.loads(body.decode('utf-8'))
|
|
except Exception as e:
|
|
raise RuntimeError(f"LLM request failed: {e}")
|