feat(core): add retry for transient HTTP and stream-level errors
Add retry mechanism driven by pi settings.json retry.provider config (timeoutMs, maxRetries, maxRetryDelayMs). HTTP-level retries handle 429/5xx with exponential backoff and jitter, respecting Retry-After headers (seconds and HTTP-date formats). Stream-level retries handle cases where the API returns 200 OK but sends an error event in the stream body. Retries only when no content has been emitted yet. Per-attempt timeout via AbortController with automatic retry. Clean abort propagation through the retry loop.
This commit is contained in:
@@ -89,6 +89,23 @@ export interface StreamOptions {
|
||||
maxTokens?: number
|
||||
onPayload?: (payload: unknown, model: ModelLike) => unknown | Promise<unknown>
|
||||
onResponse?: (response: ProviderResponseInfo, model: ModelLike) => void | Promise<void>
|
||||
/**
|
||||
* HTTP request timeout in milliseconds.
|
||||
* Applied per-attempt; on timeout the request is retried if retries remain.
|
||||
*/
|
||||
timeoutMs?: number
|
||||
/**
|
||||
* Maximum retry attempts for transient HTTP errors (429, 5xx).
|
||||
* Default: 2.
|
||||
*/
|
||||
maxRetries?: number
|
||||
/**
|
||||
* Maximum delay in milliseconds to wait for a retry when the server requests
|
||||
* a long wait via Retry-After. If the server's requested delay exceeds this
|
||||
* value, the request fails immediately. Default: 60000 (60 seconds).
|
||||
* Set to 0 to disable the cap.
|
||||
*/
|
||||
maxRetryDelayMs?: number
|
||||
}
|
||||
|
||||
export type AssistantMessageEvent =
|
||||
@@ -153,4 +170,6 @@ export interface CoreDependencies {
|
||||
now?: () => number
|
||||
uuid?: () => string
|
||||
homeDir?: () => string
|
||||
/** Injectable delay for retry backoff. Defaults to setTimeout. */
|
||||
delay?: (ms: number, signal: AbortSignal) => Promise<void>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user