Bug Description
The OMO harness stream consumer can deadlock indefinitely when an LLM provider stops emitting events but never closes the stream. This was observed with Kimi K2.6 in thinking mode, where the stream hung for 36 minutes until manually cancelled.
Reproduction Steps
- Configure an agent to use Kimi K2.6 with variant "high" (thinking enabled)
- Trigger a plan creation via
task(subagent_type="plan", ...)
- The stream starts but after some events, no more events are emitted
- The stream consumer waits indefinitely with no timeout or error
- After 36 minutes, the user must manually cancel the session
Expected Behavior
The stream should timeout if no events are received for a reasonable period (e.g., 5 minutes) and emit an error event to allow graceful degradation.
Actual Behavior
The stream consumer hangs forever, waiting for the next event that never arrives.
Environment
- OpenCode version: 1.16.2
- Provider: Kimi For Coding (kimi-k2.6)
- Variant: high (thinking enabled)
- OS: macOS
Root Cause
In packages/opencode/src/session/llm.ts, the AI SDK fullStream is converted to an Effect Stream without any timeout between events. When the provider stops emitting but doesn't close the stream, Stream.fromAsyncIterable waits forever.
Proposed Fix
Add Stream.timeout and Stream.catchCause to handle the timeout gracefully, ensuring the stream errors out after 5 minutes of inactivity instead of hanging indefinitely.
Bug Description
The OMO harness stream consumer can deadlock indefinitely when an LLM provider stops emitting events but never closes the stream. This was observed with Kimi K2.6 in thinking mode, where the stream hung for 36 minutes until manually cancelled.
Reproduction Steps
task(subagent_type="plan", ...)Expected Behavior
The stream should timeout if no events are received for a reasonable period (e.g., 5 minutes) and emit an error event to allow graceful degradation.
Actual Behavior
The stream consumer hangs forever, waiting for the next event that never arrives.
Environment
Root Cause
In
packages/opencode/src/session/llm.ts, the AI SDKfullStreamis converted to an Effect Stream without any timeout between events. When the provider stops emitting but doesn't close the stream,Stream.fromAsyncIterablewaits forever.Proposed Fix
Add
Stream.timeoutandStream.catchCauseto handle the timeout gracefully, ensuring the stream errors out after 5 minutes of inactivity instead of hanging indefinitely.