Conversation
Agent.run and Agent.run_async both documented exit_reason as "the name of the tool that satisfied a tool exit condition (in which case `last_message` is that tool's result)". That holds only when the exit tool is the last one the model requested. _check_exit_conditions is deliberately order-agnostic -- its docstring says "the order of parallel tool calls does not matter" -- while last_message is the final message of the step. With parallel tool calls the two disagree, and because exit_reason is documented as useful for routing downstream, a ConditionalRouter branching on it and then reading last_message silently consumes a different tool's output. The same claim was in three other places: the shipped docs page, which put it more strongly and also described the message's text as empty when it is None, and a comment in the tests. All four now say to locate the exit tool's result by matching tool_call_result.origin.tool_name against exit_reason. test_tool_exit_reports_the_first_matching_tool already built exactly this parallel-call shape but asserted only exit_reason, which is why the mismatch went unnoticed; it now pins last_message too. Behaviour is unchanged. See deepset-ai#12890 for the alternative -- making _check_exit_conditions report the exit tool whose result lands last, so the original promise becomes true -- which changes which tool is reported when two exit-condition tools fire in one step.
lets-order-some-fries
requested review from
sjrl
and removed request for
a team
September 23, 2026 16:04
Contributor
|
@lets-order-some-fries is attempting to deploy a commit to the deepset Team on Vercel. A member of the Team first needs to authorize it. |
1 task
Contributor
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||
sjrl
reviewed
Sep 24, 2026
sjrl
reviewed
Sep 24, 2026
sjrl
reviewed
Sep 24, 2026
sjrl
reviewed
Sep 24, 2026
sjrl
reviewed
Sep 24, 2026
sjrl
reviewed
Sep 24, 2026
Contributor
|
Please also update |
Contributor
|
Thanks for opening this! We'd prefer to keep this a docs only change for resolving the issue. |
Contributor
|
Hey @lets-order-some-fries soft ping to ask if you can work on this, this week |
Contributor
Author
|
Sure yeah, I'll work on it today. |
- Rewrap the exit_reason paragraph in the run() and run_async() docstrings, and say the *last* matching tool message there too: messages covers the whole run, so the same tool can have results from earlier steps (an errored call, or an exit an on_exit hook vetoed). - docs page: take the suggested wording. - Tests: drop the comments and the exit_result lookup; the last_message assertion covers it. - Drop the release note; this is a docs-only change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review asked for version-3.2-unstable; deepset-ai#12918 has since promoted it to version-3.2, the current versioned page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Thanks @sjrl, all addressed:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issues
exit_reasonnames a tool whose result is notlast_messagewhen tool calls run in parallel #12890Proposed Changes:
Agent.runandAgent.run_asyncdocumentedexit_reasonas "the name of the tool that satisfied a tool exit condition (in which caselast_messageis that tool's result)". That only holds when the exit tool's result happens to be the last message of the step._check_exit_conditionschecks every tool call regardless of order, whilelast_messageis just the final message, so with parallel tool calls aConditionalRouterthat branches onexit_reasonand then readslast_messagecan silently get another tool's output.This is a docs-only change; behaviour is unchanged. The exit tool's result is now described as the last tool-result message in
messageswhosetool_call_result.origin.tool_namematchesexit_reason, which may not belast_messagewhen the model calls several tools in one reply.haystack/components/agents/agent.py: theexit_reasonentry in therunandrun_asyncdocstrings.docs-website/docs/pipeline-components/agents-1/agent.mdxanddocs-website/versioned_docs/version-3.2/pipeline-components/agents-1/agent.mdx: the same correction. These also described the tool-result message'stextas empty; it isNone.test/components/agents/test_agent.py: removed a comment restating the old claim.How did you test it?
test_tool_exit_reports_the_first_matching_toolalready covered the parallel-call case but only assertedexit_reason; it now also asserts thatlast_messageis the other tool's result.pytest test/components/agents/ test/tools/: 621 passed, 16 skippedpre-commit run --fileson the four changed files: all hooks passNotes for the reviewer
versioned_docs/version-3.1still has the old sentence. I left it because 3.2 is the current versioned page.Checklist
fix:,feat:,build:,chore:,ci:,docs:,style:,refactor:,perf:,test:and added!in case the PR includes breaking changes.🤖 Generated with Claude Code