Treat local agent API failures as unhealthy

This commit is contained in:
Codex committed 2026-07-07 16:04:40 -04:00
1 parent fb0feb0028
commit f502bfbd42
1 file changed
+13 -2
+13 -2
View File
@@ -236,6 +236,13 @@ export interface AgentRunResult {
error?: string; error?: string;
} }
function agentFailureOutput(output: string): string | null {
const text = output.trim();
if (/^API call failed\b/i.test(text)) return text.slice(0, 300);
if (/connection error/i.test(text) && /failed/i.test(text)) return text.slice(0, 300);
return null;
}
/** /**
* Drive a connected agent with a one-shot headless prompt (real round-trip — SPENDS the agent's quota). * Drive a connected agent with a one-shot headless prompt (real round-trip — SPENDS the agent's quota).
* Used by /ping (liveness proof) and /dispatch (actually using the operator). * Used by /ping (liveness proof) and /dispatch (actually using the operator).
@@ -270,7 +277,9 @@ export function runLocalAgent(
child.on('close', (code) => { child.on('close', (code) => {
const latencyMs = Date.now() - t0; const latencyMs = Date.now() - t0;
const output = out.trim().slice(0, maxChars); const output = out.trim().slice(0, maxChars);
if (code === 0) finish({ ok: true, latencyMs, output }); const semanticError = agentFailureOutput(output);
if (code === 0 && !semanticError) finish({ ok: true, latencyMs, output });
else if (semanticError) finish({ ok: false, latencyMs, output, error: semanticError });
else finish({ ok: false, latencyMs, output, error: (errOut.trim() || `exited with code ${code}`).slice(0, 300) }); else finish({ ok: false, latencyMs, output, error: (errOut.trim() || `exited with code ${code}`).slice(0, 300) });
}); });
}); });
@@ -329,7 +338,9 @@ export function localAgentChat(id: string, prompt: string, opts: { model?: strin
let content = out.trim(); let content = out.trim();
if (outFile) { try { content = (readFileSync(outFile, 'utf8').trim() || content); } catch { /* fall back to stdout */ } } if (outFile) { try { content = (readFileSync(outFile, 'utf8').trim() || content); } catch { /* fall back to stdout */ } }
finish(() => { finish(() => {
if (code === 0 && content) resolve(content); const semanticError = agentFailureOutput(content);
if (code === 0 && content && !semanticError) resolve(content);
else if (semanticError) reject(new Error(semanticError));
else reject(new Error((errOut.trim() || content || `exited with code ${code}`).slice(0, 800))); else reject(new Error((errOut.trim() || content || `exited with code ${code}`).slice(0, 800)));
}); });
}); });