diff --git a/libs/core/langchain_core/utils/function_calling.py b/libs/core/langchain_core/utils/function_calling.py index 4779d262442..e6b70c4ade1 100644 --- a/libs/core/langchain_core/utils/function_calling.py +++ b/libs/core/langchain_core/utils/function_calling.py @@ -646,9 +646,13 @@ def _parse_google_docstring( for line in args_block.split("\n")[1:]: if ":" in line: arg, desc = line.split(":", maxsplit=1) - arg_descriptions[arg.strip()] = desc.strip() + arg = arg.strip() + arg_name, _, _annotations = arg.partition(" ") + if _annotations.startswith("(") and _annotations.endswith(")"): + arg = arg_name + arg_descriptions[arg] = desc.strip() elif arg: - arg_descriptions[arg.strip()] += " " + line.strip() + arg_descriptions[arg] += " " + line.strip() return description, arg_descriptions 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 ba4c50187f1..bf1a4f56337 100644 --- a/libs/core/tests/unit_tests/utils/test_function_calling.py +++ b/libs/core/tests/unit_tests/utils/test_function_calling.py @@ -71,6 +71,19 @@ def function() -> Callable: return dummy_function +@pytest.fixture() +def function_docstring_annotations() -> Callable: + def dummy_function(arg1: int, arg2: Literal["bar", "baz"]) -> None: + """dummy function + + Args: + arg1 (int): foo + arg2: one of 'bar', 'baz' + """ + + return dummy_function + + @pytest.fixture() def runnable() -> Runnable: class Args(ExtensionsTypedDict): @@ -278,6 +291,7 @@ class DummyWithClassMethod: def test_convert_to_openai_function( pydantic: type[BaseModel], function: Callable, + function_docstring_annotations: Callable, dummy_structured_tool: StructuredTool, dummy_tool: BaseTool, json_schema: dict, @@ -311,6 +325,7 @@ def test_convert_to_openai_function( for fn in ( pydantic, function, + function_docstring_annotations, dummy_structured_tool, dummy_tool, json_schema,