diff --git a/ui-tui/src/app/turnController.ts b/ui-tui/src/app/turnController.ts
index ce6cc60006..e676fbd33b 100644
--- a/ui-tui/src/app/turnController.ts
+++ b/ui-tui/src/app/turnController.ts
@@ -88,6 +88,7 @@ class TurnController {
turnTools: string[] = []
private activeTools: ActiveTool[] = []
+ private reasoningSegmentIndex: null | number = null
private activityId = 0
private reasoningStreamingTimer: Timer = null
private reasoningTimer: Timer = null
@@ -191,6 +192,33 @@ class TurnController {
})
}
+ private syncReasoningSegment() {
+ const thinking = this.reasoningText.trim()
+
+ if (!thinking) {
+ return
+ }
+
+ const msg: Msg = {
+ kind: 'trail',
+ role: 'system',
+ text: '',
+ thinking,
+ thinkingTokens: estimateTokensRough(thinking),
+ toolTokens: this.toolTokenAcc || undefined,
+ ...(this.pendingSegmentTools.length && { tools: this.pendingSegmentTools })
+ }
+
+ if (this.reasoningSegmentIndex === null) {
+ this.reasoningSegmentIndex = this.segmentMessages.length
+ this.segmentMessages = [...this.segmentMessages, msg]
+ } else {
+ this.segmentMessages = this.segmentMessages.map((item, i) => (i === this.reasoningSegmentIndex ? msg : item))
+ }
+
+ patchTurnState({ streamSegments: this.segmentMessages })
+ }
+
flushStreamingSegment() {
const raw = this.bufRef.trimStart()
const split = raw ? (hasReasoningTag(raw) ? splitReasoning(raw) : { reasoning: '', text: raw }) : { reasoning: '', text: '' }
@@ -331,7 +359,8 @@ class TurnController {
toolTokens: savedToolTokens || undefined,
...(tools.length && { tools })
}
- const finalMessages = hasDetails(finalDetails) ? [...segments, finalDetails] : [...segments]
+ const hasReasoningSegment = this.reasoningSegmentIndex !== null
+ const finalMessages = hasDetails(finalDetails) && !hasReasoningSegment ? [...segments, finalDetails] : [...segments]
if (finalText) {
finalMessages.push({ role: 'assistant', text: finalText })
@@ -391,6 +420,7 @@ class TurnController {
this.reasoningText = incoming
this.scheduleReasoning()
+ this.syncReasoningSegment()
this.pulseReasoningStreaming()
}
@@ -401,6 +431,7 @@ class TurnController {
this.reasoningText += text
this.scheduleReasoning()
+ this.syncReasoningSegment()
this.pulseReasoningStreaming()
}
@@ -485,6 +516,7 @@ class TurnController {
this.lastStatusNote = ''
this.pendingSegmentTools = []
this.protocolWarned = false
+ this.reasoningSegmentIndex = null
this.segmentMessages = []
this.turnTools = []
this.toolTokenAcc = 0
diff --git a/ui-tui/src/components/appLayout.tsx b/ui-tui/src/components/appLayout.tsx
index c4739c0555..744f6e73c9 100644
--- a/ui-tui/src/components/appLayout.tsx
+++ b/ui-tui/src/components/appLayout.tsx
@@ -18,7 +18,6 @@ import { Banner, Panel, SessionPanel } from './branding.js'
import { MessageLine } from './messageLine.js'
import { QueuedMessages } from './queuedMessages.js'
import { TextInput } from './textInput.js'
-import { ToolTrail } from './thinking.js'
const StreamingAssistant = memo(function StreamingAssistant({
busy,
@@ -36,28 +35,6 @@ const StreamingAssistant = memo(function StreamingAssistant({
return (
<>
- {progress.showProgressArea && (
-
-
-
- )}
-
{progress.streamSegments.map((msg, i) => (