File size: 6,376 Bytes
f6602fb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
import streamlit as st
import google.generativeai as genai
import os
from dotenv import load_dotenv
import http.client
import json
import shutil
# Charger les variables d'environnement
load_dotenv()
# Configurer la clé API
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
# Paramètres de sécurité
safety_settings = [
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
]
# Instructions système pour Mariam (inchangées pour brièveté, mais peuvent être affinées)
ss = """
# Prompt System pour Mariam, IA conçu par youssouf
[...]
"""
# Initialisation du modèle
model = genai.GenerativeModel('gemini-2.0-flash-exp', tools='code_execution',
safety_settings=safety_settings,
system_instruction=ss)
# Fonction de recherche web
def perform_web_search(query):
conn = http.client.HTTPSConnection("google.serper.dev")
payload = json.dumps({"q": query})
headers = {
'X-API-KEY': '9b90a274d9e704ff5b21c0367f9ae1161779b573',
'Content-Type': 'application/json'
}
try:
conn.request("POST", "/search", payload, headers)
res = conn.getresponse()
data = json.loads(res.read().decode("utf-8"))
return data
except Exception as e:
st.error(f"Erreur lors de la recherche web : {e}")
return None
finally:
conn.close()
# Formater les résultats de recherche
def format_search_results(data):
if not data:
return "Aucun résultat trouvé"
result = ""
if 'knowledgeGraph' in data:
kg = data['knowledgeGraph']
result += f"### {kg.get('title', '')}\n*{kg.get('type', '')}*\n\n{kg.get('description', '')}\n\n"
if 'organic' in data:
result += "### Résultats principaux:\n"
for item in data['organic'][:3]:
result += f"- **{item['title']}**\n {item['snippet']}\n [Lien]({item['link']})\n\n"
if 'peopleAlsoAsk' in data:
result += "### Questions fréquentes:\n"
for item in data['peopleAlsoAsk'][:2]:
result += f"- **{item['question']}**\n {item['snippet']}\n\n"
return result
# Convertir les rôles pour Streamlit
def role_to_streamlit(role):
return "assistant" if role == "model" else role
# Initialiser l'état de la session
if "chat" not in st.session_state:
st.session_state.chat = model.start_chat(history=[])
if "web_search" not in st.session_state:
st.session_state.web_search = False
if "messages" not in st.session_state:
st.session_state.messages = []
# Fonction pour effacer l’historique
def clear_chat_history():
st.session_state.chat = model.start_chat(history=[])
st.session_state.messages = []
# Créer un dossier temporaire
os.makedirs("temp", exist_ok=True)
# Titre de l’application
st.title("Mariam AI")
# Section des paramètres dans la barre latérale
with st.sidebar:
st.header("Paramètres")
st.session_state.web_search = st.toggle("Activer la recherche web", value=st.session_state.web_search,
help="Permet d’enrichir les réponses avec des informations du web.")
if st.button("Effacer l’historique", on_click=clear_chat_history):
st.success("Historique effacé.")
# Section de téléchargement de fichiers
with st.sidebar:
st.header("Téléchargement de fichiers")
st.info("Types acceptés : jpg, jpeg, png, pdf, txt")
uploaded_file = st.file_uploader("Choisir un fichier", type=['jpg', 'jpeg', 'png', 'pdf', 'txt'])
# Section de conversation
st.header("Conversation")
chat_container = st.container()
# Afficher les messages
with chat_container:
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# Champ de saisie multiligne
user_input = st.text_area("Votre message", height=100)
# Bouton pour envoyer
if st.button("Envoyer"):
if user_input:
# Ajouter le message de l’utilisateur
st.session_state.messages.append({"role": "user", "content": user_input})
# Traiter le fichier téléchargé
uploaded_gemini_file = None
if uploaded_file:
file_ext = uploaded_file.name.split('.')[-1].lower()
accepted_types = ['jpg', 'jpeg', 'png', 'pdf', 'txt']
if file_ext in accepted_types:
with open(os.path.join("temp", uploaded_file.name), "wb") as f:
f.write(uploaded_file.getbuffer())
try:
uploaded_gemini_file = genai.upload_file(os.path.join("temp", uploaded_file.name))
except Exception as e:
st.error(f"Erreur lors de l’upload du fichier : {e}")
else:
st.error("Type de fichier non accepté. Utilisez jpg, jpeg, png, pdf ou txt.")
# Recherche web si activée
web_results = None
if st.session_state.web_search:
with st.spinner("Recherche web en cours..."):
web_results = perform_web_search(user_input)
if web_results:
formatted_results = format_search_results(web_results)
user_input = f"{user_input}\n\nVoici les résultats de la recherche web. Analyse-les et donne-moi une réponse complète :\n\n{formatted_results}"
# Envoyer à Gemini
try:
if uploaded_gemini_file:
response = st.session_state.chat.send_message([uploaded_gemini_file, "\n\n", user_input])
else:
response = st.session_state.chat.send_message(user_input)
st.session_state.messages.append({"role": "assistant", "content": response.text})
with chat_container:
with st.chat_message("assistant"):
st.markdown(response.text)
except Exception as e:
st.error(f"Erreur lors de l’envoi : {e}")
# Nettoyer les fichiers temporaires
if uploaded_file:
shutil.rmtree("temp", ignore_errors=True)
os.makedirs("temp", exist_ok=True) |