Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -10,7 +10,6 @@ import openai
|
|
| 10 |
import tempfile
|
| 11 |
import json
|
| 12 |
import re
|
| 13 |
-
|
| 14 |
import markdown
|
| 15 |
from bs4 import BeautifulSoup
|
| 16 |
|
|
@@ -121,55 +120,81 @@ def markdown_to_docx(md_text: str) -> str:
|
|
| 121 |
elif el.name == "li":
|
| 122 |
doc.add_paragraph(f"• {el.get_text()}")
|
| 123 |
|
| 124 |
-
# Save into a temporary file
|
| 125 |
tmp_path = os.path.join(tempfile.gettempdir(), "draft.docx")
|
| 126 |
doc.save(tmp_path)
|
| 127 |
return tmp_path
|
| 128 |
-
|
| 129 |
-
# -----------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
def generate_legal_draft(case_text, uploaded_file=None, add_citations=True):
|
| 131 |
-
|
|
|
|
| 132 |
|
| 133 |
queries = build_queries_with_llm(case_text)
|
| 134 |
context_text, citations = pinecone_search(queries, top_k=10)
|
| 135 |
|
| 136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
1. User Input: Case details including client info, petition type, court, facts, relevant laws, and sections.
|
| 138 |
2. Knowledge Base Context: Relevant laws, case precedents, and ordinances retrieved from the vector database (Constitution of Pakistan, Punjab case law, FBR ordinances).
|
| 139 |
-
3.
|
|
|
|
| 140 |
Instructions
|
| 141 |
-
|
| 142 |
-
-
|
| 143 |
-
-
|
| 144 |
-
-
|
| 145 |
-
- Sections should include: Parties, Facts, Legal Grounds, Arguments, Prayer, etc., as per the template.
|
| 146 |
-
2. Tone & Style
|
| 147 |
-
- Use formal, professional, and persuasive legal language.
|
| 148 |
-
- Facts are objective; legal arguments are assertive.
|
| 149 |
-
- Follow the tone and phrasing style of the uploaded template document.
|
| 150 |
-
3. Content Integration
|
| 151 |
-
- Incorporate relevant context from the vector database where appropriate.
|
| 152 |
-
- Cite legal provisions clearly in-text when relevant.
|
| 153 |
-
- Ensure content is logically coherent, comprehensive, and supports the petition’s objective.
|
| 154 |
-
- Do not hallucinate laws or precedents.
|
| 155 |
-
4. References
|
| 156 |
-
- Include a "References" section at the end if citations are present.
|
| 157 |
-
- Format as: `1. Source Name (score)`
|
| 158 |
-
5. Output Rules
|
| 159 |
-
- Produce output MARKDOWN.
|
| 160 |
-
- Do not add explanations, summaries, or extra text.
|
| 161 |
-
- Maintain clarity, professionalism, and adherence to legal drafting standards.
|
| 162 |
-
- Preserve structure, tone, style, and headings from the uploaded template as much as possible.
|
| 163 |
-
6. Fallback
|
| 164 |
-
- If context or relevant laws are missing, state: "No applicable precedent found" or "Relevant law cited above."
|
| 165 |
"""
|
|
|
|
| 166 |
user_prompt = f"""
|
| 167 |
**User Input:**
|
| 168 |
{case_text}
|
|
|
|
| 169 |
**Knowledge Base Context:**
|
| 170 |
{context_text or '(no matches)'}
|
| 171 |
-
|
| 172 |
-
|
|
|
|
| 173 |
"""
|
| 174 |
|
| 175 |
try:
|
|
@@ -180,7 +205,7 @@ def generate_legal_draft(case_text, uploaded_file=None, add_citations=True):
|
|
| 180 |
{"role":"user","content":user_prompt}
|
| 181 |
],
|
| 182 |
max_completion_tokens=15000,
|
| 183 |
-
verbosity=
|
| 184 |
)
|
| 185 |
draft_md = resp.choices[0].message.content.strip()
|
| 186 |
except Exception as e:
|
|
@@ -192,7 +217,7 @@ def generate_legal_draft(case_text, uploaded_file=None, add_citations=True):
|
|
| 192 |
draft_md += f"{i}. {c['source']} (score: {c['score']:.3f})\n"
|
| 193 |
|
| 194 |
docx_path = markdown_to_docx(draft_md)
|
| 195 |
-
|
| 196 |
|
| 197 |
|
| 198 |
|
|
@@ -207,16 +232,13 @@ with gr.Blocks() as demo:
|
|
| 207 |
draft_output = gr.Markdown(label="Draft Output")
|
| 208 |
|
| 209 |
download_btn = gr.DownloadButton(label="⬇️ Download Word")
|
| 210 |
-
# draft_output1 = gr.Markdown("# HI")
|
| 211 |
|
| 212 |
btn = gr.Button("Generate Draft")
|
| 213 |
btn.click(
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
)
|
| 218 |
-
|
| 219 |
-
|
| 220 |
# ----------------- RUN -----------------
|
| 221 |
-
if __name__ == "__main__":
|
| 222 |
-
demo.launch()
|
|
|
|
| 10 |
import tempfile
|
| 11 |
import json
|
| 12 |
import re
|
|
|
|
| 13 |
import markdown
|
| 14 |
from bs4 import BeautifulSoup
|
| 15 |
|
|
|
|
| 120 |
elif el.name == "li":
|
| 121 |
doc.add_paragraph(f"• {el.get_text()}")
|
| 122 |
|
|
|
|
| 123 |
tmp_path = os.path.join(tempfile.gettempdir(), "draft.docx")
|
| 124 |
doc.save(tmp_path)
|
| 125 |
return tmp_path
|
| 126 |
+
|
| 127 |
+
# ----------------- DRAFT ANALYZER -----------------
|
| 128 |
+
def analyze_template_draft(ref_text: str) -> str:
|
| 129 |
+
"""Analyze uploaded draft structure, tone, style, headings, and expected content."""
|
| 130 |
+
if not ref_text:
|
| 131 |
+
return "(no template provided)"
|
| 132 |
+
|
| 133 |
+
system_prompt = """You are a legal draft analyzer.
|
| 134 |
+
Your task is to carefully analyze the uploaded legal draft document and summarize its full structure and style.
|
| 135 |
+
Extract the following information clearly and systematically:
|
| 136 |
+
1. Headings and subheadings (exact order).
|
| 137 |
+
2. Approximate length/word count per section.
|
| 138 |
+
3. Purpose of each section (what content it usually contains).
|
| 139 |
+
4. Writing style and tone (formal/informal, persuasive, assertive, etc.).
|
| 140 |
+
5. Formatting conventions (headings, numbering, bullet points, capitalization).
|
| 141 |
+
6. Sentence/paragraph length and complexity.
|
| 142 |
+
7. Any special legal phrases or terminology patterns.
|
| 143 |
+
8. Any notes on length and overall flow.
|
| 144 |
+
|
| 145 |
+
Return a structured MARKDOWN report that can be given as instructions to another model.
|
| 146 |
+
Do not rewrite the draft, only analyze it."""
|
| 147 |
+
|
| 148 |
+
try:
|
| 149 |
+
resp = openai_client.chat.completions.create(
|
| 150 |
+
model="gpt-4o-mini",
|
| 151 |
+
messages=[
|
| 152 |
+
{"role": "system", "content": system_prompt},
|
| 153 |
+
{"role": "user", "content": ref_text[:40000]} # limit for context
|
| 154 |
+
],
|
| 155 |
+
temperature=0.2,
|
| 156 |
+
max_tokens=4000
|
| 157 |
+
)
|
| 158 |
+
analysis = resp.choices[0].message.content.strip()
|
| 159 |
+
except Exception as e:
|
| 160 |
+
analysis = f"(Analyzer error: {e})"
|
| 161 |
+
|
| 162 |
+
return analysis
|
| 163 |
+
|
| 164 |
+
# ----------------- MAIN -----------------
|
| 165 |
def generate_legal_draft(case_text, uploaded_file=None, add_citations=True):
|
| 166 |
+
# Step 0: Show initial status
|
| 167 |
+
yield gr.update(value="🔍 Searching in Knowledge Base..."), None
|
| 168 |
|
| 169 |
queries = build_queries_with_llm(case_text)
|
| 170 |
context_text, citations = pinecone_search(queries, top_k=10)
|
| 171 |
|
| 172 |
+
yield gr.update(value="📝 Analyzing Template Document..."), None
|
| 173 |
+
ref_text = load_reference_text(uploaded_file)
|
| 174 |
+
template_analysis = analyze_template_draft(ref_text)
|
| 175 |
+
|
| 176 |
+
yield gr.update(value="⚖️ Generating Final Draft..."), None
|
| 177 |
+
system_prompt = """You are an expert legal drafter for Pakistani law. Your task is to create a professional, court-ready legal petition in MARKDOWN format using four inputs:
|
| 178 |
1. User Input: Case details including client info, petition type, court, facts, relevant laws, and sections.
|
| 179 |
2. Knowledge Base Context: Relevant laws, case precedents, and ordinances retrieved from the vector database (Constitution of Pakistan, Punjab case law, FBR ordinances).
|
| 180 |
+
3. Template Draft Analysis: A structured analysis of an uploaded legal template (headings, section purposes, tone, formatting rules, length, style).
|
| 181 |
+
4. Fallback: If some info is missing, state explicitly instead of hallucinating.
|
| 182 |
Instructions
|
| 183 |
+
- Replicate the section hierarchy and style described in the template analysis.
|
| 184 |
+
- Ensure clarity, professionalism, and persuasive legal argumentation.
|
| 185 |
+
- Integrate legal context where appropriate with accurate citations.
|
| 186 |
+
- Output must be MARKDOWN only, no explanations or extra commentary.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
"""
|
| 188 |
+
|
| 189 |
user_prompt = f"""
|
| 190 |
**User Input:**
|
| 191 |
{case_text}
|
| 192 |
+
|
| 193 |
**Knowledge Base Context:**
|
| 194 |
{context_text or '(no matches)'}
|
| 195 |
+
|
| 196 |
+
**Template Draft Analysis:**
|
| 197 |
+
{template_analysis}
|
| 198 |
"""
|
| 199 |
|
| 200 |
try:
|
|
|
|
| 205 |
{"role":"user","content":user_prompt}
|
| 206 |
],
|
| 207 |
max_completion_tokens=15000,
|
| 208 |
+
verbosity="high"
|
| 209 |
)
|
| 210 |
draft_md = resp.choices[0].message.content.strip()
|
| 211 |
except Exception as e:
|
|
|
|
| 217 |
draft_md += f"{i}. {c['source']} (score: {c['score']:.3f})\n"
|
| 218 |
|
| 219 |
docx_path = markdown_to_docx(draft_md)
|
| 220 |
+
yield gr.update(value=draft_md), markdown_to_docx(draft_md)
|
| 221 |
|
| 222 |
|
| 223 |
|
|
|
|
| 232 |
draft_output = gr.Markdown(label="Draft Output")
|
| 233 |
|
| 234 |
download_btn = gr.DownloadButton(label="⬇️ Download Word")
|
|
|
|
| 235 |
|
| 236 |
btn = gr.Button("Generate Draft")
|
| 237 |
btn.click(
|
| 238 |
+
generate_legal_draft,
|
| 239 |
+
inputs=[case_text, uploaded_file, add_citations],
|
| 240 |
+
outputs=[draft_output, download_btn]
|
| 241 |
)
|
|
|
|
|
|
|
| 242 |
# ----------------- RUN -----------------
|
| 243 |
+
if __name__ == "__main__":
|
| 244 |
+
demo.launch()
|