Files
langgraph/libs/prebuilt/tests
Eugene YurtsevandGitHub 50601dc02c feat(prebuilt): Add structured output tools to ToolNode (#5899)
* Add structured output tools to ToolNode
* Fix default tool node name to match the actual default ('tools')
* Update doc-strings to explain what inputs/outputs are for the ToolNode.
* Mark internal attributes as private (potentially breaking -- although hopefully users aren't accessing these)


## Decisions points

* OK with two properties? Done since users may be relying on
`tools_by_name` and expanding the return type will break user code.

## Changes in public/private interface

### Marked as public

* Make `tools_by_name` an official public property
* Make `structured_output_tools` a public property

### Marked as private

There should be no reason why users are accessing these attributes

```python
_tool_to_state_args
_tool_to_store_arg
_handle_tool_errors
_messages_key
```


### Usage

```python

    class OutputSchema(BaseModel):
        name: str
        age: int
        location: str

    tool_node = ToolNode([OutputSchema])

    # Test that the structured output tool is registered correctly
    assert "OutputSchema" in tool_node.structured_output_tools

    # Create a tool call that matches the schema
    tool_call = {
        "name": "OutputSchema",
        "args": {"name": "Alice", "age": 30, "location": "NYC"},
        "id": "call_123",
        "type": "tool_call",
    }

    # Test sync execution
    result = tool_node.invoke(
        {"messages": [AIMessage(content="", tool_calls=[tool_call])]}
    )

    # Should return a Command with structured response
    assert isinstance(result, list)
    assert len(result) == 1
    command = result[0]
    assert isinstance(command, Command)

    # Check the update structure
    assert "messages" in command.update
    assert "structured_response" in command.update

    # Check the tool message
    tool_message = command.update["messages"][0]
    assert isinstance(tool_message, ToolMessage)
    assert tool_message.name == "OutputSchema"
    assert tool_message.tool_call_id == "call_123"

    # Check the structured response
    structured_response = command.update["structured_response"]
    assert isinstance(structured_response, OutputSchema)
    assert structured_response.name == "Alice"
    assert structured_response.age == 30
    assert structured_response.location == "NYC"
```
2025-08-13 15:16:53 -04:00
..
2025-07-21 10:06:23 -04:00