← back to Bankrupt Leads
src/llm.py
51 lines
"""
Thin Ollama client. No cloud APIs.
Uses /api/chat with format="json" so the model returns parsable JSON.
Falls back to /api/generate for classify (string label) calls.
"""
from __future__ import annotations
import json
import os
import httpx
OLLAMA_HOST = os.environ.get("OLLAMA_HOST", "http://localhost:11434")
def chat_json(model: str, system: str, user: str, *, num_ctx: int = 32768) -> dict:
"""Chat call constrained to JSON output. Returns parsed dict."""
with httpx.Client(timeout=600) as c:
r = c.post(
f"{OLLAMA_HOST}/api/chat",
json={
"model": model,
"format": "json",
"stream": False,
"options": {"temperature": 0, "num_ctx": num_ctx},
"messages": [
{"role": "system", "content": system},
{"role": "user", "content": user},
],
},
)
r.raise_for_status()
body = r.json()["message"]["content"]
return json.loads(body)
def generate_text(model: str, prompt: str, *, num_ctx: int = 8192) -> str:
with httpx.Client(timeout=600) as c:
r = c.post(
f"{OLLAMA_HOST}/api/generate",
json={
"model": model,
"prompt": prompt,
"stream": False,
"options": {"temperature": 0, "num_ctx": num_ctx},
},
)
r.raise_for_status()
return r.json()["response"].strip()