Docfile commited on
Commit
29b8358
·
verified ·
1 Parent(s): a25169d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -152
app.py CHANGED
@@ -65,52 +65,6 @@ Mariam est une IA chaleureuse, bienveillante et authentique, conçue pour être
65
  - Pose des questions pertinentes pour mieux comprendre
66
  - Fait preuve d'écoute active
67
  - Rebondit naturellement sur les propos de l'interlocuteur
68
-
69
- ## Limites et Éthique
70
-
71
- - Honnêteté et Transparence
72
- - Reconnaît clairement ses limites
73
- - N'invente pas d'informations
74
- - Suggère de vérifier les informations importantes
75
-
76
- - Éthique et Sécurité
77
- - Refuse poliment les demandes inappropriées
78
- - Oriente vers des ressources fiables si nécessaire
79
- - Priorise toujours la sécurité et le bien-être
80
-
81
- ## Comportements Spécifiques
82
-
83
- - Accueil et Salutations
84
- - Commence les conversations de manière chaleureuse
85
- - Utilise le prénom de l'interlocuteur quand il est connu
86
- - Adapte ses salutations au moment de la journée
87
-
88
- - Gestion des Émotions
89
- - Reconnaît et valide les émotions exprimées
90
- - Offre du soutien de manière appropriée
91
- - Maintient un équilibre entre empathie et professionnalisme
92
-
93
- - Résolution de Problèmes
94
- - Propose des solutions pratiques et adaptées
95
- - Guide l'utilisateur étape par étape
96
- - Vérifie la compréhension et la satisfaction
97
-
98
- ## Exemples de Réponses Types
99
-
100
- "Bonjour [nom] ! Je suis contente de vous retrouver aujourd'hui. Comment puis-je vous aider ?"
101
-
102
- "Je comprends votre frustration face à cette situation. Prenons le temps d'explorer ensemble les solutions possibles."
103
-
104
- "Cette question est intéressante ! Laissez-moi vous expliquer cela de manière simple et claire."
105
-
106
- "Je ne suis pas sûre de la réponse exacte à cette question. Plutôt que de risquer de vous induire en erreur, je vous suggère de vérifier [source fiable]."
107
-
108
- ## Notes d'Implementation
109
-
110
- - Adapter le niveau de langage en fonction de l'interlocuteur
111
- - Maintenir une cohérence dans les réponses
112
- - Garder un historique contextuel pour des interactions plus naturelles
113
- - Mettre à jour régulièrement les connaissances et capacités
114
  """
115
 
116
  # Paramètres de sécurité pour Gemini
@@ -166,6 +120,8 @@ def initialize_session_state():
166
  st.session_state.username = None
167
  if "temp_dir" not in st.session_state:
168
  st.session_state.temp_dir = tempfile.mkdtemp()
 
 
169
 
170
  # Fonction pour effectuer une recherche web
171
  def perform_web_search(query):
@@ -309,133 +265,200 @@ Analyse ces informations et donne une réponse complète et à jour. Cite tes so
309
  finally:
310
  st.session_state.thinking = False
311
 
312
- # Fonction pour afficher l'interface
313
- def render_ui():
314
- """Affiche l'interface utilisateur de l'application."""
315
-
316
- # Configuration du thème et du titre
317
- st.set_page_config(
318
- page_title="Mariam AI",
319
- page_icon="🤖",
320
- layout="wide",
321
- initial_sidebar_state="expanded"
322
- )
323
-
324
- # Barre latérale avec paramètres
325
  with st.sidebar:
326
- st.image("https://via.placeholder.com/150x150.png?text=Mariam+AI", width=150)
327
  st.title("Mariam AI")
328
  st.caption("Votre assistante IA personnelle")
329
 
330
  # Paramètres utilisateur
331
- with st.expander("⚙️ Paramètres", expanded=False):
332
- # Nom d'utilisateur
333
- username = st.text_input("Votre nom (optionnel)", value=st.session_state.username or "")
334
- if username != st.session_state.username:
335
- st.session_state.username = username
336
-
337
- # Activation de la recherche web
338
- web_search = st.toggle(
339
- "Activer la recherche web",
340
- value=st.session_state.web_search,
341
- help="Permet à Mariam d'effectuer des recherches web pour répondre à vos questions"
342
- )
343
- if web_search != st.session_state.web_search:
344
- st.session_state.web_search = web_search
 
345
 
346
  # Actions
347
- with st.expander("🔄 Actions", expanded=False):
348
- if st.button("Nouvelle conversation", use_container_width=True):
349
- st.session_state.chat = st.session_state.model.start_chat(history=[])
350
- st.session_state.messages = []
351
- st.rerun()
352
 
353
  # À propos
354
- with st.expander("ℹ️ À propos", expanded=False):
355
- st.markdown("""
356
- **Mariam AI** est une assistante virtuelle développée par Youssouf.
357
-
358
- Elle est conçue pour être:
359
- - 🤗 Chaleureuse et empathique
360
- - 🧠 Intelligente et informative
361
- - 🛠️ Pratique et utile
362
-
363
- Basée sur la technologie Google Gemini.
364
- """)
365
 
366
  st.divider()
367
- st.caption("© 2025 Mariam AI • Tous droits réservés")
 
 
 
 
 
 
 
 
 
368
 
369
- # Contenu principal
370
- col1, col2 = st.columns([3, 1])
 
 
 
 
371
 
372
- with col1:
373
- # Titre principal
374
- st.title("💬 Discutez avec Mariam")
375
-
376
- # Zone de messages
377
- message_container = st.container(height=500, border=False)
378
-
379
- with message_container:
380
- # Afficher tous les messages
381
- for message in st.session_state.messages:
382
- with st.chat_message(message["role"]):
383
- st.markdown(message["content"])
384
-
385
- # Afficher l'indicateur "en train d'écrire"
386
- if st.session_state.thinking:
387
- with st.chat_message("assistant"):
388
- st.write("Mariam est en train de réfléchir...")
389
-
390
- # Zone de saisie et téléchargement
391
- file_col, input_col = st.columns([1, 4])
392
-
393
- with file_col:
394
- # Zone de téléchargement de fichier
395
- uploaded_file = st.file_uploader(
396
- "Fichier",
397
- type=ALL_ACCEPTED_FILES,
398
- label_visibility="collapsed",
399
- help="Téléchargez une image, un document ou un fichier audio pour en discuter avec Mariam"
400
- )
401
-
402
- with input_col:
403
- # Zone de saisie de texte
404
- user_input = st.chat_input(
405
- "Posez une question à Mariam...",
406
- disabled=st.session_state.thinking
407
- )
408
-
409
- if user_input:
410
- handle_message(user_input, uploaded_file)
411
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
 
413
- with col2:
414
- # Zone d'informations sur les fichiers
415
- st.subheader("📎 Fichiers acceptés")
416
- st.markdown("""
417
- - **Images**: jpg, jpeg, png, gif
418
- - **Documents**: pdf, txt, docx
419
- - **Audio**: mp3, wav, ogg
420
- - **Vidéo**: mp4, mov, avi
421
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
 
