Skip to content

fix(provider): recover stalled model streams - #40010

Open
dcadenas wants to merge 3 commits into
anomalyco:devfrom
dcadenas:stream-contribute
Open

fix(provider): recover stalled model streams#40010
dcadenas wants to merge 3 commits into
anomalyco:devfrom
dcadenas:stream-contribute

Conversation

@dcadenas

@dcadenas dcadenas commented Aug 1, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #37580

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

A model endpoint can return response headers and then stop producing body data. OpenCode currently waits forever in that state, which can leave foreground Task parents stranded behind a stalled child.

This adds a provider-neutral stream-idle watchdog with a safe default. It starts with a 15-minute deadline, learns from successful streams per provider and transport, and keeps the adaptive deadline between 15 and 30 minutes. An explicit chunkTimeout remains a fixed override, while false, zero, or a negative value disables the watchdog.

The watchdog recognizes either an SSE response header or stream: true in the request. This matters because the direct ChatGPT Codex endpoint was observed returning a streaming response without Content-Type. Non-streaming requests remain unchanged. When a response omits Content-Type, the watchdog activates only when the JSON request explicitly sets stream: true, covering the observed response without applying adaptive timing to unrelated fetches.

A timeout becomes a typed retryable provider error and uses the existing retry and status flow. This does not change Task orchestration, durable session records, retry policy, or UI behavior.

Related work

How did you verify your code works?

  • bun test --timeout 30000 test/provider/header-timeout.test.ts test/provider/stream-liveness.test.ts test/session/processor-effect.test.ts test/session/retry.test.ts — 72 passed
  • bun typecheck in packages/core
  • bun typecheck in packages/opencode
  • Repository pre-push typecheck — 30/30 tasks passed
  • An isolated foreground Task E2E completed normally, then completed again after a forced post-header child stall triggered the existing retry flow.
  • The missing-Content-Type case is covered directly without proxy header normalization.

Screenshots / recordings

Not applicable; there are no UI changes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on my search, I found two potentially related PRs:

  1. PR fix(opencode): make long-lived provider streams robust to silent SSE terminations #39970 - fix(opencode): make long-lived provider streams robust to silent SSE terminations

  2. PR fix: time out non-SSE streams #39516 - fix: time out non-SSE streams

These PRs appear to be addressing overlapping concerns about streaming robustness and timeouts in provider responses. You may want to review them to ensure PR #40010 doesn't duplicate existing fixes or to coordinate any related changes.

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.

SSE stream silently dropped mid-response hangs session/subagents forever — chunkTimeout has no default on the openai path

1 participant