# `WardrikCore.Retry`

Retries model calls and tool calls that fail in a way a retry may fix.

    WardrikCore.start_agent(
      agent_id: "triage",
      model: "anthropic:claude-haiku-4-5",
      retries: [attempts: 3, max_wait: :timer.seconds(10), on_exhausted: :fail]
    )

Before each retry it waits a random time of up to 1 second, then up to 2, then 4, and so on,
capped at `:max_wait`.

## Options

  * `:attempts` - retries after the first try. `6` unless set.
  * `:max_wait` - the longest wait, in milliseconds. `60_000` unless set.
  * `:on_exhausted` - what a model call does once retries run out. `:ask` waits for a person to
    say whether to try again (see `WardrikCore.Retry.Exhausted`). `:fail` fails the turn. `:ask`
    unless set.

## What's retried

  * A model call that raised, such as on a timeout, a dropped stream, a rate limit or a 5xx.
    Not a 4xx other than 408, 425 and 429, and not a call middleware refused.
  * A tool call that raised, crashed or timed out, if its tool is `idempotent` or `read_only`.

So a tool should return `{:error, reason}` for failures a retry won't fix, and raise for those
it might.

# `t`

```elixir
@type t() :: keyword()
```

An agent's `:retries`. See the options above.

# `attempts`

```elixir
@spec attempts(t()) :: non_neg_integer()
```

Returns the number of retries after the first try.

# `on_exhausted`

```elixir
@spec on_exhausted(t()) :: :ask | :fail
```

Returns what a model call does once retries run out: `:ask` or `:fail`.

# `run`

```elixir
@spec run(t(), (-&gt; answer), (answer -&gt; term() | nil), (map() -&gt; any())) ::
  {:ok, answer} | {:spent, answer, pos_integer()}
when answer: term()
```

Runs `fun`, retrying while `transient` returns a reason for its answer.

`transient` returns `nil` for an answer that shouldn't be retried. `announce` is called before
each wait. Returns `{:ok, answer}`, or `{:spent, answer, tries}` once retries run out.

# `transient?`

```elixir
@spec transient?(term()) :: boolean()
```

Returns whether a model call that failed with `reason` may succeed on retry.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