423
- # Aperçu du fichier téléchargé
424
- if uploaded_file:
425
- st.subheader("🔍 Fichier téléchargé")
426
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  file_ext = uploaded_file.name.split('.')[-1].lower()
428
 
429
  if file_ext in ACCEPTED_FILE_TYPES['image']:
430
- st.image(uploaded_file, caption=uploaded_file.name, use_column_width=True)
431
  elif file_ext in ACCEPTED_FILE_TYPES['audio']:
432
- st.audio(uploaded_file, format=f'audio/{file_ext}')
433
  elif file_ext in ACCEPTED_FILE_TYPES['video']:
434
  st.video(uploaded_file)
435
  else:
436
  st.info(f"Fichier: {uploaded_file.name}")
437
- file_details = {"Nom": uploaded_file.name, "Type": uploaded_file.type, "Taille": f"{uploaded_file.size / 1024:.1f} KB"}
438
- st.json(file_details)
 
 
 
439
 
440
  # Fonction principale
441
  def main():
@@ -447,8 +470,8 @@ def main():
447
  st.error("Erreur d'initialisation de l'API. Veuillez vérifier votre clé API dans le fichier .env")
448
  st.stop()
449
 
450
- # Afficher l'interface
451
- render_ui()
452
 
453
  # Point d'entrée principal
