Skip to content

Commit fd4b26d

Browse files
committed
fix: preserve completed signal-exit classification
1 parent ad72318 commit fd4b26d

14 files changed

Lines changed: 67 additions & 16 deletions

File tree

src/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ program
535535
process.exit(1);
536536
}
537537
jobFilter = manifest.results
538-
.filter((r) => r.exitCode !== 0 || r.error)
538+
.filter((r) => r.failed ?? (r.exitCode !== 0 || r.error))
539539
.map((r) => ({ scenarioKey: r.scenarioKey, agentName: r.agentName }));
540540
if (jobFilter.length === 0) {
541541
process.stderr.write(`\n No failed jobs in report ${manifest.reportId}. Nothing to retry.\n\n`);

src/docs-site/src/pages/cli.astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ import DocsLayout from "../layouts/DocsLayout.astro";
9090
<div class="cli-flag">
9191
<span class="cli-flag-name"><code>--failed [reportId]</code></span>
9292
<span class="cli-flag-desc">
93-
Re-run only the failed scenario/agent pairs from a previous report
94-
(default: <code>latest</code>). Pairs no longer in the config are
95-
silently dropped. Mutually exclusive with <code>--scenario</code> and
93+
Re-run only the scenario/agent pairs marked failed in a previous report
94+
(default: <code>latest</code>). Pairs no longer in the config are silently
95+
dropped. Mutually exclusive with <code>--scenario</code> and
9696
<code>--agent</code>.
9797
</span>
9898
</div>

src/docs-site/src/pages/running.astro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ export default createAgentAdapter<{ stdout: string }>({
122122
agents). Each variant appears as a separate row in the CLI output and a separate entry in
123123
reports, identified by its <code>@</code>-suffixed key (e.g., <code>create-post@with-mcp</code>).
124124
</p>
125+
<p>
126+
Report manifest entries include a <code>failed</code> boolean computed from the full run output before
127+
transcripts are stripped from <code>report.json</code>. This preserves the correct status for agents that
128+
return a final result even when their process exits non-zero during cleanup.
129+
</p>
125130
<p>
126131
See <a href="/scenarios#variants">Writing Scenarios &rarr; Variants</a> for the full field
127132
reference and examples.

src/report-ui/src/scripts/render.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ function renderScenarioHeaderRow(group: ScenarioGroup, _startIndex: number, hasS
365365

366366
function renderAgentRow(entry: ResultEntry, index: number, hasScores: boolean, scenarioKey: string): string {
367367
const s = entry.score;
368-
const isFailed = entry.exitCode !== 0 || !!entry.error;
368+
const isFailed = entry.failed ?? (entry.exitCode !== 0 || !!entry.error);
369369
const errorBtn = entry.error
370370
? `<button class="error-btn" data-error-index="${index}" title="${escapeHtml(friendlyError(entry.error))}">!</button>`
371371
: "";

src/report-ui/src/scripts/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface ResultEntry {
2828
agentName: string;
2929
durationMs: number;
3030
exitCode: number;
31+
failed?: boolean;
3132
tokenUsage?: TokenUsage;
3233
totalCostUsd?: number;
3334
score?: ScoreResult;

src/reports/writer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as fs from "node:fs";
22
import * as path from "node:path";
33
import type { RunOutput, RunResult } from "../types/output.js";
4-
import { isScoredResult } from "../types/output.js";
4+
import { isFailedRun, isScoredResult } from "../types/output.js";
55
import type { ScoredOutput, ScoredRunResult, SparseIndex } from "../types/scoring.js";
66
import type { ReportManifest, ReportResultEntry } from "../types/report.js";
77
import { generateReportHtml } from "./html.js";
@@ -151,6 +151,7 @@ function buildResultEntry(result: RunResult | ScoredRunResult, relPath: string):
151151
agentName: result.agentName,
152152
durationMs: result.output.metadata.durationMs,
153153
exitCode: result.output.metadata.exitCode,
154+
failed: isFailedRun(result.output),
154155
file: relPath,
155156
};
156157

src/scoring/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export async function scoreRunResult(result: RunResult, options?: ScoringOptions
6363
// get perfect-score defaults in env/service/agent because nothing was audited.
6464
if (isFailedRun(result.output)) {
6565
const score = buildZeroScore(result, weights, sparseIndex.lines.length > 0 ? sparseIndex : undefined, judgeAgent);
66-
options?.onProgress?.(result.scenarioKey, result.agentName, "done");
66+
options?.onProgress?.(result.scenarioKey, result.agentName, "failed");
6767
result.output.transcriptAnalysis = toTranscriptAnalysis(normalized);
6868
return {
6969
scenarioKey: result.scenarioKey,

src/types/output.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,6 @@ export function formatError(err: unknown): string {
141141
*/
142142
export function isFailedRun(output: AgentOutput): boolean {
143143
const { exitCode, error } = output.metadata;
144-
if (output.result) return Boolean(error);
144+
if (output.result !== null) return Boolean(error);
145145
return exitCode !== 0 || Boolean(error);
146146
}

src/types/report.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export interface ReportResultEntry {
2424
agentName: string;
2525
durationMs: number;
2626
exitCode: number;
27+
/** Failure classification computed before the manifest is flattened. */
28+
failed?: boolean;
2729
tokenUsage?: TokenUsage;
2830
totalCostUsd?: number;
2931
score?: ScoreResult;

src/types/scoring.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ export interface ScoringOptions {
208208
weights?: ScoringWeights;
209209
logger?: Logger;
210210
/** Called when scoring starts/finishes for a result. */
211-
onProgress?: (scenarioKey: string, agentName: string, phase: "start" | "done") => void;
211+
onProgress?: (scenarioKey: string, agentName: string, phase: "start" | "done" | "failed") => void;
212212
/** Report directory for writing raw data before judges run. */
213213
reportDir?: string;
214214
/**

0 commit comments

Comments
 (0)