Treat local agent API failures as unhealthy
This commit is contained in:
1 parent
fb0feb0028
commit
f502bfbd42
1 file changed
+13
-2
@@ -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)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user