Retry-aware LLM wrapper with backoff, telemetry hooks, and fallback.
Wraps any LangEx.LLM provider with automatic retries on transient
failures (rate limits, transport errors, server errors), linear backoff,
and configurable callbacks for observability.
Usage
LangEx.LLM.Resilient.chat(LangEx.LLM.Anthropic, messages,
model: "claude-opus-4-6",
tools: tools,
max_retries: 3,
retry_base_ms: 3_000
)Options
All options not listed below are forwarded to the underlying provider.
:max_retries— maximum retry attempts (default3):retry_base_ms— base delay between retries in ms (default3_000); actual delay isbase * (attempt + 1)(linear backoff):retryable?—fn(error_reason) -> boolean()to classify retryable errors (default: 429, transport errors, 5xx):on_success—fn(attempt, duration_ms, ai, usage) -> any():on_retry—fn(attempt, duration_ms, wait_ms, reason) -> any():on_error—fn(attempt, duration_ms, reason) -> any():fallback—fn() -> Message.AI.t()called on final failure; whennil, the error propagates as{:error, reason}
Summary
Functions
@spec chat(module(), [LangEx.LLM.message()], keyword()) :: LangEx.LLM.chat_result()
Call the provider with automatic retries. Returns {:ok, %Message.AI{}}.
On final failure, returns the fallback message if configured, or
{:error, reason} if no fallback is set.
@spec chat_with_usage(module(), [LangEx.LLM.message()], keyword()) :: LangEx.LLM.chat_with_usage_result() | LangEx.LLM.chat_result()
Like chat/3 but returns {:ok, %Message.AI{}, usage_map} with token
counts and :duration_ms.
Default retryable error classifier.
Returns true for:
- HTTP 429 (rate limit)
Req.TransportError(connection issues)- HTTP 5xx (server errors)
Format an LLM error reason into a human-readable string.