Skip to content

[Fix] The app may show raw <think> tags: frames are not split on the exclusive path #112

Closed

Description

@b-re-w

The Kotlin client matches == "<think>" and == "</think>" exactly (ChatWebSocketClient.kt ~187, ~194). The exclusive path streams through TextIteratorStreamer, which emits at word/newline boundaries, so Qwen3's <think>\n and </think>\n\n probably arrive as one frame with the newline; adaptive_special_tag_buffering (models/base.py) joins but never splits. Then the reasoning panel never opens and the tags show up in the answer. The fake engines in the tests emit one token per chunk, so this is untested. Needs a real-model confirmation.

Fix: split tag frames on the server (each tag its own frame), and/or make the client tag-aware.

Done when: a test through /api/chat/streaming with a template that emits think tags, on the exclusive path, sees frames exactly <think> and </think>.

Found in the 2026-10-03 usability audit (code reading, not run).

Activity

  1. b-re-w commented on Oct 3, 2026

    @b-re-w
    MemberAuthor

    Confirmed without running a model: feeding Qwen3-0.6B's tokenizer output for <think>\n…</think>\n\nHello token by token into TextIteratorStreamer (the one-at-a-time path) yields the frames '<think>\n' and '</think>\n\n', never an exact <think>/</think>, so the app's exact match fails. Since #127 default requests batch, but requests with repeat_penalty/typical_p/extra kwargs still take this path. Fix: split tags into their own frames on the server.

  2. b-re-w commented on Oct 3, 2026

    @b-re-w
    MemberAuthor

    Landed in develop via #136

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions