Files
Agent-System/deploy/pi-agent/settle-policy.test.mjs
T
weichenandCursor 051e69ccd1 fix(pi-agent): clear recovered SDK transients before settle
auto_retry_end success=true now drops providerTransient and lastErr so
a later agent_settled can succeed when the in-process retry landed a
real target. A new error after recovery still fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:25:41 +00:00

85 lines
3.4 KiB
JavaScript

import { strict as assert } from "node:assert";
import { applyAgentEvent, classifyRunOutcome, newSettleState } from "./settle-policy.mjs";
const ui11Events = [
{ type: "message_end", message: { stopReason: "error", errorMessage: "terminated" } },
{ type: "auto_retry_start", attempt: 1, maxAttempts: 3, errorMessage: "terminated" },
{ type: "message_end", message: { stopReason: "error", errorMessage: "Connection error." } },
{ type: "auto_retry_start", attempt: 2, errorMessage: "Connection error." },
{ type: "auto_retry_start", attempt: 3, errorMessage: "Connection error." },
{ type: "auto_retry_end", success: false, attempt: 3, finalError: "Connection error." },
{ type: "agent_settled" },
];
const state = newSettleState();
for (const ev of ui11Events) {
applyAgentEvent(state, ev);
}
assert.equal(state.succeeded, false, "agent_settled after auto_retry_end success=false is not success");
assert.equal(state.providerTransient, true);
assert.equal(state.retryFailed, true);
const settledFail = classifyRunOutcome({
...state,
missing: ["output.md"],
lastErr: "Connection error.",
});
assert.equal(settledFail.ok, false);
assert.equal(settledFail.retryable, true);
assert.match(settledFail.fallback_reason, /Connection error|terminated|auto_retry/i);
const cleanMissing = classifyRunOutcome({
succeeded: true,
retryFailed: false,
providerTransient: false,
lastErr: "",
missing: ["output.md"],
});
assert.equal(cleanMissing.ok, false);
assert.equal(cleanMissing.retryable, false, "clean settle + missing target is permanent");
assert.match(cleanMissing.fallback_reason, /missing target deliverable/);
const promptEmpty = classifyRunOutcome({
succeeded: false,
retryFailed: false,
providerTransient: false,
lastErr: "prompt_empty",
missing: [],
});
assert.equal(promptEmpty.retryable, false);
const recovered = newSettleState();
for (const ev of [
{ type: "message_end", message: { stopReason: "error", errorMessage: "terminated" } },
{ type: "auto_retry_start", attempt: 1, maxAttempts: 3, errorMessage: "terminated" },
{ type: "auto_retry_end", success: true, attempt: 1 },
{ type: "agent_settled" },
]) {
applyAgentEvent(recovered, ev);
}
assert.equal(recovered.retryFailed, false, "recovered SDK retry must clear retryFailed");
assert.equal(recovered.providerTransient, false, "recovered SDK retry must clear providerTransient");
assert.equal(recovered.lastErr, "", "recovered SDK retry must clear lastErr");
assert.equal(recovered.succeeded, true, "settle after recovered auto_retry must succeed");
const recoveredOk = classifyRunOutcome({
...recovered,
missing: [],
});
assert.equal(recoveredOk.ok, true, "settled + target present after recovered retry is success");
assert.equal(recoveredOk.retryable, false);
const recoveredThenNewError = newSettleState();
for (const ev of [
{ type: "message_end", message: { stopReason: "error", errorMessage: "terminated" } },
{ type: "auto_retry_end", success: true, attempt: 1 },
{ type: "message_end", message: { stopReason: "error", errorMessage: "Connection error." } },
{ type: "agent_settled" },
]) {
applyAgentEvent(recoveredThenNewError, ev);
}
assert.equal(recoveredThenNewError.succeeded, false, "a new error after recovery must not be masked");
assert.equal(recoveredThenNewError.providerTransient, true);
assert.match(recoveredThenNewError.lastErr, /Connection error/i);
console.log("settle-policy.test.mjs PASS");