""" Módulo que implementa el contexto del patrón Strategy para modelos de lenguaje. Este módulo contiene la clase LLMContext que mantiene una referencia a la estrategia actual y delega en ella la creación del modelo de lenguaje. """ from typing import Dict, Any, Optional from .strategies import ( LLMStrategy, OpenAIO4MiniStrategy, OpenAIGPT41MiniStrategy, AnthropicHaikuStrategy, AnthropicSonnet37Strategy, AnthropicHaiku45Strategy, ) from .config import LLMConfig class LLMContext: """ Contexto que utiliza diferentes estrategias para crear modelos de lenguaje. Esta clase es el punto central de interacción con el sistema de modelos. Mantiene una referencia a la estrategia actual y delega la creación del modelo a dicha estrategia. """ def __init__(self): """ Inicializa el contexto con las estrategias disponibles. """ # Mapeo de proveedores y modelos a estrategias self._strategies = { "openai": { "o4-mini": OpenAIO4MiniStrategy(), "gpt-4.1-mini": OpenAIGPT41MiniStrategy(), }, "anthropic": { "claude-3-5-haiku-20241022": AnthropicHaikuStrategy(), "claude-sonnet-4-5": AnthropicSonnet37Strategy(), "claude-haiku-4-5": AnthropicHaiku45Strategy(), }, } self._current_strategy: Optional[LLMStrategy] = None self._config: Optional[Dict[str, Any]] = None def set_strategy(self, config: LLMConfig) -> None: """ Establece la estrategia actual basada en la configuración. Args: config: Configuración del modelo Raises: ValueError: Si el proveedor o modelo no están soportados """ provider = config.provider.lower() # Verificar que el proveedor es válido if provider not in self._strategies: raise ValueError(f"Proveedor no soportado: {provider}") # Si se especificó un modelo, usarlo if config.model_name: model_name = config.model_name if model_name not in self._strategies[provider]: raise ValueError(f"Modelo no soportado para {provider}: {model_name}") self._current_strategy = self._strategies[provider][model_name] else: # Si no se especificó un modelo, usar el primero disponible self._current_strategy = next(iter(self._strategies[provider].values())) # Guardar la configuración self._config = config.as_dict() def get_llm(self): """ Crea y devuelve un modelo de lenguaje usando la estrategia actual. Returns: Instancia del modelo de lenguaje Raises: ValueError: Si no se ha establecido una estrategia """ if not self._current_strategy: raise ValueError("No se ha establecido una estrategia") return self._current_strategy.create_llm(self._config) def register_strategy( self, provider: str, model_name: str, strategy: LLMStrategy ) -> None: """ Registra una nueva estrategia. Args: provider: Nombre del proveedor (openai, anthropic) model_name: Nombre del modelo strategy: Instancia de la estrategia a registrar """ provider = provider.lower() # Crear el diccionario del proveedor si no existe if provider not in self._strategies: self._strategies[provider] = {} # Registrar la estrategia self._strategies[provider][model_name] = strategy