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.
$ gem install mistriA first agent
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_deltaendMistri.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 answerresult.completed? # finished cleanlyresult.awaiting_approval? # parked on a gated toolresult.aborted? # stopped by a signal or budgetresult.errored? # gave up after retriesTask-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 })