Centralize retry decisions and delays in CodexErr (#46540)

## What changed

Replace `is_retryable()` with `retry_delay(retry_count)`, which returns `None` for terminal errors and a delay for retryable errors. Prefer server advice when present; otherwise use exponential backoff with jitter. Keep `server_retry_delay()` for callers that need only the server-provided delay.

Route sampling and remote compaction errors through the shared response stream handler, which now checks retryability and obtains the delay together. Preserve server-only retry timing when the retry budget is exhausted.

## Testing

Add coverage for attempt-dependent backoff, zero-duration server advice, and terminal errors that remain non-retryable despite server advice. Update API mapping and provider tests to use the combined retry API.

GitOrigin-RevId: 903f92935e71dea043afe1fad8ccb9389471aa75
This commit is contained in:
Adam Perry @ OpenAI
2026-09-19 00:46:30 +00:00
committed by copyberry
parent b244e9bafe
commit d5b29951ac
12 changed files with 94 additions and 45 deletions
+1
View File
@@ -98,6 +98,7 @@ where
.should_retry(&err, attempt, policy.max_attempts) =>
{
let retry_attempt = attempt + 1;
// TODO(anp): Respect Retry-After from HTTP responses before retrying the request.
let delay = backoff(policy.base_delay, retry_attempt);
crate::record_retry!(retry_attempt, delay, RetryOperation::HttpRequest);
tokio::time::sleep(delay).await;