""" Runtime AI Config — mutable overrides pour le provider/model actif. Permet à l'admin de changer le fournisseur/modèle sans redémarrer. Les overrides sont stockés en mémoire (perdus au redémarrage du backend). """ import threading from typing import Optional class RuntimeAIConfig: """Singleton thread-safe pour les overrides AI runtime.""" def __init__(self): self._lock = threading.Lock() self._provider: Optional[str] = None self._model: Optional[str] = None @property def provider(self) -> Optional[str]: with self._lock: return self._provider @property def model(self) -> Optional[str]: with self._lock: return self._model @property def has_override(self) -> bool: with self._lock: return self._provider is not None def set(self, provider: Optional[str] = None, model: Optional[str] = None) -> None: """Définit les overrides. None = utiliser le défaut de settings.""" with self._lock: self._provider = provider self._model = model def clear(self) -> None: """Réinitialise aux valeurs par défaut.""" with self._lock: self._provider = None self._model = None def to_dict(self) -> dict: """Retourne l'état actuel pour les API.""" from app.config import settings with self._lock: return { "provider": self._provider or settings.AI_PROVIDER, "model": self._model or ( settings.OPENROUTER_MODEL if (self._provider or settings.AI_PROVIDER) == "openrouter" else settings.GEMINI_MODEL ), "is_overridden": self._provider is not None, "override_provider": self._provider, "override_model": self._model, } # Singleton global runtime_ai_config = RuntimeAIConfig()