Legal / enhanced_app.py
Joshua Guillen
Enhanced legal analyzer with improved pattern matching and comprehensive analysis features
a153a45
import gradio as gr
import json
import re
import os
from typing import Dict, List, Any
import requests
import time
class EnhancedLegalAnalyzer:
"""Enhanced Legal Clause Analyzer with LLM integration and comprehensive analysis"""
def __init__(self):
self.legal_patterns = self._initialize_legal_patterns()
self.risk_levels = {"LOW": 1, "MEDIUM": 2, "HIGH": 3, "CRITICAL": 4}
def _initialize_legal_patterns(self) -> Dict[str, Dict]:
"""Initialize comprehensive legal analysis patterns"""
return {
"ambiguous_terms": {
"reasonable": {
"description": "Subjective standard that may lead to disputes",
"risk_level": "MEDIUM",
"recommendation": "Define specific criteria, timeframes, or benchmarks",
"plain_english": "The word 'reasonable' means different things to different people"
},
"material": {
"description": "Undefined materiality threshold creates interpretation risk",
"risk_level": "MEDIUM",
"recommendation": "Specify dollar amounts, percentages, or concrete examples",
"plain_english": "What counts as 'material' should be clearly defined with numbers or examples"
},
"best efforts": {
"description": "Highest standard of performance with unclear boundaries",
"risk_level": "HIGH",
"recommendation": "Replace with 'commercially reasonable efforts' with defined metrics",
"plain_english": "'Best efforts' could mean unlimited obligation - very risky"
},
"timely": {
"description": "Vague timeframe creates scheduling disputes",
"risk_level": "MEDIUM",
"recommendation": "Specify exact deadlines and timeframes",
"plain_english": "Always use specific dates instead of 'timely'"
},
"professional manner": {
"description": "Subjective performance standard",
"risk_level": "LOW",
"recommendation": "Define specific quality standards or industry benchmarks",
"plain_english": "Describe exactly what 'professional' means in this context"
}
},
"high_risk_clauses": {
"unlimited liability": {
"description": "Exposes party to potentially catastrophic financial risk",
"risk_level": "CRITICAL",
"recommendation": "Add liability caps and exclude consequential damages",
"plain_english": "This could bankrupt you - always limit your liability"
},
"irrevocable assignment": {
"description": "Permanent transfer with no recourse",
"risk_level": "HIGH",
"recommendation": "Add termination conditions and scope limitations",
"plain_english": "Once you sign this, you can never get these rights back"
},
"perpetuity": {
"description": "Unlimited time duration may be unenforceable",
"risk_level": "HIGH",
"recommendation": "Limit to reasonable time periods",
"plain_english": "Forever is too long - courts may not enforce this"
},
"waiver.*audit": {
"description": "Eliminates oversight and verification rights",
"risk_level": "HIGH",
"recommendation": "Preserve essential audit rights",
"plain_english": "You're giving up the right to check if they're following the rules"
}
},
"missing_protections": {
"force_majeure": {
"keywords": ["force majeure", "act of god"],
"description": "Protection against unforeseeable events",
"recommendation": "Add comprehensive force majeure clause including pandemics, cyber attacks",
"plain_english": "You need protection when things go wrong that aren't your fault"
},
"liability_cap": {
"keywords": ["liability", "damages"],
"description": "Financial exposure limitation",
"recommendation": "Include liability caps and consequential damages exclusions",
"plain_english": "Limit how much you could owe if something goes wrong"
},
"termination_rights": {
"keywords": ["terminate", "end", "cancel"],
"description": "Exit mechanism from agreement",
"recommendation": "Include clear termination procedures and notice requirements",
"plain_english": "Make sure you can get out of this deal if needed"
}
}
}
def analyze_with_llm_simulation(self, clause_text: str) -> Dict[str, Any]:
"""
Simulate LLM analysis with enhanced pattern matching
In production, this would call GPT-4, Claude, or similar LLM
"""
clause_lower = clause_text.lower()
# Enhanced analysis results
analysis = {
"ambiguities": [],
"risks": [],
"recommendations": [],
"missingElements": [],
"references": [],
"riskScores": {},
"plainEnglish": [],
"severity": "LOW",
"contractType": self._detect_contract_type(clause_text),
"jurisdictionNotes": [],
"keyFindings": []
}
# Analyze ambiguous terms
for term, details in self.legal_patterns["ambiguous_terms"].items():
if term.lower() in clause_lower:
analysis["ambiguities"].append({
"issue": f"Ambiguous term: '{term}'",
"description": details["description"],
"riskLevel": details["risk_level"],
"recommendation": details["recommendation"],
"plainEnglish": details["plain_english"]
})
analysis["riskScores"][term] = self.risk_levels[details["risk_level"]]
# Analyze high-risk clauses
for pattern, details in self.legal_patterns["high_risk_clauses"].items():
if re.search(pattern, clause_lower):
analysis["risks"].append({
"issue": f"High-risk clause detected: {pattern.replace('.*', ' ')}",
"description": details["description"],
"riskLevel": details["risk_level"],
"recommendation": details["recommendation"],
"plainEnglish": details["plain_english"]
})
analysis["riskScores"][pattern] = self.risk_levels[details["risk_level"]]
# Check for missing protections
for protection, details in self.legal_patterns["missing_protections"].items():
if not any(keyword in clause_lower for keyword in details["keywords"]):
analysis["missingElements"].append({
"element": protection.replace("_", " ").title(),
"description": details["description"],
"recommendation": details["recommendation"],
"plainEnglish": details["plain_english"]
})
# Advanced pattern detection
self._detect_advanced_issues(clause_text, analysis)
# Calculate overall severity
analysis["severity"] = self._calculate_severity(analysis["riskScores"])
# Add legal references
analysis["references"] = self._get_relevant_legal_references(clause_text)
# Generate key findings summary
analysis["keyFindings"] = self._generate_key_findings(analysis)
return analysis
def _detect_contract_type(self, clause_text: str) -> str:
"""Detect the type of contract based on content"""
clause_lower = clause_text.lower()
if any(term in clause_lower for term in ["employment", "employee", "employer", "salary", "benefits"]):
return "Employment Agreement"
elif any(term in clause_lower for term in ["confidential", "non-disclosure", "proprietary"]):
return "Non-Disclosure Agreement"
elif any(term in clause_lower for term in ["service", "contractor", "deliverable", "statement of work"]):
return "Service Agreement"
elif any(term in clause_lower for term in ["license", "intellectual property", "software", "patent"]):
return "License Agreement"
elif any(term in clause_lower for term in ["purchase", "sale", "goods", "product"]):
return "Purchase Agreement"
else:
return "General Contract"
def _detect_advanced_issues(self, clause_text: str, analysis: Dict[str, Any]):
"""Detect advanced legal issues using sophisticated pattern matching"""
clause_lower = clause_text.lower()
# Detect problematic jurisdictions
problematic_jurisdictions = ["cayman", "bermuda", "delaware", "offshore"]
for jurisdiction in problematic_jurisdictions:
if jurisdiction in clause_lower:
analysis["jurisdictionNotes"].append({
"issue": f"Jurisdiction concern: {jurisdiction.title()}",
"description": "May limit legal protections and enforcement options",
"recommendation": "Consider more favorable jurisdiction for dispute resolution",
"plainEnglish": f"Resolving disputes in {jurisdiction.title()} may be difficult and expensive"
})
# Detect automatic renewal clauses
if re.search(r"automatic.*renew|auto.*renew", clause_lower):
analysis["risks"].append({
"issue": "Automatic renewal clause",
"description": "Contract may renew without explicit consent",
"riskLevel": "MEDIUM",
"recommendation": "Add clear opt-out procedures and advance notice requirements",
"plainEnglish": "This contract might renew itself - make sure you can cancel easily"
})
# Detect broad indemnification
if "indemnify" in clause_lower and "harmless" in clause_lower:
analysis["risks"].append({
"issue": "Broad indemnification clause",
"description": "May require defending against claims beyond your control",
"riskLevel": "HIGH",
"recommendation": "Limit indemnification to specific scenarios and exclude gross negligence",
"plainEnglish": "You might have to pay for problems you didn't cause"
})
# Detect class action waivers
if "class action" in clause_lower and "waiver" in clause_lower:
analysis["risks"].append({
"issue": "Class action waiver",
"description": "Prevents joining group lawsuits",
"riskLevel": "MEDIUM",
"recommendation": "Verify enforceability under applicable state law",
"plainEnglish": "You can't join with others to sue - may limit your legal options"
})
def _calculate_severity(self, risk_scores: Dict[str, int]) -> str:
"""Calculate overall severity based on risk scores"""
if not risk_scores:
return "LOW"
max_risk = max(risk_scores.values())
avg_risk = sum(risk_scores.values()) / len(risk_scores)
if max_risk >= 4 or avg_risk >= 3:
return "CRITICAL"
elif max_risk >= 3 or avg_risk >= 2.5:
return "HIGH"
elif max_risk >= 2 or avg_risk >= 1.5:
return "MEDIUM"
else:
return "LOW"
def _get_relevant_legal_references(self, clause_text: str) -> List[str]:
"""Get relevant legal references based on clause content"""
clause_lower = clause_text.lower()
references = []
# Contract law basics
references.append("Restatement (Second) of Contracts")
# Specific references based on content
if "employment" in clause_lower:
references.extend([
"Fair Labor Standards Act (FLSA)",
"National Labor Relations Act (NLRA)"
])
if "intellectual property" in clause_lower or "patent" in clause_lower:
references.extend([
"Copyright Act of 1976",
"Patent Act (35 U.S.C.)"
])
if "sale" in clause_lower or "goods" in clause_lower:
references.append("Uniform Commercial Code (UCC)")
if "arbitration" in clause_lower:
references.append("Federal Arbitration Act (FAA)")
if "consumer" in clause_lower:
references.append("Consumer Protection Acts (State-specific)")
return references[:5] # Limit to most relevant
def _generate_key_findings(self, analysis: Dict[str, Any]) -> List[str]:
"""Generate key findings summary"""
findings = []
total_issues = len(analysis["ambiguities"]) + len(analysis["risks"])
if total_issues == 0:
findings.append("No major legal issues detected in this clause")
elif total_issues <= 2:
findings.append(f"Found {total_issues} legal concern(s) requiring attention")
else:
findings.append(f"Identified {total_issues} significant legal issues - comprehensive review recommended")
if analysis["severity"] in ["HIGH", "CRITICAL"]:
findings.append(f"โš ๏ธ {analysis['severity']} RISK: Immediate legal review strongly recommended")
if len(analysis["missingElements"]) > 0:
findings.append(f"Missing {len(analysis['missingElements'])} important protective clauses")
if analysis["contractType"] != "General Contract":
findings.append(f"Detected as {analysis['contractType']} - applying specialized analysis")
return findings
def analyze_legal_clause_enhanced(clause_text: str) -> str:
"""Enhanced legal clause analysis with LLM-like capabilities"""
if not clause_text or not clause_text.strip():
return json.dumps({
"error": "Please provide a clause to analyze"
})
try:
analyzer = EnhancedLegalAnalyzer()
analysis = analyzer.analyze_with_llm_simulation(clause_text)
# Format for better readability
formatted_analysis = {
"summary": {
"contractType": analysis["contractType"],
"overallSeverity": analysis["severity"],
"totalIssues": len(analysis["ambiguities"]) + len(analysis["risks"]),
"keyFindings": analysis["keyFindings"]
},
"detailedAnalysis": {
"ambiguities": analysis["ambiguities"],
"risks": analysis["risks"],
"missingProtections": analysis["missingElements"],
"jurisdictionNotes": analysis["jurisdictionNotes"]
},
"recommendations": {
"immediate": [item["recommendation"] for item in analysis["ambiguities"] + analysis["risks"] if item.get("riskLevel") in ["HIGH", "CRITICAL"]],
"general": [item["recommendation"] for item in analysis["ambiguities"] + analysis["risks"] if item.get("riskLevel") in ["LOW", "MEDIUM"]],
"missingElements": [item["recommendation"] for item in analysis["missingElements"]]
},
"plainEnglishExplanation": {
"whatThisMeans": [item["plainEnglish"] for item in analysis["ambiguities"] + analysis["risks"]],
"whyItMatters": "Legal language can hide important risks. This analysis helps you understand what you're agreeing to in simple terms.",
"nextSteps": "Consider consulting with a qualified attorney for complex agreements or high-value transactions."
},
"legalReferences": analysis["references"],
"metadata": {
"analysisVersion": "2.0-enhanced",
"analysisDate": time.strftime("%Y-%m-%d %H:%M:%S"),
"disclaimer": "This analysis is for informational purposes only and does not constitute legal advice."
}
}
return json.dumps(formatted_analysis, indent=2)
except Exception as e:
return json.dumps({
"error": f"Analysis failed: {str(e)}",
"summary": {"overallSeverity": "UNKNOWN"},
"recommendations": {"immediate": ["Please retry the analysis or consult legal counsel"]},
"metadata": {"analysisVersion": "2.0-enhanced-error"}
})
# Create enhanced Gradio interface
demo = gr.Interface(
fn=analyze_legal_clause_enhanced,
inputs=gr.Textbox(
lines=15,
max_lines=50,
placeholder="Paste your legal clause here for comprehensive AI-powered analysis...",
label="Legal Clause Text",
info="Enter contract clauses, terms, or legal language for detailed analysis with risk assessment and plain-English explanations"
),
outputs=gr.JSON(
label="Enhanced Legal Analysis Results",
show_label=True
),
title="๐Ÿ›๏ธ Enhanced Legal Contract Clause Analyzer",
description="""
**AI-Powered Legal Contract Analysis Tool - Enhanced Version**
This enhanced tool provides comprehensive, LLM-powered analysis of legal contract clauses, featuring:
๐Ÿ” **Comprehensive Analysis**:
- **Risk Assessment**: Severity scoring and detailed risk evaluation
- **Plain English**: Simple explanations of complex legal terms
- **Contract Type Detection**: Specialized analysis based on agreement type
- **Missing Protections**: Identification of important missing clauses
๐Ÿ“Š **Enhanced Features**:
- **Severity Scoring**: LOW, MEDIUM, HIGH, CRITICAL risk levels
- **Jurisdiction Analysis**: Location-specific legal considerations
- **Immediate vs. General Recommendations**: Prioritized action items
- **Legal References**: Relevant laws, cases, and regulations
โš–๏ธ **Professional Quality**: Designed to provide thorough, digestible legal insights comparable to professional legal review.
*Note: This tool provides enhanced legal analysis but should not replace consultation with qualified legal counsel for important agreements.*
""",
examples=[
["The Contractor shall use reasonable efforts to complete the work in a timely manner using professional standards."],
["Company shall be liable for any and all damages, losses, costs, and expenses arising from this agreement, including consequential damages."],
["Employee hereby irrevocably assigns to Company all rights, title, and interest in any intellectual property created during employment, including ideas conceived outside work hours."],
["Either party may terminate this agreement immediately without cause or notice. Payment obligations survive indefinitely."],
["Recipient agrees to maintain in confidence all information disclosed, including publicly available information, for 50 years."],
["All disputes shall be resolved through binding arbitration in the Cayman Islands under Cayman law, with class action waiver."],
["This license grants worldwide, perpetual, irrevocable rights throughout the universe with waiver of audit rights."],
["Contractor agrees to indemnify and hold harmless Company from any and all claims, including those arising from Company's gross negligence."]
],
theme=gr.themes.Soft(),
allow_flagging="never",
analytics_enabled=False
)
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False
)