Anthropic::ToolRunner
Automatic tool execution loop
Runs a conversation with Claude where tools are automatically executed and their results are fed back to Claude until the conversation completes.
Supports auto-compaction to manage conversation length in extended sessions.
# Basic usage - iterate all messages
runner = client.beta.messages.tool_runner(
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [Anthropic::MessageParam.user("What's the weather?")],
tools: [weather_tool]
)
runner.each_message { |msg| pp msg.content }
# Step-by-step control
runner = client.beta.messages.tool_runner(...)
while msg = runner.next_message
pp msg.content
if some_condition
runner.feed_messages([MessageParam.user("Actually, also check...")])
end
end
# Streaming with tool execution
runner.each_streaming do |event|
case event
when Anthropic::ContentBlockDeltaEvent
print event.text # event.text is a streaming helper, not Message#text
end
end
Constructors
Instance methods
Iterate through messages, auto-executing tools
Yields each message response, including those with tool use. Continues until max_iterations is reached or Claude stops using tools.
If compaction is enabled, automatically compresses conversation when token usage exceeds the configured threshold.
Note: This resets the runner state before iterating.
Iterate through streaming events while auto-executing tools
Similar to each_message but yields streaming events in real-time. Tool execution still happens between streaming responses.
runner.each_streaming do |event|
case event
when Anthropic::ContentBlockDeltaEvent
if text = event.text
print text
end
end
end
Add messages to the conversation mid-loop
Use this to inject additional context or instructions during tool execution. Messages are added after the current tool results.
while msg = runner.next_message
# Check content and inject more messages if needed
runner.feed_messages([
Anthropic::MessageParam.user("Here's additional context: ..."),
])
end
Get final message after all tool execution
Runs the entire conversation and returns the last message.
Get the next message in the tool execution loop
Returns nil when the loop is complete (no more tool calls or max iterations). Use this for fine-grained control over the execution loop.
while msg = runner.next_message
pp msg.content
# Optionally inject messages
runner.feed_messages([...]) if some_condition
end
Get current runner parameters (read-only)
Useful for inspecting or logging the current state.
Run until finished and return all messages
Executes the entire tool loop and returns all messages generated.
messages = runner.run_until_finished
messages.each { |msg| pp msg.content }