454
  if __name__ == "__main__":
 
65
  - Pose des questions pertinentes pour mieux comprendre
66
  - Fait preuve d'écoute active
67
  - Rebondit naturellement sur les propos de l'interlocuteur
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  """
69
 
70
  # Paramètres de sécurité pour Gemini
 
120
  st.session_state.username = None
121
  if "temp_dir" not in st.session_state:
122
  st.session_state.temp_dir = tempfile.mkdtemp()
123
+ if "show_sidebar" not in st.session_state:
124
+ st.session_state.show_sidebar = False
125
 
126
  # Fonction pour effectuer une recherche web
127
  def perform_web_search(query):
 
265
  finally:
266
  st.session_state.thinking = False
267
 
268
+ # Fonction pour afficher la barre latérale
269
+ def render_sidebar():
270
+ """Affiche la barre latérale avec les paramètres et informations."""
 
 
 
 
 
 
 
 
 
 
271
  with st.sidebar:
272
+ st.image("https://via.placeholder.com/150x150.png?text=M", width=80)
273
  st.title("Mariam AI")
274
  st.caption("Votre assistante IA personnelle")
275
 
276
  # Paramètres utilisateur
277
+ st.subheader("⚙️ Paramètres")
278
+
279
+ # Nom d'utilisateur
280
+ username = st.text_input("Votre nom (optionnel)", value=st.session_state.username or "")
281
+ if username != st.session_state.username:
282
+ st.session_state.username = username
283
+
284
+ # Activation de la recherche web
285
+ web_search = st.toggle(
286
+ "Recherche web",
287
+ value=st.session_state.web_search,
288
+ help="Permet à Mariam d'effectuer des recherches web"
289
+ )
290
+ if web_search != st.session_state.web_search:
291
+ st.session_state.web_search = web_search
292
 
293
  # Actions
294
+ st.subheader("🔄 Actions")
295
+ if st.button("Nouvelle conversation", use_container_width=True):
296
+ st.session_state.chat = st.session_state.model.start_chat(history=[])
297
+ st.session_state.messages = []
298
+ st.rerun()
299
 
300
  # À propos
301
+ st.subheader("ℹ️ À propos")
302
+ st.markdown("""
303
+ **Mariam AI** est une assistante virtuelle développée par Youssouf.
304
+
305
+ Basée sur la technologie Google Gemini.
306
+ """)
 
 
 
 
 
307
 
308
  st.divider()
309
+ st.caption("© 2025 Mariam AI")
310
+
311
+ # Bouton pour fermer la barre latérale sur mobile
312
+ if st.button("Fermer le menu", use_container_width=True):
313
+ st.session_state.show_sidebar = False
314
+ st.rerun()
315
+
316
+ # Fonction pour afficher l'interface mobile
317
+ def render_mobile_ui():
318
+ """Affiche l'interface utilisateur optimisée pour mobile."""
319
 
320
+ # Configuration de la page
321
+ st.set_page_config(
322
+ page_title="Mariam AI",
323
+ page_icon="🤖",
324
+ initial_sidebar_state="collapsed"
325
+ )
326
 
327
+ # Custom CSS pour améliorer l'interface mobile
328
+ st.markdown("""
329
+ <style>
330
+ .stApp {
331
+ max-width: 100%;
332
+ padding: 0;
333
+ }
334
+ .stChatMessage {
335
+ padding: 8px;
336
+ }
337
+ .stTextInput > div > div > input {
338
+ height: 50px;
339
+ }
340
+ .avatar {
341
+ width: 40px !important;
342
+ height: 40px !important;
343
+ }
344
+ .stFileUploader > div > button {
345
+ height: 50px;
346
+ }
347
+ .mobile-header {
348
+ display: flex;
349
+ align-items: center;
350
+ justify-content: space-between;
351
+ padding: 10px;
352
+ background-color: #f0f2f6;
353
+ border-radius: 8px;
354
+ margin-bottom: 10px;
355
+ }
356
+ .sidebar-toggle {
357
+ cursor: pointer;
358
+ font-size: 24px;
359
+ }
360
+ .chat-container {
361
+ height: calc(100vh - 180px);
362
+ overflow-y: auto;
363
+ padding: 10px 0;
364
+ }
365
+ .input-container {
366
+ position: fixed;
367
+ bottom: 0;
368
+ left: 0;
369
+ right: 0;
370
+ padding: 10px;
371
+ background-color: white;
372
+ box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
373
+ }
374
+ @media (max-width: 768px) {
375
+ .mobile-header {
376
+ position: sticky;
377
+ top: 0;
378
+ z-index: 100;
379
+ }
380
+ }
381
+ </style>
382
+ """, unsafe_allow_html=True)
383
 
384
+ # En-tête mobile avec bouton de menu
385
+ st.markdown("""
386
+ <div class="mobile-header">
387
+ <div class="sidebar-toggle" onclick="document.querySelector('[data-testid=\\"baseButton-secondary\\"]').click();">☰</div>
388
+ <h2 style="margin:0;">Mariam AI</h2>
389
+ <div style="width:24px;"></div>
390
+ </div>
391
+ """, unsafe_allow_html=True)
392
+
393
+ # Affichage conditionnel de la barre latérale
394
+ if st.session_state.show_sidebar:
395
+ render_sidebar()
396
+ else:
397
+ # Bouton pour afficher la barre latérale
398
+ if st.button("☰ Menu", key="show_sidebar"):
399
+ st.session_state.show_sidebar = True
400
+ st.rerun()
401
+
402
+ # Conteneur de messages
403
+ message_container = st.container(height=500, border=False)
404
+ st.markdown('<div class="chat-container">', unsafe_allow_html=True)
405
+
406
+ with message_container:
407
+ # Afficher tous les messages
408
+ for message in st.session_state.messages:
409
+ with st.chat_message(message["role"]):
410
+ st.markdown(message["content"])
411
 
412
+ # Afficher l'indicateur "en train d'écrire"
413
+ if st.session_state.thinking:
414
+ with st.chat_message("assistant"):
415
+ st.write("Mariam réfléchit...")
416
+
417
+ st.markdown('</div>', unsafe_allow_html=True)
418
+
419
+ # Zone de fichier et saisie
420
+ st.markdown('<div class="input-container">', unsafe_allow_html=True)
421
+
422
+ # Conteneur pour l'uploader et l'input
423
+ input_cols = st.columns([1, 4])
424
+
425
+ with input_cols[0]:
426
+ # Zone de téléchargement simplifiée
427
+ uploaded_file = st.file_uploader(
428
+ "",
429
+ type=ALL_ACCEPTED_FILES,
430
+ label_visibility="collapsed",
431
+ key="mobile_uploader"
432
+ )
433
+
434
+ with input_cols[1]:
435
+ # Input chat simplifié
436
+ user_input = st.chat_input(
437
+ "Message à Mariam...",
438
+ disabled=st.session_state.thinking,
439
+ key="mobile_chat_input"
440
+ )
441
+
442
+ st.markdown('</div>', unsafe_allow_html=True)
443
+
444
+ # Affichage du fichier uploadé
445
+ if uploaded_file:
446
+ with st.expander(f"📎 {uploaded_file.name}", expanded=True):
447
  file_ext = uploaded_file.name.split('.')[-1].lower()
448
 
449
  if file_ext in ACCEPTED_FILE_TYPES['image']:
450
+ st.image(uploaded_file, use_column_width=True)
451
  elif file_ext in ACCEPTED_FILE_TYPES['audio']:
452
+ st.audio(uploaded_file)
453
  elif file_ext in ACCEPTED_FILE_TYPES['video']:
454
  st.video(uploaded_file)
455
  else:
456
  st.info(f"Fichier: {uploaded_file.name}")
457
+
458
+ # Traitement des messages
459
+ if user_input:
460
+ handle_message(user_input, uploaded_file)
461
+ st.rerun()
462
 
463
  # Fonction principale
464
  def main():
 
470
  st.error("Erreur d'initialisation de l'API. Veuillez vérifier votre clé API dans le fichier .env")
471
  st.stop()
472
 
473
+ # Afficher l'interface mobile responsive
474
+ render_mobile_ui()
475
 
476
  # Point d'entrée principal
477
  if __name__ == "__main__":