Keep response streams alive through connection failures (#37485)

## What changed

- Classify HTTP connection failures separately from other network errors without exposing request URLs.
- For sampling requests, retry connection failures with exponential delays from 5 to 60 seconds and show a `Reconnecting... waiting for network` stream error.
- Preserve the normal stream retry budget while waiting for the provider to become reachable. Keep the existing bounded retry behavior for other retryable errors.

## Testing

- Verify connection errors are classified without leaking URL contents.
- Verify a turn recovers after its provider becomes reachable and still applies the configured retry limit to a subsequent incomplete stream.

GitOrigin-RevId: 646553290c865a1332abd30c4a64ed9266bbfc6f
This commit is contained in:
jif
2026-08-07 18:33:46 +00:00
committed by copyberry
parent 509565820f
commit 5a0d0929e2
10 changed files with 162 additions and 12 deletions
+4
View File
@@ -9,6 +9,7 @@ use chrono::Utc;
use codex_protocol::auth::PlanType;
use codex_protocol::error::CodexErr;
use codex_protocol::error::CodexErrorDetails;
use codex_protocol::error::ConnectionFailedError;
use codex_protocol::error::RetryLimitReachedError;
use codex_protocol::error::UnexpectedResponseError;
use codex_protocol::error::UsageLimitReachedError;
@@ -148,6 +149,9 @@ pub fn map_api_error(err: ApiError) -> CodexErr {
request_id: None,
}),
TransportError::Timeout => CodexErr::RequestTimeout,
TransportError::Connection(source) => {
CodexErr::ConnectionFailed(ConnectionFailedError { source })
}
TransportError::Network(msg) | TransportError::Build(msg) => CodexErr::Stream(msg),
},
ApiError::RateLimit(msg) => CodexErr::Stream(msg),