Backend: - RuntimeAIConfig singleton: mutable in-memory overrides for provider/model - PATCH /admin/api/ai/config: change active provider/model on the fly - GET /admin/api/ai/config: read current runtime state - ai_vision.py: uses runtime_ai_config before falling back to settings - health/status endpoints reflect runtime overrides Frontend: - 'Définir comme actif' button in AI config section - Live feedback message on save
64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
"""
|
|
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()
|