Human approval
Mark a tool needs_approval: true, or give it a predicate on the
arguments, and the run suspends instead of executing it. Nothing sleeps and
no thread waits: the run returns immediately with the call parked.
send_gift = Mistri::Tool.define( "send_gift", "Sends a real gift.", needs_approval: ->(args) { args["amount"].to_i > 100 },) do |args| Gifts.send!(args)end
result = agent.run("Send Ana a $200 gift")result.awaiting_approval? # => true; nothing executedresult.pending # the calls waiting on a decisionDeciding
The decision is a one-line session write from any process, any time later. A controller action is enough:
session = Mistri::Session.new(store:, id: session_id)session.approve(call_id)session.deny(call_id, note: "over budget this quarter")Resuming
resume settles the parked calls and carries on. Approved calls execute;
denied calls answer the model with your note, in band, so it can adjust.
Mistri.agent("claude-opus-4-8", tools: tools, session: session) .resumeThe harness renders nothing. It emits an :approval_needed event and your
app draws the buttons, which is exactly the approval demo on the front
page.