Skip to content

Commit 6d7bab6

Browse files
committed
test(workflow): Move agent transfer integration tests to workflow folder
Migrated the multi-agent dynamic transfer integration tests from `flows/llm_flows/test_agent_transfer.py` to the consolidated `workflow/` directory to align with ADK 2.0 patterns. During this migration and alignment: 1. Fixed a critical runner bug in `NodeRunner._track_event_in_context` where structured parent nodes (like SequentialAgent or LoopAgent) executing legacy recursive sub-agents internally would mistakenly intercept and bubble up the sub-agent's internal routing actions, causing crashing `unrelated transfer` errors in the parent scheduler. Fixed by restricting route/transfer tracking to native node events (`not event.author` or `event.author == self._node.name`). 2. Restored five previously deleted legacy structured transfer tests (`test_auto_to_single`, `test_auto_to_auto_to_single`, `test_auto_to_sequential`, `test_auto_to_sequential_to_auto`, and `test_auto_to_loop`) to maintain regression protection. 3. Hardened the suite with dedicated new tests for sibling peer transfers, child-to-parent climbing transfers, grandchild nested transfers, self-transfer blocking, and unrelated sandbox crossing defenses. Change-Id: I2f087c211a5a78508689f4dfeea2c533219df208
1 parent 6e0c1e5 commit 6d7bab6

2 files changed

Lines changed: 324 additions & 46 deletions

File tree

src/google/adk/workflow/_node_runner.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,16 @@ def _track_event_in_context(self, event: Event, ctx: Context) -> None:
285285
ctx.output = event.content
286286
if event.long_running_tool_ids is not None:
287287
ctx._interrupt_ids.update(event.long_running_tool_ids)
288-
if event.actions.route is not None:
289-
ctx.route = event.actions.route
290-
ctx._route_emitted = True
291-
if event.actions.transfer_to_agent is not None:
292-
ctx.actions.transfer_to_agent = event.actions.transfer_to_agent
288+
# Only propagate decisions from native events (authored by this node or unspecified).
289+
# This prevents structured parent nodes (e.g. SequentialAgent) from intercepting
290+
# and bubbling up actions already handled internally by their nested sub-agents.
291+
is_native_node_event = not event.author or event.author == self._node.name
292+
if event.actions and is_native_node_event:
293+
if event.actions.route is not None:
294+
ctx.route = event.actions.route
295+
ctx._route_emitted = True
296+
if event.actions.transfer_to_agent is not None:
297+
ctx.actions.transfer_to_agent = event.actions.transfer_to_agent
293298

294299
ctx.telemetry_context.add_event(event)
295300

0 commit comments

Comments
 (0)