From df46c82ae2c732203cefc541bfed31e9d4ebdf12 Mon Sep 17 00:00:00 2001 From: Yu Zhong Date: Wed, 22 Oct 2025 23:31:08 +0800 Subject: [PATCH] feat(core): automatic set required to include all properties in strict mode (#32930) --- libs/core/langchain_core/utils/function_calling.py | 4 ++++ .../tests/unit_tests/utils/test_function_calling.py | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index 8f5bee4f5e..7a9c500e52 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -425,6 +425,10 @@ def convert_to_openai_function( oai_function["parameters"] = _recursive_set_additional_properties_false( oai_function["parameters"] ) + # All fields must be `required` + fields = oai_function["parameters"].get("properties", {}) + if isinstance(fields, dict) and fields: + oai_function["parameters"]["required"] = list(fields.keys()) return oai_function 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 3fdfd63e08..c4edce261b 100644 --- a/libs/core/tests/unit_tests/utils/test_function_calling.py +++ b/libs/core/tests/unit_tests/utils/test_function_calling.py @@ -1155,3 +1155,16 @@ def test_convert_to_openai_function_nested_strict_2() -> None: actual = convert_to_openai_function(my_function, strict=True) assert actual == expected + + +def test_convert_to_openai_function_strict_required() -> None: + class MyModel(BaseModel): + """Dummy schema.""" + + arg1: int = Field(..., description="foo") + arg2: str | None = Field(None, description="bar") + + expected = ["arg1", "arg2"] + func = convert_to_openai_function(MyModel, strict=True) + actual = func["parameters"]["required"] + assert actual == expected