Agent control flow
!!! abstract "Understanding the default agent"
* This guide shows the control flow of the default agent.
* After this, you're ready to [remix & extend mini](cookbook.md)
The following diagram shows the control flow of the mini agent:
And here is the code that implements it:
??? note "Default agent class"
- [Read on GitHub](https://github.com/swe-agent/mini-swe-agent/blob/main/src/minisweagent/agents/default.py)
- [API reference](../reference/agents/default.md)
```python
--8<-- "src/minisweagent/agents/default.py"
```
Essentially, DefaultAgent.run calls DefaultAgent.step in a loop until the agent has finished its task.
The step method is the core of the agent. It does the following:
- Queries the model for a response based on the current messages (
DefaultAgent.query, callingModel.query) - Parses the response to get the action, i.e., the shell command to execute (
DefaultAgent.parse_action) - Executes the action in the environment (
DefaultAgent.execute_action, callingEnvironment.execute) - Renders the observation message with
DefaultAgent.render_template - Adds the observation to the messages
The interesting bit is how we handle error conditions and the finish condition:
This uses exceptions of two types: TerminatingException and NonTerminatingException.
TerminatingExceptionis raised when the agent has finished its task or we hit a limit (cost, step limit, etc.)NonTerminatingExceptionis raised when the agent has not finished its task, but we want to continue the loop. In this case, all we need to do is to add a new message to the messages list, so that the LM can see the new state. There are two typical cases that we handle this way:TimeoutError: the action took too long to execute (we show partial output)FormatError: the output from the LM contained zero or multiple actions (we show the error message)
The DefaultAgent.run method catches these exceptions and handles them by adding the corresponding message to the messages list and continuing the loop.
while True:
try:
self.step()
except NonTerminatingException as e:
self.add_message("user", str(e))
except TerminatingException as e:
self.add_message("user", str(e))
return type(e).__name__, str(e)
Using exceptions for the control flow is a lot easier than passing around flags and states, especially when extending or subclassing the agent.
{% include-markdown "_footer.md" %}