"""Local AI provider — Ollama or any OpenAI-compatible API.""" from __future__ import annotations import sys from typing import Any from voice_to_notes.providers.base import AIProvider class LocalProvider(AIProvider): """Connects to Ollama or any OpenAI-compatible API server.""" def __init__(self, base_url: str = "http://localhost:11434/v1", model: str = "llama3.2") -> None: self._base_url = base_url.rstrip("/") self._model = model self._client: Any = None def _ensure_client(self) -> Any: if self._client is not None: return self._client try: from openai import OpenAI self._client = OpenAI( base_url=self._base_url, api_key="ollama", # Ollama doesn't require a real key ) except ImportError: raise RuntimeError( "openai package is required for local AI. Install with: pip install openai" ) return self._client def chat(self, messages: list[dict[str, str]], **kwargs: Any) -> str: client = self._ensure_client() response = client.chat.completions.create( model=self._model, messages=messages, temperature=kwargs.get("temperature", 0.7), max_tokens=kwargs.get("max_tokens", 2048), ) return response.choices[0].message.content or "" def is_available(self) -> bool: try: import urllib.request # Check base URL without /v1 suffix for Ollama root endpoint root_url = self._base_url.replace("/v1", "") req = urllib.request.Request(root_url, method="GET") with urllib.request.urlopen(req, timeout=2) as resp: return resp.status == 200 except Exception: return False @property def name(self) -> str: return "Ollama"