mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
fix: 'NoneType' object is not iterable
Merge https://github.com/google/adk-python/pull/3988 ### Link to Issue or Description of Change **1. Link to an existing issue (if applicable):** - Closes: https://github.com/google/adk-python/issues/3987 - Related: https://github.com/google/adk-python/issues/3596 **2. Or, if no issue exists, describe the change:** **Problem:** Idea about my use case I'm building the report generation system using google-ask (1.18.0) and building multiple subagents here, I'm passing the one subagent Agent as a tool to another Parent Agent. Note: Sub-agent can do web search. here, parent agent triggers multiple sub-agent (same agent) multiple times according to use case or complexity of the user input Describe the bug here, the bug sometimes sub agents doesn't provide the proper output and resulted in the ``` merged_text = '\n'.join(p.text for p in last_content.parts if p.text) ^^^^^^^^^^^^^^^^^^ TypeError: 'NoneType' object is not iterable and it's breaking the system of Agents workflow ``` **Solution:** Creating fallback if there is no **last_content.parts** it will return the empty parts so we won't face the NoneType issue ### Testing Plan Created a unit test file for this issue test_google_search_agent_tool_repro.py **Unit Tests:** - [X] I have added or updated unit tests for my change. - [X] All unit tests pass locally. _Please include a summary of passed `pytest` results._ 3677 passed, 2208 warnings in 42.64s **Manual End-to-End (E2E) Tests:** N/A ### Checklist - [X] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document. - [X] I have performed a self-review of my own code. - [X] I have commented my code, particularly in hard-to-understand areas. - [X] I have added tests that prove my fix is effective or that my feature works. - [X] New and existing unit tests pass locally with my changes. - [X] I have manually tested my changes end-to-end. - [ ] Any dependent changes have been merged and published in downstream modules. ### Additional context N/A Co-authored-by: Liang Wu <wuliang@google.com> COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3988 from ananthanarayanan-28:none-type-issue e6ba948345adfc5ac73a5e39d11c68236f117179 PiperOrigin-RevId: 856515019
This commit is contained in:
committed by
Copybara-Service
parent
2ed686527a
commit
7db3ce9613
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 == ''
|
||||
|
||||
Reference in New Issue
Block a user