# `ADK.LLM.Retry`
[🔗](https://github.com/zeroasterisk/adk-elixir/blob/main/lib/adk/llm/retry.ex#L1)

Retry wrapper for LLM calls with exponential backoff and jitter.

Retries on transient errors (HTTP 429, 500, 502, 503, 504, connection errors).
Does NOT retry on client errors (400, 401, 403, 404).

## Options

  * `:max_retries` - Maximum number of retry attempts (default: 3)
  * `:base_delay_ms` - Base delay in milliseconds (default: 1000)
  * `:max_delay_ms` - Maximum delay in milliseconds (default: 30_000)

## Examples

    ADK.LLM.Retry.with_retry(fn -> ADK.LLM.Gemini.generate(model, request) end)

    ADK.LLM.Retry.with_retry(
      fn -> ADK.LLM.Gemini.generate(model, request) end,
      max_retries: 5, base_delay_ms: 500
    )

# `compute_delay`

```elixir
@spec compute_delay(non_neg_integer(), pos_integer(), pos_integer()) ::
  non_neg_integer()
```

Compute backoff delay with jitter for the given attempt.

# `extract_retry_after`

```elixir
@spec extract_retry_after(%{headers: term()}) :: non_neg_integer() | nil
```

Extract a retry-after delay (in milliseconds) from a `Req.Response`.

Checks for Anthropic's `retry-after-ms` header first, then the standard
`retry-after` header (interpreted as seconds). Returns `nil` if neither
is present or parseable.

# `transient?`

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

Returns true if the error is transient and should be retried.

# `with_retry`

```elixir
@spec with_retry(
  (-&gt; {:ok, term()} | {:error, term()}),
  keyword()
) :: {:ok, term()} | {:error, term()}
```

Execute `fun` with retry logic. Returns the first success or the last error.

`fun` should return `{:ok, result}` or `{:error, reason}`.

## Options

  * `:retry_after_ms` - If set, overrides the computed backoff for the first
    retry attempt (useful when the server sends a `retry-after` header).
  * `:max_retries`, `:base_delay_ms`, `:max_delay_ms` - see module docs.
  * `:sleep_fn` - override for testing (default: `&Process.sleep/1`).

---

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