faizanwasif commited on
Commit
909c15c
·
1 Parent(s): 9800a40

fixed error api key

Browse files
Files changed (3) hide show
  1. __pycache__/agents.cpython-312.pyc +0 -0
  2. agents.py +42 -42
  3. app.py +144 -84
__pycache__/agents.cpython-312.pyc CHANGED
Binary files a/__pycache__/agents.cpython-312.pyc and b/__pycache__/agents.cpython-312.pyc differ
 
agents.py CHANGED
@@ -1,62 +1,55 @@
1
  # agents.py
2
  from langgraph.prebuilt import create_react_agent
3
  import os
4
- import uuid
5
- from typing import Dict
6
 
7
- # Secure session-based API key storage
8
- _session_keys: Dict[str, str] = {}
 
9
 
10
- def generate_session_id() -> str:
11
- """Generate a unique session ID"""
12
- return str(uuid.uuid4())
13
 
14
- def set_api_key(api_key: str, session_id: str = None) -> str:
15
- """Securely set the API key for a specific session"""
16
- if not session_id:
17
- session_id = generate_session_id()
18
-
19
- # Basic validation
20
- if not api_key or len(api_key.strip()) < 10:
21
- return None
22
-
23
- # Store securely per session
24
- _session_keys[session_id] = api_key.strip()
25
- return session_id
26
-
27
- def get_api_key(session_id: str) -> str:
28
- """Retrieve API key for session"""
29
- return _session_keys.get(session_id, None)
30
-
31
- def clear_session(session_id: str):
32
- """Clear session data"""
33
- if session_id in _session_keys:
34
- del _session_keys[session_id]
35
 
36
- def create_agent_response(prompt: str, user_input: str, session_id: str, model: str = "anthropic/claude-3-haiku-20240307") -> str:
37
  """Generic function to create and invoke any agent"""
38
  global _api_key
39
 
40
  if not _api_key:
41
- return "Error: API key not set. Please set your Claude API key first."
 
 
42
 
43
  try:
 
44
  agent = create_react_agent(
45
  model=model,
46
  tools=[],
47
  prompt=prompt
48
  )
49
 
 
50
  result = agent.invoke({
51
  "messages": [{"role": "user", "content": user_input}]
52
  })
53
 
54
  # Handle different possible return types from LangGraph
55
  if hasattr(result, 'content'):
56
- # AIMessage object
57
  return str(result.content)
58
  elif isinstance(result, dict):
59
- # Dictionary format
60
  if 'content' in result:
61
  return str(result['content'])
62
  elif 'messages' in result and len(result['messages']) > 0:
