Skip to content

feat(agents): let nested LoopAgents exit independently - #6842

Open
a2105z wants to merge 1 commit into
google:mainfrom
a2105z:feat/nested-loop-escalation-scope
Open

feat(agents): let nested LoopAgents exit independently#6842
a2105z wants to merge 1 commit into
google:mainfrom
a2105z:feat/nested-loop-escalation-scope

Conversation

@a2105z

@a2105z a2105z commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Nested LoopAgents currently treat every escalate as global: an inner exit_loop() also kills every ancestor loop. That is the Nested LoopAgents will escalate all LoopAgents #2808 report (expect 25 inner steps, get 5).
  • This implements @Jacksunwei's scoped-escalation design. escalate=True with no context stays root (today's behavior, including exit_loop). EscalationContext(type='parent') is consumed by the nearest LoopAgent, which records itself on handled_by so outer loops continue. exit_current_loop is the parent-scoped tool.
  • Optional target_agent aims the exit at a named loop. ParallelAgent ignores already-consumed parent escalations so siblings of an inner loop keep running.

Test plan

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.
uv run python -m pytest \
  tests/unittests/agents/test_loop_agent.py \
  tests/unittests/events/test_event_actions.py \
  tests/unittests/tools/test_exit_loop_tool.py \
  tests/unittests/agents/test_parallel_agent.py \
  tests/unittests/a2a/converters/test_to_adk.py::TestToAdk::test_peer_supplied_actions_cannot_mutate_caller_session \
  tests/unittests/a2a/converters/test_to_adk.py::TestToAdk::test_peer_settable_action_fields_are_exactly_inert \
  -q

57 loop/event/tool/parallel tests passed, plus the A2A peer-actions allow-list (escalation_context is not peer-settable).

Manual check: nested SequentialAgent → outer LoopAgent → inner LoopAgent with exit_current_loop should run inner×outer iterations; exit_loop still unwinds every loop.

Closes: #2808

@Jacksunwei @klateefa @hangfei @boyangsvl @wuliang229 @yeesian @xuanyang15 @steren @llalitkumarrr @GWeale @jhonratiu

escalate=True still stops every enclosing loop so exit_loop stays
backward compatible. EscalationContext(type='parent') is consumed by
the nearest LoopAgent so an outer retry loop can continue.
exit_current_loop is the parent-scoped tool.

Fixes google#2808
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nested LoopAgents will escalate all LoopAgents

2 participants