Repository navigation
fix(combo): retry pre-content streaming failures - #13630
diegosouzapw merged 3 commits into
Conversation
b770a55 to
6881c26
Compare
|
Rebased onto the current Adding production evidence, since this one is hard to reproduce synthetically. I have been running the patch on a live gateway for ~8 hours. Before it, Rate before: ~150 of 9,399 calls (1.6%) in a single day. Worth stressing what the diff does not do, since that was my main worry while writing it:
The four cases in Happy to split the test file out or adjust the log level if you would rather keep this minimal for the release branch. |
6881c26 to
170fe4e
Compare
|
Pushed a follow-up that resolves the What changed The retry decision and the protected-target error return are now extracted into
Verified locally
CI on this head confirms the gate: On the remaining reds They are not introduced by this PR. Behaviour is unchanged: a pre-content streaming upstream error retries the same target, and only when nothing has reached the client yet. |
…lures A native Codex turn pin forced maxRetries to 0 unconditionally, which also disabled same-target retries. A pre-content stream failure sends no bytes to the client, so retrying the same pinned target is safe and indistinguishable from a first attempt. Set retries stay disabled so a pinned turn can never fail over to a different target. Adds a regression test covering a pinned turn whose first attempt fails before any content is streamed.
CI status on
|
| Check | Failing items | Related to this diff? |
|---|---|---|
| Unit Tests fast-path (1-4/4) | grok reset-credit tokens, i18n pt-BR / locale catalogs, hard-lease inventory, redaction-map persistence, reset-aware quota ordering, .env.example sync |
No — no test from either changed file appears in any shard's failure list |
| API Route Typecheck | pre-existing | No |
| Docs Gates (fast-path) | fabricated-docs + i18n mirrors | No |
| Merge integrity | changelog + generated skills | No |
| No new ESLint warnings | resource-pressure-self-restart.test.ts, volcengine-plan-binding-upsert.test.ts |
No — neither file is in this diff |
The base branch release/v3.8.51 is itself red (latest Quality Gates run on 4b6b64cbc: failure), so these are inherited rather than introduced.
Local verification of the changed behaviour:
combo-responses-sse-failure-fallback+native-codex-turn-pin-10379: 16/16 passing.- The
reset-awarefailures reproduce identically on a clean checkout with this diff stashed (163 tests, 152 pass, 11 fail,404 !== 200atcombo-strategies.test.ts:203), confirming they are fixture/isolation issues unrelated to retry behaviour. - End-to-end on a sandboxed gateway: unpatched returns HTTP 502 after a single attempt; patched retries the same pinned target and returns HTTP 200 with no quality-validation error.
|
@diegosouzapw Ready for review — summary of the final state, plus production evidence from a live 103-minute soak. What this changes
The retry fires only when no content has reached the client, so it cannot duplicate or interleave output. Other quality failures (empty content, duplicate tool calls) are deliberately not retried. Verification
Production soakI ran the patched build in production for 103 minutes (2026-09-15 08:41Z–10:24Z), 1948 requests: Total 5xx 0.359% (pre-patch baseline was 0.93%). The number that matters for this PR:
Breaking the 7 server errors down by mechanism rather than by status code:
CI statusRed checks on this PR are inherited from the base branch, not introduced here. Every failing test belongs to Happy to rebase onto a green base whenever the base reds are cleared if you would rather merge on an all-green run. |
|
Fix rõ ràng và test tốt — 6/6 pass ở head hiện tại ( |
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
0b96fe9
into
cheaper-inference:release/v3.8.51
… reasons cheaper-inference#13630 gated the same-target retry after a pre-content streaming upstream error on an exact match: handlePreContentStreamRetry() (open-sse/services/combo/executeTargetClassify.ts:35) compared quality.reason !== "streaming upstream error". cheaper-inference#14314 (b3867e4) then intentionally appended the upstream detail to that reason in validateResponseQuality() ("streaming upstream error: <detail>") so the real Anthropic rejection reaches the call log. Every detailed reason failed the exact match, so protected (fallbackOnlyOnQuotaExhaustion) and native-pinned targets stopped retrying once and failed instead. validateQuality.ts now owns STREAMING_UPSTREAM_ERROR_REASON, builds the reason in one helper and exports isStreamingUpstreamErrorReason(), which the retry gate uses (bare or "<base>: <detail>", nothing else). The two reason assertions in the cheaper-inference#13630 test move to the exact new text cheaper-inference#14314 documents, and a classifier test pins both forms plus near-misses. Refs cheaper-inference#14547
…3630) * fix(combo): retry pre-content streaming failures * fix(combo): allow same-target retry for native-pinned pre-content failures A native Codex turn pin forced maxRetries to 0 unconditionally, which also disabled same-target retries. A pre-content stream failure sends no bytes to the client, so retrying the same pinned target is safe and indistinguishable from a first attempt. Set retries stay disabled so a pinned turn can never fail over to a different target. Adds a regression test covering a pinned turn whose first attempt fails before any content is streamed. * docs(changelog): add fragment for pre-content streaming retry fix Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Tóm tắt
response.failedtrước contentNguyên nhân
validateResponseQuality()phát hiệnstreaming upstream error, nhưng nhánhresult.oktrả 502 ngay trước khi luồng retry transient phía dưới được chạy. Vì vậymaxRetries: 1không có tác dụng cho lỗi pre-content SSE.Kiểm chứng
false !== truetrước patchcombo-responses-sse-failure-fallbackgit diff --check: passFollow-up: native-pinned turns
A native Codex turn pin previously forced
maxRetries = 0, which also disabled safe same-target retries. Commitd834bef0bpreserves the pin (set retries/failover remain disabled) while allowing configured same-target retries when no content reached the client. A regression test covers first-attempt pre-content failure followed by same-target success.Verified locally:
combo-responses-sse-failure-fallback+native-codex-turn-pin-10379— 16/16 passing.