Skip to content

fix(sse): retry once on STREAM_EARLY_EOF for single-model requests (#3758) - #3817

Merged
diegosouzapw merged 2 commits into
release/v3.8.25from
fix/3758-nvidia-early-close-retry
Jun 14, 2026
Merged

diegosouzapw merged 2 commits into
release/v3.8.25from
fix/3758-nvidia-early-close-retry

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Summary

NVIDIA NIM models (minimax-m3, qwen3.5-397b, glm-5.1) intermittently return a 502 "Stream ended before producing useful content" — minimax-m3 100% of the time, the others sporadically.

Addresses the NVIDIA-NIM streaming part of #3758. (The separate qwen-web validation SSRF part of the same report was already fixed in v3.8.24, #3767.)

Root cause

NIM occasionally sends HTTP 200 then closes the SSE early with zero useful frames (a transient upstream early-close), which the readiness gate correctly flags as STREAM_EARLY_EOF. But on the single-model (non-combo) path only antigravity got an early-close retry — every other provider (src/sse/handlers/chat.ts) returned the 502 immediately. (Combo routing already fails over, so this was visible only on single-model requests like the test chat.)

The readiness gate already counts reasoning/thinking deltas as useful content, so this is not a reasoning-classification bug — it's a missing retry on a flaky early-close.

Fix

A bounded one-retry generalized to any OpenAI-compatible provider:

  • Extracted a pure shouldRetryStreamEarlyEof(errorCode, attempt) (chatHelpers.ts) — true only for STREAM_EARLY_EOF and attempt < 1.
  • A per-request counter (declared outside both retry loops) caps it to exactly one re-attempt, so it can never loop.
  • Scoped strictly to the early-close: STREAM_READINESS_TIMEOUT (slow-but-alive upstream) is not retried (would only double latency), the account is not marked unavailable (an early-close is not a bad key), and forced-connection requests are excluded.

Validation (TDD)

  • New tests/unit/stream-early-eof-retry-3758.test.ts: retry-once on first early-close; bounded (no 2nd retry → 502); no retry on timeout; no markAccountUnavailable.
  • 21/21 (with stream-readiness) pass; chat-helpers/combo-stream-readiness/stream-readiness-policy green. typecheck:core clean, lint 0 errors.

The intermittent live behavior needs a NIM key to reproduce end-to-end, but the retry mechanism is fully covered by the mocked early-close test above.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant