mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 08:03:20 +00:00
test: isolate flood restoration and retained provider fixes together
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { createRuntime, syncSinglePty } from './orca-runtime-test-fixtures.spec'
|
||||
|
||||
describe('hidden-output recovery after provider reattach', () => {
|
||||
it('uses retained provider modes instead of the pre-attach redraw suffix', async () => {
|
||||
const runtime = createRuntime()
|
||||
const serializeProviderBuffer = vi.fn(async () => ({
|
||||
data: '\x1b[?1049hRetained TUI',
|
||||
cols: 100,
|
||||
rows: 30,
|
||||
seq: 1000,
|
||||
source: 'headless' as const,
|
||||
alternateScreen: true
|
||||
}))
|
||||
runtime.setPtyController({
|
||||
write: () => true,
|
||||
kill: () => true,
|
||||
getForegroundProcess: async () => null,
|
||||
serializeProviderBuffer
|
||||
})
|
||||
syncSinglePty(runtime, 'pty-1')
|
||||
runtime.onPtyData('pty-1', '\x1b[HRedraw without the original alternate-screen entry', 60)
|
||||
runtime.synchronizePtyOutputSequenceFromProvider('pty-1', {
|
||||
value: 1000,
|
||||
generation: 'continued'
|
||||
})
|
||||
|
||||
const snapshot = await runtime.serializeHiddenOutputRecoveryBuffer('pty-1', {
|
||||
scrollbackRows: 5000
|
||||
})
|
||||
|
||||
expect(snapshot).toMatchObject({ data: '\x1b[?1049hRetained TUI', alternateScreen: true })
|
||||
expect(serializeProviderBuffer).toHaveBeenCalledWith('pty-1', { scrollbackRows: 5000 })
|
||||
})
|
||||
|
||||
it('keeps the renderer fallback for providers without retained snapshots', async () => {
|
||||
const runtime = createRuntime()
|
||||
runtime.onPtyData('pty-1', 'partial redraw', 14)
|
||||
runtime.synchronizePtyOutputSequenceFromProvider('pty-1', {
|
||||
value: 1000,
|
||||
generation: 'continued'
|
||||
})
|
||||
const serializeBuffer = vi.fn(async () => ({
|
||||
data: '\x1b[?1049hRenderer TUI',
|
||||
cols: 100,
|
||||
rows: 30
|
||||
}))
|
||||
runtime.setPtyController({
|
||||
write: () => true,
|
||||
kill: () => true,
|
||||
getForegroundProcess: async () => null,
|
||||
hasRendererSerializer: () => true,
|
||||
serializeBuffer
|
||||
})
|
||||
|
||||
await expect(runtime.serializeHiddenOutputRecoveryBuffer('pty-1')).resolves.toMatchObject({
|
||||
data: '\x1b[?1049hRenderer TUI',
|
||||
source: 'renderer'
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps an authoritative main model without polling the provider', async () => {
|
||||
const runtime = createRuntime()
|
||||
const serializeProviderBuffer = vi.fn(async () => null)
|
||||
runtime.setPtyController({
|
||||
write: () => true,
|
||||
kill: () => true,
|
||||
getForegroundProcess: async () => null,
|
||||
serializeProviderBuffer
|
||||
})
|
||||
runtime.onPtyData('pty-1', '\x1b[?1049hLive TUI', 20)
|
||||
|
||||
await expect(runtime.serializeHiddenOutputRecoveryBuffer('pty-1')).resolves.toMatchObject({
|
||||
alternateScreen: true,
|
||||
source: 'headless'
|
||||
})
|
||||
expect(serializeProviderBuffer).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -47,6 +47,10 @@ export class OrcaRuntimeWithSerializeMainTerminalBuffer extends OrcaRuntimeWithA
|
||||
pendingEscapeTailAnsi?: string
|
||||
terminalOwner?: 'shell'
|
||||
} | null> {
|
||||
const restoredSnapshot = await this.serializePreferredRestoredTerminalBuffer(ptyId, opts)
|
||||
if (restoredSnapshot) {
|
||||
return restoredSnapshot
|
||||
}
|
||||
const headlessSnapshot = await this.serializeHeadlessTerminalBuffer(ptyId, {
|
||||
...opts,
|
||||
includeEmpty: true
|
||||
|
||||
@@ -23,18 +23,9 @@ export class OrcaRuntimeWithSerializeTerminalBufferFromAvailableState extends Or
|
||||
kittyKeyboardFlags?: number
|
||||
terminalOwner?: 'shell'
|
||||
} | null> {
|
||||
if (this.providerSnapshotPreferredPtys.has(ptyId)) {
|
||||
// Why: pre-attach stream bytes only form a suffix of restored state. A
|
||||
// sequenced provider snapshot safely reconciles live bytes; renderer is
|
||||
// the fallback when an older provider cannot expose that boundary.
|
||||
const providerSnapshot = await this.serializeProviderTerminalBuffer(ptyId, opts)
|
||||
if (providerSnapshot) {
|
||||
return providerSnapshot
|
||||
}
|
||||
const rendererSnapshot = await this.serializeRendererTerminalBuffer(ptyId, opts)
|
||||
if (rendererSnapshot) {
|
||||
return rendererSnapshot
|
||||
}
|
||||
const restoredSnapshot = await this.serializePreferredRestoredTerminalBuffer(ptyId, opts)
|
||||
if (restoredSnapshot) {
|
||||
return restoredSnapshot
|
||||
}
|
||||
const headlessSnapshot = await this.serializeHeadlessTerminalBuffer(ptyId, opts)
|
||||
if (headlessSnapshot) {
|
||||
@@ -58,6 +49,20 @@ export class OrcaRuntimeWithSerializeTerminalBufferFromAvailableState extends Or
|
||||
: rendererSnapshot
|
||||
}
|
||||
|
||||
protected async serializePreferredRestoredTerminalBuffer(
|
||||
ptyId: string,
|
||||
opts: { scrollbackRows?: number } = {}
|
||||
) {
|
||||
if (!this.providerSnapshotPreferredPtys.has(ptyId)) {
|
||||
return null
|
||||
}
|
||||
// Pre-attach bytes are only a suffix; older providers can fall back to the renderer.
|
||||
return (
|
||||
(await this.serializeProviderTerminalBuffer(ptyId, opts)) ??
|
||||
(await this.serializeRendererTerminalBuffer(ptyId, opts))
|
||||
)
|
||||
}
|
||||
|
||||
async serializeRendererTerminalBuffer(
|
||||
ptyId: string,
|
||||
opts: { scrollbackRows?: number } = {}
|
||||
|
||||
Reference in New Issue
Block a user