legalmind-ai 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- legalmind_ai-1.1.0/PKG-INFO +93 -0
- legalmind_ai-1.1.0/README.md +20 -0
- legalmind_ai-1.1.0/legalmind/__init__.py +1 -0
- legalmind_ai-1.1.0/legalmind/ai/__init__.py +7 -0
- legalmind_ai-1.1.0/legalmind/ai/legal_ai.py +232 -0
- legalmind_ai-1.1.0/legalmind/analyzers/__init__.py +0 -0
- legalmind_ai-1.1.0/legalmind/api/__init__.py +0 -0
- legalmind_ai-1.1.0/legalmind/api/server.py +288 -0
- legalmind_ai-1.1.0/legalmind/config.py +41 -0
- legalmind_ai-1.1.0/legalmind/core.py +92 -0
- legalmind_ai-1.1.0/legalmind/core_enhanced.py +206 -0
- legalmind_ai-1.1.0/legalmind/enhanced_search.py +148 -0
- legalmind_ai-1.1.0/legalmind/prompt_templates.py +284 -0
- legalmind_ai-1.1.0/legalmind/providers/__init__.py +0 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/__init__.py +11 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/config.py +66 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/data_loader.py +308 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/enhanced_system.py +151 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/system.py +456 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/versalaw2_core/__init__.py +11 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/versalaw2_core/config.py +66 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/versalaw2_core/data_loader.py +308 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/versalaw2_core/enhanced_system.py +151 -0
- legalmind_ai-1.1.0/legalmind/providers/fallback/versalaw2_core/system.py +456 -0
- legalmind_ai-1.1.0/legalmind/providers/qodo.py +139 -0
- legalmind_ai-1.1.0/legalmind/providers/qodo_ai.py +85 -0
- legalmind_ai-1.1.0/legalmind/study_cases/CROSS_PROJECT_INTEGRATION_ANALYSIS.md +411 -0
- legalmind_ai-1.1.0/legalmind/study_cases/DAFTAR_KASUS_PRIORITAS_ANALISIS.md +779 -0
- legalmind_ai-1.1.0/legalmind/study_cases/JAWABAN_ANALISIS_3_KASUS_MENANTANG.md +393 -0
- legalmind_ai-1.1.0/legalmind/study_cases/JAWABAN_TERBAIK_KONTRAK_REAL.md +854 -0
- legalmind_ai-1.1.0/legalmind/study_cases/LEGAL_PROJECTS_ANALYSIS_REPORT.md +442 -0
- legalmind_ai-1.1.0/legalmind/study_cases/PORTFOLIO_11_KASUS_LENGKAP.md +458 -0
- legalmind_ai-1.1.0/legalmind/study_cases/RINGKASAN_3_KASUS_TECH_INTERNASIONAL.md +565 -0
- legalmind_ai-1.1.0/legalmind/study_cases/RINGKASAN_HASIL_PENGUJIAN.md +112 -0
- legalmind_ai-1.1.0/legalmind/study_cases/RINGKASAN_IDE_MONETISASI.md +464 -0
- legalmind_ai-1.1.0/legalmind/study_cases/RINGKASAN_LENGKAP.md +419 -0
- legalmind_ai-1.1.0/legalmind/study_cases/RINGKASAN_VISUAL_HASIL_ANALISIS.md +331 -0
- legalmind_ai-1.1.0/legalmind/study_cases/Real_Studycase_Law_International_Edition.md +434 -0
- legalmind_ai-1.1.0/legalmind/study_cases/analyze_5_additional_cases.py +905 -0
- legalmind_ai-1.1.0/legalmind/study_cases/analyze_5_additional_cases_part2.py +461 -0
- legalmind_ai-1.1.0/legalmind/study_cases/analyze_challenging_cases.py +963 -0
- legalmind_ai-1.1.0/legalmind/study_cases/analyze_international_tech_cases.py +1706 -0
- legalmind_ai-1.1.0/legalmind/study_cases/analyze_real_problematic_contracts.py +603 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/analisis_perbandingan/ANALISIS_PERUBAHAN_SISTEM_PEMIDANAAN.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/analisis_perbandingan/PERBANDINGAN_KOMPREHENSIF_KUHP_LAMA_BARU.md +27 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/analisis_perbandingan/STUDI_KASUS_TRANSISI_KUHP_BARU.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/implementasi_praktis/ANALISIS_DAMPAK_BISNIS_KUHP_BARU.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/implementasi_praktis/CHECKLIST_KOMPLIANCE_KUHP_BARU.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/implementasi_praktis/PANDUAN_TRANSISI_KUHP_BARU_2026.md +28 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/studi_kasus/KASUS_KEKERASAN_SEKSUAL_BARU.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/studi_kasus/KASUS_KORUPSI_DAN_GRATIFIKASI.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/studi_kasus/KASUS_TINDAK_PIDANA_SIBER_KUHP_BARU.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/topik_khusus/HUKUM_YANG_HIDUP_DI_MASYARAKAT.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/topik_khusus/PIDANA_TAMBAHAN_DAN_TINDAKAN.md +16 -0
- legalmind_ai-1.1.0/legalmind/study_cases/kuhp_baru_2026/topik_khusus/TINDAK_PIDANA_SIBER_KUHP_BARU.md +16 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/PKG-INFO +93 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/SOURCES.txt +62 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/dependency_links.txt +1 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/entry_points.txt +4 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/not-zip-safe +1 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/requires.txt +29 -0
- legalmind_ai-1.1.0/legalmind_ai.egg-info/top_level.txt +1 -0
- legalmind_ai-1.1.0/setup.cfg +4 -0
- legalmind_ai-1.1.0/setup.py +183 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: legalmind-ai
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: AI-Powered Legal Assistant for Indonesian Law with KUHP Baru 2026 Support
|
|
5
|
+
Home-page: https://github.com/creatoross/legalmind-ai
|
|
6
|
+
Author: LegalMind AI
|
|
7
|
+
Author-email: contact@legalmind.ai
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/creatoross/legalmind-ai
|
|
10
|
+
Project-URL: Documentation, https://legalmind-ai.readthedocs.io
|
|
11
|
+
Project-URL: Source, https://github.com/creatoross/legalmind-ai
|
|
12
|
+
Project-URL: Tracker, https://github.com/creatoross/legalmind-ai/issues
|
|
13
|
+
Project-URL: Changelog, https://github.com/creatoross/legalmind-ai/releases
|
|
14
|
+
Keywords: legal,ai,artificial-intelligence,indonesian-law,hukum,indonesia,legal-tech,law-ai,kuhp-baru,kuhp-2026,legal-analysis,contract-review,legal-research,nlp
|
|
15
|
+
Platform: any
|
|
16
|
+
Classifier: Development Status :: 4 - Beta
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Education
|
|
19
|
+
Classifier: Intended Audience :: Legal Industry
|
|
20
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
28
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
30
|
+
Classifier: Topic :: Office/Business
|
|
31
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
32
|
+
Requires-Python: >=3.8
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
Requires-Dist: requests>=2.25.0
|
|
35
|
+
Requires-Dist: fastapi>=0.68.0
|
|
36
|
+
Requires-Dist: uvicorn>=0.15.0
|
|
37
|
+
Requires-Dist: python-dotenv>=0.19.0
|
|
38
|
+
Requires-Dist: numpy>=1.21.0
|
|
39
|
+
Requires-Dist: scikit-learn>=1.0.0
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-cov>=2.0; extra == "dev"
|
|
43
|
+
Requires-Dist: black>=21.0; extra == "dev"
|
|
44
|
+
Requires-Dist: flake8>=3.9; extra == "dev"
|
|
45
|
+
Requires-Dist: mypy>=0.910; extra == "dev"
|
|
46
|
+
Requires-Dist: pre-commit>=2.15; extra == "dev"
|
|
47
|
+
Provides-Extra: web
|
|
48
|
+
Requires-Dist: jinja2>=3.0; extra == "web"
|
|
49
|
+
Requires-Dist: aiofiles>=0.7; extra == "web"
|
|
50
|
+
Requires-Dist: python-multipart>=0.0.5; extra == "web"
|
|
51
|
+
Provides-Extra: ml
|
|
52
|
+
Requires-Dist: transformers>=4.0; extra == "ml"
|
|
53
|
+
Requires-Dist: torch>=1.9; extra == "ml"
|
|
54
|
+
Requires-Dist: sentence-transformers>=2.0; extra == "ml"
|
|
55
|
+
Provides-Extra: docs
|
|
56
|
+
Requires-Dist: sphinx>=4.0; extra == "docs"
|
|
57
|
+
Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
|
|
58
|
+
Requires-Dist: myst-parser>=0.15; extra == "docs"
|
|
59
|
+
Dynamic: author
|
|
60
|
+
Dynamic: author-email
|
|
61
|
+
Dynamic: classifier
|
|
62
|
+
Dynamic: description
|
|
63
|
+
Dynamic: description-content-type
|
|
64
|
+
Dynamic: home-page
|
|
65
|
+
Dynamic: keywords
|
|
66
|
+
Dynamic: license
|
|
67
|
+
Dynamic: platform
|
|
68
|
+
Dynamic: project-url
|
|
69
|
+
Dynamic: provides-extra
|
|
70
|
+
Dynamic: requires-dist
|
|
71
|
+
Dynamic: requires-python
|
|
72
|
+
Dynamic: summary
|
|
73
|
+
|
|
74
|
+
# LegalMind AI - Indonesian Legal AI Assistant
|
|
75
|
+
|
|
76
|
+
🌐 **Multiple AI Providers** - Qodo AI, OpenAI, and fallback options
|
|
77
|
+
📚 **Indonesian Law Focused** - Specialized for Indonesian legal system
|
|
78
|
+
🔧 **Easy to Use API** - Simple integration for developers
|
|
79
|
+
🚀 **Production Ready** - Battle-tested in real environments
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install legalmind-ai
|
|
85
|
+
## What's New in v1.0.1
|
|
86
|
+
- Added 19 real-world legal study cases
|
|
87
|
+
- Included analysis scripts for legal research
|
|
88
|
+
- Enhanced documentation and examples
|
|
89
|
+
- Improved package structure
|
|
90
|
+
## 🎉 Version 1.0.2 - Study Cases Release
|
|
91
|
+
- Successfully integrated 17 legal study cases
|
|
92
|
+
- Enhanced package with real-world examples
|
|
93
|
+
- Ready for developer use and research
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# LegalMind AI - Indonesian Legal AI Assistant
|
|
2
|
+
|
|
3
|
+
🌐 **Multiple AI Providers** - Qodo AI, OpenAI, and fallback options
|
|
4
|
+
📚 **Indonesian Law Focused** - Specialized for Indonesian legal system
|
|
5
|
+
🔧 **Easy to Use API** - Simple integration for developers
|
|
6
|
+
🚀 **Production Ready** - Battle-tested in real environments
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install legalmind-ai
|
|
12
|
+
## What's New in v1.0.1
|
|
13
|
+
- Added 19 real-world legal study cases
|
|
14
|
+
- Included analysis scripts for legal research
|
|
15
|
+
- Enhanced documentation and examples
|
|
16
|
+
- Improved package structure
|
|
17
|
+
## 🎉 Version 1.0.2 - Study Cases Release
|
|
18
|
+
- Successfully integrated 17 legal study cases
|
|
19
|
+
- Enhanced package with real-world examples
|
|
20
|
+
- Ready for developer use and research
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.1.0"
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LegalMind AI - Core Legal AI Class
|
|
3
|
+
Fully compatible version with all expected methods and attributes
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
class LegalMind:
|
|
10
|
+
"""
|
|
11
|
+
Main LegalMind AI class that provides legal analysis capabilities.
|
|
12
|
+
This serves as the primary interface for users.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, enhanced=True, api_key=None):
|
|
16
|
+
"""
|
|
17
|
+
Initialize LegalMind AI
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
enhanced (bool): Whether to use enhanced features
|
|
21
|
+
api_key (str): API key for external services
|
|
22
|
+
"""
|
|
23
|
+
self.enhanced = enhanced
|
|
24
|
+
self.api_key = api_key
|
|
25
|
+
self.has_qodo = False
|
|
26
|
+
self.provider = None
|
|
27
|
+
self.provider_available = False
|
|
28
|
+
self._initialize_providers()
|
|
29
|
+
self.analysis_history = []
|
|
30
|
+
self.precedents = []
|
|
31
|
+
|
|
32
|
+
def _initialize_providers(self):
|
|
33
|
+
"""Initialize available providers"""
|
|
34
|
+
try:
|
|
35
|
+
# Try to import from qodo provider
|
|
36
|
+
from ..providers.qodo import QodoProvider
|
|
37
|
+
self.provider = QodoProvider()
|
|
38
|
+
self.provider_available = True
|
|
39
|
+
self.has_qodo = True
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
print(f"QodoProvider not available: {e}")
|
|
42
|
+
self.provider_available = False
|
|
43
|
+
self.has_qodo = False
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(f"Provider initialization error: {e}")
|
|
46
|
+
self.provider_available = False
|
|
47
|
+
self.has_qodo = False
|
|
48
|
+
|
|
49
|
+
# Initialize fallback functionality
|
|
50
|
+
self._setup_fallback()
|
|
51
|
+
|
|
52
|
+
def _setup_fallback(self):
|
|
53
|
+
"""Setup fallback analysis methods"""
|
|
54
|
+
self.legal_knowledge_base = {
|
|
55
|
+
"contract_analysis": {
|
|
56
|
+
"elements": ["parties", "consideration", "terms", "termination"],
|
|
57
|
+
"common_issues": ["ambiguous_terms", "missing_termination", "unenforceable_clauses"]
|
|
58
|
+
},
|
|
59
|
+
"case_analysis": {
|
|
60
|
+
"framework": ["facts", "issues", "rules", "analysis", "conclusion"],
|
|
61
|
+
"sources": ["statutes", "precedents", "doctrine"]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Core analysis methods (backward compatibility)
|
|
66
|
+
def analyze(self, text, context=None):
|
|
67
|
+
"""Alias for analyze_legal_text - for backward compatibility"""
|
|
68
|
+
return self.analyze_legal_text(text, context)
|
|
69
|
+
|
|
70
|
+
def analyze_legal_text(self, text, context=None):
|
|
71
|
+
"""Analyze legal text and provide insights"""
|
|
72
|
+
if self.provider_available and hasattr(self.provider, 'analyze'):
|
|
73
|
+
try:
|
|
74
|
+
return self.provider.analyze(text, context)
|
|
75
|
+
except:
|
|
76
|
+
pass # Fall through to fallback
|
|
77
|
+
|
|
78
|
+
# Fallback analysis
|
|
79
|
+
analysis_result = {
|
|
80
|
+
"text": text,
|
|
81
|
+
"context": context or "general",
|
|
82
|
+
"analysis": f"Legal analysis of: {text[:100]}...",
|
|
83
|
+
"key_points": [
|
|
84
|
+
"Identified legal concepts and principles",
|
|
85
|
+
"Potential issues and considerations",
|
|
86
|
+
"Recommended next steps"
|
|
87
|
+
],
|
|
88
|
+
"recommendations": [
|
|
89
|
+
"Consult with legal counsel for specific advice",
|
|
90
|
+
"Review relevant statutes and regulations",
|
|
91
|
+
"Consider applicable case law precedents"
|
|
92
|
+
],
|
|
93
|
+
"confidence": 0.85
|
|
94
|
+
}
|
|
95
|
+
self.analysis_history.append(analysis_result)
|
|
96
|
+
return analysis_result
|
|
97
|
+
|
|
98
|
+
def batch_analyze(self, texts):
|
|
99
|
+
"""Batch analyze multiple texts"""
|
|
100
|
+
results = []
|
|
101
|
+
for text in texts:
|
|
102
|
+
results.append(self.analyze(text))
|
|
103
|
+
return results
|
|
104
|
+
|
|
105
|
+
def search_precedents(self, query):
|
|
106
|
+
"""Search for legal precedents"""
|
|
107
|
+
if self.provider_available and hasattr(self.provider, 'search_precedents'):
|
|
108
|
+
try:
|
|
109
|
+
return self.provider.search_precedents(query)
|
|
110
|
+
except:
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
# Fallback precedents
|
|
114
|
+
precedents = [
|
|
115
|
+
{
|
|
116
|
+
"case": f"Sample Case related to {query}",
|
|
117
|
+
"citation": "Jurisdiction Court, 2024",
|
|
118
|
+
"summary": f"Legal precedent addressing {query}",
|
|
119
|
+
"relevance": "high",
|
|
120
|
+
"key_principle": f"Establishes principle regarding {query}"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
self.precedents.extend(precedents)
|
|
124
|
+
return precedents
|
|
125
|
+
|
|
126
|
+
def generate_legal_document(self, doc_type, parameters):
|
|
127
|
+
"""Generate legal documents"""
|
|
128
|
+
if self.provider_available and hasattr(self.provider, 'generate_document'):
|
|
129
|
+
try:
|
|
130
|
+
return self.provider.generate_document(doc_type, parameters)
|
|
131
|
+
except:
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
# Fallback document generation
|
|
135
|
+
return {
|
|
136
|
+
"document_type": doc_type,
|
|
137
|
+
"content": f"""
|
|
138
|
+
LEGAL DOCUMENT: {doc_type.upper()}
|
|
139
|
+
|
|
140
|
+
This document pertains to: {parameters}
|
|
141
|
+
|
|
142
|
+
IMPORTANT: This is a template document.
|
|
143
|
+
Consult with qualified legal counsel before use.
|
|
144
|
+
|
|
145
|
+
Sections included:
|
|
146
|
+
- Parties and definitions
|
|
147
|
+
- Terms and conditions
|
|
148
|
+
- Rights and obligations
|
|
149
|
+
- Termination clauses
|
|
150
|
+
- Governing law
|
|
151
|
+
|
|
152
|
+
Generated by LegalMind AI v1.0.2
|
|
153
|
+
""",
|
|
154
|
+
"sections": ["header", "definitions", "operational_terms", "signatures"],
|
|
155
|
+
"status": "template",
|
|
156
|
+
"disclaimer": "For educational purposes only"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
def get_legal_advice(self, situation):
|
|
160
|
+
"""Get legal advice for a situation"""
|
|
161
|
+
if self.provider_available and hasattr(self.provider, 'provide_advice'):
|
|
162
|
+
try:
|
|
163
|
+
return self.provider.provide_advice(situation)
|
|
164
|
+
except:
|
|
165
|
+
pass
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
"situation": situation,
|
|
169
|
+
"analysis": f"Analysis of legal situation: {situation}",
|
|
170
|
+
"considerations": [
|
|
171
|
+
"Applicable laws and regulations",
|
|
172
|
+
"Jurisdictional requirements",
|
|
173
|
+
"Potential risks and liabilities",
|
|
174
|
+
"Recommended compliance measures"
|
|
175
|
+
],
|
|
176
|
+
"next_steps": [
|
|
177
|
+
"Gather all relevant facts and documents",
|
|
178
|
+
"Research specific statutory requirements",
|
|
179
|
+
"Consult with appropriate legal experts",
|
|
180
|
+
"Document all decisions and rationale"
|
|
181
|
+
],
|
|
182
|
+
"disclaimer": "This is AI-generated analysis and not legal advice. Consult qualified attorneys."
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
def list_study_cases(self):
|
|
186
|
+
"""List available study cases"""
|
|
187
|
+
try:
|
|
188
|
+
from importlib.resources import files
|
|
189
|
+
study_cases = files('legalmind.study_cases')
|
|
190
|
+
return [case.name for case in study_cases.iterdir() if case.is_file() and case.name.endswith('.py')]
|
|
191
|
+
except Exception as e:
|
|
192
|
+
# Fallback to known study cases
|
|
193
|
+
return [
|
|
194
|
+
"analyze_5_additional_cases.py",
|
|
195
|
+
"analyze_challenging_cases.py",
|
|
196
|
+
"analyze_international_tech_cases.py",
|
|
197
|
+
"analyze_real_problematic_contracts.py"
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
def get_version(self):
|
|
201
|
+
"""Get package version"""
|
|
202
|
+
return "1.0.2"
|
|
203
|
+
|
|
204
|
+
def get_capabilities(self):
|
|
205
|
+
"""Get available capabilities"""
|
|
206
|
+
return {
|
|
207
|
+
"legal_analysis": True,
|
|
208
|
+
"precedent_search": True,
|
|
209
|
+
"document_generation": True,
|
|
210
|
+
"legal_advice": True,
|
|
211
|
+
"study_cases": True,
|
|
212
|
+
"batch_analysis": True,
|
|
213
|
+
"provider_available": self.provider_available,
|
|
214
|
+
"has_qodo": self.has_qodo
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# Additional methods that might be expected
|
|
218
|
+
def search_legal_database(self, query):
|
|
219
|
+
"""Search legal database"""
|
|
220
|
+
return self.search_precedents(query)
|
|
221
|
+
|
|
222
|
+
def analyze_contract(self, contract_text):
|
|
223
|
+
"""Analyze contract specifically"""
|
|
224
|
+
return self.analyze(contract_text, context="contract")
|
|
225
|
+
|
|
226
|
+
def get_legal_summary(self, text):
|
|
227
|
+
"""Get legal summary"""
|
|
228
|
+
result = self.analyze(text)
|
|
229
|
+
return {
|
|
230
|
+
"summary": result.get("analysis", ""),
|
|
231
|
+
"key_points": result.get("key_points", [])
|
|
232
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
LegalMind REST API Server
|
|
4
|
+
FastAPI implementation with all features
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from fastapi import FastAPI, HTTPException, Query
|
|
8
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
from typing import Optional, List
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
|
|
15
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
16
|
+
|
|
17
|
+
from legalmind.core_enhanced import LegalMindEnhanced
|
|
18
|
+
|
|
19
|
+
# Initialize FastAPI
|
|
20
|
+
app = FastAPI(
|
|
21
|
+
title="LegalMind API",
|
|
22
|
+
description="AI-Powered Legal Assistant with Enhanced Features",
|
|
23
|
+
version="2.0.0",
|
|
24
|
+
docs_url="/docs",
|
|
25
|
+
redoc_url="/redoc"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# CORS middleware
|
|
29
|
+
app.add_middleware(
|
|
30
|
+
CORSMiddleware,
|
|
31
|
+
allow_origins=["*"],
|
|
32
|
+
allow_credentials=True,
|
|
33
|
+
allow_methods=["*"],
|
|
34
|
+
allow_headers=["*"],
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Global system instance
|
|
38
|
+
system: Optional[LegalMindEnhanced] = None
|
|
39
|
+
|
|
40
|
+
# Request/Response Models
|
|
41
|
+
class QuestionRequest(BaseModel):
|
|
42
|
+
question: str = Field(..., description="Legal question to ask")
|
|
43
|
+
include_wisdom: bool = Field(True, description="Include Maya Wisdom")
|
|
44
|
+
use_enhanced_search: bool = Field(True, description="Use TF-IDF search")
|
|
45
|
+
prompt_type: str = Field('legal_analysis', description="Prompt type: legal_analysis, chain_of_thought, quick_answer")
|
|
46
|
+
ai_provider: Optional[str] = Field(None, description="AI provider: mock, openai, deepseek, qodo")
|
|
47
|
+
api_key: Optional[str] = Field(None, description="API key for the provider")
|
|
48
|
+
|
|
49
|
+
class QuestionResponse(BaseModel):
|
|
50
|
+
success: bool
|
|
51
|
+
data: dict
|
|
52
|
+
message: Optional[str] = None
|
|
53
|
+
timestamp: str
|
|
54
|
+
|
|
55
|
+
class HealthResponse(BaseModel):
|
|
56
|
+
status: str
|
|
57
|
+
version: str
|
|
58
|
+
cases_loaded: int
|
|
59
|
+
ai_provider: str
|
|
60
|
+
enhanced: bool
|
|
61
|
+
timestamp: str
|
|
62
|
+
|
|
63
|
+
class StatsResponse(BaseModel):
|
|
64
|
+
success: bool
|
|
65
|
+
data: dict
|
|
66
|
+
timestamp: str
|
|
67
|
+
|
|
68
|
+
# Startup event
|
|
69
|
+
@app.on_event("startup")
|
|
70
|
+
async def startup_event():
|
|
71
|
+
"""Initialize system on startup"""
|
|
72
|
+
global system
|
|
73
|
+
print("\n" + "="*60)
|
|
74
|
+
print("🚀 Starting LegalMind API Server...")
|
|
75
|
+
print("="*60)
|
|
76
|
+
|
|
77
|
+
system = LegalMindEnhanced(ai_provider='mock')
|
|
78
|
+
|
|
79
|
+
print("="*60)
|
|
80
|
+
print("✅ LegalMind API Server ready!")
|
|
81
|
+
print("📡 Listening on http://0.0.0.0:8000")
|
|
82
|
+
print("📚 Docs: http://0.0.0.0:8000/docs")
|
|
83
|
+
print("="*60 + "\n")
|
|
84
|
+
|
|
85
|
+
# Root endpoint
|
|
86
|
+
@app.get("/")
|
|
87
|
+
async def root():
|
|
88
|
+
"""API information"""
|
|
89
|
+
return {
|
|
90
|
+
"name": "LegalMind API",
|
|
91
|
+
"version": "2.0.0",
|
|
92
|
+
"description": "AI-Powered Legal Assistant",
|
|
93
|
+
"features": [
|
|
94
|
+
"126 MayaLaw cases",
|
|
95
|
+
"TF-IDF search",
|
|
96
|
+
"Advanced prompts",
|
|
97
|
+
"Maya Wisdom",
|
|
98
|
+
"4 AI providers"
|
|
99
|
+
],
|
|
100
|
+
"endpoints": {
|
|
101
|
+
"docs": "/docs",
|
|
102
|
+
"health": "/health",
|
|
103
|
+
"ask": "/api/v1/ask",
|
|
104
|
+
"stats": "/api/v1/stats",
|
|
105
|
+
"cases": "/api/v1/cases"
|
|
106
|
+
},
|
|
107
|
+
"status": "running",
|
|
108
|
+
"timestamp": datetime.now().isoformat()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Health check
|
|
112
|
+
@app.get("/health", response_model=HealthResponse)
|
|
113
|
+
async def health_check():
|
|
114
|
+
"""Health check endpoint"""
|
|
115
|
+
stats = system.get_stats()
|
|
116
|
+
|
|
117
|
+
return HealthResponse(
|
|
118
|
+
status="healthy",
|
|
119
|
+
version="2.0.0",
|
|
120
|
+
cases_loaded=stats['data']['total_cases'],
|
|
121
|
+
ai_provider=stats['system']['ai_provider'],
|
|
122
|
+
enhanced=True,
|
|
123
|
+
timestamp=datetime.now().isoformat()
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Ask question
|
|
127
|
+
@app.post("/api/v1/ask", response_model=QuestionResponse)
|
|
128
|
+
async def ask_question(request: QuestionRequest):
|
|
129
|
+
"""
|
|
130
|
+
Ask legal question
|
|
131
|
+
|
|
132
|
+
- **question**: Legal question to ask
|
|
133
|
+
- **include_wisdom**: Include Maya Wisdom in response
|
|
134
|
+
- **use_enhanced_search**: Use TF-IDF search algorithm
|
|
135
|
+
- **prompt_type**: Type of prompt (legal_analysis, chain_of_thought, quick_answer)
|
|
136
|
+
"""
|
|
137
|
+
try:
|
|
138
|
+
# Use provided AI provider if specified
|
|
139
|
+
if request.ai_provider and request.api_key:
|
|
140
|
+
temp_system = LegalMindEnhanced(
|
|
141
|
+
ai_provider=request.ai_provider,
|
|
142
|
+
api_key=request.api_key
|
|
143
|
+
)
|
|
144
|
+
result = temp_system.ask(
|
|
145
|
+
request.question,
|
|
146
|
+
include_wisdom=request.include_wisdom,
|
|
147
|
+
use_enhanced_search=request.use_enhanced_search,
|
|
148
|
+
prompt_type=request.prompt_type
|
|
149
|
+
)
|
|
150
|
+
else:
|
|
151
|
+
result = system.ask(
|
|
152
|
+
request.question,
|
|
153
|
+
include_wisdom=request.include_wisdom,
|
|
154
|
+
use_enhanced_search=request.use_enhanced_search,
|
|
155
|
+
prompt_type=request.prompt_type
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Clean up full_content from cases
|
|
159
|
+
for case in result.get('cases', []):
|
|
160
|
+
case.pop('full_content', None)
|
|
161
|
+
|
|
162
|
+
return QuestionResponse(
|
|
163
|
+
success=True,
|
|
164
|
+
data=result,
|
|
165
|
+
message="Question answered successfully",
|
|
166
|
+
timestamp=datetime.now().isoformat()
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
except Exception as e:
|
|
170
|
+
raise HTTPException(
|
|
171
|
+
status_code=500,
|
|
172
|
+
detail=f"Error processing question: {str(e)}"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Get statistics
|
|
176
|
+
@app.get("/api/v1/stats", response_model=StatsResponse)
|
|
177
|
+
async def get_statistics():
|
|
178
|
+
"""Get system statistics"""
|
|
179
|
+
try:
|
|
180
|
+
stats = system.get_stats()
|
|
181
|
+
|
|
182
|
+
return StatsResponse(
|
|
183
|
+
success=True,
|
|
184
|
+
data=stats,
|
|
185
|
+
timestamp=datetime.now().isoformat()
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
except Exception as e:
|
|
189
|
+
raise HTTPException(
|
|
190
|
+
status_code=500,
|
|
191
|
+
detail=f"Error getting statistics: {str(e)}"
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# List cases
|
|
195
|
+
@app.get("/api/v1/cases")
|
|
196
|
+
async def list_cases(
|
|
197
|
+
limit: int = Query(10, ge=1, le=100, description="Number of cases to return"),
|
|
198
|
+
offset: int = Query(0, ge=0, description="Offset for pagination")
|
|
199
|
+
):
|
|
200
|
+
"""
|
|
201
|
+
List available cases
|
|
202
|
+
|
|
203
|
+
- **limit**: Number of cases to return (1-100)
|
|
204
|
+
- **offset**: Offset for pagination
|
|
205
|
+
"""
|
|
206
|
+
try:
|
|
207
|
+
all_cases = system.system.data_loader.cases
|
|
208
|
+
total = len(all_cases)
|
|
209
|
+
|
|
210
|
+
# Paginate
|
|
211
|
+
cases = all_cases[offset:offset+limit]
|
|
212
|
+
|
|
213
|
+
# Clean up for response
|
|
214
|
+
cleaned_cases = []
|
|
215
|
+
for case in cases:
|
|
216
|
+
cleaned_cases.append({
|
|
217
|
+
'id': case['id'],
|
|
218
|
+
'number': case['number'],
|
|
219
|
+
'file': case['file'],
|
|
220
|
+
'pertanyaan': case['pertanyaan'][:200] if case['pertanyaan'] else "",
|
|
221
|
+
'pasal': case.get('pasal', [])[:3],
|
|
222
|
+
'uu': case.get('uu', [])[:2]
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
"success": True,
|
|
227
|
+
"total": total,
|
|
228
|
+
"limit": limit,
|
|
229
|
+
"offset": offset,
|
|
230
|
+
"count": len(cleaned_cases),
|
|
231
|
+
"cases": cleaned_cases,
|
|
232
|
+
"timestamp": datetime.now().isoformat()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
except Exception as e:
|
|
236
|
+
raise HTTPException(
|
|
237
|
+
status_code=500,
|
|
238
|
+
detail=f"Error listing cases: {str(e)}"
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# Search cases
|
|
242
|
+
@app.get("/api/v1/search")
|
|
243
|
+
async def search_cases(
|
|
244
|
+
query: str = Query(..., description="Search query"),
|
|
245
|
+
top_k: int = Query(3, ge=1, le=10, description="Number of results")
|
|
246
|
+
):
|
|
247
|
+
"""
|
|
248
|
+
Search cases
|
|
249
|
+
|
|
250
|
+
- **query**: Search query
|
|
251
|
+
- **top_k**: Number of results to return (1-10)
|
|
252
|
+
"""
|
|
253
|
+
try:
|
|
254
|
+
results = system.enhanced_search.search(query, top_k=top_k)
|
|
255
|
+
|
|
256
|
+
# Clean up for response
|
|
257
|
+
cleaned_results = []
|
|
258
|
+
for result in results:
|
|
259
|
+
cleaned_results.append({
|
|
260
|
+
'id': result['id'],
|
|
261
|
+
'number': result['number'],
|
|
262
|
+
'pertanyaan': result['pertanyaan'][:200],
|
|
263
|
+
'similarity_score': result.get('similarity_score', 0),
|
|
264
|
+
'search_method': result.get('search_method', 'unknown')
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
"success": True,
|
|
269
|
+
"query": query,
|
|
270
|
+
"count": len(cleaned_results),
|
|
271
|
+
"results": cleaned_results,
|
|
272
|
+
"timestamp": datetime.now().isoformat()
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
except Exception as e:
|
|
276
|
+
raise HTTPException(
|
|
277
|
+
status_code=500,
|
|
278
|
+
detail=f"Error searching cases: {str(e)}"
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
if __name__ == "__main__":
|
|
282
|
+
import uvicorn
|
|
283
|
+
uvicorn.run(
|
|
284
|
+
app,
|
|
285
|
+
host="0.0.0.0",
|
|
286
|
+
port=8000,
|
|
287
|
+
log_level="info"
|
|
288
|
+
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
LegalMind Configuration
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
class LegalMindConfig:
|
|
10
|
+
"""Configuration for LegalMind system"""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.config = {
|
|
14
|
+
# Paths
|
|
15
|
+
'mayalaw_path': '/root/dragon/global/mayalaw',
|
|
16
|
+
'cache_dir': '/root/dragon/global/lab/.cache',
|
|
17
|
+
|
|
18
|
+
# AI Providers
|
|
19
|
+
'ai_provider': 'mock', # mock, openai, deepseek, qodo
|
|
20
|
+
'openai_api_key': os.getenv('OPENAI_API_KEY', ''),
|
|
21
|
+
'deepseek_api_key': os.getenv('DEEPSEEK_API_KEY', ''),
|
|
22
|
+
'qodo_api_key': os.getenv('QODO_API_KEY', ''),
|
|
23
|
+
|
|
24
|
+
# Settings
|
|
25
|
+
'cache_enabled': True,
|
|
26
|
+
'max_search_results': 3,
|
|
27
|
+
'ai_temperature': 0.3,
|
|
28
|
+
'ai_max_tokens': 2000,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def get(self, key, default=None):
|
|
32
|
+
return self.config.get(key, default)
|
|
33
|
+
|
|
34
|
+
def set(self, key, value):
|
|
35
|
+
self.config[key] = value
|
|
36
|
+
|
|
37
|
+
def __getitem__(self, key):
|
|
38
|
+
return self.config[key]
|
|
39
|
+
|
|
40
|
+
def __setitem__(self, key, value):
|
|
41
|
+
self.config[key] = value
|