Skip to content

processor.ts: merge multiple reasoning-start/end cycles into one part #27987

@1269699120

Description

@1269699120

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):

  1. Add lastReasoningPart field to ProcessorContext interface
  2. In reasoning-start handler: if ctx.lastReasoningPart exists, reuse it instead of creating a new part
  3. In reasoning-end handler: save the ended part to ctx.lastReasoningPart before deleting from reasoningMap
  4. 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

  1. Configure an OpenAI-compatible API provider that streams reasoning_content field (e.g., DeepSeek via a proxy like chenbei)
  2. Send a query that triggers reasoning (any question)
  3. 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions