fix: keep codex redraws off pty batch path (#3992)
This commit is contained in:
parent
5e7d097682
commit
dd1b28ba2e
|
|
@ -3266,6 +3266,40 @@ describe('registerPtyHandlers', () => {
|
|||
}
|
||||
})
|
||||
|
||||
it('sends larger ANSI redraws immediately after terminal input', async () => {
|
||||
vi.useFakeTimers()
|
||||
const mockProc = createMockProc()
|
||||
spawnMock.mockReturnValue(mockProc.proc)
|
||||
|
||||
try {
|
||||
registerPtyHandlers(mainWindow as never)
|
||||
const spawnResult = (await handlers.get('pty:spawn')!(null, {
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
cwd: '/tmp'
|
||||
})) as { id: string }
|
||||
const writeListener = getPtyWriteListener()
|
||||
|
||||
writeListener(null, {
|
||||
id: spawnResult.id,
|
||||
data: 'a'
|
||||
})
|
||||
mainWindow.webContents.send.mockClear()
|
||||
|
||||
const redraw = `\x1b[2J\x1b[H${'codex composer redraw '.repeat(80)}`
|
||||
mockProc.emitData(redraw)
|
||||
|
||||
expect(mainWindow.webContents.send).toHaveBeenCalledWith('pty:data', {
|
||||
id: spawnResult.id,
|
||||
data: redraw
|
||||
})
|
||||
vi.advanceTimersByTime(8)
|
||||
expect(mainWindow.webContents.send).toHaveBeenCalledTimes(1)
|
||||
} finally {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('batches combined pending output that exceeds the interactive size limit', async () => {
|
||||
vi.useFakeTimers()
|
||||
const mockProc = createMockProc()
|
||||
|
|
|
|||
|
|
@ -946,12 +946,23 @@ export function registerPtyHandlers(
|
|||
// large output and non-interactive output must still use the batcher.
|
||||
const INTERACTIVE_OUTPUT_WINDOW_MS = 100
|
||||
const INTERACTIVE_OUTPUT_MAX_CHARS = 1024
|
||||
const INTERACTIVE_REDRAW_MAX_CHARS = PTY_BATCH_FLUSH_CHUNK_CHARS
|
||||
const BACKGROUND_OUTPUT_INPUT_QUIET_MS = 50
|
||||
const BACKGROUND_OUTPUT_MAX_INPUT_HOLD_MS = 250
|
||||
let lastRendererInputAt = Number.NEGATIVE_INFINITY
|
||||
let lastRendererInputPtyId: string | null = null
|
||||
let backgroundFlushHeldSince: number | null = null
|
||||
|
||||
function isLikelyInteractiveRedraw(data: string): boolean {
|
||||
if (data.length <= INTERACTIVE_OUTPUT_MAX_CHARS) {
|
||||
return true
|
||||
}
|
||||
// Why: Codex-style TUIs can repaint more than 1 KB per keypress. ANSI
|
||||
// control redraws are still latency-sensitive, while plain command output
|
||||
// should stay on the throughput batch path.
|
||||
return data.length <= INTERACTIVE_REDRAW_MAX_CHARS && data.includes('\x1b[')
|
||||
}
|
||||
|
||||
function getChunkStartSeq(endSeq: number | undefined, data: string): number | undefined {
|
||||
return typeof endSeq === 'number' ? Math.max(0, endSeq - data.length) : undefined
|
||||
}
|
||||
|
|
@ -1176,7 +1187,7 @@ export function registerPtyHandlers(
|
|||
const nextData = pending.data
|
||||
const lastInputAt = lastInputAtByPty.get(payload.id)
|
||||
const isInteractiveOutput =
|
||||
nextData.length <= INTERACTIVE_OUTPUT_MAX_CHARS &&
|
||||
isLikelyInteractiveRedraw(nextData) &&
|
||||
lastInputAt !== undefined &&
|
||||
performance.now() - lastInputAt <= INTERACTIVE_OUTPUT_WINDOW_MS
|
||||
if (isInteractiveOutput) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue