diff --git a/src/google/adk/agents/base_agent.py b/src/google/adk/agents/base_agent.py index 18a5de47..b53ef923 100644 --- a/src/google/adk/agents/base_agent.py +++ b/src/google/adk/agents/base_agent.py @@ -135,8 +135,10 @@ async def run_async( Yields: Event: the events generated by the agent. """ - - with tracer.start_as_current_span(f'agent_run [{self.name}]'): + span = tracer.start_span( + f'agent_run [{self.name}]' + ) # Start the span explicitly + try: ctx = self._create_invocation_context(parent_context) if event := await self.__handle_before_agent_callback(ctx): @@ -152,6 +154,8 @@ async def run_async( if event := await self.__handle_after_agent_callback(ctx): yield event + finally: + span.end() # End the span explicitly @final async def run_live( diff --git a/src/google/adk/agents/loop_agent.py b/src/google/adk/agents/loop_agent.py index 219e0c22..b75eca0f 100644 --- a/src/google/adk/agents/loop_agent.py +++ b/src/google/adk/agents/loop_agent.py @@ -16,6 +16,7 @@ from __future__ import annotations +from google.genai import types from typing import AsyncGenerator from typing import Optional @@ -48,9 +49,29 @@ async def _run_async_impl( while not self.max_iterations or times_looped < self.max_iterations: for sub_agent in self.sub_agents: async for event in sub_agent.run_async(ctx): - yield event + yield event # Yield the event immediately if event.actions.escalate: - return + # Ensure the escalation message is processed immediately + if event.content and event.content.parts: + for part in event.content.parts: + if part.function_response.response: + # Yield the escalation message as a new event + yield Event( + invocation_id=ctx.invocation_id, + author=sub_agent.name, + branch=ctx.branch, + content=types.Content( + role='assistant', + parts=[ + types.Part( + text=part.function_response.response.get( + 'message' + ), + ) + ], + ), + ) + return # Exit the loop after escalation times_looped += 1 return diff --git a/src/google/adk/flows/llm_flows/base_llm_flow.py b/src/google/adk/flows/llm_flows/base_llm_flow.py index b6b45fcd..f1a1d410 100644 --- a/src/google/adk/flows/llm_flows/base_llm_flow.py +++ b/src/google/adk/flows/llm_flows/base_llm_flow.py @@ -497,7 +497,8 @@ async def _call_llm_async( # Calls the LLM. llm = self.__get_llm(invocation_context) - with tracer.start_as_current_span('call_llm'): + span = tracer.start_span(f'call_llm') # Start the span explicitly + try: if invocation_context.run_config.support_cfc: invocation_context.live_request_queue = LiveRequestQueue() async for llm_response in self.run_live(invocation_context): @@ -537,6 +538,8 @@ async def _call_llm_async( llm_response = altered_llm_response yield llm_response + finally: + span.end() # End the span explicitly async def _handle_before_model_callback( self, diff --git a/src/google/adk/runners.py b/src/google/adk/runners.py index 3c384a87..23975ee8 100644 --- a/src/google/adk/runners.py +++ b/src/google/adk/runners.py @@ -172,7 +172,8 @@ async def run_async( Yields: The events generated by the agent. """ - with tracer.start_as_current_span('invocation'): + span = tracer.start_span('invocation') # Start the span explicitly + try: session = self.session_service.get_session( app_name=self.app_name, user_id=user_id, session_id=session_id ) @@ -199,6 +200,9 @@ async def run_async( if not event.partial: self.session_service.append_event(session=session, event=event) yield event + finally: + # Ensure the span is finished when the function exits + span.end() async def _append_new_message_to_session( self,