NutrigenieLLM / client /pages /nutri_old.py
Sahm269's picture
Upload 12 files
5b2d4e7 verified
import streamlit as st
import time
from server.mistral.mistralapi import MistralAPI
from server.security.prompt_guard import Guardrail
from projects.LLM_project.server.db.db_sqlite import (
load_conversations,
load_messages,
update_conversation,
create_conversation,
save_message,
)
def nutri_page():
# Interface Streamlit
# st.set_page_config(page_title="Nutrigénie", layout="wide")
# Section pour afficher l'historique de la conversation
conversation_history = load_conversations()
# st.sidebar.title("Navigation")
st.sidebar.title("Historique")
for conversation_id, _, title in conversation_history:
if (
"conversation_id" in st.session_state
and st.session_state.conversation_id == conversation_id
):
# Bouton désactivé pour la conversation active
st.sidebar.button(
f"🟢 {title}", key=f"conversation_{conversation_id}", disabled=True
)
else:
# Bouton actif pour les autres conversations
if st.sidebar.button(title, key=f"conversation_{conversation_id}"):
# Charger la conversation sélectionnée
st.session_state.conversation_id = conversation_id
st.session_state.messages = load_messages(conversation_id)
update_conversation(conversation_id=st.session_state.conversation_id)
st.rerun()
st.title("Parlez au Nutrigénie")
# Historique de la conversation
if "conversation_id" not in st.session_state:
st.session_state.conversation_id = None
# Affichage des messages précédents
if st.session_state.conversation_id:
st.session_state.messages = load_messages(st.session_state.conversation_id)
if "mistral_model" not in st.session_state:
st.session_state["mistral_model"] = "mistral-large-latest"
if "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
if message["role"] == "user":
with st.chat_message("user"): # Utilisez votre avatar utilisateur
st.markdown(message["content"])
elif message["role"] == "assistant":
with st.chat_message(
"assistant", avatar="client/assets/avatar_bot_big.jpg"
): # Avatar personnalisé pour l'assistant
st.markdown(message["content"])
# Initialisation de Mistral
mistral = MistralAPI(model=st.session_state["mistral_model"])
if prompt := st.chat_input("Dîtes quelque-chose"):
if st.session_state.conversation_id is None:
retries = 0
max_retries = 3
while retries < max_retries:
try:
title = mistral.auto_wrap(
prompt
) # Utiliser le début du message comme titre
except Exception as e:
# Vérifier explicitement si l'erreur est une 429 (rate limit exceeded)
if hasattr(e, "status_code") and e.status_code == 429:
retries += 1
wait_time = 2 ** retries # Temps d'attente exponentiel
st.warning(
f"Limite de requêtes atteinte (429). Nouvel essai dans {wait_time} secondes..."
)
time.sleep(wait_time)
else:
# Gérer d'autres types d'erreurs
st.error(
f"Erreur : Impossible de traiter votre demande (déetails : {str(e)})"
)
st.stop()
if title is not None:
break
# Si tous les retries échouent, retourner un message d'erreur
if title is None:
st.error(
"Impossible d'obtenir une réponse. Limite de requêtes atteinte après plusieurs tentatives."
)
st.stop()
st.session_state.conversation_id = create_conversation(title=title)
st.session_state.messages.append({"role": "user", "content": prompt})
save_message(
conversation_id=st.session_state.conversation_id,
role="user",
content=prompt,
)
with st.chat_message("user"):
st.markdown(prompt)
###################
#### Guardrail ####
###################
try:
guardrail = Guardrail()
except Exception as e:
st.error(
f"Guardrail introuvable. Veuillez relancer le conteneur pour recréer le guardrail. Détails : {e}"
)
st.stop()
# is_supported = await guardrail.analyze_language(prompt)
# if not is_supported:
# st.warning("To use our bot in a safe manner, you must do the conversation in either english, french, german or spanish. If necessary you may use an online translator.")
# st.stop()
is_safe = guardrail.analyze_query(prompt)
if not is_safe:
st.warning(
"Le prompt semble violer nos considérations éthiques. Nous vous invitons à poser une autre question."
)
st.stop()
####################
###### PROMPT ######
####################
with st.chat_message("assistant", avatar="client/assets/avatar_bot_big.jpg"):
retries = 0
max_retries = 3
while retries < max_retries:
response = ""
response_placeholder = st.empty()
try:
stream_response = mistral.stream(
st.session_state.messages
) # Utiliser le début du message comme titr
# Traiter la réponse en streaming
for chunk in stream_response:
response += chunk.data.choices[0].delta.content
response_placeholder.markdown(response)
time.sleep(
0.03
) # Petit délai pour simuler le flux en temps réel
except Exception as e:
if hasattr(e, "status_code") and e.status_code == 429:
# Gestion explicite de l'erreur 429 (Rate Limit Exceeded)
retries += 1
wait_time = 2 ** retries # Délai exponentiel : 2, 4, 8 secondes
st.warning(
f"Limite de requêtes atteinte (429). Nouvel essai dans {wait_time} secondes..."
)
time.sleep(wait_time)
else:
# Gestion d'autres types d'erreurs
st.error(
f"Erreur : Impossible de traiter votre demande (détails : {str(e)})"
)
response_placeholder.markdown(
"Erreur lors de la génération de la réponse."
)
st.stop()
if stream_response is not None:
break # Si le streaming réussit, on sort de la boucle
# Si toutes les tentatives échouent, message d'erreur final
if retries >= max_retries:
st.error(
"Impossible d'obtenir une réponse. Limite de requêtes atteinte après plusieurs tentatives."
)
response = (
"Erreur : Limite de requêtes atteinte après plusieurs tentatives."
)
st.session_state.messages.append({"role": "assistant", "content": response})
save_message(
conversation_id=st.session_state.conversation_id,
role="assistant",
content=response,
)