""" Chiamate LLM via Ollama """ import json import httpx from typing import AsyncGenerator, Optional import config async def llm_call(prompt: str, model: Optional[str] = None) -> str: """Chiamata semplice a Ollama - restituisce risposta completa.""" model = model or config.OLLAMA_MODEL async with httpx.AsyncClient(timeout=120.0) as client: response = await client.post( f"{config.OLLAMA_URL}/api/generate", json={ "model": model, "prompt": prompt, "stream": False } ) response.raise_for_status() return response.json()["response"] async def llm_stream(prompt: str, model: Optional[str] = None) -> AsyncGenerator[str, None]: """Chiamata streaming a Ollama - yields tokens.""" model = model or config.OLLAMA_MODEL async with httpx.AsyncClient(timeout=120.0) as client: async with client.stream( "POST", f"{config.OLLAMA_URL}/api/generate", json={ "model": model, "prompt": prompt, "stream": True } ) as response: response.raise_for_status() async for line in response.aiter_lines(): if line: try: data = json.loads(line) yield data.get("response", "") except json.JSONDecodeError: continue async def llm_chat(messages: list, model: Optional[str] = None) -> AsyncGenerator[str, None]: """Chat mode - streaming.""" model = model or config.OLLAMA_MODEL async with httpx.AsyncClient(timeout=120.0) as client: async with client.stream( "POST", f"{config.OLLAMA_URL}/api/chat", json={ "model": model, "messages": messages, "stream": True } ) as response: response.raise_for_status() async for line in response.aiter_lines(): if line: try: data = json.loads(line) if "content" in data: yield data["content"] except json.JSONDecodeError: continue