fix(agents): only stop ParallelAgent on direct sub-agent escalation - #1491
mithun-sudo wants to merge 1 commit into
Conversation
Match adk-python: nested escalate events must not cancel sibling branches. Adds regression test for LoopAgent nested under ParallelAgent.
30bda8e to
47810f7
Compare
|
Hi @mithun-sudo, thank you for your contribution. we appreciate you taking the time to submit this PR. It is currently under review by our team, and we will keep you updated if any additional information is required. |
wikaaaaa
left a comment
There was a problem hiding this comment.
Thank you for the contribution! LGTM, two minor comments.
| } | ||
|
|
||
| ImmutableSet<String> directSubAgentNames = | ||
| currentSubAgents.stream().map(BaseAgent::name).collect(ImmutableSet.toImmutableSet()); |
There was a problem hiding this comment.
Can we add .filter(Objects::nonNull) here?
ImmutableSet<String> directSubAgentNames =
currentSubAgents.stream()
.map(BaseAgent::name)
.filter(Objects::nonNull)
.collect(ImmutableSet.toImmutableSet());
Mocked agents have null names because BaseAgent.name() is a final method that cannot be mocked. And ImmutableSet.toImmutableSet() throws NullPointerException if any stream element is null.
BaseAgent already has a workaround like this -
adk-java/core/src/main/java/com/google/adk/agents/BaseAgent.java
Lines 160 to 164 in c1a2960
| new UnsupportedOperationException("runLive is not defined for ParallelAgent yet.")); | ||
| } | ||
|
|
||
| private static boolean asksThisAgentToExit(Event event, Set<String> directSubAgentNames) { |
There was a problem hiding this comment.
Can you please add a comment with a brief explanation why we check directSubAgentNames?
Sth like python has -
https://github.com/google/adk-python/blob/7ae1c9b026c84bf8a65921003f71b0f30c8e3166/src/google/adk/agents/parallel_agent.py#L70
Match adk-python: nested escalate events must not cancel sibling branches. Adds regression test for LoopAgent nested under ParallelAgent.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
Problem:
ParallelAgentstops all parallel branches when any event hasescalate=true, including escalation from nested sub-agents (e.g. an agent inside aLoopAgentsub-branch). adk-python only stops when the escalating event's author is a direct sub-agent (_asks_this_agent_to_exit).Solution:
Filter
takeUntilwithasksThisAgentToExit(), which requires bothescalate=trueandevent.author()in the set of direct sub-agent names. Matches adk-python parity without changing behavior for direct sub-agent escalation (existing test still passes).Testing Plan
Unit Tests:
Summary:
./mvnw -pl core clean compile test -Dtest=ParallelAgentEscalationTest— 2 tests passed./mvnw -Prelease clean package— BUILD SUCCESSrunAsync_nestedLoopEscalation_keepsSiblingBranchesRunningfails on main (stream completes after 1 nested escalate) and passes with this changerunAsync_escalationEvent_shortCircuitsOtherAgentsstill passes (direct sub-agent escalate still short-circuits siblings)Manual End-to-End (E2E) Tests:
Not applicable — behavior covered by unit tests; no user-facing API or runtime config change.
Checklist
Additional context
Python reference:
src/google/adk/agents/parallel_agent.py—_asks_this_agent_to_exittests/unittests/agents/test_parallel_agent.py—test_run_async_keeps_siblings_when_a_nested_loop_ends_itself