Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 00045e6

Browse files
Natfiiclaude
andcommitted
fix(terminal): expand thinking tag stripping to cover commentary and tool_output
stripThinkingTags only removed <think> and <thinking> tags. Models also leak <commentary>, <tool_output>, <analysis>, <reflection>, and <inner_monologue> blocks. Expand the regex to strip all internal reasoning tags when the setting is enabled. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c78e855 commit 00045e6

2 files changed

Lines changed: 41 additions & 6 deletions

File tree

app/src/main/java/com/zeroclaw/android/ui/screen/terminal/TerminalViewModel.kt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -774,10 +774,20 @@ class TerminalViewModel(
774774
"No chat provider configured \u2014 use /help to see admin commands, " +
775775
"or add a provider in Settings > API Keys."
776776

777-
/** Pattern matching common chain-of-thought tag variants across models. */
777+
/**
778+
* Pattern matching chain-of-thought and internal reasoning tags
779+
* across models.
780+
*
781+
* Covers `<think>`, `<thinking>`, `<commentary>`, `<tool_output>`,
782+
* `<analysis>`, `<reflection>`, and `<inner_monologue>` tag pairs.
783+
*/
778784
private val THINKING_TAG_REGEX =
779785
Regex(
780-
"<(?:think|thinking)>[\\s\\S]*?</(?:think|thinking)>",
786+
"<(?:think|thinking|commentary|tool_output|analysis" +
787+
"|reflection|inner_monologue)>" +
788+
"[\\s\\S]*?" +
789+
"</(?:think|thinking|commentary|tool_output|analysis" +
790+
"|reflection|inner_monologue)>",
781791
RegexOption.IGNORE_CASE,
782792
)
783793

@@ -803,13 +813,14 @@ class TerminalViewModel(
803813
Regex("""Bound (.+) to (\w+) \((\w+)\)\. Restart daemon to apply\.""")
804814

805815
/**
806-
* Removes chain-of-thought thinking tags from a model response.
816+
* Removes chain-of-thought and internal reasoning tags from a model response.
807817
*
808-
* Strips `<think>...</think>` and `<thinking>...</thinking>` blocks
809-
* emitted by reasoning models (Gemma, DeepSeek-R1, QwQ, etc.).
818+
* Strips `<think>`, `<thinking>`, `<commentary>`, `<tool_output>`,
819+
* `<analysis>`, `<reflection>`, and `<inner_monologue>` blocks
820+
* emitted by reasoning models.
810821
*
811822
* @param text Raw model response.
812-
* @return Response with thinking blocks removed and whitespace trimmed.
823+
* @return Response with reasoning blocks removed and whitespace trimmed.
813824
*/
814825
fun stripThinkingTags(text: String): String = text.replace(THINKING_TAG_REGEX, "").trim()
815826

app/src/test/java/com/zeroclaw/android/ui/screen/terminal/TerminalViewModelTest.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,30 @@ class TerminalViewModelTest {
172172
assertEquals("Final answer.", result)
173173
}
174174

175+
@Test
176+
@DisplayName("removes commentary tags from response")
177+
fun `removes commentary tags from response`() {
178+
val input = "<commentary>Internal notes.</commentary>The answer."
179+
val result = TerminalViewModel.stripThinkingTags(input)
180+
assertEquals("The answer.", result)
181+
}
182+
183+
@Test
184+
@DisplayName("removes tool_output tags from response")
185+
fun `removes tool_output tags from response`() {
186+
val input = "<tool_output>curl result here</tool_output>Summary."
187+
val result = TerminalViewModel.stripThinkingTags(input)
188+
assertEquals("Summary.", result)
189+
}
190+
191+
@Test
192+
@DisplayName("removes analysis tags from response")
193+
fun `removes analysis tags from response`() {
194+
val input = "<analysis>We have curl and can reach...</analysis>Yes, I can."
195+
val result = TerminalViewModel.stripThinkingTags(input)
196+
assertEquals("Yes, I can.", result)
197+
}
198+
175199
@Test
176200
@DisplayName("passes through text without thinking tags")
177201
fun `passes through text without thinking tags`() {

0 commit comments

Comments
 (0)