Legal_AI_Agent / utils /admin_interface.py
cryogenic22's picture
Update utils/admin_interface.py
251054f verified
import streamlit as st # Add this at the top
from datetime import datetime
import json
import os
from pathlib import Path
class AdminInterface:
def __init__(self, case_manager, vector_store, document_processor):
self.case_manager = case_manager
self.vector_store = vector_store
self.document_processor = document_processor
# Initialize session state for admin
if 'admin_authenticated' not in st.session_state:
st.session_state.admin_authenticated = False
if 'users' not in st.session_state:
st.session_state.users = {}
if 'prompts' not in st.session_state:
st.session_state.prompts = self._load_default_prompts()
def _load_default_prompts(self):
return {
"system_prompt": """You are a legal AI assistant analyzing legal documents.
Follow these guidelines:
1. Provide accurate legal analysis
2. Cite specific sections from documents
3. Maintain formal legal language
4. Consider jurisdictional context""",
"user_prompt": """Please analyze the following legal question:
{query}
Based on these documents:
{context}
Provide a structured analysis with:
1. Key findings
2. Relevant citations
3. Legal implications"""
}
def render(self):
if not st.session_state.admin_authenticated:
self._render_login()
else:
self._render_admin_panel()
def _render_login(self):
st.title("🔒 Admin Login")
with st.form("admin_login"):
username = st.text_input("Username")
password = st.text_input("Password", type="password")
submit = st.form_submit_button("Login")
if submit:
if username == "admin" and password == "demo":
st.session_state.admin_authenticated = True
st.success("Login successful!")
st.rerun()
else:
st.error("Invalid credentials")
def _render_admin_panel(self):
st.title("⚙️ Admin Panel")
tab1, tab2, tab3, tab4 = st.tabs([
"Prompt Management",
"Ontology Editor",
"User Management",
"System Settings"
])
with tab1:
self._render_prompt_management()
with tab2:
self._render_ontology_editor()
with tab3:
self._render_user_management()
with tab4:
self._render_system_settings()
def _render_prompt_management(self):
st.subheader("🔤 Prompt Templates")
# System prompt
st.markdown("### System Prompt")
new_system_prompt = st.text_area(
"System Instructions",
value=st.session_state.prompts["system_prompt"],
height=200
)
# User prompt
st.markdown("### User Prompt Template")
new_user_prompt = st.text_area(
"Query Template",
value=st.session_state.prompts["user_prompt"],
height=200
)
if st.button("Save Prompts"):
st.session_state.prompts = {
"system_prompt": new_system_prompt,
"user_prompt": new_user_prompt
}
# Save to file
self._save_prompts()
st.success("Prompts updated successfully!")
def _render_ontology_editor(self):
st.subheader("📚 Legal Ontology Editor")
# Load current ontology
ontology = self._load_ontology()
# Display ontology editor
st.json(ontology)
# Upload new ontology
uploaded_file = st.file_uploader("Upload new ontology (JSON)", type="json")
if uploaded_file:
try:
new_ontology = json.load(uploaded_file)
self._save_ontology(new_ontology)
st.success("Ontology updated successfully!")
st.rerun()
except Exception as e:
st.error(f"Error updating ontology: {str(e)}")
# Add new concept
st.markdown("### Add New Concept")
with st.form("add_concept"):
concept_label = st.text_input("Concept Label")
concept_type = st.selectbox("Type", ["LegalConcept", "Jurisdiction", "Process"])
concept_desc = st.text_area("Description")
related = st.text_input("Related Concepts (comma-separated)")
if st.form_submit_button("Add Concept"):
try:
new_concept = {
"@id": f"concept:{concept_label.replace(' ', '')}",
"@type": f"vocab:{concept_type}",
"rdfs:label": concept_label,
"rdfs:comment": concept_desc,
"vocab:relatedConcepts": [x.strip() for x in related.split(",")]
}
ontology["@graph"].append(new_concept)
self._save_ontology(ontology)
st.success("Concept added successfully!")
st.rerun()
except Exception as e:
st.error(f"Error adding concept: {str(e)}")
def _render_user_management(self):
st.subheader("👥 User Management")
# List existing users
st.markdown("### Current Users")
for username, user_data in st.session_state.users.items():
col1, col2, col3 = st.columns([2, 2, 1])
with col1:
st.write(f"**{username}**")
with col2:
st.write(f"Access: {', '.join(user_data['case_access'])}")
with col3:
if st.button("🗑️", key=f"del_user_{username}"):
del st.session_state.users[username]
st.success(f"User {username} deleted")
st.rerun()
# Add new user
st.markdown("### Add User")
with st.form("add_user"):
new_username = st.text_input("Username")
new_password = st.text_input("Password", type="password")
cases = self.case_manager.get_all_cases()
case_access = st.multiselect(
"Case Access",
options=[case['id'] for case in cases],
format_func=lambda x: next(c['title'] for c in cases if c['id'] == x)
)
if st.form_submit_button("Add User"):
if new_username in st.session_state.users:
st.error("Username already exists")
else:
st.session_state.users[new_username] = {
"password": new_password,
"case_access": case_access
}
st.success(f"User {new_username} added successfully!")
st.rerun()
def _render_system_settings(self):
st.subheader("⚙️ System Settings")
# Vector store settings
st.markdown("### Vector Store Settings")
with st.form("vector_store_settings"):
chunk_size = st.number_input(
"Document Chunk Size",
min_value=100,
max_value=2000,
value=500,
help="Number of characters per document chunk"
)
top_k = st.number_input(
"Search Results (Top K)",
min_value=1,
max_value=10,
value=3,
help="Number of similar chunks to return in search"
)
similarity_threshold = st.slider(
"Similarity Threshold",
min_value=0.0,
max_value=1.0,
value=0.7,
help="Minimum similarity score for chunk matching"
)
if st.form_submit_button("Save Settings"):
self._save_system_settings({
"chunk_size": chunk_size,
"top_k": top_k,
"similarity_threshold": similarity_threshold
})
st.success("Settings saved successfully!")
# Model settings
st.markdown("### Model Settings")
with st.form("model_settings"):
model = st.selectbox(
"Claude Model",
["claude-3-sonnet-20240229", "claude-3-opus-20240229", "claude-3-haiku-20240229"],
help="Select Claude model version"
)
temperature = st.slider(
"Temperature",
min_value=0.0,
max_value=1.0,
value=0.2,
help="Controls response creativity"
)
max_tokens = st.number_input(
"Max Response Tokens",
min_value=100,
max_value=4096,
value=1500,
help="Maximum length of responses"
)
if st.form_submit_button("Save Model Settings"):
self._save_model_settings({
"model": model,
"temperature": temperature,
"max_tokens": max_tokens
})
st.success("Model settings saved!")
# Backup and restore
st.markdown("### 💾 Backup & Restore")
col1, col2 = st.columns(2)
with col1:
if st.button("📤 Export All Data"):
try:
data = self._export_all_data()
st.download_button(
"Download Backup",
data=json.dumps(data, indent=2),
file_name=f"suomoto_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
mime="application/json"
)
except Exception as e:
st.error(f"Error exporting data: {str(e)}")
with col2:
uploaded_file = st.file_uploader("📥 Restore from Backup", type="json")
if uploaded_file:
try:
backup_data = json.load(uploaded_file)
if st.button("Restore Data"):
self._restore_from_backup(backup_data)
st.success("Data restored successfully!")
st.rerun()
except Exception as e:
st.error(f"Error restoring data: {str(e)}")
def _save_prompts(self):
"""Save prompts to JSON file."""
try:
with open(os.path.join('/data', 'prompts.json'), 'w') as f:
json.dump(st.session_state.prompts, f, indent=2)
except Exception as e:
st.error(f"Error saving prompts: {str(e)}")
def _load_ontology(self):
"""Load current ontology from file."""
try:
with open(os.path.join('/data', 'legal_ontology.json'), 'r') as f:
return json.load(f)
except Exception:
return {"@graph": []}
def _save_ontology(self, ontology: dict):
"""Save updated ontology to file."""
try:
with open(os.path.join('/data', 'legal_ontology.json'), 'w') as f:
json.dump(ontology, f, indent=2)
except Exception as e:
st.error(f"Error saving ontology: {str(e)}")
def _save_system_settings(self, settings: dict):
"""Save system settings to file."""
try:
with open(os.path.join('/data', 'system_settings.json'), 'w') as f:
json.dump(settings, f, indent=2)
except Exception as e:
st.error(f"Error saving settings: {str(e)}")
def _save_model_settings(self, settings: dict):
"""Save model settings to file."""
try:
with open(os.path.join('/data', 'model_settings.json'), 'w') as f:
json.dump(settings, f, indent=2)
except Exception as e:
st.error(f"Error saving model settings: {str(e)}")
def _export_all_data(self):
"""Export all system data for backup."""
return {
"prompts": st.session_state.prompts,
"ontology": self._load_ontology(),
"users": st.session_state.users,
"system_settings": self._load_system_settings(),
"model_settings": self._load_model_settings(),
"export_date": datetime.now().isoformat()
}
def _restore_from_backup(self, backup_data: dict):
"""Restore system from backup data."""
try:
# Validate backup data
required_keys = ["prompts", "ontology", "users", "system_settings", "model_settings"]
if not all(key in backup_data for key in required_keys):
raise ValueError("Invalid backup data format")
# Restore each component
st.session_state.prompts = backup_data["prompts"]
self._save_prompts()
self._save_ontology(backup_data["ontology"])
st.session_state.users = backup_data["users"]
self._save_system_settings(backup_data["system_settings"])
self._save_model_settings(backup_data["model_settings"])
except Exception as e:
raise Exception(f"Error restoring from backup: {str(e)}")
def _load_system_settings(self):
"""Load system settings from file."""
try:
with open(os.path.join('/data', 'system_settings.json'), 'r') as f:
return json.load(f)
except Exception:
return {
"chunk_size": 500,
"top_k": 3,
"similarity_threshold": 0.7
}
def _load_model_settings(self):
"""Load model settings from file."""
try:
with open(os.path.join('/data', 'model_settings.json'), 'r') as f:
return json.load(f)
except Exception:
return {
"model": "claude-3-sonnet-20240229",
"temperature": 0.2,
"max_tokens": 1500
}