Spaces:
Sleeping
Sleeping
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, | |
) | |