google / google/adk-python

[legacy path] Nested pydantic model tool parameter fails under VERTEX_AI when the function also has a fallback-parsed parameter — only with JSON_SCHEMA_FOR_FUNC_DECL disabled

Offen
#6,984 9 Kommentare 0 Reaktionen 1 zugewiesene Person Beansprucht von @llalitkumarrr Auf GitHub ansehen
request clarification tools
Vorherrschende Sprache
Python
Sterne
21.5k
Forks
4k
Ø Merge
1 T. 14 Std.
Gemergte PRs (30 T.)
37

Beschreibung

> **Update (2026-09-03):** Scope corrected — this only affects the legacy declaration path, i.e. when `JSON_SCHEMA_FOR_FUNC_DECL` is disabled. Default `FunctionTool` usage is not affected. See my comment below for the end-to-end reproduction.

## 🔴 Required Information

**Describe the Bug:**
When a tool function has a parameter that the strict parser in `_function_parameter_parse_util` does not handle (e.g. `datetime.datetime`), `from_function_with_options` falls back to building each parameter's schema from pydantic's JSON schema. In that fallback, the `GEMINI_API` variant runs `_sanitize_schema_formats_for_gemini` (which, among other things, turns `$ref`/`$defs` into `ref`/`defs`), but the `VERTEX_AI` variant validates the raw JSON schema directly with `types.Schema.model_validate`. Any *nested* pydantic model parameter therefore fails on Vertex with `$ref` / `$defs` `extra_forbidden` errors, and the surfaced `ValueError` blames that (valid) model parameter rather than the parameter that triggered the fallback.

Net effect: the same tool works on the Gemini Developer API but cannot be registered on Vertex AI.

**Steps to Reproduce:**
1. `pip install google-adk`
2. Run the snippet under *Minimal Reproduction Code*

**Expected Behavior:**
Both variants produce a declaration; on Vertex, `p` is described as an object with nested `addr` (the `GEMINI_API` variant already emits `defs`/`ref` for it).

**Observed Behavior:**
```text
GEMINI_API: True
...
pydantic_core._pydantic_core.ValidationError: 2 validation errors for Schema
properties.addr.$ref
Extra inputs are not permitted [type=extra_forbidden, input_value='#/$defs/Addr', input_type=str]
$defs
Extra inputs are not permitted [type=extra_forbidden, ...]
...
ValueError: Failed to parse the parameter p: __main__.Person of function schedule for automatic function calling. ...
```

**Environment Details:**

- ADK Library Version (pip show google-adk): 2.8.0 (also reproduces on `main`)
- Desktop OS: macOS (arm64)
- Python Version (python -V): 3.14.7

**Model Information:**

- Are you using LiteLLM: No
- Which model is being used: N/A (reproduces at declaration-build time; variant selected explicitly via `from_function_with_options(func, GoogleLLMVariant.VERTEX_AI)`)

---

## 🟡 Optional Information

**Regression:**
Unknown.

**Logs:**
See *Observed Behavior* above.

**Screenshots / Video:**
N/A

**Additional Context:**
- The nested model alone (no fallback-triggering parameter) works on both variants, because the strict parser handles `BaseModel` recursively; the failure needs the function to enter the pydantic fallback path.
- #6381 added Vertex-specific `anyOf` flattening in `_function_tool_declarations.py`, but the fallback path in `_automatic_function_calling_util.from_function_with_options` has no `$ref`/`$defs` handling for `VERTEX_AI`.
- I'm not planning a PR for this one; happy for anyone to pick it up. Reported with AI assistance; reproduced and reviewed by me.

**Minimal Reproduction Code:**
```python
import datetime
import pydantic
from google.adk.tools._automatic_function_calling_util import from_function_with_options
from google.adk.utils.variant_utils import GoogleLLMVariant

class Addr(pydantic.BaseModel):
city: str

class Person(pydantic.BaseModel):
name: str
addr: Addr

def schedule(p: Person, when: datetime.datetime) -> str:
"""Schedule a visit.

Args:
p: the person
when: visit time
"""
return "ok"

print("GEMINI_API:", from_function_with_options(schedule, GoogleLLMVariant.GEMINI_API).parameters is not None)
print("VERTEX_AI :", from_function_with_options(schedule, GoogleLLMVariant.VERTEX_AI).parameters is not None)
```

**How often has this issue occurred?:**

- Always (100%)

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.