Repository navigation
fix(agents): route the turn after a paused single_turn sub-agent back to its delegator - #7605
Open
Somay-kousis wants to merge 2 commits into
Open
Somay-kousis wants to merge 2 commits into
Somay-kousis wants to merge 2 commits into
Conversation
… to its delegator
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.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
Problem:
A
mode='single_turn'sub-agent that pauses on a tool confirmation takes every later turn.find_agent_to_runmaps an agent inside a delegation back to its delegator through_resolve_task_delegator, but that helper only checksmode == "task". A paused single_turn agent is the last author, so it is picked as the agent to run: a new user message goes to it instead of the root, and after an approval it replies to the user directly while the root's call to it never gets a response.Solution:
Check
mode in DELEGATED_TASK_MODES(taskandsingle_turn, fromutils/_agent_mode.py) instead of== "task". The paused single_turn agent now resolves to its delegator on both paths that call the helper: the resume path (the user answers the confirmation; the delegator resumes the sub-agent and gets its result) and the event scan (the user sends a new message; the delegator answers it). Chat sub-agents keep their sticky routing.Testing Plan
Unit Tests:
I have added or updated unit tests for my change.
All unit tests pass locally.
test_find_agent_to_run_routes_single_turn_agent_to_its_delegatorintests/unittests/agents/test_agent_router.py, next to the existing task-mode test. Parametrized over the mode as a string and asAgentMode.SINGLE_TURN, a delegator that is the root or a nested chat agent, and whether the user answered the pending call.test_run_async_paused_single_turn_agent_returns_turn_to_delegatorintests/unittests/test_runners.py, end to end throughRunner: a root with a single_turn sub-agent whose tool needs confirmation. Parametrized over the next user turn (a new message, approve, reject) andResumabilityConfig(is_resumable=False/True). It checks the tool ran only on approve, the root replies on turn 2, the sub-agent never gets a chat turn, and turn 3 goes to the root.Before the fix (main at 4dbb55d):
After the fix:
pytest tests/unittests/agents tests/unittests/test_runners.py tests/unittests/runners tests/unittests/flows tests/unittests/workflow: this branch3540 passed, 1 skipped, 5 xfailed, 1 xpassed; with main's_agent_router.py,14 failed, 3526 passed, 1 skipped, 6 xfailed(the 14 are the new tests). The xpass istest_single_turn_child_agent_interrupt_and_resumeintest_llm_agent_interruptions.py(xfail "Single-turn agent as subagent not supported yet"), which now passes. I left its marker alone; happy to drop it here if you want.pyink --checkandisort --check-onlyare clean on the changed files.mypy src/google/adk/agents/_agent_router.py: no issues, same as main.Manual End-to-End (E2E) Tests:
The script from the issue: a chat root with a single_turn
helperwhosepaytool needs confirmation, onInMemoryRunnerwith fake models.User types something else after the pause. Before:
After:
User approves. Before:
After:
Approving after an unrelated message also works on this branch: the root answers the message, then the approval resumes
helperand the root gets its result.Checklist
Additional context
No open PR touches
_agent_router.py. The task-mode mapping came in with c5ee35e.