Repository navigation
feat: preserve pre-stream upstream statuses and retry hints #558
Description
Problem
After #554, compatible nonstream calls preserve observed upstream429/503 and bounded Retry-After, but stream:true text/function requests still collapse an upstream HTTP rejection to502 and discard its safe hint before any client SSE starts. External clients lose the transient status/header even though this is still a plain JSON error boundary.
Expected behavior
- All four registered adapters, text/function streams: capture only observed upstream429/503 and existing bounded integer-seconds Retry-After; preserve current classifications, response-start/possible-billing flags and best-effort body cancellation.
- Before any client SSE frame, /api/v1 returns that429/503 with matching numeric error.code and canonical safe Retry-After after required failed-attempt usage/outcome audit. /v1 retains502/symbolic errors but receives the bounded header.
- Already-started streams keep HTTP200 and existing safe SSE failure shape; no new upstream status/hint metadata or provider diagnostics escape. Local/persistence/cancellation errors and other upstream statuses cannot inherit hints/status.
- No new retry/sleep, fallback eligibility, raw bodies/headers, exact provider cause parsing, billed-cost inference, schema-pin/dependency/storage change or complete feat: complete OpenRouter external-client compatibility #116 claim. Jev feat: add Jev-assisted managed routing #7 remains unresolved.
Acceptance
Issue/branch/English plan before code; meaningful public-boundary red before implementation; all routes/bases/text-function modes and actual pinned SDKs. Cover success/denial/persistence waits/failures, malformed hints, pre/post-frame isolation, private accounting, unchanged cancellation/fallback semantics. Run npm run check; update relevant contracts/PRD/architecture/acceptance/compatibility/handoff and open a ready PR.
Primary sources checked 2026-10-29: https://openrouter.ai/docs/api_reference/errors-and-debugging and https://openrouter.ai/docs/api_reference/streaming . This increment addresses the documented plain JSON pre-stream boundary, not all streaming errors.
Implementation evidence
Initial red reproduced104 expected missing-status/hint failures among144 public-boundary cases; minimal production changes made all144 pass. All268 new tests pass, including96 actual OpenAI/OpenRouter/AI SDK cases. The first full run found9 existing expectations for the intentionally superseded compatible pre-stream mapping; only those pre-stream expectations changed. Integrated focused regressions passed711 cases, retaining legacy/invalid502, midstream, cancellation, signed-Gemini and persistence/privacy assertions. Final npm run check passed8,212 cases with one optional external PostgreSQL skip, zero failures/cancellations and all six offline source-integrity checks. See plan. Source pins, dependencies and operational/storage schemas are unchanged. Full #116 and unresolved #7 stay open.
Activity