Joshua Guillen
Enhanced legal analyzer with improved pattern matching and comprehensive analysis features
a153a45
| #!/usr/bin/env python3 | |
| """ | |
| Test Suite for Enhanced Legal Clause Analyzer | |
| Compares original vs enhanced performance | |
| """ | |
| import json | |
| import sys | |
| import os | |
| from enhanced_app import analyze_legal_clause_enhanced | |
| def test_enhanced_analyzer(): | |
| """Test the enhanced legal analyzer""" | |
| print("ποΈ ENHANCED LEGAL CLAUSE ANALYZER - TEST SUITE") | |
| print("=" * 70) | |
| test_cases = [ | |
| { | |
| "name": "Vague Performance Standards", | |
| "clause": "The Contractor shall perform the services in a professional manner using reasonable efforts to complete the work in a timely fashion.", | |
| "expected_issues": ["reasonable efforts", "professional manner", "timely fashion"], | |
| "difficulty": "Easy" | |
| }, | |
| { | |
| "name": "Unlimited Liability Exposure", | |
| "clause": "Company shall be liable for any and all damages, losses, costs, and expenses arising from or related to this agreement, including consequential damages.", | |
| "expected_issues": ["unlimited liability", "consequential damages", "liability cap"], | |
| "difficulty": "Medium" | |
| }, | |
| { | |
| "name": "Overly Broad IP Assignment", | |
| "clause": "Employee hereby irrevocably assigns to Company all rights, title, and interest in any and all intellectual property created during employment, including ideas conceived outside of work hours.", | |
| "expected_issues": ["overly broad", "outside work hours", "irrevocable assignment"], | |
| "difficulty": "Hard" | |
| }, | |
| { | |
| "name": "Problematic Termination Terms", | |
| "clause": "Either party may terminate this agreement immediately without cause or notice. Upon termination, all obligations cease except payment obligations which survive indefinitely.", | |
| "expected_issues": ["immediate termination", "no notice", "indefinite survival"], | |
| "difficulty": "Medium" | |
| }, | |
| { | |
| "name": "Overly Broad Confidentiality", | |
| "clause": "Recipient agrees to maintain in confidence all information disclosed by Discloser, including publicly available information, for a period of 50 years.", | |
| "expected_issues": ["publicly available", "50 years", "overly broad"], | |
| "difficulty": "Medium" | |
| }, | |
| { | |
| "name": "Complex Commercial Terms", | |
| "clause": "All disputes shall be resolved through binding arbitration in the Cayman Islands under Cayman law, with each party waiving rights to class action lawsuits.", | |
| "expected_issues": ["offshore jurisdiction", "class action waiver", "binding arbitration"], | |
| "difficulty": "Hard" | |
| } | |
| ] | |
| total_score = 0 | |
| max_possible_score = 0 | |
| for i, test_case in enumerate(test_cases, 1): | |
| print(f"\nπ TEST {i}: {test_case['name']}") | |
| print(f"Difficulty: {test_case['difficulty']}") | |
| print("-" * 50) | |
| print(f"π Clause: {test_case['clause']}") | |
| # Run enhanced analysis | |
| result = analyze_legal_clause_enhanced(test_case['clause']) | |
| try: | |
| parsed_result = json.loads(result) | |
| if "error" in parsed_result: | |
| print(f"β Error: {parsed_result['error']}") | |
| continue | |
| # Display enhanced analysis structure | |
| summary = parsed_result.get('summary', {}) | |
| detailed = parsed_result.get('detailedAnalysis', {}) | |
| recommendations = parsed_result.get('recommendations', {}) | |
| plain_english = parsed_result.get('plainEnglishExplanation', {}) | |
| print(f"\nπ Enhanced Analysis Results:") | |
| print(f" β’ Contract Type: {summary.get('contractType', 'Unknown')}") | |
| print(f" β’ Overall Severity: {summary.get('overallSeverity', 'Unknown')}") | |
| print(f" β’ Total Issues: {summary.get('totalIssues', 0)}") | |
| print(f" β’ Ambiguities: {len(detailed.get('ambiguities', []))}") | |
| print(f" β’ Risks: {len(detailed.get('risks', []))}") | |
| print(f" β’ Missing Protections: {len(detailed.get('missingProtections', []))}") | |
| print(f" β’ Jurisdiction Notes: {len(detailed.get('jurisdictionNotes', []))}") | |
| # Check coverage of expected issues | |
| all_findings = [] | |
| # Extract text from detailed analysis | |
| for ambiguity in detailed.get('ambiguities', []): | |
| all_findings.append(ambiguity.get('issue', '')) | |
| all_findings.append(ambiguity.get('description', '')) | |
| all_findings.append(ambiguity.get('plainEnglish', '')) | |
| for risk in detailed.get('risks', []): | |
| all_findings.append(risk.get('issue', '')) | |
| all_findings.append(risk.get('description', '')) | |
| all_findings.append(risk.get('plainEnglish', '')) | |
| # Add recommendations | |
| for rec_list in recommendations.values(): | |
| if isinstance(rec_list, list): | |
| all_findings.extend(rec_list) | |
| # Add plain English explanations | |
| if isinstance(plain_english.get('whatThisMeans'), list): | |
| all_findings.extend(plain_english['whatThisMeans']) | |
| issues_found = 0 | |
| for expected in test_case['expected_issues']: | |
| found = any(expected.lower() in finding.lower() for finding in all_findings if finding) | |
| if found: | |
| issues_found += 1 | |
| print(f" β Found expected issue: {expected}") | |
| else: | |
| print(f" β Missing expected issue: {expected}") | |
| coverage_score = (issues_found / len(test_case['expected_issues'])) * 100 | |
| print(f"π Coverage Score: {coverage_score:.1f}% ({issues_found}/{len(test_case['expected_issues'])})") | |
| # Enhanced quality assessment | |
| quality_score = 0 | |
| max_quality = 10 # Increased for enhanced features | |
| # Check for detailed recommendations | |
| immediate_recs = recommendations.get('immediate', []) | |
| general_recs = recommendations.get('general', []) | |
| if immediate_recs or general_recs: | |
| quality_score += 2 | |
| print(" β Comprehensive recommendations provided") | |
| else: | |
| print(" β No recommendations provided") | |
| # Check for risk severity assessment | |
| if summary.get('overallSeverity') != 'Unknown': | |
| quality_score += 2 | |
| print(" β Risk severity assessment provided") | |
| else: | |
| print(" β No risk severity assessment") | |
| # Check for plain English explanations | |
| if plain_english.get('whatThisMeans'): | |
| quality_score += 2 | |
| print(" β Plain English explanations provided") | |
| else: | |
| print(" β No plain English explanations") | |
| # Check for contract type detection | |
| if summary.get('contractType') != 'General Contract': | |
| quality_score += 1 | |
| print(" β Contract type detected") | |
| else: | |
| print(" β Generic contract type") | |
| # Check for legal references | |
| references = parsed_result.get('legalReferences', []) | |
| if references and len(references) > 0: | |
| quality_score += 1 | |
| print(" β Legal references provided") | |
| else: | |
| print(" β No legal references") | |
| # Check for missing protections identification | |
| missing = detailed.get('missingProtections', []) | |
| if missing and len(missing) > 0: | |
| quality_score += 1 | |
| print(" β Missing protections identified") | |
| else: | |
| print(" β No missing protections identified") | |
| # Check for key findings | |
| key_findings = summary.get('keyFindings', []) | |
| if key_findings and len(key_findings) > 0: | |
| quality_score += 1 | |
| print(" β Key findings summary provided") | |
| else: | |
| print(" β No key findings summary") | |
| quality_percentage = (quality_score / max_quality) * 100 | |
| print(f"π― Enhanced Quality Score: {quality_percentage:.1f}% ({quality_score}/{max_quality})") | |
| # Display some key findings for verification | |
| if key_findings: | |
| print(f"\nπ‘ Key Findings:") | |
| for finding in key_findings[:3]: # Show first 3 | |
| print(f" β’ {finding}") | |
| # Calculate overall test score | |
| test_score = (coverage_score + quality_percentage) / 2 | |
| total_score += test_score | |
| max_possible_score += 100 | |
| print(f"π Overall Test Score: {test_score:.1f}%") | |
| except json.JSONDecodeError as e: | |
| print(f"β ERROR: Invalid JSON response - {e}") | |
| except Exception as e: | |
| print(f"β ERROR: {e}") | |
| # Final summary | |
| print("\n" + "=" * 70) | |
| print("π ENHANCED ANALYZER TEST SUMMARY") | |
| print("=" * 70) | |
| overall_score = (total_score / max_possible_score) * 100 if max_possible_score > 0 else 0 | |
| print(f"Overall Enhanced System Score: {overall_score:.1f}%") | |
| print(f"\nπ PERFORMANCE ASSESSMENT:") | |
| if overall_score >= 85: | |
| print("π EXCELLENT: System provides professional-grade legal analysis") | |
| elif overall_score >= 70: | |
| print("β GOOD: System provides solid legal analysis with room for improvement") | |
| elif overall_score >= 55: | |
| print("β οΈ ADEQUATE: System provides basic analysis but needs enhancement") | |
| else: | |
| print("β POOR: System requires significant improvement") | |
| print(f"\nπ IMPROVEMENT FROM ORIGINAL:") | |
| original_score = 53.3 # From previous test | |
| improvement = overall_score - original_score | |
| print(f"Original Score: {original_score:.1f}%") | |
| print(f"Enhanced Score: {overall_score:.1f}%") | |
| print(f"Improvement: +{improvement:.1f} percentage points") | |
| if improvement > 20: | |
| print("π SIGNIFICANT IMPROVEMENT achieved!") | |
| elif improvement > 10: | |
| print("π GOOD IMPROVEMENT achieved!") | |
| elif improvement > 0: | |
| print("π MODEST IMPROVEMENT achieved") | |
| else: | |
| print("β οΈ No improvement - further work needed") | |
| print(f"\nπ‘ NEXT STEPS FOR FURTHER IMPROVEMENT:") | |
| if overall_score < 90: | |
| print("1. π€ Integrate actual LLM API (GPT-4, Claude, etc.)") | |
| print("2. π Expand legal knowledge base with more patterns") | |
| print("3. π― Add industry-specific analysis modules") | |
| print("4. π Implement user feedback learning system") | |
| print("5. π Add jurisdiction-specific legal databases") | |
| if __name__ == "__main__": | |
| test_enhanced_analyzer() |