Skip to content

TUI renders each reasoning token on a separate line for models with per-token reasoning cycles #22241

@bamboodew

Description

@bamboodew

Describe the bug

Some models (e.g., zhipu/glm via OpenAI-compatible API) emit a separate reasoning-startreasoning-deltareasoning-end cycle for every single token during thinking/reasoning output. This causes the TUI to render each token as an independent Thinking: line:

Thinking: The
Thinking: user
Thinking: said
Thinking: hello

Instead of the expected continuous paragraph:

Thinking: The user said hello

Root cause

In processor.ts, each reasoning-start event creates a new reasoning Part with a unique partID. Models like DeepSeek emit one start, many deltas, and one end — so one part is created. But models like zhipu/glm wrap each token in its own start/delta/end cycle, creating a new part per token.

The TUI's <code streaming={true}> component appends new content as a new line on each reactive update. Since each token creates a separate part (and thus a separate ReasoningPart component instance), each token renders on its own line.

Steps to reproduce

  1. Configure an OpenAI-compatible provider with a model that has per-token reasoning events (e.g., zhipu/glm-5 via gateway)
  2. Send any message that triggers thinking/reasoning
  3. Observe each thinking token displayed on a separate line with Thinking: prefix

Expected behavior

Thinking content should render as a continuous paragraph, regardless of how the model streams reasoning events.

Environment

  • OS: Windows 11
  • OpenCode: dev branch
  • Model: zhipu/glm-5 via Mify gateway (OpenAI-compatible format)

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