diff --git a/src/google/adk/tools/_automatic_function_calling_util.py b/src/google/adk/tools/_automatic_function_calling_util.py index 392e256b33..aef4424a49 100644 --- a/src/google/adk/tools/_automatic_function_calling_util.py +++ b/src/google/adk/tools/_automatic_function_calling_util.py @@ -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 @@ -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 diff --git a/tests/unittests/tools/test_from_function_with_options.py b/tests/unittests/tools/test_from_function_with_options.py index a3f68ee11c..2146dec7db 100644 --- a/tests/unittests/tools/test_from_function_with_options.py +++ b/tests/unittests/tools/test_from_function_with_options.py @@ -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