Graph node for executing tool calls from AI messages.
Extracts tool_calls from the last %Message.AI{}, dispatches each
call to its matching %LangEx.Tool{} in parallel, and returns
%Message.Tool{} results.
Control-flow tools
A tool function may return a %LangEx.Command{} instead of a plain
value. The command's :update is merged into the graph state (a tool
updating active_agent, appending its own messages, etc.) and its
:goto joins the node's routing. A %Message.Tool{} correlated by
tool_call_id is guaranteed for every call — one is synthesized when
the command does not carry it — so the provider always sees a reply
for each requested call. When no tool returns a command the node keeps
returning a plain %{messages_key => [...]} update.
Usage in a graph
tools = [
%LangEx.Tool{
name: "get_weather",
description: "Get weather for a city",
parameters: %{...},
function: fn %{"city" => city} -> %{temp: 22, city: city} end
}
]
graph =
Graph.new(messages: {[], &Message.add_messages/2})
|> Graph.add_node(:agent, ChatModel.node(model: "gpt-4o", tools: tools))
|> Graph.add_node(:tools, LangEx.Tool.Node.node(tools))
|> Graph.add_conditional_edges(:agent, &LangEx.Tool.Node.tools_condition/1, %{
tools: :tools,
__end__: :__end__
})
|> Graph.add_edge(:__start__, :agent)
|> Graph.add_edge(:tools, :agent)
|> Graph.compile()Options
:messages_key— state key holding the message list (default:messages):handle_tool_errors— error handling strategy (defaulttrue):true— catch all errors, return error%Message.Tool{}false— let exceptions propagateString.t()— catch all, return this string as error content(Exception.t() -> String.t())— custom handler
:wrap_tool_call— interceptorfn(request, execute) -> result:max_concurrency— cap on parallel tool tasks (defaultSystem.schedulers_online()):timeout— per-tool timeout in ms (default30_000)
Summary
Functions
Returns a graph node function that executes tool calls.
Routing condition for tool-calling workflows.
Types
@type error_handler() :: boolean() | String.t() | (Exception.t() -> String.t())
Functions
@spec node( [LangEx.Tool.t()], keyword() ) :: (map() -> map())
Returns a graph node function that executes tool calls.
The returned function reads the last %Message.AI{} from state,
executes each tool_call in parallel, and returns the results
as %Message.Tool{} messages under the configured messages key.
Routing condition for tool-calling workflows.
Returns :tools when the last message has pending tool calls,
:__end__ otherwise. Use with Graph.add_conditional_edges/4.
Options
:messages_key— state key (default:messages)