mirror of
https://github.com/stablyai/orca.git
synced 2026-09-24 08:02:33 +00:00
* perf(runtime): memoize onPtyData tail wait scan to halve per-chunk work onPtyData runs per raw PTY chunk (hundreds/sec during verbose builds and agent token streaming). For any terminal past the 2000-line / 256KB tail cap it built the full wait text (a map/trim/filter/join over the entire retained tail) and lower-cased + scanned it twice per chunk — once for the pre-append tail and once for the post-append tail — producing hundreds of KB of transient string allocation per chunk and steady main-process GC/CPU pressure under load. Cache the post-append wait state (text + lower-cased blocked-signal scan) on the pty/leaf record and reuse it as the next chunk's pre-append state. The prior chunk's post-append tail *is* this chunk's pre-append tail, so the cached scan is exact; reuse is gated on fromTail so the empty-tail preview fallback (which depends on a value updated after append) is never reused stale. This drops per-chunk full-tail scans from 2N to N+1. Adds an equivalence test proving the memoized stamping is byte-for-byte identical to the recompute-both-sides reference across split prompts, partial lines, ready-after-blocked demotion, and tail eviction, plus a count assertion (memoized N+1 vs reference 2N scans). Co-authored-by: Orca <help@stably.ai> * fix(runtime): clear memoized wait cache when a disconnected transcript is pruned pruneDisconnectedPtyTranscript empties a disconnected PTY record's retained tail but left the new tailWaitState memo untouched. If such a record resumed output (adoption/reattach while a leaf keeps it alive), onPtyData would reuse the stale pre-prune wait state (fromTail=true) as the next chunk's previous state and could miss or mis-time the waitBlockedAt stamp on that first chunk. Clear tailWaitState in the prune reset so the resumed chunk recomputes from the emptied tail. Adds a runtime guard (prune clears the cache) and a sim equivalence test covering prune-then-resume stamping. Co-authored-by: Orca <help@stably.ai> * docs(runtime): reword wait-scan comment that named a removed function Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai>
44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
/**
|
|
* Regression: pruneDisconnectedPtyTranscript empties a disconnected PTY's
|
|
* retained tail. The onPtyData wait-scan memoization caches the tail's wait
|
|
* state on the record (tailWaitState) and reuses it as the next chunk's
|
|
* "previous" state — so the prune MUST also clear that cache, or a record that
|
|
* resumes output after adoption/reattach would reuse a stale (pre-prune,
|
|
* possibly blocked) wait state and mis-stamp waitBlockedAt on its first chunk.
|
|
*/
|
|
import { describe, expect, it } from 'vitest'
|
|
import { OrcaRuntimeService } from './orca-runtime'
|
|
import type { TerminalTailWaitState } from './orca-runtime'
|
|
|
|
type PtyRecord = {
|
|
connected: boolean
|
|
tailBuffer: string[]
|
|
tailWaitState?: TerminalTailWaitState
|
|
}
|
|
type RuntimeInternals = {
|
|
recordPtyWorktree: (p: string, w: string, s?: { connected?: boolean }) => PtyRecord
|
|
pruneDisconnectedPtyTranscript: (pty: PtyRecord) => void
|
|
}
|
|
|
|
describe('pruneDisconnectedPtyTranscript clears the wait-scan cache', () => {
|
|
it('empties the tail and drops tailWaitState so resume recomputes', () => {
|
|
const runtime = new OrcaRuntimeService()
|
|
const internals = runtime as unknown as RuntimeInternals
|
|
const pty = internals.recordPtyWorktree('pty-1', 'wt-1', { connected: true })
|
|
|
|
// Simulate an established, blocked tail with a memoized wait state.
|
|
pty.tailBuffer = ['Update available! Press Enter to continue.']
|
|
pty.tailWaitState = {
|
|
waitText: 'update available! press enter to continue.',
|
|
signal: { reason: 'codex-update-prompt', index: 0 },
|
|
fromTail: true
|
|
}
|
|
|
|
pty.connected = false
|
|
internals.pruneDisconnectedPtyTranscript(pty)
|
|
|
|
expect(pty.tailBuffer).toEqual([])
|
|
expect(pty.tailWaitState).toBeUndefined()
|
|
})
|
|
})
|