diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index c664ec03e3d..aa288bedc53 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -788,9 +788,12 @@ def _recursive_set_additional_properties_false( schema["additionalProperties"] = False # Recursively check 'properties' and 'items' if they exist + if "anyOf" in schema: + for sub_schema in schema["anyOf"]: + _recursive_set_additional_properties_false(sub_schema) if "properties" in schema: - for value in schema["properties"].values(): - _recursive_set_additional_properties_false(value) + for sub_schema in schema["properties"].values(): + _recursive_set_additional_properties_false(sub_schema) if "items" in schema: _recursive_set_additional_properties_false(schema["items"]) diff --git a/libs/core/tests/unit_tests/utils/test_function_calling.py b/libs/core/tests/unit_tests/utils/test_function_calling.py index 126c1753f4e..f75ae304937 100644 --- a/libs/core/tests/unit_tests/utils/test_function_calling.py +++ b/libs/core/tests/unit_tests/utils/test_function_calling.py @@ -497,6 +497,61 @@ def test_convert_to_openai_function_nested_strict() -> None: assert actual == expected +def test_convert_to_openai_function_strict_union_of_objects_arg_type() -> None: + class NestedA(BaseModel): + foo: str + + class NestedB(BaseModel): + bar: int + + class NestedC(BaseModel): + baz: bool + + def my_function(my_arg: Union[NestedA, NestedB, NestedC]) -> None: + """Dummy function.""" + + expected = { + "name": "my_function", + "description": "Dummy function.", + "parameters": { + "properties": { + "my_arg": { + "anyOf": [ + { + "properties": {"foo": {"title": "Foo", "type": "string"}}, + "required": ["foo"], + "title": "NestedA", + "type": "object", + "additionalProperties": False, + }, + { + "properties": {"bar": {"title": "Bar", "type": "integer"}}, + "required": ["bar"], + "title": "NestedB", + "type": "object", + "additionalProperties": False, + }, + { + "properties": {"baz": {"title": "Baz", "type": "boolean"}}, + "required": ["baz"], + "title": "NestedC", + "type": "object", + "additionalProperties": False, + }, + ] + } + }, + "required": ["my_arg"], + "type": "object", + "additionalProperties": False, + }, + "strict": True, + } + + actual = convert_to_openai_function(my_function, strict=True) + assert actual == expected + + json_schema_no_description_no_params = { "title": "dummy_function", }