google / google/adk-python

Annotated parameters breaks `_preprocess_args` when using recursive type aliases or any unresolvable forward reference

Aperta
#6,878 3 commenti 3 reazioni 1 assegnatario Rivendicata da @surajksharma07 Vedi su GitHub
core request clarification
Lingua principale
Python
Stelle
21.5k
Fork
4k
Merge medio
1g 14h
PR unite (30g)
37

Descrizione

## 🔴 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: https://github.com/google/adk-python/pull/6879

**Steps to Reproduce:**

1. Declare a tool containing parameter with a recursive type:
```python
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__}
```

2. 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:

```python
{"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:

```python
# 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?:**

- Always (100%)

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.