Update app.py
Browse files
app.py
CHANGED
@@ -229,116 +229,6 @@ retriever = rag_loader.get_retriever(k=5) # Reduced k for faster retrieval
|
|
229 |
# Cache for processed questions
|
230 |
question_cache = {}
|
231 |
|
232 |
-
# prompt_template = ChatPromptTemplate.from_messages([
|
233 |
-
# ("system", """أنت مساعد مفيد يجيب على الأسئلة باللغة العربية باستخدام المعلومات المقدمة.
|
234 |
-
# استخدم المعلومات التالية للإجابة على السؤال:
|
235 |
-
|
236 |
-
# {context}
|
237 |
-
|
238 |
-
# إذا لم تكن المعلومات كافية للإجابة على السؤال بشكل كامل، قل لا أعرف.
|
239 |
-
# أجب بشكل دقيق.
|
240 |
-
# /n
|
241 |
-
# أذكر رقم المادة أو الفصل حسب الحالة.
|
242 |
-
# أذكر اسم ورقم القانون ان كان متوفرا وان لم يكن لا تذكر شيئا.
|
243 |
-
# """),
|
244 |
-
# ("human", "{question}")
|
245 |
-
# ])
|
246 |
-
|
247 |
-
# prompt_template = ChatPromptTemplate.from_messages([
|
248 |
-
# ("system", """Vous êtes un assistant juridique spécialisé qui:
|
249 |
-
|
250 |
-
# 1. CONTEXTE ET SOURCES
|
251 |
-
# - Base vos réponses uniquement sur le contexte fourni : {context}
|
252 |
-
# - Cite systématiquement les références juridiques précises (article, chapitre)
|
253 |
-
# - Mentionne le nom et numéro de la loi si disponible
|
254 |
-
|
255 |
-
# 2. STRUCTURE DE RÉPONSE
|
256 |
-
# - Commence par la réponse directe
|
257 |
-
# - Cite ensuite la référence juridique exacte
|
258 |
-
# - Développe l'explication si nécessaire
|
259 |
-
|
260 |
-
# 3. RÈGLES CRUCIALES
|
261 |
-
# - Répond exclusivement en arabe
|
262 |
-
# - Dit "Je ne peux pas répondre de façon précise" si le contexte est insuffisant
|
263 |
-
# - Ne fait jamais d'interprétation au-delà du texte fourni
|
264 |
-
# - Reste factuel et précis
|
265 |
-
# - Ne cite que les informations présentes dans le contexte
|
266 |
-
|
267 |
-
# 4. FORMAT
|
268 |
-
# - Utilise des puces ou paragraphes courts pour la clarté
|
269 |
-
# - Met en évidence les références juridiques
|
270 |
-
# - Structure la réponse de façon hiérarchique
|
271 |
-
# """),
|
272 |
-
# ("human", "{question}")
|
273 |
-
# ])
|
274 |
-
|
275 |
-
|
276 |
-
# prompt_template = ChatPromptTemplate.from_messages([
|
277 |
-
# ("system", """Vous êtes un assistant juridique expert hautement qualifié. Votre rôle est d'analyser et de répondre aux questions juridiques avec précision et nuance.:
|
278 |
-
|
279 |
-
# PROCESSUS D'ANALYSE ET DE RÉPONSE :
|
280 |
-
|
281 |
-
# 1. ANALYSE DES SOURCES
|
282 |
-
# - Analysez d'abord le contexte fourni : {context}
|
283 |
-
# - Si le contexte est insuffisant, utilisez la recherche web pour compléter
|
284 |
-
# - Privilégiez toujours les sources officielles et la jurisprudence récente
|
285 |
-
# - Vérifiez la date et la validité des informations trouvées
|
286 |
-
|
287 |
-
# 2. STRUCTURE DE RÉPONSE
|
288 |
-
# Organisez votre réponse selon cette hiérarchie :
|
289 |
-
# a) Réponse synthétique initiale (1-2 phrases)
|
290 |
-
# b) Base légale et références précises
|
291 |
-
# c) Développement détaillé
|
292 |
-
# d) Nuances et cas particuliers
|
293 |
-
# e) Sources utilisées
|
294 |
-
# f) Répond exclusivement en arabe
|
295 |
-
|
296 |
-
# 3. PRÉCISION JURIDIQUE
|
297 |
-
# - Respectez la terminologie juridique exacte
|
298 |
-
# - Différenciez clairement :
|
299 |
-
# * Les obligations légales ("doit", "est tenu de")
|
300 |
-
# * Les recommandations ("peut", "il est conseillé")
|
301 |
-
# * Les interdictions ("ne peut pas", "est interdit")
|
302 |
-
# - Citez textuellement les articles pertinents
|
303 |
-
# - Précisez la hiérarchie des normes applicables
|
304 |
-
|
305 |
-
# 4. GESTION DE L'INCERTITUDE
|
306 |
-
# Si une information est :
|
307 |
-
# - Absente du contexte : Indiquez "Le contexte fourni ne permet pas de répondre à cet aspect"
|
308 |
-
# - Incomplète : Précisez "Selon les informations disponibles..."
|
309 |
-
# - Ambiguë : Exposez les différentes interprétations possibles
|
310 |
-
# - Dépassée : Mentionnez la nécessité de vérifier les mises à jour
|
311 |
-
|
312 |
-
# 5. UTILISATION DE LA RECHERCHE WEB
|
313 |
-
# Quand vous utilisez la recherche web :
|
314 |
-
# - Indiquez clairement : "Selon la recherche web complémentaire..."
|
315 |
-
# - chercher toujours au Maroc
|
316 |
-
# - Citez les sources consultées
|
317 |
-
# - Précisez la date de l'information
|
318 |
-
# - Mentionnez si l'information nécessite une vérification
|
319 |
-
|
320 |
-
# 6. LIMITATIONS ET AVERTISSEMENTS
|
321 |
-
# - Précisez si la réponse nécessite une consultation juridique professionnelle
|
322 |
-
# - Indiquez les limites de votre analyse
|
323 |
-
# - Signalez les évolutions législatives possibles
|
324 |
-
# - Mentionnez les variations juridictionnelles si pertinent
|
325 |
-
|
326 |
-
# FORMAT DE CITATION :
|
327 |
-
# - Articles de loi : [Loi n°X-XX du JJ/MM/AAAA, Article XX]
|
328 |
-
# - Jurisprudence : [Juridiction, Date, n° de pourvoi]
|
329 |
-
# - Sources en ligne : [Nom de la source, Date de consultation]
|
330 |
-
|
331 |
-
# RESTRICTIONS :
|
332 |
-
# - Ne pas faire d'interprétation extensive sans base légale
|
333 |
-
# - Ne pas donner de conseil juridique personnalisé
|
334 |
-
# - Ne pas spéculer sur des situations hypothétiques
|
335 |
-
# - Ne pas affirmer des points controversés sans mentionner les débats existants
|
336 |
-
|
337 |
-
# Question à traiter : {question}
|
338 |
-
# """),
|
339 |
-
# ("human", "{question}")
|
340 |
-
# ])
|
341 |
-
|
342 |
prompt_template = ChatPromptTemplate.from_messages([
|
343 |
("system", """Vous êtes un assistant juridique expert qualifié. Analysez et répondez aux questions juridiques avec précision.
|
344 |
|
@@ -347,11 +237,6 @@ prompt_template = ChatPromptTemplate.from_messages([
|
|
347 |
2. Utilisez la recherche web si la reponse n'existe pas dans le contexte
|
348 |
3. Privilégiez les sources officielles et la jurisprudence récente
|
349 |
|
350 |
-
FORMAT DE CITATION :
|
351 |
-
- Articles de loi : [Loi n°X-XX du JJ/MM/AAAA, Article XX]
|
352 |
-
- Jurisprudence : [Juridiction, Date, n° de pourvoi]
|
353 |
-
- Sources en ligne : [Nom de la source, Date de consultation]
|
354 |
-
|
355 |
Question à traiter : {question}
|
356 |
"""),
|
357 |
("human", "{question}")
|
@@ -503,117 +388,6 @@ def process_question(question: str) -> Iterator[str]:
|
|
503 |
except Exception as e:
|
504 |
yield f"Erreur lors du traitement : {str(e)}"
|
505 |
|
506 |
-
# def process_question(question: str) -> Iterator[str]:
|
507 |
-
# """
|
508 |
-
# Process the question and return a response generator for streaming.
|
509 |
-
# """
|
510 |
-
# if question in question_cache:
|
511 |
-
# yield question_cache[question][0]
|
512 |
-
# return
|
513 |
-
|
514 |
-
# relevant_docs = retriever(question)
|
515 |
-
# context = "\n".join([doc.page_content for doc in relevant_docs])
|
516 |
-
|
517 |
-
# prompt = prompt_template.format_messages(
|
518 |
-
# context=context,
|
519 |
-
# question=question
|
520 |
-
# )
|
521 |
-
|
522 |
-
# full_response = ""
|
523 |
-
# try:
|
524 |
-
# for chunk in llm.stream(prompt):
|
525 |
-
# if isinstance(chunk, str):
|
526 |
-
# current_chunk = chunk
|
527 |
-
# else:
|
528 |
-
# current_chunk = chunk.content
|
529 |
-
|
530 |
-
# full_response += current_chunk
|
531 |
-
# yield full_response # Send the updated response in streaming
|
532 |
-
|
533 |
-
# question_cache[question] = (full_response, context)
|
534 |
-
# except Exception as e:
|
535 |
-
# yield f"Erreur lors du traitement : {str(e)}"
|
536 |
-
|
537 |
-
# def process_question(question: str) -> Iterator[str]:
|
538 |
-
# """
|
539 |
-
# Process the question and return a response generator for streaming, including sources.
|
540 |
-
# """
|
541 |
-
# if question in question_cache:
|
542 |
-
# yield question_cache[question][0]
|
543 |
-
# return
|
544 |
-
|
545 |
-
# # Récupérer les documents pertinents
|
546 |
-
# relevant_docs = retriever(question)
|
547 |
-
# context = "\n".join([doc.page_content for doc in relevant_docs])
|
548 |
-
# sources = [doc.metadata.get("source", "Source inconnue") for doc in relevant_docs]
|
549 |
-
# sources = os.path.splitext(sources[0])[0] if sources else "غير معروف"
|
550 |
-
|
551 |
-
# # Générer le prompt
|
552 |
-
# prompt = prompt_template.format_messages(
|
553 |
-
# context=context,
|
554 |
-
# question=question
|
555 |
-
# )
|
556 |
-
|
557 |
-
# full_response = ""
|
558 |
-
# try:
|
559 |
-
# # Streaming de la réponse
|
560 |
-
# for chunk in llm.stream(prompt):
|
561 |
-
# if isinstance(chunk, str):
|
562 |
-
# current_chunk = chunk
|
563 |
-
# else:
|
564 |
-
# current_chunk = chunk.content
|
565 |
-
|
566 |
-
# full_response += current_chunk
|
567 |
-
# yield full_response # Envoyer la réponse mise à jour en streaming
|
568 |
-
|
569 |
-
# # Ajouter les sources à la réponse finale
|
570 |
-
# if sources:
|
571 |
-
# sources_str = "\nSources :\n" + "\n".join(f"- {source}" for source in sources)
|
572 |
-
# full_response += sources_str
|
573 |
-
# yield sources_str # Envoyer les sources
|
574 |
-
|
575 |
-
# # Mettre en cache la réponse complète
|
576 |
-
# question_cache[question] = (full_response, context)
|
577 |
-
# except Exception as e:
|
578 |
-
# yield f"Erreur lors du traitement : {str(e)}"
|
579 |
-
|
580 |
-
|
581 |
-
# def process_question(question: str) -> tuple[str, list[str]]:
|
582 |
-
# # Check cache first
|
583 |
-
# if question in question_cache:
|
584 |
-
# return question_cache[question]
|
585 |
-
|
586 |
-
# # Get relevant documents using the retriever
|
587 |
-
# relevant_docs = retriever(question)
|
588 |
-
|
589 |
-
# # Extract the content and sources
|
590 |
-
# context = "\n".join(doc.page_content for doc in relevant_docs)
|
591 |
-
# sources = [doc.metadata["source"] for doc in relevant_docs]
|
592 |
-
# sources = os.path.splitext(sources[0])[0] if sources else "غير معروف"
|
593 |
-
|
594 |
-
# # Generate the prompt with the context
|
595 |
-
# prompt = prompt_template.format(
|
596 |
-
# context=context,
|
597 |
-
# question=question
|
598 |
-
# )
|
599 |
-
|
600 |
-
# full_response = ""
|
601 |
-
|
602 |
-
# try:
|
603 |
-
# for chunk in llm.stream(prompt):
|
604 |
-
# if isinstance(chunk, str):
|
605 |
-
# current_chunk = chunk
|
606 |
-
# else:
|
607 |
-
# current_chunk = chunk.content
|
608 |
-
|
609 |
-
# full_response += current_chunk
|
610 |
-
# yield full_response, sources # Send the updated response in streaming
|
611 |
-
|
612 |
-
# question_cache[question,sources] = (full_response, context)
|
613 |
-
# except Exception as e:
|
614 |
-
# yield f"Erreur lors du traitement : {str(e)}"
|
615 |
-
|
616 |
-
|
617 |
|
618 |
def gradio_stream(question: str, chat_history: list) -> Iterator[list]:
|
619 |
"""
|
@@ -631,28 +405,6 @@ def gradio_stream(question: str, chat_history: list) -> Iterator[list]:
|
|
631 |
updated_chat = chat_history + [[question, f"Erreur : {str(e)}"]]
|
632 |
yield updated_chat
|
633 |
|
634 |
-
# def gradio_stream(question: str, chat_history: list) -> Iterator[list]:
|
635 |
-
# """
|
636 |
-
# Format the output for Gradio Chatbot component with streaming, including sources.
|
637 |
-
# """
|
638 |
-
# full_response = ""
|
639 |
-
# sources_str = ""
|
640 |
-
# try:
|
641 |
-
# for partial_response in process_question(question):
|
642 |
-
# if "Sources :" in partial_response:
|
643 |
-
# # Les sources sont ajoutées à la réponse finale
|
644 |
-
# sources_str = partial_response
|
645 |
-
# updated_chat = chat_history + [[question, full_response + "\n" + sources_str]]
|
646 |
-
# else:
|
647 |
-
# # Construire progressivement la réponse
|
648 |
-
# full_response = partial_response
|
649 |
-
# updated_chat = chat_history + [[question, full_response]]
|
650 |
-
# yield updated_chat
|
651 |
-
# except Exception as e:
|
652 |
-
# # Gestion des erreurs lors du streaming
|
653 |
-
# updated_chat = chat_history + [[question, f"Erreur : {str(e)}"]]
|
654 |
-
# yield updated_chat
|
655 |
-
|
656 |
|
657 |
# Gradio interface
|
658 |
with gr.Blocks(css=css) as demo:
|
@@ -677,412 +429,3 @@ with gr.Blocks(css=css) as demo:
|
|
677 |
send.click(gradio_stream, [message, chatbot], chatbot)
|
678 |
|
679 |
demo.launch(share=True)
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
# # def process_question(question: str):
|
696 |
-
# # """
|
697 |
-
# # Process the question and yield the answer progressively.
|
698 |
-
# # """
|
699 |
-
# # # Check cache first
|
700 |
-
# # if question in question_cache:
|
701 |
-
# # yield question_cache[question] # Retourne directement depuis le cache si disponible
|
702 |
-
|
703 |
-
# # relevant_docs = retriever(question)
|
704 |
-
# # context = "\n".join([doc.page_content for doc in relevant_docs])
|
705 |
-
|
706 |
-
# # prompt = prompt_template.format_messages(
|
707 |
-
# # context=context,
|
708 |
-
# # question=question
|
709 |
-
# # )
|
710 |
-
|
711 |
-
# # response = "" # Initialise la réponse
|
712 |
-
# # # Ici, nous supposons que 'llm.stream' est un générateur qui renvoie des chunks
|
713 |
-
# # for chunk in llm.stream(prompt): # suppose que llm.stream renvoie des chunks de réponse
|
714 |
-
# # if isinstance(chunk, str):
|
715 |
-
# # response += chunk # Accumulez la réponse si c'est déjà une chaîne
|
716 |
-
# # else:
|
717 |
-
# # response += chunk.content # Sinon, prenez le contenu du chunk (si chunk est un type d'objet spécifique)
|
718 |
-
|
719 |
-
# # yield response, context # Renvoie la réponse mise à jour et le contexte
|
720 |
-
|
721 |
-
# # # Mettez le résultat en cache à la fin
|
722 |
-
# # # question_cache[question] = (response, context)
|
723 |
-
|
724 |
-
# def process_question(question: str) -> Generator[Tuple[str, str], None, None]:
|
725 |
-
# """
|
726 |
-
# Process the question and yield the answer progressively.
|
727 |
-
# """
|
728 |
-
# # Check cache first
|
729 |
-
# if question in question_cache:
|
730 |
-
# yield question_cache[question]
|
731 |
-
|
732 |
-
# relevant_docs = retriever(question)
|
733 |
-
# context = "\n".join([doc.page_content for doc in relevant_docs])
|
734 |
-
|
735 |
-
# prompt = prompt_template.format_messages(
|
736 |
-
# context=context,
|
737 |
-
# question=question
|
738 |
-
# )
|
739 |
-
|
740 |
-
# current_response = ""
|
741 |
-
# for chunk in llm.stream(prompt):
|
742 |
-
# if isinstance(chunk, str):
|
743 |
-
# current_response += chunk
|
744 |
-
# else:
|
745 |
-
# current_response += chunk.content
|
746 |
-
# yield current_response, context
|
747 |
-
# # Mettez le résultat en cache à la fin
|
748 |
-
# question_cache[question] = (response, context)
|
749 |
-
|
750 |
-
# # CSS personnalisé avec l'importation de Google Fonts
|
751 |
-
# custom_css = """
|
752 |
-
# /* Import Google Fonts - Noto Sans Arabic */
|
753 |
-
# @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@300;400;500;600;700&display=swap');
|
754 |
-
|
755 |
-
# /* Styles généraux */
|
756 |
-
# :root {
|
757 |
-
# --primary-color: #4299e1;
|
758 |
-
# --secondary-color: #666666;
|
759 |
-
# --accent-color: #4299E1;
|
760 |
-
# --background-color: #ffffff;
|
761 |
-
# --border-radius: 8px;
|
762 |
-
# --font-family-arabic: 'Noto Sans Arabic', Arial, sans-serif;
|
763 |
-
# }
|
764 |
-
|
765 |
-
# /* Style de base */
|
766 |
-
# body {
|
767 |
-
# font-family: var(--font-family-arabic);
|
768 |
-
# background-color: var(--background-color);
|
769 |
-
# color: var(--primary-color);
|
770 |
-
# }
|
771 |
-
|
772 |
-
# /* Styles pour le texte RTL */
|
773 |
-
# .rtl-text {
|
774 |
-
# text-align: right !important;
|
775 |
-
# direction: rtl !important;
|
776 |
-
# font-family: var(--font-family-arabic) !important;
|
777 |
-
# }
|
778 |
-
|
779 |
-
# .rtl-text textarea {
|
780 |
-
# text-align: right !important;
|
781 |
-
# direction: rtl !important;
|
782 |
-
# padding: 1rem !important;
|
783 |
-
# border-radius: var(--border-radius) !important;
|
784 |
-
# border: 1px solid #E2E8F0 !important;
|
785 |
-
# background-color: #ffffff !important;
|
786 |
-
# color: var(--primary-color) !important;
|
787 |
-
# font-size: 1.1rem !important;
|
788 |
-
# line-height: 1.6 !important;
|
789 |
-
# font-family: var(--font-family-arabic) !important;
|
790 |
-
# }
|
791 |
-
|
792 |
-
# /* Style du titre */
|
793 |
-
# .app-title {
|
794 |
-
# font-family: var(--font-family-arabic) !important;
|
795 |
-
# font-size: 2rem !important;
|
796 |
-
# font-weight: 700 !important;
|
797 |
-
# color: white !important; /* Texte en blanc */
|
798 |
-
# background-color: #3e2b1f !important; /* Fond marron foncé */
|
799 |
-
# margin-bottom: 1rem !important;
|
800 |
-
# margin-top: 1rem !important;
|
801 |
-
# text-align: center !important;
|
802 |
-
# }
|
803 |
-
|
804 |
-
# /* Styles des étiquettes */
|
805 |
-
# .rtl-text label {
|
806 |
-
# font-family: var(--font-family-arabic) !important;
|
807 |
-
# font-size: 1.2rem !important;
|
808 |
-
# font-weight: 600 !important;
|
809 |
-
# color: #000000 !important; /* Couleur noire pour les étiquettes */
|
810 |
-
# margin-bottom: 0.5rem !important;
|
811 |
-
# }
|
812 |
-
|
813 |
-
# /* Centrer le bouton */
|
814 |
-
# button.primary-button {
|
815 |
-
# font-family: var(--font-family-arabic) !important;
|
816 |
-
# background-color: var(--accent-color) !important;
|
817 |
-
# color: white !important;
|
818 |
-
# padding: 0.75rem 1.5rem !important;
|
819 |
-
# border-radius: var(--border-radius) !important;
|
820 |
-
# font-weight: 600 !important;
|
821 |
-
# font-size: 1.1rem !important;
|
822 |
-
# transition: all 0.3s ease !important;
|
823 |
-
# width: 200px !important; /* Réduit la largeur du bouton */
|
824 |
-
# margin: 0 auto !important; /* Centrage horizontal */
|
825 |
-
# display: block !important; /* Nécessaire pour que le margin auto fonctionne */
|
826 |
-
# }
|
827 |
-
|
828 |
-
|
829 |
-
# button.primary-button:hover {
|
830 |
-
# background-color: #3182CE !important;
|
831 |
-
# transform: translateY(-1px) !important;
|
832 |
-
# }
|
833 |
-
|
834 |
-
# /* Styles des boîtes de texte */
|
835 |
-
# .textbox-container {
|
836 |
-
# background-color: #b45f06 !important;
|
837 |
-
# padding: 1.5rem !important;
|
838 |
-
# border-radius: var(--border-radius) !important;
|
839 |
-
# box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
840 |
-
# margin-bottom: 1rem !important;
|
841 |
-
# }
|
842 |
-
|
843 |
-
# /* Animation de chargement */
|
844 |
-
# .loading {
|
845 |
-
# animation: pulse 2s infinite;
|
846 |
-
# }
|
847 |
-
|
848 |
-
# @keyframes pulse {
|
849 |
-
# 0% { opacity: 1; }
|
850 |
-
# 50% { opacity: 0.5; }
|
851 |
-
# 100% { opacity: 1; }
|
852 |
-
# }
|
853 |
-
|
854 |
-
# /* Style du statut */
|
855 |
-
# .status-text {
|
856 |
-
# font-family: var(--font-family-arabic) !important;
|
857 |
-
# text-align: center !important;
|
858 |
-
# color: var(--secondary-color) !important;
|
859 |
-
# font-size: 1rem !important;
|
860 |
-
# margin-top: 1rem !important;
|
861 |
-
# }
|
862 |
-
# """
|
863 |
-
|
864 |
-
# # Interface Gradio avec streaming
|
865 |
-
# with gr.Blocks(css=custom_css) as iface:
|
866 |
-
# with gr.Column(elem_classes="container"):
|
867 |
-
# gr.Markdown(
|
868 |
-
# "# نظام الأسئلة والأجوبة الذكي",
|
869 |
-
# elem_classes="app-title rtl-text"
|
870 |
-
# )
|
871 |
-
|
872 |
-
# with gr.Column(elem_classes="textbox-container"):
|
873 |
-
# input_text = gr.Textbox(
|
874 |
-
# label="السؤال",
|
875 |
-
# placeholder="اكتب سؤالك هنا...",
|
876 |
-
# lines=1,
|
877 |
-
# elem_classes="rtl-text"
|
878 |
-
# )
|
879 |
-
|
880 |
-
# with gr.Row():
|
881 |
-
# with gr.Column():
|
882 |
-
# answer_box = gr.Textbox(
|
883 |
-
# label="الإجابة",
|
884 |
-
# lines=5,
|
885 |
-
# elem_classes="rtl-text textbox-container"
|
886 |
-
# )
|
887 |
-
|
888 |
-
# submit_btn = gr.Button(
|
889 |
-
# "إرسال السؤال",
|
890 |
-
# elem_classes="primary-button",
|
891 |
-
# variant="primary"
|
892 |
-
# )
|
893 |
-
|
894 |
-
# # def stream_response(question):
|
895 |
-
# # response_stream = process_question(question)
|
896 |
-
# # for response, _ in response_stream:
|
897 |
-
# # gr.update(value=response)
|
898 |
-
# # yield response
|
899 |
-
|
900 |
-
# def stream_response(question):
|
901 |
-
# for chunk_response, _ in process_question(question):
|
902 |
-
# yield chunk_response
|
903 |
-
# time.sleep(0.05)
|
904 |
-
|
905 |
-
# submit_btn.click(
|
906 |
-
# fn=stream_response,
|
907 |
-
# inputs=input_text,
|
908 |
-
# outputs=answer_box,
|
909 |
-
# api_name="predict",
|
910 |
-
# queue=False
|
911 |
-
# )
|
912 |
-
|
913 |
-
# if __name__ == "__main__":
|
914 |
-
# iface.launch(
|
915 |
-
# share=True,
|
916 |
-
# server_name="0.0.0.0",
|
917 |
-
# server_port=7860,
|
918 |
-
# max_threads=3,
|
919 |
-
# show_error=True
|
920 |
-
# )
|
921 |
-
|
922 |
-
# # # Interface Gradio avec la correction
|
923 |
-
# # with gr.Blocks(css=custom_css) as iface:
|
924 |
-
# # with gr.Column(elem_classes="container"):
|
925 |
-
# # gr.Markdown(
|
926 |
-
# # "# نظام الأسئلة والأجوبة الذكي",
|
927 |
-
# # elem_classes="app-title rtl-text"
|
928 |
-
# # )
|
929 |
-
|
930 |
-
# # with gr.Column(elem_classes="textbox-container"):
|
931 |
-
# # input_text = gr.Textbox(
|
932 |
-
# # label="السؤال",
|
933 |
-
# # placeholder="اكتب سؤالك هنا...",
|
934 |
-
# # lines=1,
|
935 |
-
# # elem_classes="rtl-text"
|
936 |
-
# # )
|
937 |
-
|
938 |
-
# # with gr.Row():
|
939 |
-
# # with gr.Column():
|
940 |
-
# # answer_box = gr.Textbox(
|
941 |
-
# # label="الإجابة",
|
942 |
-
# # lines=5,
|
943 |
-
# # elem_classes="rtl-text textbox-container"
|
944 |
-
# # )
|
945 |
-
# # # with gr.Column(scale=1):
|
946 |
-
# # # context_box = gr.Textbox(
|
947 |
-
# # # label="السياق المستخدم",
|
948 |
-
# # # lines=4,
|
949 |
-
# # # elem_classes="rtl-text textbox-container"
|
950 |
-
# # # )
|
951 |
-
|
952 |
-
# # submit_btn = gr.Button(
|
953 |
-
# # "إرسال السؤال",
|
954 |
-
# # elem_classes="primary-button",
|
955 |
-
# # variant="primary"
|
956 |
-
# # )
|
957 |
-
|
958 |
-
|
959 |
-
# # def on_submit(question):
|
960 |
-
# # for response, context in process_question(question):
|
961 |
-
# # yield response # Yield À CHAQUE itération
|
962 |
-
|
963 |
-
|
964 |
-
# # submit_btn.click(
|
965 |
-
# # fn=on_submit,
|
966 |
-
# # inputs=input_text,
|
967 |
-
# # outputs=answer_box,
|
968 |
-
# # api_name="predict",
|
969 |
-
# # queue=False,
|
970 |
-
# # )
|
971 |
-
|
972 |
-
|
973 |
-
# # if __name__ == "__main__":
|
974 |
-
# # iface.launch(
|
975 |
-
# # share=True,
|
976 |
-
# # server_name="0.0.0.0",
|
977 |
-
# # server_port=7860,
|
978 |
-
# # max_threads=3,
|
979 |
-
# # show_error=True,
|
980 |
-
# # )
|
981 |
-
|
982 |
-
# # def process_question(question: str):
|
983 |
-
# # """
|
984 |
-
# # Process the question and yield the answer progressively.
|
985 |
-
# # """
|
986 |
-
# # # Check cache first
|
987 |
-
# # if question in question_cache:
|
988 |
-
# # yield question_cache[question] # Retourne directement depuis le cache si disponible
|
989 |
-
|
990 |
-
# # relevant_docs = retriever(question)
|
991 |
-
# # context = "\n".join([doc.page_content for doc in relevant_docs])
|
992 |
-
|
993 |
-
# # prompt = prompt_template.format_messages(
|
994 |
-
# # context=context,
|
995 |
-
# # question=question
|
996 |
-
# # )
|
997 |
-
|
998 |
-
# # response = "" # Initialise la réponse
|
999 |
-
# # # Ici, nous supposons que 'llm.stream' est un générateur qui renvoie des chunks
|
1000 |
-
# # for chunk in llm.stream(prompt): # suppose que llm.stream renvoie des chunks de réponse
|
1001 |
-
# # if isinstance(chunk, str):
|
1002 |
-
# # response += chunk # Accumulez la réponse si c'est déjà une chaîne
|
1003 |
-
# # else:
|
1004 |
-
# # response += chunk.content # Sinon, prenez le contenu du chunk (si chunk est un type d'objet spécifique)
|
1005 |
-
|
1006 |
-
# # yield response, context # Renvoie la réponse mise à jour et le contexte
|
1007 |
-
|
1008 |
-
# # # Mettez le résultat en cache à la fin
|
1009 |
-
# # question_cache[question] = (response, context)
|
1010 |
-
|
1011 |
-
# # # Custom CSS for right-aligned text in textboxes
|
1012 |
-
# # custom_css = """
|
1013 |
-
# # .rtl-text {
|
1014 |
-
# # text-align: right !important;
|
1015 |
-
# # direction: rtl !important;
|
1016 |
-
# # }
|
1017 |
-
# # .rtl-text textarea {
|
1018 |
-
# # text-align: right !important;
|
1019 |
-
# # direction: rtl !important;
|
1020 |
-
# # }
|
1021 |
-
# # """
|
1022 |
-
|
1023 |
-
# # # Gradio interface with queue
|
1024 |
-
# # with gr.Blocks(css=custom_css) as iface:
|
1025 |
-
# # with gr.Column():
|
1026 |
-
# # input_text = gr.Textbox(
|
1027 |
-
# # label="السؤال",
|
1028 |
-
# # placeholder="اكتب سؤالك هنا...",
|
1029 |
-
# # lines=2,
|
1030 |
-
# # elem_classes="rtl-text"
|
1031 |
-
# # )
|
1032 |
-
|
1033 |
-
# # with gr.Row():
|
1034 |
-
# # answer_box = gr.Textbox(
|
1035 |
-
# # label="الإجابة",
|
1036 |
-
# # lines=4,
|
1037 |
-
# # elem_classes="rtl-text"
|
1038 |
-
# # )
|
1039 |
-
# # context_box = gr.Textbox(
|
1040 |
-
# # label="السياق المستخدم",
|
1041 |
-
# # lines=8,
|
1042 |
-
# # elem_classes="rtl-text"
|
1043 |
-
# # )
|
1044 |
-
|
1045 |
-
# # submit_btn = gr.Button("إرسال")
|
1046 |
-
|
1047 |
-
# # submit_btn.click(
|
1048 |
-
# # fn=process_question,
|
1049 |
-
# # inputs=input_text,
|
1050 |
-
# # outputs=[answer_box, context_box],
|
1051 |
-
# # api_name="predict",
|
1052 |
-
# # queue=True # Utiliser le système de queue pour un traitement asynchrone
|
1053 |
-
# # )
|
1054 |
-
|
1055 |
-
# # if __name__ == "__main__":
|
1056 |
-
# # iface.launch(
|
1057 |
-
# # share=True,
|
1058 |
-
# # server_name="0.0.0.0",
|
1059 |
-
# # server_port=7860,
|
1060 |
-
# # max_threads=3, # Controls concurrency
|
1061 |
-
# # show_error=True
|
1062 |
-
# # )
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
# # def process_question(question: str):
|
1067 |
-
# # """
|
1068 |
-
# # Process the question and return the answer and context
|
1069 |
-
# # """
|
1070 |
-
# # # Check cache first
|
1071 |
-
# # if question in question_cache:
|
1072 |
-
# # return question_cache[question], "" # Retourne la réponse cachée et un statut vide
|
1073 |
-
# # relevant_docs = retriever(question)
|
1074 |
-
# # context = "\n".join([doc.page_content for doc in relevant_docs])
|
1075 |
-
# # prompt = prompt_template.format_messages(
|
1076 |
-
# # context=context,
|
1077 |
-
# # question=question
|
1078 |
-
# # )
|
1079 |
-
# # response = ""
|
1080 |
-
# # for chunk in llm.stream(prompt):
|
1081 |
-
# # if isinstance(chunk, str):
|
1082 |
-
# # response += chunk
|
1083 |
-
# # else:
|
1084 |
-
# # response += chunk.content
|
1085 |
-
# # # Mettez le résultat en cache à la fin
|
1086 |
-
# # question_cache[question] = (response, context)
|
1087 |
-
# # return response, context
|
1088 |
-
|
|
|
229 |
# Cache for processed questions
|
230 |
question_cache = {}
|
231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
prompt_template = ChatPromptTemplate.from_messages([
|
233 |
("system", """Vous êtes un assistant juridique expert qualifié. Analysez et répondez aux questions juridiques avec précision.
|
234 |
|
|
|
237 |
2. Utilisez la recherche web si la reponse n'existe pas dans le contexte
|
238 |
3. Privilégiez les sources officielles et la jurisprudence récente
|
239 |
|
|
|
|
|
|
|
|
|
|
|
240 |
Question à traiter : {question}
|
241 |
"""),
|
242 |
("human", "{question}")
|
|
|
388 |
except Exception as e:
|
389 |
yield f"Erreur lors du traitement : {str(e)}"
|
390 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
391 |
|
392 |
def gradio_stream(question: str, chat_history: list) -> Iterator[list]:
|
393 |
"""
|
|
|
405 |
updated_chat = chat_history + [[question, f"Erreur : {str(e)}"]]
|
406 |
yield updated_chat
|
407 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
|
409 |
# Gradio interface
|
410 |
with gr.Blocks(css=css) as demo:
|
|
|
429 |
send.click(gradio_stream, [message, chatbot], chatbot)
|
430 |
|
431 |
demo.launch(share=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|