Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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/_function_parameter_parse_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from google.genai import types
import pydantic
from enum import Enum

from ..utils.variant_utils import GoogleLLMVariant

Expand Down Expand Up @@ -145,6 +146,15 @@ def _parse_schema_from_parameter(
schema.type = _py_builtin_type_to_schema_type[param.annotation]
_raise_if_schema_unsupported(variant, schema)
return schema
if isinstance(param.annotation, type) and issubclass(param.annotation, Enum):
schema.type = types.Type.STRING
schema.enum = [e.value for e in param.annotation]
if param.default is not inspect.Parameter.empty:
if not _is_default_value_compatible(param.default, param.annotation):
raise ValueError(default_value_error_msg)
schema.default = param.default

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The handling of default values for Enum parameters is incorrect and will lead to a ValueError.

There are two issues with the current implementation:

  1. The _is_default_value_compatible function does not support Enum types and will always return False, causing an exception to be raised on line 154 if a default value is present.
  2. On line 155, schema.default is assigned the Enum member itself (param.default) instead of its value. Since the schema type is STRING, the default value should also be a string (i.e., param.default.value).

The suggested change below fixes both problems by performing the compatibility check locally and ensuring the correct value is assigned to schema.default.

Suggested change
if not _is_default_value_compatible(param.default, param.annotation):
raise ValueError(default_value_error_msg)
schema.default = param.default
default_value = param.default.value if isinstance(param.default, Enum) else param.default
if default_value not in schema.enum:
raise ValueError(default_value_error_msg)
schema.default = default_value

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

This is due to reason that the default value get wipped of by this function

Copy link
Author

@SOORAJTS2001 SOORAJTS2001 Oct 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per this PR Gemini API now supports default value, hence commented the above function

_raise_if_schema_unsupported(variant, schema)
return schema
if (
get_origin(param.annotation) is Union
# only parse simple UnionType, example int | str | float | bool
Expand Down
20 changes: 19 additions & 1 deletion tests/unittests/tools/test_build_function_declaration.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# TODO: crewai requires python 3.10 as minimum
# from crewai_tools import FileReadTool
from pydantic import BaseModel

from enum import Enum

def test_string_input():
def simple_function(input_str: str) -> str:
Expand Down Expand Up @@ -219,6 +219,24 @@ def simple_function(
assert function_decl.parameters.properties['input_dir'].type == 'ARRAY'
assert function_decl.parameters.properties['input_dir'].items.type == 'OBJECT'

def test_enums():

class InputEnum(Enum):
AGENT = "agent"
TOOL = "tool"

def simple_function(input:InputEnum):
return input.value

function_decl = _automatic_function_calling_util.build_function_declaration(
func=simple_function
)

assert function_decl.name == 'simple_function'
assert function_decl.parameters.type == 'OBJECT'
assert function_decl.parameters.properties['input'].type == 'STRING'
assert function_decl.parameters.properties['input'].enum == ['agent', 'tool']
Comment on lines 223 to 240

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The new test for enums only covers the basic case without a default value. To ensure the implementation is robust and to prevent regressions, it's important to add test cases for function parameters with default values. This would have helped catch the bug with default value handling in the current implementation.

Please consider adding tests for the following scenarios:

  • A valid default value provided as an enum member (e.g., param: MyEnum = MyEnum.VALUE).
  • A valid default value provided as a raw value (e.g., param: MyEnum = 'value').
  • An invalid default value, which should raise a ValueError.

Here's an example of how you could structure these tests:

import pytest

def test_enum_with_default_member():
    class InputEnum(Enum):
        AGENT = "agent"
        TOOL = "tool"

    def simple_function(input: InputEnum = InputEnum.AGENT):
        return input.value

    function_decl = _automatic_function_calling_util.build_function_declaration(
        func=simple_function
    )
    assert function_decl.parameters.properties['input'].default == 'agent'

def test_enum_with_invalid_default():
    class InputEnum(Enum):
        AGENT = "agent"
        TOOL = "tool"

    def simple_function(input: InputEnum = "invalid_default"):
        return input.value

    with pytest.raises(ValueError):
        _automatic_function_calling_util.build_function_declaration(
            func=simple_function
        )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test cases for default value as well as invalid value



def test_basemodel_list():
class ChildInput(BaseModel):
Expand Down