-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Problem
I found two issues in the _run_stream
method of the MultiStepAgent
class (src/smolagents/agents.py, lines 537-606):
-
Duplicate yield when max_steps is reached: When an agent reaches max_steps, the final
action_step
gets yielded twice - once in the finally block (line 601) and again on line 605. This causes consumers of the stream to receive duplicate step events. -
NameError when max_steps=0: If
max_steps
is set to 0, the while loop never executes, soaction_step
is never defined. However, line 605 tries to yield this undefined variable, causing a NameError.
Steps to reproduce
For the duplicate yield issue:
- Create an agent with max_steps=2
- Run the agent with stream=True
- The agent will execute 2 steps
- On the final step (step 2), the while loop executes normally
- The finally block on line 601 yields the action_step for step 2
- step_number is incremented to 3, causing the while loop to exit
- The condition on line 604 evaluates to True (returned_final_answer is False and step_number is 3)
- Line 605 tries to yield action_step again, causing a duplicate
For the NameError issue:
- Create an agent with max_steps=0
- Run the agent with stream=True
- The while loop condition (step_number <= 0) is False from the start, so the loop never executes
- action_step is never defined because it's only created inside the while loop
- The condition on line 604 evaluates to True (returned_final_answer is False and step_number is 1)
- Line 605 tries to yield action_step, but it was never defined, causing a NameError
Actual behavior and error logs
This analysis is based on code review rather than runtime errors. Based on the code logic:
For the duplicate yield case (max_steps > 0):
- When the agent reaches max_steps, the execution flow leads to the same action_step being yielded twice
- First yield happens in the finally block (line 601) as part of normal step execution
- Second yield happens on line 605 when the condition on line 604 is True
- This means stream consumers would receive duplicate action_step events for the final step
For the NameError case (max_steps = 0):
- The while loop never executes because step_number (1) is not <= max_steps (0)
- Since action_step is only created inside the while loop (line 569), it never gets defined
- When line 604's condition evaluates to True, line 605 attempts to yield action_step
- Since action_step was never defined, this would raise a NameError: local variable 'action_step' referenced before assignment
The root cause is that line 605 assumes action_step is always defined, but this is only true when the while loop has executed at least once.
Expected behavior
- Each action_step should only be yielded once
- The code should handle edge cases like max_steps=0 gracefully without errors
- Line 605 should be removed since action_step is already yielded in the finally block
Environment:
- OS: Windows 11
- Python version: 3.13.3
- Package version: latest (main branch)
Checklist
- I have searched the existing issues and have not found a similar bug report.
- I have provided a minimal, reproducible example.
- I have provided the full traceback of the error.
- I have provided my environment details.
- I am willing to work on this issue and submit a pull request.