馃敶 Required Information
Describe the Bug:
Annotated parameters breaks _preprocess_args when using recursive type aliases or any unresolvable forward reference on the fallback path when we are unable to get_type_hints() in src/google/adk/tools/function_tool.py, fixed by PR: #6879
Steps to Reproduce:
- Declare a tool containing parameter with a recursive type:
def get_tools() -> list[FunctionTool}:
Recursive = Union[int, str, list["Recursive"]]
def fn(
user: Annotated[UserModel, Field(description="A user")],
data: Recursive = None,
) -> dict:
return {"name": user.name, "type": type(user).__name__}
- Try and call the tool
Expected Behavior:
user is converted to a UserModel instance before the function runs (as it is on the normal path where get_type_hints() succeeds and strips the Annotated wrapper). The tool executes and returns:
{"name": "Alice", "type": "UserModel"}
Observed Behavior:
get_type_hints() raises NameError, so _preprocess_args falls back to the raw param.annotation, which is still Annotated[UserModel, ...]wrapped. None of the conversion branches recognise the wrapper, so the dict is passed through unconverted:
# tool._preprocess_args({"user": {"name": "Alice", "age": 30}})
{'user': {'name': 'Alice', 'age': 30}} # still a dict, not a UserModel
When the tool body then accesses user.name, it raises:
Traceback (most recent call last):
...
File "src/google/adk/tools/function_tool.py", line 353, in run_async
return await self._invoke_callable(self.func, args_to_call)
File "src/google/adk/tools/function_tool.py", line 378, in _invoke_callable
return target(**args_to_call)
File ".../your_tool.py", line 19, in fn
return {"name": user.name, "type": type(user).__name__}
^^^^^^^^^
AttributeError: 'dict' object has no attribute 'name'
(The line numbers in function_tool.py are relative to the current main.)
Environment Details:
- ADK Library Version: 2.7.1
- Desktop OS: MacOS
- Python Version: 3.13
Model Information:
- Are you using LiteLLM: No
- Which model is being used: gemini-3.7-flash
馃煛 Optional Information
Regression:
Not a regression.
How often has this issue occurred?:
馃敶 Required Information
Describe the Bug:
Annotated parameters breaks
_preprocess_argswhen using recursive type aliases or any unresolvable forward reference on the fallback path when we are unable toget_type_hints()insrc/google/adk/tools/function_tool.py, fixed by PR: #6879Steps to Reproduce:
Expected Behavior:
useris converted to aUserModelinstance before the function runs (as it is on the normal path whereget_type_hints()succeeds and strips theAnnotatedwrapper). The tool executes and returns:{"name": "Alice", "type": "UserModel"}Observed Behavior:
get_type_hints()raisesNameError, so_preprocess_argsfalls back to the rawparam.annotation, which is stillAnnotated[UserModel, ...]wrapped. None of the conversion branches recognise the wrapper, so the dict is passed through unconverted:When the tool body then accesses
user.name, it raises:(The line numbers in
function_tool.pyare relative to the currentmain.)Environment Details:
Model Information:
馃煛 Optional Information
Regression:
Not a regression.
How often has this issue occurred?: