| from transformers import pipeline |
| import gradio as gr |
| import re |
|
|
| |
| MODEL_ID = "google/flan-t5-small" |
| simplifier = pipeline("text2text-generation", model=MODEL_ID) |
|
|
|
|
| |
|
|
| def too_similar(src: str, out: str) -> bool: |
| src_clean = src.lower().strip() |
| out_clean = out.lower().strip() |
| if out_clean.startswith(src_clean): |
| return True |
| if len(out_clean) < 40: |
| return True |
| src_words = set(src_clean.split()) |
| out_words = set(out_clean.split()) |
| if not src_words: |
| return True |
| overlap = len(src_words & out_words) / len(src_words) |
| return overlap > 0.78 |
|
|
|
|
| def fallback_explanation(text: str, lang: str = "en") -> str: |
| txt = text.strip() |
|
|
| if lang == "fr": |
| return ( |
| "### 🗣️ Explication en français simple\n" |
| f"- **Texte original :** {txt}\n" |
| "- Ce texte contient une règle ou une obligation administrative/juridique.\n" |
| "- Il faut bien vérifier qui doit faire quoi, dans quel délai, et quelles sont les conséquences.\n" |
| "- Si le texte mentionne une *décision définitive*, cela signifie qu’on **ne peut plus la contester** après ce délai.\n" |
| "\n**En résumé :** ce texte décrit ce qu’il faut faire et les conséquences si on ne le fait pas." |
| ) |
|
|
| return ( |
| "### 🗣️ Explanation in simple English\n" |
| f"- **Original clause:** {txt}\n" |
| "- This text contains a rule or an obligation.\n" |
| "- Check who must act, what must be done, and when.\n" |
| "- If it says a decision becomes *final*, that means it **cannot be challenged later**.\n" |
| "\n**In short:** this tells you what must be done and what happens if you don’t." |
| ) |
|
|
|
|
| |
|
|
| def simplify_legal(text, lang): |
| text = (text or "").strip() |
| if not text: |
| return "Veuillez coller un texte juridique ou administratif." if lang == "fr" else "Please paste a legal or administrative text." |
|
|
| if lang == "fr": |
| prompt = f""" |
| Tu es un assistant juridique qui explique les textes administratifs ou juridiques en français simple. |
| Réécris, simplifie ET explique le texte suivant pour qu'une personne sans formation juridique puisse le comprendre. |
| Conserve les chiffres, les délais et les conditions importants. |
| Utilise des puces si utile. |
| Termine par une phrase commençant par "En résumé :" |
| |
| Texte : |
| {text} |
| |
| Explication en français simple : |
| """ |
| else: |
| prompt = f""" |
| You are a legal communication assistant. |
| Rewrite, simplify AND explain the following legal or administrative clause for a non-lawyer. |
| Keep all numbers, dates, deadlines, and conditions correct. |
| If there are legal or Latin terms, explain them briefly. |
| Use bullet points to make it readable. |
| End with a one-sentence summary starting with "In short:". |
| |
| Clause: |
| {text} |
| |
| Explanation in simple English: |
| """ |
|
|
| result = simplifier(prompt, max_new_tokens=320, do_sample=False, temperature=0.0)[0]["generated_text"].strip() |
|
|
| if too_similar(text, result): |
| return fallback_explanation(text, lang) |
|
|
| return result |
|
|
|
|
| |
|
|
| with gr.Blocks( |
| title="Talk2Law — Legal Text Explainer", |
| theme=gr.themes.Soft(primary_hue="indigo", secondary_hue="blue") |
| ) as demo: |
|
|
| |
| gr.HTML( |
| """ |
| <div style="text-align: center; margin-bottom: 25px;"> |
| <h1 style="color:#283593; font-size: 2.2em;">⚖️ Talk2Law</h1> |
| <h3 style="color:#455A64;">Explain complex legal texts in simple French or English</h3> |
| <p style="color:#607D8B; font-size: 0.95em;"> |
| Paste a clause below — the app will simplify, reformulate, and explain it clearly. |
| </p> |
| </div> |
| """ |
| ) |
|
|
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| lang = gr.Radio( |
| ["English", "Français"], |
| value="English", |
| label="🌐 Language / Langue", |
| interactive=True, |
| ) |
|
|
| inp = gr.Textbox( |
| lines=8, |
| placeholder="Paste your legal or administrative text here...", |
| label="📜 Legal / Administrative Text", |
| ) |
|
|
| btn = gr.Button("🧩 Explain / Expliquer", variant="primary") |
| clear_btn = gr.Button("🧹 Clear / Effacer") |
|
|
| gr.Markdown("### 💡 Example Texts / Exemples") |
| gr.Examples( |
| examples=[ |
| ["The appeal must be filed within thirty days from the notification of this decision; otherwise, the decision becomes final."], |
| ["This contract is concluded intuitu personae and may not be assigned without the other party’s prior written consent."], |
| ["Toute réclamation doit être introduite dans un délai de trente jours suivant la notification de la décision."], |
| ], |
| inputs=[inp] |
| ) |
|
|
| with gr.Column(scale=1): |
| out = gr.Markdown(label="✅ Explanation / Explication") |
|
|
| |
| btn.click(fn=simplify_legal, inputs=[inp, lang], outputs=out) |
| clear_btn.click(fn=lambda: "", inputs=None, outputs=inp) |
|
|
| |
| gr.HTML( |
| """ |
| <hr> |
| <p style="text-align:center; color:gray; font-size:0.85em;"> |
| ⚠️ Talk2Law simplifies and explains texts for educational purposes only.<br> |
| Cette application ne fournit pas de conseils juridiques. |
| </p> |
| """ |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|