mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 00:04:01 +00:00
perf(runtime): cache unchanged prompt verification tail
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
AGENT_PROMPT_HOOK_EFFECT_TIMEOUT_MS,
|
||||
type AgentPromptActivity,
|
||||
isAgentPromptStalledError,
|
||||
readAgentPromptWaitText,
|
||||
resolveAgentPromptEffectTimeoutMs,
|
||||
verifyAgentPromptSubmission
|
||||
} from './agent-prompt-submission-verification'
|
||||
@@ -23,6 +24,17 @@ function activity(overrides: Partial<AgentPromptActivity> = {}): AgentPromptActi
|
||||
describe('agent prompt submission verification', () => {
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('reuses wait text while the PTY output sequence is unchanged', () => {
|
||||
const cache: { outputSequence?: number; waitText?: string } = {}
|
||||
const readWaitText = vi.fn(() => 'retained terminal tail')
|
||||
|
||||
expect(readAgentPromptWaitText(cache, 7, readWaitText)).toBe('retained terminal tail')
|
||||
expect(readAgentPromptWaitText(cache, 7, readWaitText)).toBe('retained terminal tail')
|
||||
expect(readAgentPromptWaitText(cache, 8, readWaitText)).toBe('retained terminal tail')
|
||||
|
||||
expect(readWaitText).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('accepts an observed working transition', async () => {
|
||||
vi.useFakeTimers()
|
||||
let current = activity()
|
||||
|
||||
@@ -22,6 +22,11 @@ export type AgentPromptActivity = Readonly<{
|
||||
status: 'working' | 'permission' | 'idle' | null
|
||||
}>
|
||||
|
||||
export type AgentPromptWaitTextCache = {
|
||||
outputSequence?: number
|
||||
waitText?: string
|
||||
}
|
||||
|
||||
type AgentPromptVerificationOptions = {
|
||||
baseline: AgentPromptActivity
|
||||
readActivity: () => AgentPromptActivity
|
||||
@@ -47,6 +52,20 @@ export function isAgentPromptStalledError(error: unknown): boolean {
|
||||
)
|
||||
}
|
||||
|
||||
export function readAgentPromptWaitText(
|
||||
cache: AgentPromptWaitTextCache,
|
||||
outputSequence: number,
|
||||
readWaitText: () => string
|
||||
): string {
|
||||
if (cache.outputSequence === outputSequence && cache.waitText !== undefined) {
|
||||
return cache.waitText
|
||||
}
|
||||
const waitText = readWaitText()
|
||||
cache.outputSequence = outputSequence
|
||||
cache.waitText = waitText
|
||||
return waitText
|
||||
}
|
||||
|
||||
export async function verifyAgentPromptSubmission(
|
||||
options: AgentPromptVerificationOptions
|
||||
): Promise<void> {
|
||||
|
||||
@@ -106,6 +106,8 @@ import {
|
||||
} from '../../shared/agent-prompt-injection'
|
||||
import {
|
||||
type AgentPromptActivity,
|
||||
type AgentPromptWaitTextCache,
|
||||
readAgentPromptWaitText,
|
||||
resolveAgentPromptEffectTimeoutMs,
|
||||
verifyAgentPromptSubmission
|
||||
} from './agent-prompt-submission-verification'
|
||||
@@ -19366,7 +19368,8 @@ export class OrcaRuntimeService {
|
||||
|
||||
private getTerminalAgentStatusSnapshot(
|
||||
handle: string,
|
||||
expectedPtyId: string
|
||||
expectedPtyId: string,
|
||||
waitTextOverride?: string
|
||||
): TerminalAgentStatusSnapshot {
|
||||
const pty = this.getLivePtyForHandle(handle)
|
||||
if (pty) {
|
||||
@@ -19386,11 +19389,9 @@ export class OrcaRuntimeService {
|
||||
{ title: pty.pty.title, updatedAt: pty.pty.titleUpdatedAt },
|
||||
{ title: pty.pty.lastOscTitle, updatedAt: pty.pty.lastOscTitleAt }
|
||||
)
|
||||
const waitText = buildTerminalWaitText(
|
||||
pty.pty.tailBuffer,
|
||||
pty.pty.tailPartialLine,
|
||||
pty.pty.preview
|
||||
)
|
||||
const waitText =
|
||||
waitTextOverride ??
|
||||
buildTerminalWaitText(pty.pty.tailBuffer, pty.pty.tailPartialLine, pty.pty.preview)
|
||||
return {
|
||||
waitText,
|
||||
waitBlockedAt: pty.pty.waitBlockedAt,
|
||||
@@ -19418,7 +19419,9 @@ export class OrcaRuntimeService {
|
||||
{ title: this.tabs.get(leaf.tabId)?.title, updatedAt: 0 }
|
||||
)
|
||||
return {
|
||||
waitText: buildTerminalWaitText(leaf.tailBuffer, leaf.tailPartialLine, leaf.preview),
|
||||
waitText:
|
||||
waitTextOverride ??
|
||||
buildTerminalWaitText(leaf.tailBuffer, leaf.tailPartialLine, leaf.preview),
|
||||
waitBlockedAt: leaf.waitBlockedAt,
|
||||
title: title?.title ?? null,
|
||||
titleStatus: title ? detectAgentStatusFromTitle(title.title) : leaf.lastAgentStatus,
|
||||
@@ -20077,7 +20080,8 @@ export class OrcaRuntimeService {
|
||||
}
|
||||
assertAgentPromptRequestActive(options.signal)
|
||||
this.assertAgentPromptGeneration(ptyId, generation)
|
||||
const baseline = this.getAgentPromptActivity(handle, ptyId)
|
||||
const waitTextCache: AgentPromptWaitTextCache = {}
|
||||
const baseline = this.getAgentPromptActivity(handle, ptyId, waitTextCache)
|
||||
this.assertAgentPromptPermissionSafe(permissionBaseline, baseline)
|
||||
const suffixWrote = this.ptyController?.write(ptyId, AGENT_PROMPT_SUBMIT) ?? false
|
||||
if (!suffixWrote) {
|
||||
@@ -20085,7 +20089,7 @@ export class OrcaRuntimeService {
|
||||
}
|
||||
await verifyAgentPromptSubmission({
|
||||
baseline,
|
||||
readActivity: () => this.getAgentPromptActivity(handle, ptyId),
|
||||
readActivity: () => this.getAgentPromptActivity(handle, ptyId, waitTextCache),
|
||||
timeoutMs: resolveAgentPromptEffectTimeoutMs(this.getPtyAgent(ptyId)),
|
||||
signal: options.signal
|
||||
})
|
||||
@@ -20114,8 +20118,13 @@ export class OrcaRuntimeService {
|
||||
}
|
||||
}
|
||||
|
||||
private getAgentPromptActivity(handle: string, ptyId: string): AgentPromptActivity {
|
||||
private getAgentPromptActivity(
|
||||
handle: string,
|
||||
ptyId: string,
|
||||
waitTextCache?: AgentPromptWaitTextCache
|
||||
): AgentPromptActivity {
|
||||
this.assertLiveTerminalHandleTargetsPty(handle, ptyId)
|
||||
const outputSequence = this.getPtyOutputSequence(ptyId)
|
||||
const explicitCandidate = this.getFreshExplicitAgentStatusForHandle(handle)
|
||||
const explicitFloor = this.agentPromptExplicitStatusFloorByPtyId.get(ptyId)
|
||||
const explicit =
|
||||
@@ -20133,7 +20142,14 @@ export class OrcaRuntimeService {
|
||||
(!explicit ||
|
||||
lifecycle.updatedAt > explicit.updatedAt ||
|
||||
(lifecycle.updatedAt === explicit.updatedAt && lifecycle.status === 'permission'))
|
||||
const terminal = this.getTerminalAgentStatusSnapshot(handle, ptyId)
|
||||
const waitText = waitTextCache
|
||||
? readAgentPromptWaitText(
|
||||
waitTextCache,
|
||||
outputSequence,
|
||||
() => this.getTerminalAgentStatusSnapshot(handle, ptyId).waitText
|
||||
)
|
||||
: undefined
|
||||
const terminal = this.getTerminalAgentStatusSnapshot(handle, ptyId, waitText)
|
||||
const status = this.hasAuthoritativeTerminalWaitPermission(terminal, explicit, lifecycle)
|
||||
? 'permission'
|
||||
: lifecycleIsNewer
|
||||
@@ -20148,7 +20164,7 @@ export class OrcaRuntimeService {
|
||||
// stateStartedAt, not updatedAt — same-state tool/prompt pings refresh updatedAt and would
|
||||
// otherwise pass off an in-progress turn as a new one.
|
||||
explicitWorkingStartedAt: explicit?.status === 'working' ? explicit.stateStartedAt : null,
|
||||
outputSequence: this.getPtyOutputSequence(ptyId),
|
||||
outputSequence,
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user