Runtime control

Stopping

Trip an abort signal from anywhere: another thread, a job, a Stop button. The partial turn persists and the session resumes cleanly later. A long-running report agent can be cut off the moment someone closes the tab.

signal = Mistri::AbortSignal.new
agent.run("Compile the quarterly reliability report.", signal: signal)
# elsewhere
signal.abort!

Budgets

Ceilings are opt-in and off by default. A run that hits one stops with result.stopped_by_budget? true, distinct from a user abort, and a message naming the ceiling it reached:

budget = Mistri::Budget.new(turns: 20, cost_usd: 2.00)
agent = Mistri.agent("claude-opus-4-8", budget: budget)

tokens: and wall_clock: are there when you need them. Thinking is never constrained by default.

Retries

Transient failures (429s, 5xx, timeouts, dropped streams) retry with backoff, invisibly to the model. So does a completion that answers with nothing at all, an intermittent provider behavior that would otherwise end the run in silence. On by default; tune or disable per agent:

policy = Mistri::RetryPolicy.new(attempts: 5)
Mistri.agent("claude-opus-4-8", retries: policy)
Mistri.agent("claude-opus-4-8", retries: false)

Each retried attempt emits a :retry event carrying attempt, max_attempts, and delay in seconds, so a UI can show “reconnecting, attempt 2 of 3.” The failed attempt’s own :error is held back: :error reaches your stream only when the run truly gives up, so you never render an error the harness is about to walk back. A run that exhausts its retries returns result.errored? with the error recorded on the session, never a half-written turn.