Files
fn_registry/python/functions/infra/ollama_chat.py
T
egutierrez cbc4c5eafa feat: add Python core and infra functions — PWA, geocoding, POI matching
Nuevas funciones Python: build_guide_prompt, generate_pwa_manifest,
generate_service_worker, match_pois_to_interests (core), nominatim_reverse_geocode,
ollama_chat, overpass_nearby_pois (infra). Incluye tests unitarios.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 23:47:19 +02:00

71 lines
2.3 KiB
Python

"""Envía una solicitud de chat completion a Ollama (API local compatible con OpenAI)."""
import json
import urllib.request
import urllib.error
from typing import Any
def ollama_chat(
messages: list[dict],
model: str = "llama3.1:8b",
base_url: str = "http://localhost:11434",
temperature: float = 0.7,
max_tokens: int = 1024,
) -> dict:
"""Envía una solicitud de chat completion a Ollama.
Args:
messages: Lista de mensajes con formato {"role": "system"|"user"|"assistant", "content": str}.
model: Nombre del modelo Ollama a usar.
base_url: URL base de la instancia Ollama.
temperature: Temperatura de generación (0.0 - 1.0).
max_tokens: Número máximo de tokens a generar.
Returns:
Dict con content, model, total_duration_ms y eval_count.
Raises:
RuntimeError: Si Ollama no está corriendo o retorna error HTTP.
"""
url = f"{base_url}/api/chat"
payload = {
"model": model,
"messages": messages,
"stream": False,
"options": {
"temperature": temperature,
"num_predict": max_tokens,
},
}
body = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(
url,
data=body,
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=60) as resp:
raw = resp.read()
except urllib.error.URLError as exc:
reason = str(exc.reason) if hasattr(exc, "reason") else str(exc)
if "connection refused" in reason.lower() or "111" in reason:
raise RuntimeError(f"Ollama no está corriendo en {base_url}") from exc
raise RuntimeError(f"Error de conexión con Ollama: {reason}") from exc
except urllib.error.HTTPError as exc:
raise RuntimeError(f"Ollama retornó HTTP {exc.code}: {exc.reason}") from exc
response: dict[str, Any] = json.loads(raw)
content: str = response["message"]["content"]
total_duration_ns: int = response.get("total_duration", 0)
total_duration_ms: int = int(total_duration_ns / 1_000_000)
eval_count: int = response.get("eval_count", 0)
return {
"content": content,
"model": response.get("model", model),
"total_duration_ms": total_duration_ms,
"eval_count": eval_count,
}