Retry
Agent routes can opt into automatic retry of transient LLM failures via the retry field on agent(). Retries apply to rate limits, server errors, network timeouts, and OpenAI overload responses — but not to non-transient errors like invalid API keys or model-not-found.
Configuring retry
Set retry on the agent() descriptor:
import { agent } from "@dawn-ai/sdk"
export default agent({
model: "gpt-5-mini",
retry: { maxAttempts: 5, baseDelay: 500 },
systemPrompt: "You are a helpful assistant.",
})| Field | Default | Notes |
|---|---|---|
maxAttempts | 3 | Total number of attempts (including the first call). 1 disables retry. |
baseDelay | 1000 (ms) | Base delay before the first retry. Backoff is exponential with jitter. |
If retry is omitted, agents use the defaults (3 attempts, 1s base delay). To disable retry entirely, set maxAttempts: 1.
What's retried
The retry policy retries on errors whose message indicates a transient condition:
- Rate limits:
429,rate limit - Server errors:
500,502,503 - Network errors:
ECONNRESET,ECONNREFUSED,ETIMEDOUT,timeout,network - OpenAI transient:
overloaded,server_error
Anything else (invalid API key, model not found, schema validation errors, abort) fails immediately without retry.
Backoff
Delay before retry n (zero-indexed) is:
delay = min(baseDelay * 2^n + jitter, 10s)
jitter = random(0, 500ms)So with the defaults (1s base, 3 attempts):
| Attempt | Delay before this attempt |
|---|---|
| 1 (initial) | 0 |
| 2 | ~1000–1500 ms |
| 3 | ~2000–2500 ms |
The non-stream fallback honors the configured baseDelay. The cap at 10 seconds prevents pathological backoff for long retry chains.
Streaming behavior
For streaming routes, retry only applies if the failure happens before any token or event is yielded to the client. The current streaming path starts retries with a 1-second base delay regardless of the configured baseDelay. Once content has streamed, the partial response is committed — Dawn cannot retry a partially-emitted stream because the client has already seen content. In that case the error propagates through the stream.
If you need stronger retry guarantees in streaming mode, wrap the call at a higher level in your client or use /threads/:id/runs/wait for operations where partial output is not useful.
Abort signals
An Agent Protocol viewer disconnect does not abort the run; the run stays available for the thread to resume. An AG-UI disconnect, explicit Agent Protocol cancellation (POST /threads/:id/cancel), and server shutdown do abort the run. The resulting signal reaches agent execution and tools as ctx.signal, but provider and tool operations must cooperate with that signal for pending I/O to stop promptly.
Per-route, not global
Retry is configured per agent() descriptor. Different routes can have different policies:
// Critical billing-related route — fail fast on transient errors
export default agent({
model: "gpt-5-mini",
retry: { maxAttempts: 1 },
systemPrompt: "...",
})// Best-effort summarization route — patient retry
export default agent({
model: "gpt-5-mini",
retry: { maxAttempts: 5, baseDelay: 2000 },
systemPrompt: "...",
})There is no global retry config — each route states its own intent.