fix(tui): ignore late thinking deltas after completion (#31055)
* fix(tui): ignore late thinking deltas after completion Prevent stale reasoning events from repainting the TUI status after a turn has already completed and the UI is idle. * test(tui): restore timers after thinking delta assertion Keep fake timer cleanup in a finally block so assertion failures cannot leak timer mode into later tests.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { STARTUP_IMAGE, STARTUP_QUERY } from '../config/env.js'
|
||||
import { STREAM_BATCH_MS } from '../config/timing.js'
|
||||
import { SETUP_REQUIRED_TITLE, buildSetupRequiredSections } from '../content/setup.js'
|
||||
import { buildSetupRequiredSections, SETUP_REQUIRED_TITLE } from '../content/setup.js'
|
||||
import type {
|
||||
CommandsCatalogResponse,
|
||||
ConfigFullResponse,
|
||||
@@ -313,6 +313,10 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
}
|
||||
|
||||
case 'thinking.delta': {
|
||||
if (!getUiState().busy) {
|
||||
return
|
||||
}
|
||||
|
||||
const text = ev.payload?.text
|
||||
|
||||
if (text !== undefined) {
|
||||
@@ -340,6 +344,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
|
||||
if (p.kind === 'goal') {
|
||||
sys(p.text)
|
||||
|
||||
const brief = p.text.startsWith('✓')
|
||||
? '✓ goal complete'
|
||||
: p.text.startsWith('↻')
|
||||
@@ -347,8 +352,10 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
: p.text.startsWith('⏸')
|
||||
? '⏸ goal paused'
|
||||
: 'ready'
|
||||
|
||||
setStatus(brief)
|
||||
restoreStatusAfter(6000)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -356,6 +363,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
|
||||
if (p.kind === 'compressing') {
|
||||
sys(p.text)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -528,6 +536,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
case 'tool.complete': {
|
||||
const inlineDiffText =
|
||||
ev.payload.inline_diff && getUiState().inlineDiffs ? stripAnsi(String(ev.payload.inline_diff)).trim() : ''
|
||||
|
||||
const resultText = ev.payload.result_text ? stripAnsi(String(ev.payload.result_text)) : undefined
|
||||
|
||||
if (inlineDiffText) {
|
||||
@@ -589,7 +598,6 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
sys(`[bg ${ev.payload.task_id}] ${ev.payload.text}`)
|
||||
|
||||
return
|
||||
|
||||
case 'review.summary': {
|
||||
// Self-improvement background review emitted a persistent summary
|
||||
// of what it saved to memory/skills. Surface it as a system line
|
||||
@@ -597,6 +605,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
// flash. Python-side already formats it as "💾 Self-improvement
|
||||
// review: …".
|
||||
const text = String(ev.payload?.text ?? '').trim()
|
||||
|
||||
if (text) {
|
||||
sys(text)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user