Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/google/adk/tools/_automatic_function_calling_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@ def from_function_with_options(
parameters_json_schema[name] = types.Schema.model_validate(
json_schema_dict
)
if param.default is not inspect.Parameter.empty:
if param.default is not None:
parameters_json_schema[name].default = param.default
else:
parameters_json_schema[name].nullable = True
except Exception as e:
_function_parameter_parse_util._raise_for_unsupported_param(
param, func.__name__, e
Expand All @@ -392,6 +397,11 @@ def from_function_with_options(
type='OBJECT',
properties=parameters_json_schema,
)
declaration.parameters.required = (
_function_parameter_parse_util._get_required_fields(
declaration.parameters
)
)

if variant == GoogleLLMVariant.GEMINI_API:
return declaration
Expand Down
33 changes: 33 additions & 0 deletions tests/unittests/tools/test_from_function_with_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,36 @@ async def test_function(param: str) -> AsyncGenerator[Dict[str, str], None]:
# VERTEX_AI should extract yield type (Dict[str, str]) from AsyncGenerator
assert declaration.response is not None
assert declaration.response.type == types.Type.OBJECT


def test_required_fields_set_in_json_schema_fallback():
"""Test that required fields are populated when the json_schema fallback path is used.

When a parameter has a complex union type (e.g. list[str] | None) that
_parse_schema_from_parameter can't handle, from_function_with_options falls
back to the parameters_json_schema branch. This test verifies that the
required fields are correctly populated in that fallback branch.

Regression test for https://github.com/google/adk-python/issues/4798
"""

def complex_tool(
query: str,
mode: str = "default",
tags: list[str] | None = None,
) -> str:
"""A tool where one param has a complex union type."""
return query

declaration = _automatic_function_calling_util.from_function_with_options(
complex_tool, GoogleLLMVariant.GEMINI_API
)

assert declaration.name == 'complex_tool'
assert declaration.parameters.type == 'OBJECT'
# 'query' has no default → must be required
assert declaration.parameters.required is not None
assert 'query' in declaration.parameters.required
# 'mode' and 'tags' have defaults → must NOT be required
assert 'mode' not in declaration.parameters.required
assert 'tags' not in declaration.parameters.required