Skip to content

Commit 43ccb5b

Browse files
committed
Fix SWE-bench evaluator dataset preparation
1 parent 7602e14 commit 43ccb5b

4 files changed

Lines changed: 490 additions & 8 deletions

File tree

‎src/agentpatchcheck/swebench-cli.ts‎

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ import {
1818
SWE_BENCH_STANDARD_BASELINE_TAG,
1919
type SWEbenchAdapterResult,
2020
} from "./swebench-adapter";
21+
import {
22+
prepareSWEbenchEvaluatorDataset,
23+
type SWEbenchEvaluatorMetadataAuthority,
24+
type SWEbenchSourceDatasetIdentity,
25+
} from "./swebench-evaluator-dataset";
2126

2227
const SWE_BENCH_EVALUATOR_BRIDGE_PATH = fileURLToPath(
2328
new URL("../../scripts/swebench-verification-bridge.mjs", import.meta.url),
@@ -75,15 +80,19 @@ export interface SWEbenchBootstrapConfiguration {
7580
classification: "formal-frozen" | "engineering-validation";
7681
engineeringValidation: boolean;
7782
instanceIds: readonly string[];
83+
sourceDataset?: SWEbenchSourceDatasetIdentity;
84+
sourceDatasetSha256: string;
85+
metadataAuthority?: SWEbenchEvaluatorMetadataAuthority;
7886
}
7987

8088
interface SWEbenchBootstrapManifest {
8189
name: string;
8290
version: string;
83-
fullSubset: { path: string };
84-
evaluator: { dataset: string; revision: string; timeoutSeconds: number };
91+
fullSubset: { path: string; sha256?: string };
92+
evaluator: { dataset: string; revision: string; timeoutSeconds: number; metadataAuthority?: SWEbenchEvaluatorMetadataAuthority };
8593
execution: { classification: "formal-frozen" | "engineering-validation"; deepseekModel: string };
8694
instanceIds: string[];
95+
sourceDataset?: SWEbenchSourceDatasetIdentity;
8796
}
8897

8998
type SWEbenchSourceIdentity =
@@ -147,6 +156,36 @@ function resolveManifestPath(manifestDirectory: string, value: unknown, field: s
147156
return resolve(manifestDirectory, path);
148157
}
149158

159+
function parseSourceDatasetIdentity(value: unknown): SWEbenchSourceDatasetIdentity | undefined {
160+
if (value === undefined) return undefined;
161+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("SWE-bench bootstrap manifest sourceDataset must be an object.");
162+
const source = value as Record<string, unknown>;
163+
const revision = requireManifestString(source.revision, "sourceDataset.revision");
164+
const sha256 = requireManifestString(source.sha256, "sourceDataset.sha256");
165+
if (!/^[0-9a-f]{40}$/u.test(revision)) throw new Error("SWE-bench bootstrap sourceDataset revision must be a full commit SHA.");
166+
if (!/^[0-9a-f]{64}$/u.test(sha256)) throw new Error("SWE-bench bootstrap sourceDataset sha256 must be a SHA-256.");
167+
return {
168+
name: requireManifestString(source.name, "sourceDataset.name"),
169+
split: requireManifestString(source.split, "sourceDataset.split"),
170+
revision,
171+
sha256,
172+
};
173+
}
174+
175+
function parseMetadataAuthority(value: unknown): SWEbenchEvaluatorMetadataAuthority | undefined {
176+
if (value === undefined) return undefined;
177+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("SWE-bench bootstrap metadataAuthority must be an object.");
178+
const authority = value as Record<string, unknown>;
179+
const revision = requireManifestString(authority.revision, "evaluator.metadataAuthority.revision");
180+
if (!/^[0-9a-f]{40}$/u.test(revision)) throw new Error("SWE-bench bootstrap metadataAuthority revision must be a full commit SHA.");
181+
return {
182+
dataset: requireManifestString(authority.dataset, "evaluator.metadataAuthority.dataset"),
183+
split: requireManifestString(authority.split, "evaluator.metadataAuthority.split"),
184+
revision,
185+
primitive: requireManifestString(authority.primitive, "evaluator.metadataAuthority.primitive"),
186+
};
187+
}
188+
150189
export async function loadSWEbenchBootstrapConfiguration(
151190
projectRoot: string,
152191
environment: NodeJS.ProcessEnv = process.env,
@@ -176,6 +215,10 @@ export async function loadSWEbenchBootstrapConfiguration(
176215
throw new Error("SWE-bench bootstrap evaluator timeoutSeconds must be a positive integer.");
177216
if (manifest.execution.classification !== "formal-frozen" && manifest.execution.classification !== "engineering-validation")
178217
throw new Error("SWE-bench bootstrap execution classification is invalid.");
218+
const sourceDataset = parseSourceDatasetIdentity(manifest.sourceDataset);
219+
const metadataAuthority = parseMetadataAuthority(manifest.evaluator.metadataAuthority);
220+
const sourceDatasetSha256 = requireManifestString(manifest.fullSubset.sha256, "fullSubset.sha256");
221+
if (!/^[0-9a-f]{64}$/u.test(sourceDatasetSha256)) throw new Error("SWE-bench bootstrap fullSubset sha256 must be a SHA-256.");
179222
const manifestDirectory = dirname(manifestPath);
180223
return {
181224
manifestPath,
@@ -191,6 +234,9 @@ export async function loadSWEbenchBootstrapConfiguration(
191234
classification: manifest.execution.classification,
192235
engineeringValidation: manifest.execution.classification === "engineering-validation",
193236
instanceIds: [...manifest.instanceIds],
237+
sourceDataset,
238+
sourceDatasetSha256,
239+
metadataAuthority,
194240
};
195241
}
196242

@@ -279,6 +325,7 @@ interface SWEbenchCliDependencies {
279325
runEvaluatorPreflight: typeof preflightSWEbenchEvaluator;
280326
runInstance: typeof runSWEbenchInstance;
281327
runPostRunEvaluator: typeof runSWEbenchPostRunEvaluator;
328+
prepareEvaluatorDataset: typeof prepareSWEbenchEvaluatorDataset;
282329
}
283330

284331
const defaultDependencies: SWEbenchCliDependencies = {
@@ -291,6 +338,7 @@ const defaultDependencies: SWEbenchCliDependencies = {
291338
runEvaluatorPreflight: preflightSWEbenchEvaluator,
292339
runInstance: runSWEbenchInstance,
293340
runPostRunEvaluator: runSWEbenchPostRunEvaluator,
341+
prepareEvaluatorDataset: prepareSWEbenchEvaluatorDataset,
294342
};
295343

296344
function optionValue(argv: string[], name: string, required = true): string | undefined {
@@ -587,13 +635,29 @@ export async function runSWEbenchCli(
587635
attempt: options.attempt,
588636
});
589637
let grading: SWEbenchGradingResult;
638+
let preparedEvaluatorDatasetPath: string | null = null;
639+
let preparedEvaluatorDatasetProvenancePath: string | null = null;
590640
if (result.prediction === null || result.predictionPath === null) {
591641
grading = createNotRunGradingResult(result);
592642
} else {
593643
try {
644+
if (bootstrap.sourceDataset === undefined) throw new Error("SWE-bench bootstrap sourceDataset provenance is required for grading.");
645+
const preparedEvaluatorDataset = await resolvedDependencies.prepareEvaluatorDataset({
646+
sourceDatasetPath: bootstrap.evaluatorDatasetPath,
647+
sourceDatasetSha256: bootstrap.sourceDatasetSha256,
648+
sourceDataset: bootstrap.sourceDataset,
649+
evaluatorRevision: bootstrap.evaluatorRevision,
650+
evaluatorPythonPath: evaluator.evaluatorPythonPath,
651+
evaluatorSourceRoot: evaluator.evaluatorSourceRoot,
652+
metadataAuthority: bootstrap.metadataAuthority,
653+
outputPath: join(artifactRoot, "evaluator-input.jsonl"),
654+
provenancePath: join(artifactRoot, "evaluator-input.provenance.json"),
655+
});
656+
preparedEvaluatorDatasetPath = preparedEvaluatorDataset.datasetPath;
657+
preparedEvaluatorDatasetProvenancePath = preparedEvaluatorDataset.provenancePath;
594658
grading = await resolvedDependencies.runPostRunEvaluator({
595659
predictionPath: result.predictionPath,
596-
datasetPath: bootstrap.evaluatorDatasetPath,
660+
datasetPath: preparedEvaluatorDataset.datasetPath,
597661
instanceId: result.instance.instance_id,
598662
configuration: evaluator,
599663
});
@@ -602,7 +666,7 @@ export async function runSWEbenchCli(
602666
version: 2,
603667
instanceId: result.instance.instance_id,
604668
normalizedStatus: "infrastructure_error",
605-
reason: "post_run_evaluator_invocation_failed",
669+
reason: preparedEvaluatorDatasetPath === null ? "evaluator_input_preparation_failed" : "post_run_evaluator_invocation_failed",
606670
officialReportPath: null,
607671
officialRunId: null,
608672
evaluatorVersion: evaluator.evaluatorVersion,
@@ -636,6 +700,8 @@ export async function runSWEbenchCli(
636700
evaluatorVersion: evaluator.evaluatorVersion,
637701
outputDirectory,
638702
evaluatorArtifactRoot: artifactRoot,
703+
evaluatorInputPath: preparedEvaluatorDatasetPath,
704+
evaluatorInputProvenancePath: preparedEvaluatorDatasetProvenancePath,
639705
},
640706
workspacePath: result.workspace?.path ?? null,
641707
runtimeRecordPath: result.runtimeRecordPath,

0 commit comments

Comments
 (0)