From 1338258da398879ac4b9bd3d2d88f6af45af7451 Mon Sep 17 00:00:00 2001 From: 9chait9 <9chait9@gmail.com> Date: Sat, 18 Apr 2026 03:15:39 -0700 Subject: [PATCH] Fix issue #5349: Sub-agent with sequential LRO tools fails to resume. - Fix Bug 1: Update `should_pause_invocation` in `invocation_context.py` to check for existing `FunctionResponse` before pausing. - Fix Bug 2: Update `llm_agent.py` to track `sub_agent_paused` and only set `end_of_agent=True` if the agent did not pause. --- src/google/adk/agents/invocation_context.py | 17 ++++++++++++++++- src/google/adk/agents/llm_agent.py | 18 +++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/google/adk/agents/invocation_context.py b/src/google/adk/agents/invocation_context.py index b2032c5325..f91cf4557f 100644 --- a/src/google/adk/agents/invocation_context.py +++ b/src/google/adk/agents/invocation_context.py @@ -390,9 +390,24 @@ def should_pause_invocation(self, event: Event) -> bool: if not event.long_running_tool_ids or not event.get_function_calls(): return False + # Check if we have already received a response for the long-running tool call + # Get all events in the current invocation + events = self._get_events(current_invocation=True) + for fc in event.get_function_calls(): if fc.id in event.long_running_tool_ids: - return True + # Check if there's a function response for this fc.id + has_response = False + for e in events: + for fr in e.get_function_responses(): + if fr.id == fc.id: + has_response = True + break + if has_response: + break + + if not has_response: + return True return False diff --git a/src/google/adk/agents/llm_agent.py b/src/google/adk/agents/llm_agent.py index 0f7cc2b7d9..796368c4ed 100644 --- a/src/google/adk/agents/llm_agent.py +++ b/src/google/adk/agents/llm_agent.py @@ -181,7 +181,15 @@ async def _convert_tool_union_to_tools( return [FunctionTool(func=tool_union)] # At this point, tool_union must be a BaseToolset - return await tool_union.get_tools_with_prefix(ctx) + try: + return await tool_union.get_tools_with_prefix(ctx) + except Exception as e: + logger.warning( + 'Failed to get tools from toolset %s: %s', + type(tool_union).__name__, + e, + ) + return [] class LlmAgent(BaseAgent): @@ -466,12 +474,16 @@ async def _run_async_impl( if agent_state is not None and ( agent_to_transfer := self._get_subagent_to_resume(ctx) ): + sub_agent_paused = False async with Aclosing(agent_to_transfer.run_async(ctx)) as agen: async for event in agen: + if ctx.should_pause_invocation(event): + sub_agent_paused = True yield event - ctx.set_agent_state(self.name, end_of_agent=True) - yield self._create_agent_state_event(ctx) + if not sub_agent_paused: + ctx.set_agent_state(self.name, end_of_agent=True) + yield self._create_agent_state_event(ctx) return should_pause = False