diff --git a/libs/core/langchain_core/tools/base.py b/libs/core/langchain_core/tools/base.py index ff264edac32..cf755284614 100644 --- a/libs/core/langchain_core/tools/base.py +++ b/libs/core/langchain_core/tools/base.py @@ -605,6 +605,9 @@ class ChildTool(BaseTool): def _to_args_and_kwargs( self, tool_input: Union[str, dict], tool_call_id: Optional[str] ) -> tuple[tuple, dict]: + if self.args_schema is not None and not get_fields(self.args_schema): + # StructuredTool with no args + return (), {} tool_input = self._parse_input(tool_input, tool_call_id) # For backwards compatibility, if run_input is a string, # pass as a positional argument. diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index b331abea7da..b21fc139a21 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -575,6 +575,19 @@ def test_structured_tool_from_function_with_run_manager() -> None: ) +def test_structured_tool_from_parameterless_function() -> None: + """Test parameterless function of structured tool.""" + + def foo() -> str: + """Docstring.""" + return "invoke foo" + + structured_tool = StructuredTool.from_function(foo) + + assert structured_tool.run({}) == "invoke foo" + assert structured_tool.run("") == "invoke foo" + + def test_named_tool_decorator() -> None: """Test functionality when arguments are provided as input to decorator."""