Claude
refactor: use API-reported supports_vision instead of hardcoded model names
d82da85 unverified
Raw
History Blame Contribute Delete
2.1 kB
"""
Interface abstraite commune à tous les providers IA.
"""
# 1. stdlib
from abc import ABC, abstractmethod
from typing import Any
# 2. local
from app.schemas.model_config import ModelInfo, ProviderType
def is_vision_model(model: Any) -> bool:
"""Détermine si un modèle supporte les entrées image.
Les modèles Gemini sont tous multimodaux ; les modèles texte-only (ex :
embedding, AQA) ne contiennent pas 'gemini' dans leur identifiant.
"""
name = (getattr(model, "name", "") or "").lower()
display = (getattr(model, "display_name", "") or "").lower()
return "gemini" in name or "vision" in name or "vision" in display
class AIProvider(ABC):
"""Interface commune à tous les providers IA (Google, Mistral, …)."""
@property
@abstractmethod
def provider_type(self) -> ProviderType: ...
@abstractmethod
def is_configured(self) -> bool:
"""Retourne True si les credentials nécessaires sont présents en environnement."""
...
@abstractmethod
def list_models(self) -> list[ModelInfo]:
"""Liste les modèles disponibles pour ce provider.
Lève RuntimeError si le provider n'est pas configuré.
Propage les exceptions réseau/API sans les masquer.
"""
...
@abstractmethod
def generate_content(
self,
image_bytes: bytes,
prompt: str,
model_id: str,
supports_vision: bool = True,
) -> str:
"""Envoie une image + prompt à l'IA et retourne le texte brut de la réponse.
Args:
image_bytes: contenu JPEG de l'image dérivée.
prompt: texte du prompt rendu depuis le template.
model_id: identifiant technique du modèle à utiliser.
supports_vision: True si le modèle accepte les images (déterminé
par l'API du provider lors du listing, stocké en BDD).
Returns:
Texte brut retourné par l'API (avant parsing).
Raises:
RuntimeError: si le provider n'est pas configuré.
"""
...