fix(subagent): close Codex provider review findings
This commit is contained in:
@@ -90,8 +90,6 @@ class ProtocolPeer {
|
||||
|
||||
interface FakeChildOptions {
|
||||
readonly pid?: number
|
||||
readonly stdin?: boolean
|
||||
readonly stdout?: boolean
|
||||
readonly exitOnTerminate?: boolean
|
||||
readonly waitForExitResult?: boolean
|
||||
readonly doneError?: Error
|
||||
@@ -161,8 +159,8 @@ function fakeChild(options: FakeChildOptions = {}): FakeChild {
|
||||
})
|
||||
const handle: SubprocessHandle = {
|
||||
pid: options.pid ?? 1234,
|
||||
stdin: options.stdin === false ? undefined : toChild,
|
||||
stdout: options.stdout === false ? undefined : fromChild,
|
||||
stdin: toChild,
|
||||
stdout: fromChild,
|
||||
stderr: undefined,
|
||||
collected: {},
|
||||
done,
|
||||
@@ -334,7 +332,6 @@ describe('CodexAppServerWire', () => {
|
||||
const wire = new CodexAppServerWire(child.handle.stdout!, child.handle.stdin!)
|
||||
expect(wire.collectOutput()).toEqual([])
|
||||
wire.start()
|
||||
wire.start()
|
||||
|
||||
const initializing = wire.initialize(new AbortController().signal)
|
||||
const initialize = await child.peer.nextMethod('initialize')
|
||||
@@ -451,27 +448,6 @@ describe('CodexAppServerWire', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('rejects a turn before thread publication and a second one-shot turn', async () => {
|
||||
const child = fakeChild()
|
||||
const wire = new CodexAppServerWire(child.handle.stdout!, child.handle.stdin!)
|
||||
await expect(wire.runTurn(['task'], new AbortController().signal, () => false))
|
||||
.rejects.toThrow('before thread/start')
|
||||
const initialized = await initializeWire()
|
||||
const first = initialized.wire.runTurn(
|
||||
['task'],
|
||||
new AbortController().signal,
|
||||
() => false,
|
||||
)
|
||||
await initialized.child.peer.nextMethod('turn/start')
|
||||
await expect(initialized.wire.runTurn(
|
||||
['again'],
|
||||
new AbortController().signal,
|
||||
() => false,
|
||||
)).rejects.toThrow('already started')
|
||||
initialized.wire.close()
|
||||
await expect(first).rejects.toThrow('transport closed')
|
||||
})
|
||||
|
||||
it('fails closed for empty output, malformed messages, phases, and terminal status', async () => {
|
||||
const scenarios: Array<{
|
||||
readonly frames: JsonObject[]
|
||||
@@ -757,6 +733,17 @@ describe('CodexAppServerWire', () => {
|
||||
await expect(pending).rejects.toThrow('stdout broke')
|
||||
wire.close()
|
||||
}
|
||||
{
|
||||
const child = fakeChild()
|
||||
const wire = new CodexAppServerWire(child.handle.stdout!, child.handle.stdin!)
|
||||
wire.start()
|
||||
const pending = wire.initialize(new AbortController().signal)
|
||||
await child.peer.nextMethod('initialize')
|
||||
child.toChild.emit('error', new Error('stdin broke'))
|
||||
await expect(pending).rejects.toThrow('stdin broke')
|
||||
wire.close()
|
||||
child.toChild.emit('error', new Error('late stdin close'))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -918,16 +905,6 @@ describe('run lifecycle and quiescence', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('rejects a missing protocol stream after reaping the unpublished child', async () => {
|
||||
for (const options of [{ stdin: false }, { stdout: false }]) {
|
||||
const child = fakeChild(options)
|
||||
await expect(startCodexRun(request(), runSpec(child)))
|
||||
.rejects.toThrow('dropped a piped protocol stream')
|
||||
expect(child.terminate).toHaveBeenCalledTimes(1)
|
||||
expect(child.waitForExit).toHaveBeenCalledTimes(1)
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps overlapping runs isolated', async () => {
|
||||
const first = fakeChild()
|
||||
const second = fakeChild()
|
||||
|
||||
Reference in New Issue
Block a user