Qwen3.x / Deepseek-R1 / o1 stream model thinking via
delta.reasoning_content during SSE; the final answer arrives later via
delta.content. Previously chat.js parsed only delta.content, so any
thinking time appeared to the user as a long empty pause followed by a
sudden answer.
Both generator functions (sendMessage, sendMessageWithCustomHistory)
gain an opts.onThinking(text) callback that fires only when the server
actually streams reasoning_content. Backward compatible: existing
callers ignore the option, see no behaviour change.
handleUserInput now passes an onThinking callback that lazy-creates a
<details class="chat-thinking"> block above the answer span on the
first reasoning delta. When the first content delta arrives, the
thinking block auto-collapses into a "thinking (click to expand)"
summary so the answer is the visible focus.
If a response never thinks (thinking off, simple prompt, etc.), no
thinking DOM element is ever created — no visual artefact at all.
Existing enable_thinking:false request bodies kept for now; this change
is rendering-only and activates automatically the moment any caller
flips thinking on.