Handle context length errors consistently across response transports (#60482)

## Why

HTTP 400 responses with `context_length_exceeded` need to reach context-window recovery so manual compaction can retry with less history. Streaming context-window failures should end the stream immediately.

## What changed

- Map `context_length_exceeded` through the shared terminal provider error parser for HTTP 400 responses and events without an HTTP status.
- Return SSE context-window failures immediately.
- Preserve retryable handling for WebSocket errors carrying HTTP 503, even when their code is `context_length_exceeded`.

## Testing

Add coverage for WebSocket status handling and immediate SSE termination with retry headers. Update the manual compaction test to verify recovery from an HTTP 400 context-window error by dropping one history item and retrying.

GitOrigin-RevId: 56d8c831c2fad2ca1318318a3b4258fcc516d689
This commit is contained in:
Charlie Marsh
2026-11-10 00:55:34 +00:00
committed by copyberry
parent d9446b4b01
commit 1885417cd4
6 changed files with 46 additions and 10 deletions
+3
View File
@@ -96,6 +96,9 @@ pub(crate) fn parse_terminal_provider_error(
.and_then(Value::as_str)
.filter(|message| !message.trim().is_empty());
match (code, status) {
("context_length_exceeded", None | Some(StatusCode::BAD_REQUEST)) => {
Some(ApiError::ContextWindowExceeded)
}
// A non-streaming 400 already follows the ordinary invalid-request path.
("invalid_access_program" | "unsupported_access_program", None) => {
Some(ApiError::InvalidRequest {