import logging from typing import Optional from src.llm.base_provider import LLMProvider from src.llm.hf_provider import HuggingFaceProvider from src.llm.ollama_provider import OllamaProvider from utils.config import config from src.services.hf_monitor import hf_monitor logger = logging.getLogger(__name__) class ProviderNotAvailableError(Exception): """Raised when no provider is available""" pass class LLMFactory: """Factory for creating LLM providers with intelligent priority""" _instance = None _providers = {} def __new__(cls): if cls._instance is None: cls._instance = super(LLMFactory, cls).__new__(cls) return cls._instance def get_provider(self, preferred_provider: Optional[str] = None) -> LLMProvider: """ Get an LLM provider based on preference and availability. NEW PRIORITY: HF Endpoint > Ollama > Error """ # Check if HF should be primary (when token available and endpoint ready) if config.hf_token: hf_status = hf_monitor.get_endpoint_status() if hf_status["available"]: try: logger.info("🎯 Using HF Endpoint as PRIMARY provider") return HuggingFaceProvider( model_name="DavidAU/OpenAi-GPT-oss-20b-abliterated-uncensored-NEO-Imatrix-gguf" ) except Exception as e: logger.warning(f"Failed to initialize HF provider: {e}") # Try Ollama as secondary if config.ollama_host: try: logger.info("🦙 Using Ollama as SECONDARY provider") return OllamaProvider( model_name=config.local_model_name ) except Exception as e: logger.warning(f"Failed to initialize Ollama provider: {e}") raise ProviderNotAvailableError("No LLM providers are available") # Global factory instance llm_factory = LLMFactory()