mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
test(agent-session): await the fake Codex child's requests in compact-exit
Restarting after a mid-command exit runs the exit settlement, a fresh acquire and the queued send's handover through the SQL workers before turn/start, which outran vi.waitFor's 1 s poll under load. The shared fake Codex now resolves nextRequest(method) when a child receives that request; compact-exit awaits it instead of polling the calls list. Seen once in a contended local sweep (8 ms SQL reply delay plus CPU load): "expected [] to have a length of 1" at the turn/start poll. The new version passed 5/5 under the same delay.
This commit is contained in:
@@ -80,14 +80,16 @@ it('delivers what waited behind the command once its child dies mid-command, wit
|
||||
'agentSession.create',
|
||||
harness.createIntentParams()
|
||||
)
|
||||
const compacting = harness.codex.nextRequest('thread/compact/start')
|
||||
const command = await startCompact(created.fence)
|
||||
await vi.waitFor(() => expect(calls('thread/compact/start')).toHaveLength(1))
|
||||
await compacting
|
||||
await send('after the exit')
|
||||
|
||||
const restarted = harness.codex.nextRequest('turn/start')
|
||||
const dead = exitChild()
|
||||
|
||||
await vi.waitFor(() => expect(calls('turn/start')).toHaveLength(1))
|
||||
expect(calls('turn/start')[0]).not.toBe(dead)
|
||||
expect(await restarted).not.toBe(dead)
|
||||
expect(calls('turn/start')).toHaveLength(1)
|
||||
const settled = await snapshot()
|
||||
const turn = settled.items.find(
|
||||
(item) => item.itemId === structuredAgentSessionCommandTurn(command).itemId
|
||||
@@ -103,8 +105,9 @@ it('ends a command Codex has not opened a turn for by stopping its child, and th
|
||||
'agentSession.create',
|
||||
harness.createIntentParams()
|
||||
)
|
||||
const compacting = harness.codex.nextRequest('thread/compact/start')
|
||||
const command = await startCompact(created.fence)
|
||||
await vi.waitFor(() => expect(calls('thread/compact/start')).toHaveLength(1))
|
||||
await compacting
|
||||
const first = threadChild()
|
||||
const { itemId, turnId } = structuredAgentSessionCommandTurn(command)
|
||||
|
||||
@@ -123,7 +126,8 @@ it('ends a command Codex has not opened a turn for by stopping its child, and th
|
||||
const turn = (await snapshot()).items.find((item) => item.itemId === itemId)
|
||||
expect(readAgentJournalTurn(turn?.body)?.state).toBe('interrupted')
|
||||
})
|
||||
const restarted = harness.codex.nextRequest('turn/start')
|
||||
await send('after the stop')
|
||||
await vi.waitFor(() => expect(calls('turn/start')).toHaveLength(1))
|
||||
expect(calls('turn/start')[0]).not.toBe(first)
|
||||
expect(await restarted).not.toBe(first)
|
||||
expect(calls('turn/start')).toHaveLength(1)
|
||||
})
|
||||
|
||||
+11
@@ -51,12 +51,15 @@ export type FakeCodex = {
|
||||
connections: FakeCodexConnection[]
|
||||
openConnection: typeof openCodexAppServerConnection
|
||||
live: () => FakeCodexConnection
|
||||
/** Resolves with the child that next receives `method`. */
|
||||
nextRequest: (method: string) => Promise<FakeCodexConnection>
|
||||
notify: (method: string, params: unknown) => void
|
||||
ask: (id: number, method: string, params: unknown) => void
|
||||
}
|
||||
|
||||
function fakeCodex(): FakeCodex {
|
||||
const connections: FakeCodexConnection[] = []
|
||||
const requestWaiters = new Map<string, ((connection: FakeCodexConnection) => void)[]>()
|
||||
const openConnection: typeof openCodexAppServerConnection = async (launch, handlers = {}) => {
|
||||
const connection: FakeCodexConnection = {
|
||||
launch,
|
||||
@@ -68,6 +71,10 @@ function fakeCodex(): FakeCodex {
|
||||
closed: false,
|
||||
request: async (method, params) => {
|
||||
connection.calls.push({ method, params })
|
||||
requestWaiters
|
||||
.get(method)
|
||||
?.splice(0)
|
||||
.forEach((resolve) => resolve(connection))
|
||||
if (method === 'thread/start') {
|
||||
return { thread: { id: THREAD, path: '/rollouts/integration.jsonl' } }
|
||||
}
|
||||
@@ -123,6 +130,10 @@ function fakeCodex(): FakeCodex {
|
||||
connections,
|
||||
openConnection,
|
||||
live,
|
||||
nextRequest: (method) =>
|
||||
new Promise((resolve) => {
|
||||
requestWaiters.set(method, [...(requestWaiters.get(method) ?? []), resolve])
|
||||
}),
|
||||
notify: (method, params) => live().handlers.onNotification?.(method, params),
|
||||
ask: (id, method, params) => live().handlers.onServerRequest?.({ id, method, params })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user