diff --git a/src/google/adk/tools/agent_tool.py b/src/google/adk/tools/agent_tool.py index ea40bee0..2b82b663 100644 --- a/src/google/adk/tools/agent_tool.py +++ b/src/google/adk/tools/agent_tool.py @@ -207,7 +207,7 @@ class AgentTool(BaseTool): # to avoid "Attempted to exit cancel scope in a different task" errors await runner.close() - if not last_content: + if last_content is None or last_content.parts is None: return '' merged_text = '\n'.join( p.text for p in last_content.parts if p.text and not p.thought diff --git a/src/google/adk/tools/google_search_agent_tool.py b/src/google/adk/tools/google_search_agent_tool.py index 77cb6fed..c88a986b 100644 --- a/src/google/adk/tools/google_search_agent_tool.py +++ b/src/google/adk/tools/google_search_agent_tool.py @@ -123,7 +123,7 @@ class GoogleSearchAgentTool(AgentTool): last_content = event.content last_grounding_metadata = event.grounding_metadata - if not last_content: + if last_content is None or last_content.parts is None: return '' merged_text = '\n'.join(p.text for p in last_content.parts if p.text) if isinstance(self.agent, LlmAgent) and self.agent.output_schema: diff --git a/tests/unittests/tools/test_agent_tool.py b/tests/unittests/tools/test_agent_tool.py index 48a7a995..90231871 100644 --- a/tests/unittests/tools/test_agent_tool.py +++ b/tests/unittests/tools/test_agent_tool.py @@ -900,3 +900,45 @@ def test_agent_tool_with_input_schema_uses_json_schema_feature( }, 'response_json_schema': {'type': 'object'}, } + + +@mark.asyncio +async def test_run_async_handles_none_parts_in_response(): + """Verify run_async handles None parts in response without raising TypeError.""" + + # Mock model for the tool_agent that returns content with parts=None + # This simulates the condition causing the TypeError + tool_agent_model = testing_utils.MockModel.create( + responses=[ + LlmResponse( + content=types.Content(parts=None), + ) + ] + ) + + tool_agent = Agent( + name='tool_agent', + model=tool_agent_model, + ) + + agent_tool = AgentTool(agent=tool_agent) + + session_service = InMemorySessionService() + session = await session_service.create_session( + app_name='test_app', user_id='test_user' + ) + + invocation_context = InvocationContext( + invocation_id='invocation_id', + agent=tool_agent, + session=session, + session_service=session_service, + ) + tool_context = ToolContext(invocation_context=invocation_context) + + # This should not raise `TypeError: 'NoneType' object is not iterable`. + tool_result = await agent_tool.run_async( + args={'request': 'test request'}, tool_context=tool_context + ) + + assert tool_result == ''