Getting started

Mistri is an agent harness for Ruby applications. It runs the model loop, executes tools, streams every event, and persists sessions to a store you own. Zero runtime dependencies.

Terminal window
$ gem install mistri

A first agent

weather.rb
require "mistri"
weather = Mistri::Tool.define(
"get_weather", "Current weather for a city.",
schema: -> { string :city, "City name", required: true },
) do |args|
Weather.for(args["city"])
end
agent = Mistri.agent("claude-opus-4-8", tools: [weather])
agent.run("What should I wear in Lahore today?") do |event|
print event.delta if event.type == :text_delta
end

Mistri.agent infers the provider from the model id (claude-*, gpt-*, gemini-*) and reads the matching key from ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY. Pass api_key: to set it explicitly.

What a run returns

Every run returns a Result:

result = agent.run("Name three Ruby web frameworks.")
result.text # the final answer
result.completed? # finished cleanly
result.awaiting_approval? # parked on a gated tool
result.aborted? # stopped by a signal or budget
result.errored? # gave up after retries

Task-mode runs also carry result.output, the parsed and validated object.

Images and provider options

Images are first-class on all three providers, and anything provider-specific passes straight through:

bytes = File.binread("chart.png")
photo = Mistri::Content::Image.from_bytes(bytes, mime_type: "image/png")
agent.run("What trend does this chart show?", images: [photo])
Mistri.agent("gpt-5.5",
provider_options: { reasoning: { effort: "high" } })
Mistri.agent("claude-opus-4-8", provider_options: { cache: false })