""" Factory para criação de providers LLM com fallback automático """ import os from typing import Optional, List, Dict, Any from .base import BaseLLM from .huggingface import HuggingFaceLLM from .openai import OpenAILLM from .anthropic import AnthropicLLM from .ollama import OllamaLLM def create_llm( provider: Optional[str] = None, model_id: Optional[str] = None, fallback: bool = True, **kwargs ) -> Optional[BaseLLM]: """ Cria instância de LLM com base no provider especificado Args: provider: Nome do provider (huggingface, openai, anthropic, ollama) Se None, usa variável de ambiente LLM_PROVIDER model_id: ID do modelo. Se None, usa default do provider fallback: Se True, tenta outros providers em caso de falha **kwargs: Argumentos adicionais para o provider Returns: Instância de BaseLLM ou None se nenhum provider disponível """ # Define provider if provider is None: provider = os.getenv("LLM_PROVIDER", "huggingface").lower() # Lista de providers para tentar (com fallback) if fallback: providers_to_try = _get_fallback_order(provider) else: providers_to_try = [provider] # Tenta cada provider for prov in providers_to_try: llm = _create_provider(prov, model_id, **kwargs) if llm and llm.is_available(): return llm return None def _get_fallback_order(primary: str) -> List[str]: """ Define ordem de fallback com base no provider primário Args: primary: Provider primário Returns: Lista de providers na ordem de tentativa """ # Ordem de preferência: primário -> outros disponíveis all_providers = ["huggingface", "openai", "anthropic", "ollama"] # Coloca primário primeiro if primary in all_providers: all_providers.remove(primary) all_providers.insert(0, primary) return all_providers def _create_provider( provider: str, model_id: Optional[str] = None, **kwargs ) -> Optional[BaseLLM]: """ Cria instância específica de provider Args: provider: Nome do provider model_id: ID do modelo **kwargs: Argumentos adicionais Returns: Instância de BaseLLM ou None """ try: if provider == "huggingface": if model_id is None: model_id = os.getenv("HF_MODEL_ID", "mistralai/Mistral-7B-Instruct-v0.2") api_token = os.getenv("HF_TOKEN", "") return HuggingFaceLLM(model_id, api_token, **kwargs) elif provider == "openai": if model_id is None: model_id = os.getenv("OPENAI_MODEL_ID", "gpt-3.5-turbo") api_key = os.getenv("OPENAI_API_KEY", "") return OpenAILLM(model_id, api_key, **kwargs) elif provider == "anthropic": if model_id is None: model_id = os.getenv("ANTHROPIC_MODEL_ID", "claude-3-haiku-20240307") api_key = os.getenv("ANTHROPIC_API_KEY", "") return AnthropicLLM(model_id, api_key, **kwargs) elif provider == "ollama": if model_id is None: model_id = os.getenv("OLLAMA_MODEL_ID", "llama2") base_url = os.getenv("OLLAMA_BASE_URL", "http://localhost:11434") return OllamaLLM(model_id, base_url, **kwargs) else: return None except Exception: return None def get_available_providers() -> Dict[str, Dict[str, Any]]: """ Lista todos os providers disponíveis e suas informações Returns: Dicionário com informações de cada provider """ providers_info = {} for provider_name in ["huggingface", "openai", "anthropic", "ollama"]: llm = _create_provider(provider_name) if llm: providers_info[provider_name] = { "available": llm.is_available(), "info": llm.get_model_info(), "error": llm.last_error if llm.last_error else None } else: providers_info[provider_name] = { "available": False, "info": None, "error": "Provider não pôde ser criado" } return providers_info