Files
irc-bot/bot/llm_client.py
tocmo0nlord b154f63cfa Initial implementation of IRC LLM bot
Full implementation from spec: ZNC/IRC client with TLS, Ollama LLM backend,
per-user SQLite conversation memory, and Flask web admin portal with 7 pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 22:08:53 -04:00

71 lines
2.2 KiB
Python

import httpx
import logging
logger = logging.getLogger(__name__)
def generate(prompt: str, system: str, config: dict) -> str:
host = config.get("ollama_host", "192.168.2.10")
port = config.get("ollama_port", 11434)
model = config.get("ollama_model", "llama3.1")
timeout = config.get("response_timeout_seconds", 30)
num_predict = config.get("ollama_num_predict", 120)
num_ctx = config.get("ollama_num_ctx", 2048)
temperature = config.get("ollama_temperature", 0.7)
max_length = config.get("max_response_length", 400)
url = f"http://{host}:{port}/api/generate"
payload = {
"model": model,
"system": system,
"prompt": prompt,
"stream": False,
"options": {
"temperature": temperature,
"num_predict": num_predict,
"num_ctx": num_ctx,
},
}
logger.debug(f"[LLM] POST {url} model={model} prompt_len={len(prompt)}")
try:
response = httpx.post(url, json=payload, timeout=timeout)
response.raise_for_status()
text = response.json().get("response", "").strip()
if len(text) > max_length:
text = text[:max_length].rsplit(" ", 1)[0] + ""
logger.debug(f"[LLM] Response ({len(text)} chars): {text[:80]}")
return text
except httpx.TimeoutException:
logger.error(f"[LLM] Timeout after {timeout}s")
raise TimeoutError(f"Ollama did not respond within {timeout}s")
except Exception as e:
logger.error(f"[LLM] Request failed: {e}")
raise
def build_prompt(
user_message: str,
nick: str,
persistent_history: list[dict],
context_buffer: list[str],
) -> str:
parts = []
if persistent_history:
parts.append("--- Past conversation with this user ---")
for ex in persistent_history:
parts.append(f"User: {ex['user']}")
parts.append(f"Assistant: {ex['assistant']}")
parts.append("--- End of past conversation ---")
if context_buffer:
parts.append("--- Recent channel activity ---")
parts.extend(context_buffer)
parts.append("--- End of channel activity ---")
parts.append(f"{nick} asks: {user_message}")
return "\n".join(parts)