From 9c1d65695ec8825c3e987152126be1aa7aa522f0 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 29 Apr 2026 21:07:00 -0400 Subject: [PATCH] fix(prebuilt): default ToolRuntime tools to empty list (#7650) Makes `ToolRuntime.tools` default to an empty list when not provided, which avoids requiring callers and tests to pass it explicitly. Adds a focused regression test covering direct `ToolRuntime` construction without `tools`. Created with [Deep Agents CLI](https://docs.langchain.com/oss/python/deepagents/cli/overview) using gpt-5.4 (provider: openai). --- libs/prebuilt/langgraph/prebuilt/tool_node.py | 4 ++-- libs/prebuilt/tests/test_tool_node.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libs/prebuilt/langgraph/prebuilt/tool_node.py b/libs/prebuilt/langgraph/prebuilt/tool_node.py index 3137309da..f5aa4d86d 100644 --- a/libs/prebuilt/langgraph/prebuilt/tool_node.py +++ b/libs/prebuilt/langgraph/prebuilt/tool_node.py @@ -44,7 +44,7 @@ import inspect import json from collections.abc import Awaitable, Callable from copy import copy, deepcopy -from dataclasses import dataclass, replace +from dataclasses import dataclass, field, replace from types import UnionType from typing import ( TYPE_CHECKING, @@ -1723,9 +1723,9 @@ class ToolRuntime(_DirectlyInjectedToolArg, Generic[ContextT, StateT]): context: ContextT config: RunnableConfig stream_writer: StreamWriter - tools: list[BaseTool] tool_call_id: str | None store: BaseStore | None + tools: list[BaseTool] = field(default_factory=list) execution_info: ExecutionInfo | None = None server_info: ServerInfo | None = None diff --git a/libs/prebuilt/tests/test_tool_node.py b/libs/prebuilt/tests/test_tool_node.py index c30787f74..acc5522fa 100644 --- a/libs/prebuilt/tests/test_tool_node.py +++ b/libs/prebuilt/tests/test_tool_node.py @@ -2016,6 +2016,19 @@ async def test_tool_node_inject_runtime_dynamic_tool_via_wrap_tool_call_async() assert tool_message.tool_call_id == "call_dynamic_2" +def test_tool_runtime_defaults_tools_to_empty_list() -> None: + runtime = ToolRuntime( + state={}, + context=None, + config={}, + stream_writer=lambda *args, **kwargs: None, + tool_call_id=None, + store=None, + ) + + assert runtime.tools == [] + + def test_tool_runtime_forwards_execution_info_server_info_and_tools() -> None: """Test that execution_info, server_info, and tools are forwarded from Runtime to ToolRuntime.""" from langgraph.runtime import ExecutionInfo, ServerInfo