fix: handle stream interruption for OpenAI-compatible providers#21727
fix: handle stream interruption for OpenAI-compatible providers#21727jwcrystal wants to merge 2 commits intoanomalyco:devfrom
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: Based on my search, I found one potentially related PR: PR #19116 - fix(opencode): reconnect on network disruptions (VPN switch, SSE timeout, connection reset) This PR addresses similar network and SSE timeout issues, though it appears to focus on reconnection rather than the specific retry mechanism for incomplete responses. However, it may have overlapping concerns around SSE timeout handling and connection reset patterns. All other results were either the current PR (21727) itself or unrelated retry/error handling fixes. No other significant duplicate PRs found. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
Three fixes for Ollama/cloud models using OpenAI-compatible format where responses can be interrupted mid-stream: 1. retry.ts: Add SSE timeout, connection reset, abort, and stream truncation patterns to retryable error matching so interrupted streams are automatically retried. 2. message-v2.ts: Classify 'SSE read timed out' errors as APIError(isRetryable: true) instead of Unknown, so the retry mechanism recognizes and retries chunk timeouts. 3. openai-compatible-chat-language-model.ts: When the TransformStream flush() is called without a finish_reason from the provider while output is still active (text/reasoning/tool-call), emit an error event. This triggers the error handling path which retries rather than silently accepting a truncated response. Tests: 5 new retryable() cases + 1 fromError() SSE timeout case, all passing.
f495243 to
8a0fea2
Compare
Issue for this PR
Closes #20466
Related #15393, #17680, #17574, #17307
Type of change
What does this PR do?
OpenAI-compatible providers (Ollama, cloud models) can interrupt SSE streams mid-response. Previously, opencode silently accepted the truncated output as a complete response — no retry, no error, just a cut-off answer.
Three fixes:
retry.ts— Added SSE timeout, connection reset, abort, and stream truncation patterns toretryable()matching so interrupted streams are automatically retried.message-v2.ts— ClassifiedSSE read timed outerrors asAPIError(isRetryable: true)instead ofUnknown, so the retry mechanism recognizes and retries chunk timeouts.openai-compatible-chat-language-model.ts— Whenflush()is called without afinish_reasonfrom the provider while output is still active (text/reasoning/tool-call), emit anerrorevent. This triggers the error handling path which retries, rather than silently accepting a truncated response.How did you verify your code works?
retryable()test cases: SSE timeout, connection reset, aborted, stream ended unexpectedly, existing rate-limit still passesfromError()test case:SSE read timed out→APIError(isRetryable: true, code: SSE_TIMEOUT)retry.test.tsandmessage-v2.test.tspassScreenshots / recordings
N/A — backend fix, no UI changes.
Checklist