Executes tool use blocks in parallel and returns tool result blocks.
Takes ToolUse content blocks from an assistant message, runs the
corresponding tools concurrently, and returns ToolResult content blocks
ready to be placed in a user message.
Omni's generation loop uses this internally, but it's also useful
when you handle tool execution yourself — for example, with schema-only
tools where the loop breaks and hands ToolUse blocks back to you:
# Schema-only tool — loop breaks, response contains ToolUse blocks
tool_uses = Enum.filter(response.message.content, &match?(%ToolUse{}, &1))
# Build a tool map and execute
tool_map = %{"search" => search_tool, "fetch" => fetch_tool}
results = Tool.Runner.run(tool_uses, tool_map)
# Place results in the next user message
message = Omni.message(role: :user, content: results)
Summary
Functions
Executes tool uses in parallel, returning results in input order.
Functions
@spec run( [Omni.Content.ToolUse.t()], %{required(String.t()) => Omni.Tool.t()}, timeout() ) :: [ Omni.Content.ToolResult.t() ]
Executes tool uses in parallel, returning results in input order.
tool_map is a %{name => %Tool{}} map keyed by tool name strings. Each
tool use is looked up by name — missing tools (hallucinated names), tools
that raise, and tools that exceed the timeout all produce error results
with is_error: true. Every input ToolUse produces exactly one output
ToolResult, always in the same order.
The default timeout is 5000ms per tool.