"""Provider resolution: Settings -> LLMClient.""" from tutor.config import Settings from tutor.services.llm.base import LLMClient from tutor.services.llm.fake import FakeLLMClient from tutor.services.llm.openai_compat import OpenAICompatClient GEMINI_OPENAI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/" _PRESET_BASE_URLS: dict[str, str | None] = { "gemini": GEMINI_OPENAI_BASE_URL, "mistral": "https://api.mistral.ai/v1", "ollama": "http://localhost:11434/v1", # premium mode: reached over Tailscale in M5 "openai": None, # SDK default } def create_llm_client(settings: Settings) -> LLMClient: if settings.llm_provider == "fake": return FakeLLMClient() api_key = settings.llm_api_key.get_secret_value() if settings.llm_api_key else None if settings.llm_provider == "ollama": api_key = api_key or "ollama" # local servers accept any non-empty key if not api_key: msg = f"LLM_API_KEY is required for provider '{settings.llm_provider}'" raise ValueError(msg) return OpenAICompatClient( model=settings.llm_model, api_key=api_key, base_url=settings.llm_base_url or _PRESET_BASE_URLS[settings.llm_provider], timeout_s=settings.llm_timeout_s, )