Compare commits

...
3 Commits
Author SHA1 Message Date
xavier 4ce11d0bfe fix: mise à jour de l'identifiant du modèle Gemini vers gemini-3.5-flash-lite
Build and Push Docker Image / build-and-push (push) Successful in 40s
2026-10-07 15:17:03 +02:00
xavier b3d92558fc fix: correction de l'indentation Python dans models.py provoquant le crash du backend
Build and Push Docker Image / build-and-push (push) Successful in 41s
2026-10-07 14:55:42 +02:00
xavier ec37ac06fe fix: retrait de la dépendance au logger manquant et priorisation de Gemini Direct
Build and Push Docker Image / build-and-push (push) Successful in 42s
2026-10-07 14:39:40 +02:00
2 changed files with 21 additions and 45 deletions

No files matched your search

+5 -11
View File
@@ -1,33 +1,29 @@
from openai import OpenAI from openai import OpenAI
from fastapi import HTTPException from fastapi import HTTPException
from .models import SystemSettings from .models import SystemSettings
from .logger import system_logger
def get_ai_response(messages: list, settings: SystemSettings) -> str: def get_ai_response(messages: list, settings: SystemSettings) -> str:
"""Route la conversation vers le premier fournisseur IA disponible, priorité à Gemini Direct.""" """Route la conversation vers le premier fournisseur IA disponible, priorité à Gemini Direct."""
if not settings: if not settings:
system_logger.error("Configuration système introuvable lors de l'appel IA.")
raise HTTPException(status_code=500, detail="Configuration système introuvable.") raise HTTPException(status_code=500, detail="Configuration système introuvable.")
formatted_messages = [{"role": msg.role, "content": msg.content} for msg in messages] formatted_messages = [{"role": msg.role, "content": msg.content} for msg in messages]
try: try:
# 1. Priorité absolue : Test Gemini direct (Rapide, sans intermédiaire) # 1. Priorité absolue : Test Gemini direct
if settings.gemini_api_key: if settings.gemini_api_key:
client = OpenAI( client = OpenAI(
base_url="https://generativelanguage.googleapis.com/v1beta/openai/", base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
api_key=settings.gemini_api_key api_key=settings.gemini_api_key
) )
# Utilisation de l'identifiant standard API pour la version Flash # Correction : Utilisation exacte du modèle 3.5 Flash-Lite
model = "gemini-1.5-flash" model = "gemini-3.5-flash-lite"
system_logger.info(f"Appel IA via Google Gemini direct (Modèle: {model})")
response = client.chat.completions.create(model=model, messages=formatted_messages) response = client.chat.completions.create(model=model, messages=formatted_messages)
# 2. Test OpenRouter (Fallback) # 2. Test OpenRouter (Fallback)
elif settings.openrouter_api_key: elif settings.openrouter_api_key:
client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=settings.openrouter_api_key) client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=settings.openrouter_api_key)
model = "google/gemini-1.5-pro" # Identifiant mis à jour et valide model = "google/gemini-3.5-flash-lite"
system_logger.info(f"Appel IA via OpenRouter (Modèle: {model})")
response = client.chat.completions.create( response = client.chat.completions.create(
model=model, model=model,
messages=formatted_messages, messages=formatted_messages,
@@ -38,14 +34,12 @@ def get_ai_response(messages: list, settings: SystemSettings) -> str:
elif settings.deepseek_api_key: elif settings.deepseek_api_key:
client = OpenAI(base_url="https://api.deepseek.com/v1", api_key=settings.deepseek_api_key) client = OpenAI(base_url="https://api.deepseek.com/v1", api_key=settings.deepseek_api_key)
model = "deepseek-chat" model = "deepseek-chat"
system_logger.info(f"Appel IA via DeepSeek (Modèle: {model})")
response = client.chat.completions.create(model=model, messages=formatted_messages) response = client.chat.completions.create(model=model, messages=formatted_messages)
# 4. Test Groq # 4. Test Groq
elif settings.groq_api_key: elif settings.groq_api_key:
client = OpenAI(base_url="https://api.groq.com/openai/v1", api_key=settings.groq_api_key) client = OpenAI(base_url="https://api.groq.com/openai/v1", api_key=settings.groq_api_key)
model = "llama3-8b-8192" model = "llama3-8b-8192"
system_logger.info(f"Appel IA via Groq (Modèle: {model})")
response = client.chat.completions.create(model=model, messages=formatted_messages) response = client.chat.completions.create(model=model, messages=formatted_messages)
else: else:
@@ -54,5 +48,5 @@ def get_ai_response(messages: list, settings: SystemSettings) -> str:
return response.choices[0].message.content return response.choices[0].message.content
except Exception as e: except Exception as e:
system_logger.error(f"Erreur API IA : {str(e)}") print(f"Erreur API IA : {str(e)}")
raise HTTPException(status_code=502, detail=f"Détail du fournisseur : {str(e)}") raise HTTPException(status_code=502, detail=f"Détail du fournisseur : {str(e)}")
+16 -34
View File
@@ -1,60 +1,44 @@
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Text from sqlalchemy import Column, Integer, String, Boolean, ForeignKey, DateTime, Float
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from datetime import datetime, timezone from datetime import datetime, timezone
from .database import Base from .database import Base
from sqlalchemy import Float, DateTime
from datetime import datetime, timezone
class User(Base): class User(Base):
__tablename__ = "users" __tablename__ = "users"
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True, nullable=False) email = Column(String, unique=True, index=True)
username = Column(String, unique=True, index=True, nullable=False) username = Column(String, unique=True, index=True)
hashed_password = Column(String, nullable=False) hashed_password = Column(String)
totp_secret = Column(String, nullable=False) totp_secret = Column(String)
is_admin = Column(Boolean, default=False) is_admin = Column(Boolean, default=False)
projects = relationship("Project", back_populates="owner")
# Relation : Un utilisateur peut avoir plusieurs projets
projects = relationship("Project", back_populates="owner", cascade="all, delete-orphan")
class Project(Base): class Project(Base):
__tablename__ = "projects" __tablename__ = "projects"
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
title = Column(String, nullable=False) title = Column(String, index=True)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
is_pinned = Column(Boolean, default=False) is_pinned = Column(Boolean, default=False)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False) user_id = Column(Integer, ForeignKey("users.id"))
# Relations
owner = relationship("User", back_populates="projects") owner = relationship("User", back_populates="projects")
messages = relationship("Message", back_populates="project", cascade="all, delete-orphan") messages = relationship("Message", back_populates="project", cascade="all, delete-orphan")
class Message(Base): class Message(Base):
__tablename__ = "messages" __tablename__ = "messages"
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
role = Column(String, nullable=False) # Ex: 'user', 'assistant', 'worker_1', 'system' role = Column(String)
content = Column(Text, nullable=False) content = Column(String)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
project_id = Column(Integer, ForeignKey("projects.id"), nullable=False) project_id = Column(Integer, ForeignKey("projects.id"))
# Relation
project = relationship("Project", back_populates="messages") project = relationship("Project", back_populates="messages")
class SystemSettings(Base): class SystemSettings(Base):
__tablename__ = "system_settings" __tablename__ = "system_settings"
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
# Serveur Mail (Obligatoire)
smtp_host = Column(String, nullable=False) smtp_host = Column(String, nullable=False)
smtp_port = Column(Integer, nullable=False) smtp_port = Column(Integer, nullable=False)
smtp_user = Column(String, nullable=False) smtp_user = Column(String, nullable=False)
smtp_password = Column(String, nullable=False) smtp_password = Column(String, nullable=False)
# Clés API (Optionnelles)
openrouter_api_key = Column(String, nullable=True) openrouter_api_key = Column(String, nullable=True)
openrouter_management_key = Column(String, nullable=True) openrouter_management_key = Column(String, nullable=True)
groq_api_key = Column(String, nullable=True) groq_api_key = Column(String, nullable=True)
@@ -68,22 +52,20 @@ class SystemSettings(Base):
class AIModel(Base): class AIModel(Base):
"""Stocke la liste des modèles extraits depuis les fournisseurs.""" """Stocke la liste des modèles extraits depuis les fournisseurs."""
__tablename__ = "ai_models" __tablename__ = "ai_models"
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
provider = Column(String, index=True) # ex: openrouter, groq provider = Column(String, index=True)
model_id = Column(String, unique=True, index=True) # ex: google/gemini-1.5-pro model_id = Column(String, unique=True, index=True)
name = Column(String) name = Column(String)
context_length = Column(Integer) context_length = Column(Integer)
pricing_prompt = Column(Float) # Coût pour 1M tokens pricing_prompt = Column(Float)
pricing_completion = Column(Float) pricing_completion = Column(Float)
last_updated = Column(DateTime, default=lambda: datetime.now(timezone.utc)) last_updated = Column(DateTime, default=lambda: datetime.now(timezone.utc))
class FinancialLog(Base): class FinancialLog(Base):
"""Suivi financier par fournisseur.""" """Suivi financier par fournisseur."""
__tablename__ = "financial_logs" __tablename__ = "financial_logs"
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
provider = Column(String, index=True) provider = Column(String, index=True)
balance = Column(Float) # Crédit restant balance = Column(Float)
total_usage = Column(Float) # Consommation totale total_usage = Column(Float)
checked_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) checked_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))