When editing a model's response in Web UI that contains a reasoning block, the reasoning gets duplicated and a new copy is encased in <think></think> tags. This is recent new behaviour (I updated yesterday after about a week) and it seems unintended. Before, reasoning was non-editable at all, so it seems part of the idea was to expose it to editing.
I asked the DeepWiki bot to summarise and identify the cause. It found the (probable) affected files, but couldn't trace which commit introduced the change, since the files were apparently reorganised recently.
The following summary was written by the DeepWiki bot. It also suggested to tag @allozaur
(Sorry if this report is not up to par. I can only use GitHub with a phone app atm.)
Description
When editing an assistant message that contains a reasoning/thinking block, the reasoning content is duplicated in the display and the stored message is corrupted.
Steps to reproduce (Web UI)
- Use a reasoning model (e.g. Gemma 4 E4b)
- Ask a question and receive a response that includes a thinking block
- Click Edit on the assistant message
- Save the edit (with or without changes)
Expected behavior
The reasoning block is editable and saved correctly, with no duplication.
Actual behavior
- In edit mode, the reasoning appears twice: once as the collapsible "Reasoning" block (rendered from
reasoningContent), and again as <think>...</think> literal text in the textarea.
- After saving,
content contains <think>...</think> as embedded literal text, while reasoningContent retains the original unchanged value. This causes the duplication to persist in the rendered view.
- When the next message is generated, the corrupted message is sent to the backend as context, with both
reasoning_content and <think> tags in content.
Root cause
rawEditContent in ChatMessage.svelte (lines 48–90) reconstructs the full message for the edit textarea, wrapping reasoning in <think>...</think> tags. However, editAssistantMessage in chat.svelte.ts only writes the edited text to content and never updates or clears reasoningContent. The shouldBranch path has the same issue — it creates a new message with content: newContent but no reasoningContent field at all.
Relevant files:
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessage.svelte — rawEditContent construction (lines 48–90)
tools/ui/src/lib/stores/chat.svelte.ts — editAssistantMessage save paths (lines 1445–1463)
Additional notes
The REASONING_TAGS are hardcoded as <think>/</think> regardless of model. The codebase already deprecated embedding reasoning tags in content in favor of a dedicated reasoningContent field (LEGACY_REASONING_TAGS). The current approach re-introduces the same anti-pattern.
A correct fix would require editAssistantMessage to parse <think>...</think> out of the edited content, store the extracted text in reasoningContent, and store only the remaining text in content. Alternatively, reasoning could be exposed as a separate editable field in the UI rather than serialized into the textarea.
When editing a model's response in Web UI that contains a reasoning block, the reasoning gets duplicated and a new copy is encased in
<think></think>tags. This is recent new behaviour (I updated yesterday after about a week) and it seems unintended. Before, reasoning was non-editable at all, so it seems part of the idea was to expose it to editing.I asked the DeepWiki bot to summarise and identify the cause. It found the (probable) affected files, but couldn't trace which commit introduced the change, since the files were apparently reorganised recently.
The following summary was written by the DeepWiki bot. It also suggested to tag @allozaur
(Sorry if this report is not up to par. I can only use GitHub with a phone app atm.)
Description
When editing an assistant message that contains a reasoning/thinking block, the reasoning content is duplicated in the display and the stored message is corrupted.
Steps to reproduce (Web UI)
Expected behavior
The reasoning block is editable and saved correctly, with no duplication.
Actual behavior
reasoningContent), and again as<think>...</think>literal text in the textarea.contentcontains<think>...</think>as embedded literal text, whilereasoningContentretains the original unchanged value. This causes the duplication to persist in the rendered view.reasoning_contentand<think>tags incontent.Root cause
rawEditContentinChatMessage.svelte(lines 48–90) reconstructs the full message for the edit textarea, wrapping reasoning in<think>...</think>tags. However,editAssistantMessageinchat.svelte.tsonly writes the edited text tocontentand never updates or clearsreasoningContent. TheshouldBranchpath has the same issue — it creates a new message withcontent: newContentbut noreasoningContentfield at all.Relevant files:
tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessage.svelte—rawEditContentconstruction (lines 48–90)tools/ui/src/lib/stores/chat.svelte.ts—editAssistantMessagesave paths (lines 1445–1463)Additional notes
The
REASONING_TAGSare hardcoded as<think>/</think>regardless of model. The codebase already deprecated embedding reasoning tags incontentin favor of a dedicatedreasoningContentfield (LEGACY_REASONING_TAGS). The current approach re-introduces the same anti-pattern.A correct fix would require
editAssistantMessageto parse<think>...</think>out of the edited content, store the extracted text inreasoningContent, and store only the remaining text incontent. Alternatively, reasoning could be exposed as a separate editable field in the UI rather than serialized into the textarea.