grshot commited on
Commit
183b832
·
1 Parent(s): 890d080

Update error handling

Browse files
Files changed (2) hide show
  1. agent.py +35 -5
  2. app.py +27 -26
agent.py CHANGED
@@ -187,19 +187,49 @@ def build_agent_graph(provider: str = "groq"):
187
  # Assistant: reasoning step that plans next action
188
  def assistant_node(state: MessagesState) -> dict:
189
  try:
 
 
 
 
190
  messages = state["messages"]
 
 
 
 
191
  response = llm_with_tools.invoke(messages)
 
 
192
 
193
  # Validate response format
194
- if not response or not isinstance(
195
- response, (AIMessage, HumanMessage, SystemMessage)
196
- ):
197
- raise ValueError("Invalid response format from LLM")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
  return {"messages": response}
200
  except Exception as e:
201
  error_msg = f"Error in assistant node: {str(e)}"
202
- return {"messages": AIMessage(content=f"FINAL ANSWER: {error_msg}")}
 
 
 
 
 
203
 
204
  # Stubbed retriever node for future integration
205
  def retriever_node(state: MessagesState):
 
187
  # Assistant: reasoning step that plans next action
188
  def assistant_node(state: MessagesState) -> dict:
189
  try:
190
+ # Validate input state
191
+ if not isinstance(state, dict) or "messages" not in state:
192
+ raise ValueError("Invalid state format")
193
+
194
  messages = state["messages"]
195
+ if not messages:
196
+ raise ValueError("Empty message list")
197
+
198
+ # Invoke LLM
199
  response = llm_with_tools.invoke(messages)
200
+ if response is None:
201
+ raise ValueError("LLM returned None response")
202
 
203
  # Validate response format
204
+ if not isinstance(response, (AIMessage, HumanMessage, SystemMessage)):
205
+ raise ValueError(f"Invalid response type from LLM: {type(response)}")
206
+
207
+ # Validate response content
208
+ if not hasattr(response, "content") or response.content is None:
209
+ raise ValueError("Response missing content")
210
+
211
+ if not isinstance(response.content, str):
212
+ raise ValueError(f"Invalid content type: {type(response.content)}")
213
+
214
+ # Ensure response has content
215
+ if not response.content.strip():
216
+ raise ValueError("Empty response content")
217
+
218
+ # Add FINAL ANSWER prefix if missing
219
+ content = response.content
220
+ if "FINAL ANSWER:" not in content:
221
+ content = f"FINAL ANSWER: {content}"
222
+ response = AIMessage(content=content)
223
 
224
  return {"messages": response}
225
  except Exception as e:
226
  error_msg = f"Error in assistant node: {str(e)}"
227
+ print(f"Assistant node error: {error_msg}") # Log error for debugging
228
+ return {
229
+ "messages": AIMessage(
230
+ content="FINAL ANSWER: Error occurred while processing request. Please try again."
231
+ )
232
+ }
233
 
234
  # Stubbed retriever node for future integration
235
  def retriever_node(state: MessagesState):
app.py CHANGED
@@ -25,53 +25,54 @@ class BasicAgent:
25
  def __call__(self, question: str) -> str:
26
  print(f"Agent received question (first 50 chars): {question[:50]}...")
27
  try:
 
 
 
28
  # Create properly typed messages
29
- system_msg = SystemMessage(
30
- content="""You are a helpful AI assistant. Format your final answer as:
31
- FINAL ANSWER: [your answer here]"""
32
- )
33
  human_msg = HumanMessage(content=question)
34
- msgs: List[AnyMessage] = [system_msg, human_msg]
35
 
36
  # Create and cast the state
37
  input_state = cast(MessagesState, {"messages": msgs})
38
 
39
- # Invoke the graph
40
- result = self.graph.invoke(input_state)
 
 
 
 
41
 
42
- # Validate response
43
- if not isinstance(result, dict) or "messages" not in result:
44
- raise ValueError("Invalid response structure from agent graph")
45
 
46
- if not result["messages"]:
47
- raise ValueError("Empty message list in response")
48
 
49
- # Get the last message content
50
  last_msg = result["messages"][-1]
51
  if not isinstance(last_msg, (AIMessage, HumanMessage, SystemMessage)):
52
- raise ValueError(f"Invalid message type: {type(last_msg)}")
53
 
 
54
  answer = last_msg.content
55
  if not isinstance(answer, str):
56
- raise ValueError(f"Invalid answer type: {type(answer)}")
57
 
58
- # Ensure proper formatting
59
  if not answer.strip():
60
  return "Error: Empty response from agent"
61
 
62
- if "FINAL ANSWER:" not in answer:
63
- # If no prefix, return as is
64
- return answer
65
-
66
- # Extract the actual answer after "FINAL ANSWER:"
67
- final_answer = answer.split("FINAL ANSWER:", 1)[1].strip()
68
- if not final_answer:
69
- return "Error: Empty answer after FINAL ANSWER prefix"
70
 
71
- return final_answer
 
72
 
73
  except Exception as e:
74
- error_msg = f"Error in agent call: {str(e)}"
75
  print(error_msg)
76
  return error_msg
77
 
 
25
  def __call__(self, question: str) -> str:
26
  print(f"Agent received question (first 50 chars): {question[:50]}...")
27
  try:
28
+ # Import system prompt from agent module
29
+ from agent import system_prompt
30
+
31
  # Create properly typed messages
 
 
 
 
32
  human_msg = HumanMessage(content=question)
33
+ msgs: List[AnyMessage] = [system_prompt, human_msg]
34
 
35
  # Create and cast the state
36
  input_state = cast(MessagesState, {"messages": msgs})
37
 
38
+ # Invoke the graph with proper error handling
39
+ try:
40
+ result = self.graph.invoke(input_state)
41
+ except Exception as e:
42
+ print(f"Graph invocation error: {str(e)}")
43
+ return f"Error: Failed to process request - {str(e)}"
44
 
45
+ # Validate response structure
46
+ if not isinstance(result, dict):
47
+ return "Error: Invalid response format from agent"
48
 
49
+ if "messages" not in result or not result["messages"]:
50
+ return "Error: No response messages from agent"
51
 
52
+ # Get the last message
53
  last_msg = result["messages"][-1]
54
  if not isinstance(last_msg, (AIMessage, HumanMessage, SystemMessage)):
55
+ return f"Error: Invalid message type - {type(last_msg)}"
56
 
57
+ # Get and validate content
58
  answer = last_msg.content
59
  if not isinstance(answer, str):
60
+ return f"Error: Invalid answer type - {type(answer)}"
61
 
 
62
  if not answer.strip():
63
  return "Error: Empty response from agent"
64
 
65
+ # Handle FINAL ANSWER prefix
66
+ if "FINAL ANSWER:" in answer:
67
+ parts = answer.split("FINAL ANSWER:", 1)
68
+ if len(parts) == 2 and parts[1].strip():
69
+ return parts[1].strip()
 
 
 
70
 
71
+ # If no prefix or empty after prefix, return full answer
72
+ return answer.strip()
73
 
74
  except Exception as e:
75
+ error_msg = f"Error processing request: {str(e)}"
76
  print(error_msg)
77
  return error_msg
78