fix(subagent): merge terminal and process facts

This commit is contained in:
pku-xht committed 2026-08-19 01:10:29 +08:00
1 parent 34d313693d
commit 72884ec430
2 files changed
+19 -10

No files matched your search

+8 -2
View File
@@ -363,6 +363,12 @@ export async function startCodexRun(
: `${failure}\n${permission}`
return diagnostic
}
const withProcessOutcome = (facts: CodexFailureFacts): CodexFailureFacts => {
const outcome = processFailureFacts?.outcome
return outcome === undefined
? facts
: { ...facts, outcome }
}
const publishedProcessFailure = processFailure.catch(
async (error: unknown): Promise<never> => {
// Frames already queued by the exiting app-server remain authoritative.
@@ -382,7 +388,7 @@ export async function startCodexRun(
// Let stderr already queued with the terminal frame contribute its
// fixed permission fact before the non-completed result is snapshotted.
await new Promise<void>((resolve) => { setImmediate(resolve) })
const facts = wire.collectFailure()
const facts = withProcessOutcome(wire.collectFailure())
return { ...terminal, diagnostic: recordFailureDiagnostic(facts) }
} catch (error: unknown) {
// Give stderr data already queued in Node one turn to reach the wire
@@ -407,7 +413,7 @@ export async function startCodexRun(
? error.facts
: endedBeforeTerminal && processFailureFacts !== undefined
? processFailureFacts
: wire.collectFailure()
: withProcessOutcome(wire.collectFailure())
recordFailureDiagnostic(facts)
throw error instanceof CodexRunFailure
? error
@@ -1661,16 +1661,17 @@ describe('run lifecycle and quiescence', () => {
child.peer.respond(turnStart, { turn: { id: 'turn-1' } })
setImmediate(() => {
child.stderr.write('approval policy is Never; reject command')
child.peer.send(
agentMessage('partial answer', null),
turnCompleted('failed', 'turn-1', 'thread-1', {
codexErrorInfo: 'contextWindowExceeded',
}),
)
})
child.peer.send(
agentMessage('partial answer', null),
turnCompleted('failed', 'turn-1', 'thread-1', {
codexErrorInfo: 'contextWindowExceeded',
}),
)
child.settle({ exitCode: 17, signal: null })
await expect(run.result).resolves.toEqual({
output: [{ type: 'text', text: 'partial answer' }],
diagnostic: `${expectedFailureDiagnostic('turn', 'contextWindowExceeded')}\nCodex unattended decision (mode: never; request: command execution; decision: denied): Codex rejected an escalation because the selected policy never asks for approval`,
diagnostic: `${expectedFailureDiagnostic('turn', 'contextWindowExceeded', { outcome: { exitCode: 17, signal: null } })}\nCodex unattended decision (mode: never; request: command execution; decision: denied): Codex rejected an escalation because the selected policy never asks for approval`,
stopReason: 'max-tokens',
})
await run.dispose()
@@ -1735,7 +1736,9 @@ describe('run lifecycle and quiescence', () => {
child.settle({ exitCode: 17, signal: null })
await expect(run.result).resolves.toEqual({
output: [],
diagnostic: expectedFailureDiagnostic('turn', 'other'),
diagnostic: expectedFailureDiagnostic('turn', 'other', {
outcome: { exitCode: 17, signal: null },
}),
stopReason: 'error',
})
await run.dispose().catch(() => {})