From 41d1c352709d3a22e192a185bf8632efab788d09 Mon Sep 17 00:00:00 2001 From: Nick Hollon Date: Wed, 27 May 2026 18:57:19 -0400 Subject: [PATCH] Wire subagent_name through StructuredTool.from_function StructuredTool.from_function now accepts subagent_name= as a named parameter and passes it to the constructed StructuredTool instance. Completes the trio of subagent_name entry points: BaseTool attribute, @tool decorator, StructuredTool.from_function. --- libs/core/langchain_core/tools/structured.py | 4 ++ libs/core/tests/unit_tests/test_tools.py | 44 ++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/libs/core/langchain_core/tools/structured.py b/libs/core/langchain_core/tools/structured.py index 8b67e3b4547..5b7741b6036 100644 --- a/libs/core/langchain_core/tools/structured.py +++ b/libs/core/langchain_core/tools/structured.py @@ -143,6 +143,7 @@ class StructuredTool(BaseTool): response_format: Literal["content", "content_and_artifact"] = "content", parse_docstring: bool = False, error_on_invalid_docstring: bool = False, + subagent_name: str | Callable[[ToolCall], str] | None = None, **kwargs: Any, ) -> StructuredTool: """Create tool from a given function. @@ -171,6 +172,8 @@ class StructuredTool(BaseTool): to parse parameter descriptions from Google Style function docstrings. error_on_invalid_docstring: if `parse_docstring` is provided, configure whether to raise `ValueError` on invalid Google Style docstrings. + subagent_name: Name of the subagent this tool should route to (static + string or callable that resolves the name from the `ToolCall`). **kwargs: Additional arguments to pass to the tool Returns: @@ -248,6 +251,7 @@ class StructuredTool(BaseTool): description=description_, return_direct=return_direct, response_format=response_format, + subagent_name=subagent_name, **kwargs, ) diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index f53a5801aa2..d5e9b37b60e 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -3813,3 +3813,47 @@ def test_tool_decorator_subagent_name_defaults_to_none() -> None: return str(x) assert plain.subagent_name is None + + +# --- StructuredTool.from_function subagent_name passthrough tests --- + + +def test_structured_tool_from_function_passes_subagent_name_static() -> None: + def my_func(x: int) -> str: + return f"x={x}" + + t = StructuredTool.from_function( + func=my_func, + name="my_func", + description="Test tool for subagent_name passthrough.", + subagent_name="x_agent", + ) + assert t.subagent_name == "x_agent" + + +def test_structured_tool_from_function_passes_subagent_name_callable() -> None: + def my_func(target: str) -> str: + return f"target={target}" + + def resolver(call: ToolCall) -> str: + return str(call["args"]["target"]) + + t = StructuredTool.from_function( + func=my_func, + name="my_func", + description="Test tool for callable subagent_name.", + subagent_name=resolver, + ) + assert t.subagent_name is resolver + + +def test_structured_tool_from_function_subagent_name_defaults_to_none() -> None: + def my_func(x: int) -> str: + return str(x) + + t = StructuredTool.from_function( + func=my_func, + name="my_func", + description="Plain tool.", + ) + assert t.subagent_name is None