File size: 2,095 Bytes
02197c5
2d76892
02197c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d76892
02197c5
 
 
 
 
 
 
 
 
 
 
 
2d76892
02197c5
 
 
 
 
2d76892
 
d82da85
 
 
 
 
 
 
2d76892
 
 
 
 
 
d82da85
 
2d76892
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""
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é.
        """
        ...