@@ -66,19 +59,23 @@ def create_agent_response(prompt: str, user_input: str, session_id: str, model:
66
  elif isinstance(last_msg, dict) and 'content' in last_msg:
67
  return str(last_msg['content'])
68
  elif isinstance(result, str):
69
- # Direct string response
70
  return result
71
 
72
  # Fallback: convert whatever we got to string
 
73
  return str(result)
74
 
75
  except Exception as e:
76
- return f"Error: Unable to process request - {str(e)}"
 
 
77
 
78
  # ==================== CORE AGENT FUNCTIONS ====================
79
 
80
- def judge_agent(student_arg: str, opponent_arg: str = "", documents: str = "", session_id: str = "") -> str:
81
  """Judge agent for evaluating legal arguments"""
 
82
  prompt = """You are an experienced federal judge presiding over a courtroom.
83
 
84
  Your role is to:
@@ -93,10 +90,11 @@ ALWAYS respond in this exact format: Judge: [your response]
93
  Keep responses 2-4 sentences, focusing on legal analysis."""
94
 
95
  user_input = f"Student Argument: {student_arg}\nOpponent Argument: {opponent_arg}\nCase Documents: {documents}"
96
- return create_agent_response(prompt, user_input, session_id)
97
 
98
- def opponent_agent(student_arg: str, case_context: str = "", session_id: str = "") -> str:
99
  """Opponent agent for counter-arguments"""
 
100
  prompt = """You are a skilled attorney arguing the opposing side in this case.
101
 
102
  Your role is to:
@@ -111,10 +109,11 @@ ALWAYS respond in this exact format: Opponent: [your response]
111
  Keep responses 2-4 sentences, focused on strong legal counter-arguments."""
112
 
113
  user_input = f"Student's Argument: {student_arg}\nCase Context: {case_context}"
114
- return create_agent_response(prompt, user_input, session_id)
115
 
116
- def narrator_agent(context: str, student_arg: str = "", opponent_arg: str = "", session_id: str = "") -> str:
117
  """Enhanced narrator agent that handles courtroom atmosphere AND side character arguments"""
 
118
  prompt = """You are a courtroom narrator who describes the scene and occasionally voices side characters.
119
 
120
  Your roles include:
@@ -136,10 +135,9 @@ Otherwise format as: "Narrator: [your narration]"
136
  Keep responses 2-4 sentences, atmospheric and engaging."""
137
 
138
  user_input = f"Context: {context}\nStudent Argument: {student_arg}\nOpponent Argument: {opponent_arg}"
139
- return create_agent_response(prompt, user_input, session_id)
140
 
141
  # ==================== AGENT REGISTRY ====================
142
- # Simplified registry with only the three core agents
143
  AVAILABLE_AGENTS = {
144
  'judge': judge_agent,
145
  'opponent': opponent_agent,
@@ -151,4 +149,6 @@ def get_agent_response(agent_type: str, *args, **kwargs) -> str:
151
  if agent_type in AVAILABLE_AGENTS:
152
  return AVAILABLE_AGENTS[agent_type](*args, **kwargs)
153
  else:
154
- return f"Error: Unknown agent type '{agent_type}'. Available agents: {list(AVAILABLE_AGENTS.keys())}"
 
 
 
1
  # agents.py
2
  from langgraph.prebuilt import create_react_agent
3
  import os
4
+ import logging
 
5
 
6
+ # Set up logging
7
+ logging.basicConfig(level=logging.INFO)
8
+ logger = logging.getLogger(__name__)
9
 
10
+ # Simple global API key storage
11
+ _api_key = None
 
12
 
13
+ def set_api_key(api_key: str) -> bool:
14
+ """Set the API key for Claude"""
15
+ global _api_key
16
+ if api_key and api_key.strip():
17
+ _api_key = api_key.strip()
18
+ os.environ["ANTHROPIC_API_KEY"] = _api_key
19
+ logger.info("API key set successfully")
20
+ return True
21
+ else:
22
+ logger.error("Invalid API key provided")
23
+ return False
 
 
 
 
 
 
 
 
 
 
24
 
25
+ def create_agent_response(prompt: str, user_input: str, model: str = "anthropic:claude-3-haiku-20240307") -> str:
26
  """Generic function to create and invoke any agent"""
27
  global _api_key
28
 
29
  if not _api_key:
30
+ error_msg = "API key not set. Please set your Claude API key first."
31
+ logger.error(error_msg)
32
+ return f"Error: {error_msg}"
33
 
34
  try:
35
+ logger.info(f"Creating agent with model: {model}")
36
  agent = create_react_agent(
37
  model=model,
38
  tools=[],
39
  prompt=prompt
40
  )
41
 
42
+ logger.info("Invoking agent with user input")
43
  result = agent.invoke({
44
  "messages": [{"role": "user", "content": user_input}]
45
  })
46
 
47
  # Handle different possible return types from LangGraph
48
  if hasattr(result, 'content'):
49
+ logger.info("Received AIMessage response")
50
  return str(result.content)
51
  elif isinstance(result, dict):
52
+ logger.info("Received dict response")
53
  if 'content' in result:
54
  return str(result['content'])
55
  elif 'messages' in result and len(result['messages']) > 0:
 
59
  elif isinstance(last_msg, dict) and 'content' in last_msg:
60
  return str(last_msg['content'])
61
  elif isinstance(result, str):
62
+ logger.info("Received string response")
63
  return result
64
 
65
  # Fallback: convert whatever we got to string
66
+ logger.warning("Using fallback response conversion")
67
  return str(result)
68
 
69
  except Exception as e:
70
+ error_msg = f"Unable to process request - {str(e)}"
71
+ logger.error(f"Agent error: {error_msg}", exc_info=True)
72
+ return f"Error: {error_msg}"
73
 
74
  # ==================== CORE AGENT FUNCTIONS ====================
75
 
76
+ def judge_agent(student_arg: str, opponent_arg: str = "", documents: str = "") -> str:
77
  """Judge agent for evaluating legal arguments"""
78
+ logger.info("Judge agent called")
79
  prompt = """You are an experienced federal judge presiding over a courtroom.
80
 
81
  Your role is to:
 
90
  Keep responses 2-4 sentences, focusing on legal analysis."""
91
 
92
  user_input = f"Student Argument: {student_arg}\nOpponent Argument: {opponent_arg}\nCase Documents: {documents}"
93
+ return create_agent_response(prompt, user_input)
94
 
95
+ def opponent_agent(student_arg: str, case_context: str = "") -> str:
96
  """Opponent agent for counter-arguments"""
97
+ logger.info("Opponent agent called")
98
  prompt = """You are a skilled attorney arguing the opposing side in this case.
99
 
100
  Your role is to:
 
109
  Keep responses 2-4 sentences, focused on strong legal counter-arguments."""
110
 
111
  user_input = f"Student's Argument: {student_arg}\nCase Context: {case_context}"
112
+ return create_agent_response(prompt, user_input)
113
 
114
+ def narrator_agent(context: str, student_arg: str = "", opponent_arg: str = "") -> str:
115
  """Enhanced narrator agent that handles courtroom atmosphere AND side character arguments"""
116
+ logger.info("Narrator agent called")
117
  prompt = """You are a courtroom narrator who describes the scene and occasionally voices side characters.
118
 
119
  Your roles include:
 
135
  Keep responses 2-4 sentences, atmospheric and engaging."""
136
 
137
  user_input = f"Context: {context}\nStudent Argument: {student_arg}\nOpponent Argument: {opponent_arg}"
138
+ return create_agent_response(prompt, user_input)
139
 
140
  # ==================== AGENT REGISTRY ====================
 
141
  AVAILABLE_AGENTS = {
142
  'judge': judge_agent,
143
  'opponent': opponent_agent,
 
149
  if agent_type in AVAILABLE_AGENTS:
150
  return AVAILABLE_AGENTS[agent_type](*args, **kwargs)
151
  else:
152
+ error_msg = f"Unknown agent type '{agent_type}'. Available agents: {list(AVAILABLE_AGENTS.keys())}"
153
+ logger.error(error_msg)
154
+ return f"Error: {error_msg}"
app.py CHANGED
@@ -1,10 +1,15 @@
1
  import gradio as gr
2
  import time
 
3
  from typing import Dict, List, Tuple, Optional
4
- from agents import judge_agent, opponent_agent, narrator_agent, set_api_key, generate_session_id, clear_session
5
  from dotenv import load_dotenv
6
  import os
7
 
 
 
 
 
8
  # Load environment variables
9
  load_dotenv()
10
 
@@ -16,32 +21,41 @@ class LawTrainingSystem:
16
  self.student_side = None
17
  self.conversation_history = []
18
  self.processing_lock = False
19
- self.session_id = None
20
 
21
  def set_api_key(self, api_key: str):
22
  """Set the API key for the agents"""
23
- if api_key and api_key.strip():
24
- self.session_id = set_api_key(api_key)
25
- if self.session_id:
26
- return "✅ API Key set successfully!"
 
 
 
 
 
 
 
27
  else:
28
- return "❌ Invalid API key format"
29
- else:
30
- return "❌ Please enter a valid API key"
 
 
 
31
 
32
- def clear_session(self):
33
- """Clear session data when done"""
34
- if self.session_id:
35
- clear_session(self.session_id)
36
- self.session_id = None
37
-
38
  def initialize_session(self, case_title: str, case_description: str, student_side: str):
39
  """Initialize a new training session"""
40
- self.session_active = True
41
- self.current_case = {"title": case_title, "description": case_description}
42
- self.student_side = student_side
43
- self.conversation_history = []
44
- return f"Session initialized: {case_title} - You are the {student_side}"
 
 
 
 
 
45
 
46
  def is_processing(self) -> bool:
47
  """Check if system is currently processing a response"""
@@ -50,6 +64,7 @@ class LawTrainingSystem:
50
  def set_processing(self, status: bool):
51
  """Set processing lock status"""
52
  self.processing_lock = status
 
53
 
54
  # Global system instance
55
  system = LawTrainingSystem()
@@ -58,55 +73,72 @@ system = LawTrainingSystem()
58
  def generate_judge_response(student_message: str, opponent_message: str = "", documents: str = "") -> str:
59
  """Generate Judge AI response"""
60
  try:
61
- return judge_agent(student_message, opponent_message, documents, system.session_id)
 
62
  except Exception as e:
63
- return f"Judge: I'm having trouble processing your argument. Could you please rephrase it?"
 
64
 
65
  def generate_opponent_response(student_message: str) -> str:
66
  """Generate Opponent AI response"""
67
  try:
 
68
  case_context = f"Case: {system.current_case['title']} - {system.current_case['description']}" if system.current_case else ""
69
- return opponent_agent(student_message, case_context, system.session_id)
70
  except Exception as e:
71
- return f"Opponent: I'm experiencing technical difficulties. Please try again."
 
72
 
73
  def generate_narrator_response(context: str, student_message: str = "", opponent_message: str = "") -> str:
74
  """Generate Narrator AI response - handles side character arguments too"""
75
  try:
76
- return narrator_agent(context, student_message, opponent_message, system.session_id)
 
77
  except Exception as e:
78
- return f"Narrator: The courtroom atmosphere is tense as technical difficulties arise..."
 
79
 
80
  # ==================== UI RESPONSE HANDLERS ====================
81
  def handle_student_response(student_message: str, judge_history: List, opponent_history: List, narrator_history: List) -> Tuple:
82
  """Process student message and generate AI responses"""
83
 
84
- # Initialize histories if they are None
85
- if judge_history is None:
86
- judge_history = []
87
- if opponent_history is None:
88
- opponent_history = []
89
- if narrator_history is None:
90
- narrator_history = []
91
-
92
- # Prevent multiple simultaneous processing
93
- if system.is_processing():
94
- return student_message, judge_history, opponent_history, narrator_history, gr.update(interactive=False)
95
-
96
- if not system.session_active:
97
- return student_message, judge_history, opponent_history, narrator_history, gr.update(interactive=True)
98
-
99
- # Set processing lock
100
- system.set_processing(True)
101
-
102
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  # Generate opponent response first
 
104
  opponent_response = generate_opponent_response(student_message)
105
 
106
  # Generate judge response (evaluating both student and opponent)
 
107
  judge_response = generate_judge_response(student_message, opponent_response)
108
 
109
  # Generate narrator response (describing the courtroom scene)
 
110
  narrator_response = generate_narrator_response("Arguments presented", student_message, opponent_response)
111
 
112
  # Update chat histories
@@ -114,49 +146,72 @@ def handle_student_response(student_message: str, judge_history: List, opponent_
114
  opponent_history.append({"role": "assistant", "content": opponent_response})
115
  narrator_history.append({"role": "assistant", "content": narrator_response})
116
 
 
 
117
  # Clear student input and re-enable
118
  return "", judge_history, opponent_history, narrator_history, gr.update(interactive=True)
119
 
 
 
 
120
  finally:
121
  # Always release processing lock
122
  system.set_processing(False)
123
 
124
  def start_case_session(case_title: str, case_description: str, student_side: str) -> Tuple:
125
  """Initialize a new case session"""
126
- if not system.session_id:
127
- return gr.update(), gr.update(), gr.update(), gr.update(), gr.update(interactive=False)
128
-
129
- if not case_title or not case_description:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  return gr.update(), gr.update(), gr.update(), gr.update(), gr.update(interactive=False)
131
-
132
- # Initialize system
133
- init_message = system.initialize_session(case_title, case_description, student_side)
134
-
135
- # Generate initial context from Narrator
136
- initial_context = generate_narrator_response(f"Case session begins: {case_title}")
137
-
138
- # Create initial chat histories
139
- judge_history = [{"role": "assistant", "content": "Judge: I am ready to evaluate your arguments based on legal precedent and constitutional law."}]
140
- opponent_side = 'prosecution' if student_side == 'defense' else 'defense'
141
- opponent_history = [{"role": "assistant", "content": f"Opponent: I will argue for the {opponent_side} side. Present your case."}]
142
- narrator_history = [{"role": "assistant", "content": initial_context}]
143
-
144
- return (
145
- judge_history,
146
- opponent_history,
147
- narrator_history,
148
- gr.update(visible=True),
149
- gr.update(interactive=True)
150
- )
151
 
152
  def upload_case_documents(files) -> str:
153
  """Handle case document uploads"""
154
- if not files:
155
- return "No documents uploaded"
156
-
157
- # TODO: Process uploaded documents with document parsing
158
- file_names = [f.name for f in files]
159
- return f"Uploaded {len(files)} documents: {', '.join(file_names)}"
 
 
 
 
 
 
160
 
161
  # ==================== GRADIO INTERFACE ====================
162
  def create_law_training_interface():
@@ -322,13 +377,18 @@ def create_law_training_interface():
322
 
323
  # ==================== MAIN EXECUTION ====================
324
  if __name__ == "__main__":
325
- # Create and launch the interface
326
- app = create_law_training_interface()
327
-
328
- # Launch configuration
329
- app.launch(
330
- server_name="0.0.0.0",
331
- server_port=7860,
332
- share=False,
333
- debug=True
334
- )
 
 
 
 
 
 
1
  import gradio as gr
2
  import time
3
+ import logging
4
  from typing import Dict, List, Tuple, Optional
5
+ from agents import judge_agent, opponent_agent, narrator_agent, set_api_key
6
  from dotenv import load_dotenv
7
  import os
8
 
9
+ # Set up logging
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
12
+
13
  # Load environment variables
14
  load_dotenv()
15
 
 
21
  self.student_side = None
22
  self.conversation_history = []
23
  self.processing_lock = False
24
+ self.api_key_set = False
25
 
26
  def set_api_key(self, api_key: str):
27
  """Set the API key for the agents"""
28
+ try:
29
+ if api_key and api_key.strip():
30
+ success = set_api_key(api_key)
31
+ if success:
32
+ self.api_key_set = True
33
+ logger.info("API key set successfully in system")
34
+ return "✅ API Key set successfully!"
35
+ else:
36
+ self.api_key_set = False
37
+ logger.error("Failed to set API key")
38
+ return "❌ Invalid API key format"
39
  else:
40
+ self.api_key_set = False
41
+ logger.error("Empty API key provided")
42
+ return "❌ Please enter a valid API key"
43
+ except Exception as e:
44
+ logger.error(f"Error setting API key: {e}", exc_info=True)
45
+ return f"❌ Error setting API key: {str(e)}"
46
 
 
 
 
 
 
 
47
  def initialize_session(self, case_title: str, case_description: str, student_side: str):
48
  """Initialize a new training session"""
49
+ try:
50
+ self.session_active = True
51
+ self.current_case = {"title": case_title, "description": case_description}
52
+ self.student_side = student_side
53
+ self.conversation_history = []
54
+ logger.info(f"Session initialized: {case_title} - Student side: {student_side}")
55
+ return f"Session initialized: {case_title} - You are the {student_side}"
56
+ except Exception as e:
57
+ logger.error(f"Error initializing session: {e}", exc_info=True)
58
+ raise
59
 
60
  def is_processing(self) -> bool:
61
  """Check if system is currently processing a response"""
 
64
  def set_processing(self, status: bool):
65
  """Set processing lock status"""
66
  self.processing_lock = status
67
+ logger.info(f"Processing lock set to: {status}")
68
 
69
  # Global system instance
70
  system = LawTrainingSystem()
 
73
  def generate_judge_response(student_message: str, opponent_message: str = "", documents: str = "") -> str:
74
  """Generate Judge AI response"""
75
  try:
76
+ logger.info("Generating judge response")
77
+ return judge_agent(student_message, opponent_message, documents)
78
  except Exception as e:
79
+ logger.error(f"Error in judge response: {e}", exc_info=True)
80
+ return f"Judge: I'm having trouble processing your argument. Error: {str(e)}"
81
 
82
  def generate_opponent_response(student_message: str) -> str:
83
  """Generate Opponent AI response"""
84
  try:
85
+ logger.info("Generating opponent response")
86
  case_context = f"Case: {system.current_case['title']} - {system.current_case['description']}" if system.current_case else ""
87
+ return opponent_agent(student_message, case_context)
88
  except Exception as e:
89
+ logger.error(f"Error in opponent response: {e}", exc_info=True)
90
+ return f"Opponent: I'm experiencing technical difficulties. Error: {str(e)}"
91
 
92
  def generate_narrator_response(context: str, student_message: str = "", opponent_message: str = "") -> str:
93
  """Generate Narrator AI response - handles side character arguments too"""
94
  try:
95
+ logger.info("Generating narrator response")
96
+ return narrator_agent(context, student_message, opponent_message)
97
  except Exception as e:
98
+ logger.error(f"Error in narrator response: {e}", exc_info=True)
99
+ return f"Narrator: The courtroom atmosphere is tense as technical difficulties arise. Error: {str(e)}"
100
 
101
  # ==================== UI RESPONSE HANDLERS ====================
102
  def handle_student_response(student_message: str, judge_history: List, opponent_history: List, narrator_history: List) -> Tuple:
103
  """Process student message and generate AI responses"""
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  try:
106
+ logger.info(f"Processing student response: {student_message[:50]}...")
107
+
108
+ # Initialize histories if they are None
109
+ if judge_history is None:
110
+ judge_history = []
111
+ if opponent_history is None:
112
+ opponent_history = []
113
+ if narrator_history is None:
114
+ narrator_history = []
115
+
116
+ # Prevent multiple simultaneous processing
117
+ if system.is_processing():
118
+ logger.warning("System is already processing, skipping request")
119
+ return student_message, judge_history, opponent_history, narrator_history, gr.update(interactive=False)
120
+
121
+ if not system.session_active:
122
+ logger.warning("No active session")
123
+ return student_message, judge_history, opponent_history, narrator_history, gr.update(interactive=True)
124
+
125
+ if not system.api_key_set:
126
+ logger.warning("API key not set")
127
+ return student_message, judge_history, opponent_history, narrator_history, gr.update(interactive=True)
128
+
129
+ # Set processing lock
130
+ system.set_processing(True)
131
+
132
  # Generate opponent response first
133
+ logger.info("Generating opponent response")
134
  opponent_response = generate_opponent_response(student_message)
135
 
136
  # Generate judge response (evaluating both student and opponent)
137
+ logger.info("Generating judge response")
138
  judge_response = generate_judge_response(student_message, opponent_response)
139
 
140
  # Generate narrator response (describing the courtroom scene)
141
+ logger.info("Generating narrator response")
142
  narrator_response = generate_narrator_response("Arguments presented", student_message, opponent_response)
143
 
144
  # Update chat histories
 
146
  opponent_history.append({"role": "assistant", "content": opponent_response})
147
  narrator_history.append({"role": "assistant", "content": narrator_response})
148
 
149
+ logger.info("All responses generated successfully")
150
+
151
  # Clear student input and re-enable
152
  return "", judge_history, opponent_history, narrator_history, gr.update(interactive=True)
153
 
154
+ except Exception as e:
155
+ logger.error(f"Error in handle_student_response: {e}", exc_info=True)
156
+ return student_message, judge_history, opponent_history, narrator_history, gr.update(interactive=True)
157
  finally:
158
  # Always release processing lock
159
  system.set_processing(False)
160
 
161
  def start_case_session(case_title: str, case_description: str, student_side: str) -> Tuple:
162
  """Initialize a new case session"""
163
+ try:
164
+ logger.info(f"Starting case session: {case_title}")
165
+
166
+ if not system.api_key_set:
167
+ logger.warning("Cannot start session - API key not set")
168
+ return gr.update(), gr.update(), gr.update(), gr.update(), gr.update(interactive=False)
169
+
170
+ if not case_title or not case_description:
171
+ logger.warning("Cannot start session - missing case details")
172
+ return gr.update(), gr.update(), gr.update(), gr.update(), gr.update(interactive=False)
173
+
174
+ # Initialize system
175
+ init_message = system.initialize_session(case_title, case_description, student_side)
176
+
177
+ # Generate initial context from Narrator
178
+ logger.info("Generating initial narrator context")
179
+ initial_context = generate_narrator_response(f"Case session begins: {case_title}")
180
+
181
+ # Create initial chat histories
182
+ judge_history = [{"role": "assistant", "content": "Judge: I am ready to evaluate your arguments based on legal precedent and constitutional law."}]
183
+ opponent_side = 'prosecution' if student_side == 'defense' else 'defense'
184
+ opponent_history = [{"role": "assistant", "content": f"Opponent: I will argue for the {opponent_side} side. Present your case."}]
185
+ narrator_history = [{"role": "assistant", "content": initial_context}]
186
+
187
+ logger.info("Case session started successfully")
188
+
189
+ return (
190
+ judge_history,
191
+ opponent_history,
192
+ narrator_history,
193
+ gr.update(visible=True),
194
+ gr.update(interactive=True)
195
+ )
196
+
197
+ except Exception as e:
198
+ logger.error(f"Error starting case session: {e}", exc_info=True)
199
  return gr.update(), gr.update(), gr.update(), gr.update(), gr.update(interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
  def upload_case_documents(files) -> str:
202
  """Handle case document uploads"""
203
+ try:
204
+ if not files:
205
+ return "No documents uploaded"
206
+
207
+ # TODO: Process uploaded documents with document parsing
208
+ file_names = [f.name for f in files]
209
+ logger.info(f"Uploaded {len(files)} documents: {file_names}")
210
+ return f"Uploaded {len(files)} documents: {', '.join(file_names)}"
211
+
212
+ except Exception as e:
213
+ logger.error(f"Error uploading documents: {e}", exc_info=True)
214
+ return f"Error uploading documents: {str(e)}"
215
 
216
  # ==================== GRADIO INTERFACE ====================
217
  def create_law_training_interface():
 
377
 
378
  # ==================== MAIN EXECUTION ====================
379
  if __name__ == "__main__":
380
+ try:
381
+ logger.info("Starting Law Training System")
382
+ # Create and launch the interface
383
+ app = create_law_training_interface()
384
+
385
+ # Launch configuration
386
+ app.launch(
387
+ server_name="0.0.0.0",
388
+ server_port=7860,
389
+ share=False,
390
+ debug=True
391
+ )
392
+ except Exception as e:
393
+ logger.error(f"Failed to start application: {e}", exc_info=True)
394
+ raise