8000
We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
Environment:
google-adk
[1.1.1]
[3.13]
LlmAgent
gemini-2.0-flash-live-preview-04-09
AgentTool
gemini-2.5-pro-preview-05-06
gemini-2.0-flash
Problem Description: When using an LlmAgent (Root Agent) that is configured for streaming and multimodal input, and providing it with a tool that is an AgentTool (wrapping another LlmAgent, let's call it TaskExecutionAgent), an AttributeError occurs if the Root Agent's LLM attempts to call the TaskExecutionAgentTool.
TaskExecutionAgent
AttributeError
TaskExecutionAgentTool
The error AttributeError: 'AgentTool' object has no attribute 'func' originates from google/adk/flows/llm_flows/functions.py during the processing of the tool call.
AttributeError: 'AgentTool' object has no attribute 'func'
google/adk/flows/llm_flows/functions.py
Steps to Reproduce / Code Context:
Define a TaskExecutionAgent (e.g., an LlmAgent designed for specific multi-step logic).
# From agent_config.py task_execution_agent = LlmAgent( model="gemini-2.0-flash", # Or any model name="TaskExecutionAgent", instruction="...", description="...", )
Wrap this task_execution_agent with AgentTool:
task_execution_agent
# From agent_config.py from google.adk.tools.agent_tool import AgentTool task_execution_agent_tool = AgentTool(agent=task_execution_agent)
Provide this task_execution_agent_tool in the tools list of a Root LlmAgent that is multimodal and streaming:
task_execution_agent_tool
tools
# From agent_config.py all_root_agent_tools = [ # ... other tools (e.g., patched MCPTools) ... task_execution_agent_tool ] root_agent = LlmAgent( model="gemini-2.0-flash-live-preview-04-09", # Multimodal streaming model name="mcp_streaming_assistant", instruction="... instruction to sometimes call TaskExecutionAgentTool ...", tools=all_root_agent_tools, )
Initiate a scenario (e.g., via video stream input) where the root_agent's LLM decides to call TaskExecutionAgentTool.
root_agent
Observed Behavior (Error Traceback): The application crashes with the following traceback when TaskExecutionAgentTool is invoked:
Traceback (most recent call last): File ".../main.py", line 369, in agent_to_client_messaging # Line in my WebSocket handling async for event in live_events: ... (lines from adk/runners.py, adk/agents/base_agent.py, adk/agents/llm_agent.py) ... File ".../google/adk/flows/llm_flows/base_llm_flow.py", line 378, in _postprocess_live function_response_event = await functions.handle_function_calls_live( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invocation_context, model_response_event, llm_request.tools_dict ) File ".../google/adk/flows/llm_flows/functions.py", line 233, in handle_function_calls_live function_response = await _process_function_live_helper( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tool, tool_context, function_call, function_args, invocation_context ) File ".../google/adk/flows/llm_flows/functions.py", line 313, in _process_function_live_helper elif inspect.isasyncgenfunction(tool.func): # ERROR OCCURS HERE ^^^^^^^^^ AttributeError: 'AgentTool' object has no attribute 'func'
Workaround Applied:
Based on introspection and previous successful patching of MCPTool instances (though MCPTools are now handled via MCPToolset in ADK 1.1.1, the patching principle for objects needing a .func attribute seemed relevant), we found that AgentTool instances also:
MCPTool
callable(agent_tool_instance)
False
run_async
We patched the AgentTool instance similarly to MCPTool by adding a .func attribute pointing to its run_async method:
.func
# In agent_config.py, after creating task_execution_agent_tool if hasattr(task_execution_agent_tool, 'run_async') and callable(getattr(task_execution_agent_tool, 'run_async')): task_execution_agent_tool.func = task_execution_agent_tool.run_async logging.info(f"Patched AgentTool '{task_execution_agent_tool.name}' with .func attribute pointing to its run_async method.") else: logging.warning(f"Could not patch AgentTool ...")
This patch resolved the AttributeError: 'AgentTool' object has no attribute 'func' and allowed the TaskExecutionAgentTool to be called successfully.
The KeyError: 'request' Issue and Solution (Related to AgentTool Invocation): After applying the .func patch, a subsequent KeyError: 'request' occurred within AgentTool.run_async (at google/adk/tools/agent_tool.py, line 101). This was resolved by:
KeyError: 'request'
AgentTool.run_async
google/adk/tools/agent_tool.py
request
{"user_goal": "...", "seen_items": [...]}
Expected Behavior / Suggestion:
It seems the ADK's function/tool handling mechanism in google.adk.flows.llm_flows.functions.py might be too generally reliant on a .func attribute for tools that are not caught by more specific type checks (like isinstance(tool, SomeSpecificADKToolType)).
google.adk.flows.llm_flows.functions.py
isinstance(tool, SomeSpecificADKToolType)
args['request']
Clarifying these interaction patterns and ideally making AgentTool work more seamlessly out-of-the-box would significantly improve the developer experience when building complex, delegated multi-agent systems with ADK.