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.
This commit is contained in:
Nick Hollon
2026-05-27 18:57:19 -04:00
parent df2b4cfdc4
commit 41d1c35270
2 changed files with 48 additions and 0 deletions

View File

@@ -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,
)

View File

@@ -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