Omni.Tool.Runner (Omni v1.3.0)

Copy Markdown View Source

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

run(tool_uses, tool_map, timeout \\ 5000)

@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.