Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs-website/docs/pipeline-components/agents-1/agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The `exit_reason` output tells you why the agent stopped, which makes it easy to
- `"text"`: the model returned a complete reply with no tool calls.
- `"length"`: the model reached its output-token limit. `last_message` may contain a partial response.
- `"content_filter"`: a content filter stopped the model response. `last_message` may contain a partial response.
- the name of the tool that satisfied a tool exit condition. In this case `last_message` is that tool's result — a tool-result `ChatMessage` whose `text` is empty — so `exit_reason` tells you how to consume it.
- the name of the tool that satisfied a tool exit condition. Its result is the last tool-result `ChatMessage` in `messages` whose `tool_call_result.origin.tool_name` matches `exit_reason`; read it from `tool_call_result.result`. When the model calls several tools in one reply, this may not be `last_message`.
- `"max_agent_steps"`: the agent reached `max_agent_steps` before meeting an exit condition.
- a custom reason set by a hook through the `stop_run` state key, such as `"token_budget_exceeded"` from the [`TokenBudgetHook`](./token-budget.mdx).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The `exit_reason` output tells you why the agent stopped, which makes it easy to
- `"text"`: the model returned a complete reply with no tool calls.
- `"length"`: the model reached its output-token limit. `last_message` may contain a partial response.
- `"content_filter"`: a content filter stopped the model response. `last_message` may contain a partial response.
- the name of the tool that satisfied a tool exit condition. In this case `last_message` is that tool's result — a tool-result `ChatMessage` whose `text` is empty — so `exit_reason` tells you how to consume it.
- the name of the tool that satisfied a tool exit condition. Its result is the last tool-result `ChatMessage` in `messages` whose `tool_call_result.origin.tool_name` matches `exit_reason`; read it from `tool_call_result.result`. When the model calls several tools in one reply, this may not be `last_message`.
- `"max_agent_steps"`: the agent reached `max_agent_steps` before meeting an exit condition.
- a custom reason set by a hook through the `stop_run` state key, such as `"token_budget_exceeded"` from the [`TokenBudgetHook`](./token-budget.mdx).

Expand Down
14 changes: 8 additions & 6 deletions haystack/components/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -866,9 +866,10 @@ def run(
- "exit_reason": Why the Agent stopped, useful for routing the output downstream (e.g. with a
`ConditionalRouter`). One of: `"text"` (the model returned a complete reply with no tool calls),
`"length"` or `"content_filter"` (the model returned an incomplete reply, which may contain partial
text), the name of the tool that satisfied a tool exit condition (in which case `last_message` is that
tool's result), or `"max_agent_steps"` (the Agent hit `max_agent_steps` before meeting an exit
condition), or a custom reason a hook supplied through the `stop_run` state key.
text), the name of the tool that satisfied a tool exit condition (its result is the last tool message in
`messages` whose `tool_call_result.origin.tool_name` matches it, which may not be `last_message` when
the model called several tools at once), or `"max_agent_steps"` (the Agent hit `max_agent_steps` before
meeting an exit condition), or a custom reason a hook supplied through the `stop_run` state key.
- Any additional keys defined in the `state_schema`.
"""
agent_inputs = {"messages": messages, "streaming_callback": streaming_callback, **kwargs}
Expand Down Expand Up @@ -952,9 +953,10 @@ async def run_async(
- "exit_reason": Why the Agent stopped, useful for routing the output downstream (e.g. with a
`ConditionalRouter`). One of: `"text"` (the model returned a complete reply with no tool calls),
`"length"` or `"content_filter"` (the model returned an incomplete reply, which may contain partial
text), the name of the tool that satisfied a tool exit condition (in which case `last_message` is that
tool's result), or `"max_agent_steps"` (the Agent hit `max_agent_steps` before meeting an exit
condition), or a custom reason a hook supplied through the `stop_run` state key.
text), the name of the tool that satisfied a tool exit condition (its result is the last tool message in
`messages` whose `tool_call_result.origin.tool_name` matches it, which may not be `last_message` when
the model called several tools at once), or `"max_agent_steps"` (the Agent hit `max_agent_steps` before
meeting an exit condition), or a custom reason a hook supplied through the `stop_run` state key.
- Any additional keys defined in the `state_schema`.
"""
agent_inputs = {"messages": messages, "streaming_callback": streaming_callback, **kwargs}
Expand Down
2 changes: 1 addition & 1 deletion test/components/agents/test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,6 @@ def test_exit_condition_exits(self, weather_tool):
assert "last_message" in result
assert isinstance(result["last_message"], ChatMessage)
assert result["messages"][-1] == result["last_message"]
# The exit reason is the tool that triggered the exit, and `last_message` is that tool's result.
assert result["exit_reason"] == "weather_tool"

def test_exit_condition_on_tool_provided_at_runtime(self, weather_tool):
Expand Down Expand Up @@ -1254,6 +1253,7 @@ def test_tool_exit_reports_the_first_matching_tool(self, weather_tool, component
)
result = agent.run([ChatMessage.from_user("Go")])
assert result["exit_reason"] == "parrot"
assert result["last_message"].tool_call_result.origin.tool_name == "weather_tool"

def test_max_steps_exit(self, weather_tool, caplog):
"""Exhausting `max_agent_steps` before meeting an exit condition reports `"max_agent_steps"`."""
Expand Down
Loading