1414
1515from __future__ import annotations
1616
17+ import json
18+ import logging
1719from typing import Any
1820from typing import TYPE_CHECKING
1921
2325
2426from . import _automatic_function_calling_util
2527from ..agents .common_configs import AgentRefConfig
28+ from ..events .event import Event
2629from ..memory .in_memory_memory_service import InMemoryMemoryService
30+ from ..sessions import Session
2731from ..utils .context_utils import Aclosing
2832from ._forwarding_artifact_service import ForwardingArtifactService
2933from .base_tool import BaseTool
3438if TYPE_CHECKING :
3539 from ..agents .base_agent import BaseAgent
3640
41+ logger = logging .getLogger (__name__ )
42+
3743
3844class AgentTool (BaseTool ):
3945 """A tool that wraps an agent.
@@ -138,7 +144,8 @@ async def run_async(
138144 role = 'user' ,
139145 parts = [
140146 types .Part .from_text (
141- text = str (args ) if isinstance (args , str ) else json .dumps (args ))
147+ text = str (args ) if isinstance (args , str ) else json .dumps (args )
148+ )
142149 ],
143150 )
144151 invocation_context = tool_context ._invocation_context
@@ -175,16 +182,18 @@ async def run_async(
175182 # Collect all text chunks from streaming response instead of just last content
176183 chunks : list [str ] = []
177184 sub_agent_events = []
178-
185+
179186 def iter_text_parts (parts ):
180187 """Safely iterate over parts and extract text, skipping None values."""
181188 for p in parts or []:
182- if hasattr (p , " text" ) and p .text is not None :
189+ if hasattr (p , ' text' ) and p .text is not None :
183190 yield p .text
184-
191+
185192 async with Aclosing (
186193 runner .run_async (
187- user_id = sub_agent_session .user_id , session_id = sub_agent_session .id , new_message = content
194+ user_id = sub_agent_session .user_id ,
195+ session_id = sub_agent_session .id ,
196+ new_message = content ,
188197 )
189198 ) as agen :
190199 async for event in agen :
@@ -196,54 +205,42 @@ def iter_text_parts(parts):
196205 sub_agent_events .append (event )
197206
198207 if sub_agent_events and hasattr (tool_context , '_invocation_context' ):
199- from ..sessions import Session
200- from ..events .event import Event
201-
202208 main_session = tool_context ._invocation_context .session
203- if main_session and hasattr (tool_context ._invocation_context , 'session_service' ):
209+ if main_session and hasattr (
210+ tool_context ._invocation_context , 'session_service'
211+ ):
204212 session_service = tool_context ._invocation_context .session_service
205- parent_agent_name = tool_context ._invocation_context .agent .name if hasattr (tool_context ._invocation_context , 'agent' ) else "root_agent"
206-
213+ parent_agent_name = (
214+ tool_context ._invocation_context .agent .name
215+ if hasattr (tool_context ._invocation_context , 'agent' )
216+ else 'root_agent'
217+ )
218+
207219 for sub_event in sub_agent_events :
208220
209221 try :
210222 if hasattr (sub_event , 'branch' ) and sub_event .branch :
211223 event_branch = sub_event .branch
212224 else :
213- event_branch = f"{ parent_agent_name } .{ self .agent .name } "
214-
215- copied_event = Event (
216- id = sub_event .id ,
217- invocation_id = sub_event .invocation_id ,
218- author = sub_event .author ,
219- branch = event_branch ,
220- actions = sub_event .actions ,
221- content = sub_event .content ,
222- long_running_tool_ids = sub_event .long_running_tool_ids ,
223- partial = sub_event .partial ,
224- turn_complete = sub_event .turn_complete ,
225- error_code = sub_event .error_code ,
226- error_message = sub_event .error_message ,
227- interrupted = sub_event .interrupted ,
228- grounding_metadata = sub_event .grounding_metadata ,
229- custom_metadata = sub_event .custom_metadata ,
230- usage_metadata = sub_event .usage_metadata ,
231- citation_metadata = getattr (sub_event , 'citation_metadata' , None ),
232- )
233-
225+ event_branch = f'{ parent_agent_name } .{ self .agent .name } '
226+
227+ copied_event = sub_event .model_copy (update = {'branch' : event_branch })
228+
234229 await session_service .append_event (main_session , copied_event )
235230 except Exception as e :
236- import logging
237- logger = logging .getLogger (__name__ )
238- logger .warning (f"Erro ao copiar evento do sub-agente { self .agent .name } para sessão principal: { e } " )
231+ logger .warning (
232+ "Error copying sub-agent event from '%s' to main session: %s" ,
233+ self .agent .name ,
234+ e ,
235+ )
239236
240237 # Clean up runner resources (especially MCP sessions)
241238 # to avoid "Attempted to exit cancel scope in a different task" errors
242239 await runner .close ()
243240
244241 # Merge all collected chunks into final text
245- merged_text = "" .join (chunks )
246-
242+ merged_text = '' .join (chunks )
243+
247244 if not merged_text :
248245 return ''
249246 if isinstance (self .agent , LlmAgent ) and self .agent .output_schema :
@@ -252,7 +249,7 @@ def iter_text_parts(parts):
252249 ).model_dump (exclude_none = True )
253250 else :
254251 tool_result = merged_text
255-
252+
256253 return tool_result
257254
258255 @override
0 commit comments