diff --git a/letta/agents/letta_agent.py b/letta/agents/letta_agent.py index c8c5284d..619d0902 100644 --- a/letta/agents/letta_agent.py +++ b/letta/agents/letta_agent.py @@ -940,7 +940,10 @@ class LettaAgent(BaseAgent): tool_call_id=tool_call_id, request_heartbeat=request_heartbeat, ) - if tool_call_name not in valid_tool_names: + # Check if tool rule is violated - if so, we'll force continuation + tool_rule_violated = tool_call_name not in valid_tool_names + + if tool_rule_violated: base_error_message = f"[ToolConstraintError] Cannot call {tool_call_name}, valid tools to call include: {valid_tool_names}." violated_rule_messages = tool_rules_solver.guess_rule_violation(tool_call_name) if violated_rule_messages: @@ -969,7 +972,7 @@ class LettaAgent(BaseAgent): # get the function response limit target_tool = next((x for x in agent_state.tools if x.name == tool_call_name), None) - return_char_limit = target_tool.return_char_limit + return_char_limit = target_tool.return_char_limit if target_tool else None function_response_string = validate_function_response( tool_execution_result.func_return, return_char_limit=return_char_limit, truncate=truncate ) @@ -981,15 +984,20 @@ class LettaAgent(BaseAgent): # 4. Register tool call with tool rule solver # Resolve whether or not to continue stepping continue_stepping = request_heartbeat - tool_rules_solver.register_tool_call(tool_name=tool_call_name) - if tool_rules_solver.is_terminal_tool(tool_name=tool_call_name): - if continue_stepping: - stop_reason = LettaStopReason(stop_reason=StopReasonType.tool_rule.value) - continue_stepping = False - elif tool_rules_solver.has_children_tools(tool_name=tool_call_name): - continue_stepping = True - elif tool_rules_solver.is_continue_tool(tool_name=tool_call_name): + + # Force continuation if tool rule was violated to give the model another chance + if tool_rule_violated: continue_stepping = True + else: + tool_rules_solver.register_tool_call(tool_name=tool_call_name) + if tool_rules_solver.is_terminal_tool(tool_name=tool_call_name): + if continue_stepping: + stop_reason = LettaStopReason(stop_reason=StopReasonType.tool_rule.value) + continue_stepping = False + elif tool_rules_solver.has_children_tools(tool_name=tool_call_name): + continue_stepping = True + elif tool_rules_solver.is_continue_tool(tool_name=tool_call_name): + continue_stepping = True # 5a. Persist Steps to DB # Following agent loop to persist this before messages