Public Access
chore: Serveur 100% stable, ports corrigés, prêt pour le RAG
Build and Push Docker Image / build-and-push (push) Successful in 1m50s
Build and Push Docker Image / build-and-push (push) Successful in 1m50s
This commit is contained in:
1 parent
7125842853
commit
ffe820b00f
20 files changed
+7772
-198
No files matched your search
+77
-54
@@ -1,73 +1,96 @@
|
||||
import os
|
||||
import time
|
||||
from dotenv import load_dotenv
|
||||
import openai
|
||||
from openai import OpenAI
|
||||
from modules.logger import log_event
|
||||
|
||||
# Initialisation du client OpenRouter avec l'API compatible OpenAI
|
||||
load_dotenv()
|
||||
|
||||
api_key_openrouter = os.getenv("OPENROUTER_API_KEY") or "sk-or-v1-cle-non-definie"
|
||||
|
||||
client = OpenAI(
|
||||
base_url="https://openrouter.ai/api/v1",
|
||||
api_key=os.getenv("OPENROUTER_API_KEY", "VOTRE_CLE_ICI") # À définir dans le .env
|
||||
api_key=api_key_openrouter
|
||||
)
|
||||
|
||||
def interroger_openrouter(prompt, type_modele="openrouter_chat", premium=False, max_retries=3):
|
||||
"""
|
||||
Interroge l'API OpenRouter avec gestion des erreurs 402 (Plafond) et 429 (Rate Limit).
|
||||
Bascule entre les modèles gratuits et premiums (VIP/Payant) selon le choix utilisateur.
|
||||
"""
|
||||
|
||||
# Sélection dynamique des modèles selon l'abonnement
|
||||
if premium:
|
||||
if type_modele == "openrouter_code":
|
||||
nom_modele_api = "anthropic/claude-3.5-sonnet"
|
||||
nom_affichage = "OpenRouter (Claude 3.5 Sonnet - Premium)"
|
||||
couleur = "#d97757" # Orange Anthropic
|
||||
else:
|
||||
nom_modele_api = "openai/gpt-4o-mini"
|
||||
nom_affichage = "OpenRouter (GPT-4o Mini - Premium)"
|
||||
couleur = "#10a37f" # Vert OpenAI
|
||||
else:
|
||||
if type_modele == "openrouter_code":
|
||||
nom_modele_api = "qwen/qwen-2.5-coder-32b-instruct:free"
|
||||
nom_affichage = "OpenRouter (Qwen Coder - Gratuit)"
|
||||
couleur = "#4a90e2" # Bleu clair
|
||||
else:
|
||||
nom_modele_api = "meta-llama/llama-3.1-8b-instruct:free"
|
||||
nom_affichage = "OpenRouter (Llama 3.1 - Gratuit)"
|
||||
couleur = "#4a90e2" # Bleu clair
|
||||
CATALOGUE_MODELES = {
|
||||
"gratuit": {
|
||||
"openrouter_chat": "google/gemma-4-31b-it:free",
|
||||
"openrouter_code": "cohere/north-mini-code:free",
|
||||
"openrouter_droit": "z-ai/glm-5.2:free"
|
||||
},
|
||||
"premium": {
|
||||
"openrouter_chat": "openai/gpt-4o-mini",
|
||||
"openrouter_code": "anthropic/claude-3.5-sonnet",
|
||||
"openrouter_droit": "mistralai/mistral-large-2411"
|
||||
}
|
||||
}
|
||||
|
||||
def verifier_cle_api():
|
||||
cle = os.getenv("OPENROUTER_API_KEY")
|
||||
if not cle or cle == "sk-or-v1-cle-non-definie":
|
||||
raise Exception("Clé OPENROUTER_API_KEY absente dans le fichier .env.")
|
||||
return cle
|
||||
|
||||
def interroger_openrouter(prompt: str, type_modele: str = "openrouter_chat", premium: bool = False, max_retries: int = 2):
|
||||
verifier_cle_api()
|
||||
gamme = "premium" if premium else "gratuit"
|
||||
nom_modele_api = CATALOGUE_MODELES[gamme].get(type_modele, CATALOGUE_MODELES[gamme]["openrouter_chat"])
|
||||
nom_affichage = f"OpenRouter ({nom_modele_api.split('/')[-1]})"
|
||||
couleur = "#d97757" if premium else "#4a90e2"
|
||||
|
||||
for tentative in range(max_retries):
|
||||
try:
|
||||
start_time = time.time()
|
||||
response = client.chat.completions.create(
|
||||
model=nom_modele_api,
|
||||
messages=[{"role": "user", "content": prompt}]
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
extra_headers={
|
||||
"HTTP-Referer": "https://aethas38.duckdns.org",
|
||||
"X-Title": "Aethas38 Multi-IA"
|
||||
},
|
||||
timeout=20.0
|
||||
)
|
||||
texte = response.choices[0].message.content
|
||||
return texte, couleur, "OpenRouter", nom_affichage
|
||||
|
||||
except openai.RateLimitError as e:
|
||||
temps_attente = 2 ** tentative
|
||||
log_event("WARNING", "OPENROUTER", f"Limite de taux atteinte (429). Essai {tentative + 1}/{max_retries}. Attente de {temps_attente}s...")
|
||||
time.sleep(temps_attente)
|
||||
if tentative == max_retries - 1:
|
||||
log_event("ERROR", "OPENROUTER", "Échec définitif suite aux limites de taux (429).")
|
||||
raise Exception("Service temporairement saturé sur OpenRouter. Veuillez réessayer.")
|
||||
|
||||
except openai.APIStatusError as e:
|
||||
if e.status_code == 402:
|
||||
log_event("CRITICAL", "OPENROUTER", "Erreur 402 : Fonds insuffisants ou limite de clé atteinte.")
|
||||
raise Exception("Action requise : Limite de facturation atteinte sur OpenRouter.")
|
||||
else:
|
||||
log_event("ERROR", "OPENROUTER", f"Code {e.status_code} : {e.message}")
|
||||
raise Exception(f"Erreur API OpenRouter : {e.status_code}")
|
||||
|
||||
except openai.APIConnectionError as e:
|
||||
log_event("ERROR", "OPENROUTER", f"Erreur réseau : {e}")
|
||||
raise Exception("Impossible de joindre les serveurs d'OpenRouter.")
|
||||
usage = response.usage
|
||||
tokens_in = usage.prompt_tokens if usage else 0
|
||||
tokens_out = usage.completion_tokens if usage else 0
|
||||
return texte, couleur, "OpenRouter", nom_affichage, tokens_in, tokens_out
|
||||
|
||||
except Exception as e:
|
||||
log_event("ERROR", "OPENROUTER", f"Erreur inattendue : {e}")
|
||||
raise e
|
||||
|
||||
return None, None, None, None
|
||||
log_event("WARNING", "OPENROUTER", f"Tentative {tentative + 1} échouée pour {nom_modele_api} : {e}")
|
||||
if tentative == max_retries - 1:
|
||||
raise e
|
||||
time.sleep(1)
|
||||
|
||||
return None, None, None, None, 0, 0
|
||||
|
||||
def interroger_openrouter_multi(prompt: str, type_modele: str = "openrouter_code", premium: bool = False) -> list:
|
||||
verifier_cle_api()
|
||||
|
||||
if premium:
|
||||
modeles = ["anthropic/claude-3.5-sonnet", "openai/gpt-4o-mini"]
|
||||
else:
|
||||
# Modèles gratuits réactifs sans blocage de quota
|
||||
modeles = ["cohere/north-mini-code:free", "google/gemma-4-31b-it:free"]
|
||||
|
||||
reponses = []
|
||||
for modele in modeles:
|
||||
try:
|
||||
res = client.chat.completions.create(
|
||||
model=modele,
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
extra_headers={
|
||||
"HTTP-Referer": "https://aethas38.duckdns.org",
|
||||
"X-Title": "Aethas38 Multi-IA"
|
||||
},
|
||||
timeout=15.0
|
||||
)
|
||||
contenu = res.choices[0].message.content
|
||||
if contenu:
|
||||
reponses.append({"modele": modele, "texte": contenu})
|
||||
except Exception as e:
|
||||
log_event("WARNING", "OPENROUTER_MULTI", f"Échec rapide pour {modele} : {e}")
|
||||
continue
|
||||
|
||||
return reponses
|
||||
Reference in new issue
Block a user