Description
Describe the bug
Some API providers (e.g. chenbei proxy) send reasoning_content split across multiple reasoning-start/reasoning-end cycles, each containing only 1-2 characters.
This causes the TUI to display dozens of tiny ▶ Thought for 2ms blocks instead of one complete reasoning block.
Root Cause
In processor.ts, each reasoning-start creates a new ReasoningPart. When the provider emits multiple reasoning cycles for the same reasoning content, each cycle
gets its own part, fragmenting the display.
Fix
Save the last ended reasoning part and reuse it when a new reasoning-start arrives, instead of creating a new part each time.
Changes (packages/opencode/src/session/processor.ts):
- Add lastReasoningPart field to ProcessorContext interface
- In reasoning-start handler: if ctx.lastReasoningPart exists, reuse it instead of creating a new part
- In reasoning-end handler: save the ended part to ctx.lastReasoningPart before deleting from reasoningMap
- Reset ctx.lastReasoningPart = undefined in stream cleanup
Diff:
interface ProcessorContext extends Input {
reasoningMap: Record<string, MessageV2.ReasoningPart>
- lastReasoningPart: MessageV2.ReasoningPart | undefined
}
// reasoning-start:
if (value.id in ctx.reasoningMap) return
- if (ctx.lastReasoningPart) {
- ctx.reasoningMap[value.id] = ctx.lastReasoningPart
- ctx.lastReasoningPart = undefined
- return
- }
// reasoning-end:
yield* session.updatePart(ctx.reasoningMap[value.id])
- ctx.lastReasoningPart = ctx.reasoningMap[value.id]
delete ctx.reasoningMap[value.id]
// cleanup:
ctx.reasoningMap = {}
- ctx.lastReasoningPart = undefined
Plugins
nothing
OpenCode version
1.15.3
Steps to reproduce
- Configure an OpenAI-compatible API provider that streams
reasoning_content field (e.g., DeepSeek via a proxy like chenbei)
- Send a query that triggers reasoning (any question)
- Observe the TUI output: many
▶ Thought for 2ms lines appear, each expandable to show only 1-2 characters
Expected: One single reasoning block containing all reasoning text
Actual: Many small reasoning blocks, each containing only a fragment of the full reasoning text
Screenshot and/or share link
2026-05-17_0918_opencode_hello-fix.log
Operating System
windows 11
Terminal
windows Terminal
Description
Describe the bug
Some API providers (e.g. chenbei proxy) send reasoning_content split across multiple reasoning-start/reasoning-end cycles, each containing only 1-2 characters.
This causes the TUI to display dozens of tiny ▶ Thought for 2ms blocks instead of one complete reasoning block.
Root Cause
In processor.ts, each reasoning-start creates a new ReasoningPart. When the provider emits multiple reasoning cycles for the same reasoning content, each cycle
gets its own part, fragmenting the display.
Fix
Save the last ended reasoning part and reuse it when a new reasoning-start arrives, instead of creating a new part each time.
Changes (packages/opencode/src/session/processor.ts):
Diff:
interface ProcessorContext extends Input {
reasoningMap: Record<string, MessageV2.ReasoningPart>
}
// reasoning-start:
if (value.id in ctx.reasoningMap) return
// reasoning-end:
yield* session.updatePart(ctx.reasoningMap[value.id])
delete ctx.reasoningMap[value.id]
// cleanup:
ctx.reasoningMap = {}
Plugins
nothing
OpenCode version
1.15.3
Steps to reproduce
reasoning_contentfield (e.g., DeepSeek via a proxy like chenbei)▶ Thought for 2mslines appear, each expandable to show only 1-2 charactersExpected: One single reasoning block containing all reasoning text
Actual: Many small reasoning blocks, each containing only a fragment of the full reasoning text
Screenshot and/or share link
2026-05-17_0918_opencode_hello-fix.log
Operating System
windows 11
Terminal
windows Terminal