Update AI models to use Mistral by default for better performance
Update backend AI agent to support Mistral API alongside OpenAI and Replit integrations. Default filter model changed to 'mistral-small-latest' and synthesis model to 'mistral-large-latest'. Frontend transparency page updated to reflect these changes and new configuration variables. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 923ae0e3-a363-4db8-b04a-e8baca2a1330 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: ec257d30-4a6a-4c7b-85f5-c18945dba29f Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8af7d2ec-2cc3-4ece-8af3-9f071488d072/923ae0e3-a363-4db8-b04a-e8baca2a1330/qrVKaka Replit-Helium-Checkpoint-Created: true
This commit is contained in:
@@ -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},
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ export default function Transparence() {
|
||||
<div className="bg-muted/40 border border-border/50 p-5 space-y-2">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-widest text-primary">Modèle utilisé</p>
|
||||
<p className="text-foreground/90 text-sm leading-relaxed">
|
||||
OpenAI GPT-4o mini par défaut (configurable via la variable d'environnement <code className="bg-muted px-1 py-0.5 rounded text-xs">OPENAI_FILTER_MODEL</code>). 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 <code className="bg-muted px-1 py-0.5 rounded text-xs">FILTER_MODEL</code>). Le modèle est interrogé via l'API Mistral AI — aucun fine-tuning ni entraînement n'est effectué sur les contributions des utilisateurs.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -153,7 +153,7 @@ export default function Transparence() {
|
||||
<div className="bg-muted/40 border border-border/50 p-5 space-y-2">
|
||||
<p className="font-mono text-xs font-semibold uppercase tracking-widest text-primary">Modèle utilisé</p>
|
||||
<p className="text-foreground/90 text-sm leading-relaxed">
|
||||
OpenAI GPT-4o par défaut (configurable via <code className="bg-muted px-1 py-0.5 rounded text-xs">OPENAI_SYNTHESIS_MODEL</code>). Un modèle plus puissant est utilisé ici pour produire un résumé de meilleure qualité.
|
||||
Mistral Large par défaut (configurable via <code className="bg-muted px-1 py-0.5 rounded text-xs">SYNTHESIS_MODEL</code>). Un modèle plus puissant est utilisé ici pour produire un résumé de meilleure qualité.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -272,8 +272,8 @@ export default function Transparence() {
|
||||
{ label: "Backend", val: "Python / Flask" },
|
||||
{ label: "Base de données", val: "PostgreSQL" },
|
||||
{ label: "Frontend", val: "React + Vite" },
|
||||
{ label: "IA de modération", val: "OpenAI GPT-4o mini (défaut)" },
|
||||
{ label: "IA de synthèse", val: "OpenAI GPT-4o (défaut)" },
|
||||
{ label: "IA de modération", val: "Mistral small (défaut) — configurable via FILTER_MODEL" },
|
||||
{ label: "IA de synthèse", val: "Mistral large (défaut) — configurable via SYNTHESIS_MODEL" },
|
||||
{ label: "Données personnelles", val: "Aucune (pseudonyme facultatif uniquement)" },
|
||||
{ label: "Trackers / publicité", val: "Aucun" },
|
||||
{ label: "Inscription requise", val: "Non" },
|
||||
|
||||
Reference in New Issue
Block a user