fix: return recovery action descriptors (#174)

Co-authored-by: AgentRun Codex <agentrun-codex@users.noreply.github.com>
This commit is contained in:
Lyon
2026-06-12 01:20:02 +08:00
committed by GitHub
parent 1a9b6debbb
commit 216209ca95
11 changed files with 298 additions and 74 deletions
+33 -1
View File
@@ -422,7 +422,39 @@ async function runFailureCase(options: { client: ManagerClient; managerUrl: stri
}
const command = await options.client.get(`/api/v1/runs/${item.runId}/commands/${item.commandId}`) as { state?: string };
assert.equal(command.state, "failed", options.mode);
assertNoSecretLeak(events);
const envelope = await options.client.get(`/api/v1/runs/${item.runId}/commands/${item.commandId}/result`) as JsonRecord;
if (options.mode === "provider-503-terminal") {
const classification = envelope.terminalClassification as JsonRecord;
const liveness = envelope.liveness as JsonRecord;
const timeoutBudget = liveness.timeoutBudget as JsonRecord;
assert.equal(classification.category, "provider-failed");
assert.equal(classification.providerEvidence, "failure-kind");
assert.equal(classification.providerInterruptionKnown, true);
assert.equal(classification.failureKind, "provider-http-error");
assert.equal(liveness.phase, "terminal");
assert.equal(typeof liveness.lastEventAgeMs, "number");
assert.equal(timeoutBudget.timeoutKind, "idle");
assert.equal(typeof timeoutBudget.idleElapsedMs, "number");
assertRecoveryActionDescriptors(liveness.recoveryActions);
}
assertNoSecretLeak({ events, envelope });
}
function assertRecoveryActionDescriptors(value: unknown): void {
assert.ok(Array.isArray(value), "recoveryActions must be an array");
const text = JSON.stringify(value);
assert.equal(text.includes("./scripts/agentrun sessions"), false, "server recoveryActions must not expose old sessions CLI paths");
assert.equal(text.includes("./scripts/agentrun commands"), false, "server recoveryActions must not expose old commands CLI paths");
assert.equal(text.includes("bun scripts/cli.ts agentrun"), false, "server recoveryActions must not hardcode render-only client commands");
for (const item of value) {
const action = item as JsonRecord;
assert.equal(Object.prototype.hasOwnProperty.call(action, "command"), false, "recovery action must be a descriptor, not a rendered command string");
assert.equal(typeof action.action, "string");
assert.equal(typeof action.operation, "string");
assert.equal(typeof action.resourceKind, "string");
assert.equal(typeof action.resourceName, "string");
assert.equal(action.valuesPrinted, false);
}
}
function eventPayload(event: { payload: unknown }): JsonRecord {