diff --git a/artifacts/flask-api/ai_agent.py b/artifacts/flask-api/ai_agent.py index 4401ef2..9c48a6f 100644 --- a/artifacts/flask-api/ai_agent.py +++ b/artifacts/flask-api/ai_agent.py @@ -1,6 +1,6 @@ """ Agent IA pour le filtrage éthique et la synthèse démocratique. -Utilise les Intégrations IA de Replit (OpenAI proxy). +Supporte Mistral AI, OpenAI, et les intégrations Replit AI. """ import json import os @@ -10,25 +10,35 @@ from legal_framework import LEGAL_FILTER_PROMPT, SYNTHESIS_PROMPT logger = logging.getLogger(__name__) +MISTRAL_BASE_URL = "https://api.mistral.ai/v1" + _client: OpenAI | None = None def get_client() -> OpenAI: """ - Supporte deux modes : - - Replit AI Integration : AI_INTEGRATIONS_OPENAI_BASE_URL + AI_INTEGRATIONS_OPENAI_API_KEY - - Auto-hébergement standard : OPENAI_API_KEY (+ OPENAI_BASE_URL optionnel pour proxy) + Supporte trois modes (par ordre de priorité) : + 1. Replit AI Integration : AI_INTEGRATIONS_OPENAI_BASE_URL + AI_INTEGRATIONS_OPENAI_API_KEY + 2. Mistral AI : MISTRAL_API_KEY (+ MISTRAL_BASE_URL optionnel) + 3. OpenAI standard : OPENAI_API_KEY (+ OPENAI_BASE_URL optionnel) """ global _client if _client is None: replit_base = os.environ.get("AI_INTEGRATIONS_OPENAI_BASE_URL") replit_key = os.environ.get("AI_INTEGRATIONS_OPENAI_API_KEY") + mistral_key = os.environ.get("MISTRAL_API_KEY") + mistral_base = os.environ.get("MISTRAL_BASE_URL", MISTRAL_BASE_URL) std_key = os.environ.get("OPENAI_API_KEY") std_base = os.environ.get("OPENAI_BASE_URL") if replit_base and replit_key: + logger.info("Utilisation de l'intégration Replit AI") _client = OpenAI(base_url=replit_base, api_key=replit_key) + elif mistral_key: + logger.info("Utilisation de l'API Mistral AI (%s)", mistral_base) + _client = OpenAI(base_url=mistral_base, api_key=mistral_key) elif std_key: + logger.info("Utilisation de l'API OpenAI") kwargs = {"api_key": std_key} if std_base: kwargs["base_url"] = std_base @@ -36,7 +46,7 @@ def get_client() -> OpenAI: else: raise RuntimeError( "Aucune clé IA configurée. " - "Définissez OPENAI_API_KEY dans le fichier .env " + "Définissez MISTRAL_API_KEY ou OPENAI_API_KEY dans le fichier .env, " "ou configurez les intégrations Replit AI." ) return _client @@ -49,10 +59,10 @@ def filter_idea(content: str) -> dict: """ try: client = get_client() - filter_model = os.environ.get("OPENAI_FILTER_MODEL", "gpt-4o-mini") + filter_model = os.environ.get("FILTER_MODEL", os.environ.get("OPENAI_FILTER_MODEL", "mistral-small-latest")) response = client.chat.completions.create( model=filter_model, - max_completion_tokens=300, + max_tokens=300, response_format={"type": "json_object"}, messages=[ {"role": "system", "content": LEGAL_FILTER_PROMPT}, @@ -112,11 +122,11 @@ def synthesize_ideas(ideas: list[str]) -> str: ) try: client = get_client() - synthesis_model = os.environ.get("OPENAI_SYNTHESIS_MODEL", "gpt-4o") + synthesis_model = os.environ.get("SYNTHESIS_MODEL", os.environ.get("OPENAI_SYNTHESIS_MODEL", "mistral-large-latest")) ideas_text = "\n".join(f"{i + 1}. {idea}" for i, idea in enumerate(ideas)) response = client.chat.completions.create( model=synthesis_model, - max_completion_tokens=1200, + max_tokens=1200, messages=[ {"role": "system", "content": SYNTHESIS_PROMPT}, { diff --git a/artifacts/voix-du-peuple/src/pages/transparence.tsx b/artifacts/voix-du-peuple/src/pages/transparence.tsx index b97ddc8..d3fd2bf 100644 --- a/artifacts/voix-du-peuple/src/pages/transparence.tsx +++ b/artifacts/voix-du-peuple/src/pages/transparence.tsx @@ -81,7 +81,7 @@ export default function Transparence() {
Modèle utilisé
- OpenAI GPT-4o mini par défaut (configurable via la variable d'environnement OPENAI_FILTER_MODEL). Le modèle est interrogé via l'API OpenAI — aucun fine-tuning ni entraînement n'est effectué sur les contributions des utilisateurs.
+ Mistral Small par défaut (configurable via la variable d'environnement FILTER_MODEL). Le modèle est interrogé via l'API Mistral AI — aucun fine-tuning ni entraînement n'est effectué sur les contributions des utilisateurs.
Modèle utilisé
- OpenAI GPT-4o par défaut (configurable via OPENAI_SYNTHESIS_MODEL). Un modèle plus puissant est utilisé ici pour produire un résumé de meilleure qualité.
+ Mistral Large par défaut (configurable via SYNTHESIS_MODEL). Un modèle plus puissant est utilisé ici pour produire un résumé de meilleure qualité.