[PR #6707] feat: support dynamic tools via callable in tool node #5230

Closed
opened 2026-02-20 17:51:25 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langchain-ai/langgraph/pull/6707

State: closed
Merged: No


Add support for dynamic tools in ToolNode. Instead of passing a static list of tools, you can now pass a callable
that returns a list of tools. The callable is invoked on each ToolNode invocation, allowing the available tools to change
between calls.

This is important because it enables dynamic registration of tools for agents created w/ create_agent

Key changes:

  • ToolNode tools parameter now accepts Sequence[BaseTool | Callable] | Callable[[], Sequence[BaseTool]]
  • Tools provider is detected by checking for a callable with no required arguments
  • Dynamic providers must return BaseTool instances (not plain functions)
  • All existing features (state injection, error handling, etc.) work with dynamic tools

Still TODO

  • Look into optimizations, especially re redundant signature inspection when the list of tools is static :)

Sample functionality :)

from langchain_core.tools import tool                                                                              
from langgraph.prebuilt import ToolNode                                                                            
                                                                                                                   
@tool                                                                                                              
def add(a: int, b: int) -> int:                                                                                    
    """Add two numbers."""                                                                                         
    return a + b                                                                                                   
                                                                                                                   
@tool                                                                                                              
def multiply(a: int, b: int) -> int:                                                                               
    """Multiply two numbers."""                                                                                    
    return a * b                                                                                                   
                                                                                                                   
# Tools can change dynamically based on external state                                                             
available_tools = [add]                                                                                            
                                                                                                                   
def get_tools():                                                                                                   
    return available_tools                                                                                         
                                                                                                                   
# Pass a callable instead of a list                                                                                
tool_node = ToolNode(get_tools)                                                                                    
                                                                                                                   
# Initially only "add" is available                                                                                
print(tool_node.tools_by_name.keys())  # dict_keys(['add'])                                                        
                                                                                                                   
# Later, add more tools                                                                                            
available_tools.append(multiply)                                                                                   
                                                                                                                   
# Now both tools are available (no restart needed)                                                                 
print(tool_node.tools_by_name.keys())  # dict_keys(['add', 'multiply'])              
**Original Pull Request:** https://github.com/langchain-ai/langgraph/pull/6707 **State:** closed **Merged:** No --- Add support for dynamic tools in `ToolNode`. Instead of passing a static list of tools, you can now pass a callable that returns a list of tools. The callable is invoked on each `ToolNode` invocation, allowing the available tools to change between calls. This is important because it enables dynamic registration of tools for agents created w/ `create_agent` Key changes: - ToolNode tools parameter now accepts `Sequence[BaseTool | Callable] | Callable[[], Sequence[BaseTool]]` - Tools provider is detected by checking for a callable with no required arguments - Dynamic providers must return `BaseTool` instances (not plain functions) - All existing features (state injection, error handling, etc.) work with dynamic tools Still TODO * Look into optimizations, especially re redundant signature inspection when the list of tools is static :) Sample functionality :) ```py from langchain_core.tools import tool from langgraph.prebuilt import ToolNode @tool def add(a: int, b: int) -> int: """Add two numbers.""" return a + b @tool def multiply(a: int, b: int) -> int: """Multiply two numbers.""" return a * b # Tools can change dynamically based on external state available_tools = [add] def get_tools(): return available_tools # Pass a callable instead of a list tool_node = ToolNode(get_tools) # Initially only "add" is available print(tool_node.tools_by_name.keys()) # dict_keys(['add']) # Later, add more tools available_tools.append(multiply) # Now both tools are available (no restart needed) print(tool_node.tools_by_name.keys()) # dict_keys(['add', 'multiply']) ```
yindo added the pull-request label 2026-02-20 17:51:25 -05:00
yindo closed this issue 2026-02-20 17:51:25 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#5230