Skip to content

Commit 15ad941

Browse files
Merge the refreshed swe-bench-pro scaffold base into the capability gate
The base branch now applies this same capability gate to the swe-bench-pro agent as part of fixing five seed-agent defects, so that file conflicted. Resolved by taking the base's version verbatim: the gate is still applied there, just by the base commit rather than by this PR, which drops swe-bench-pro from this PR's diff without changing the merged result. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2 parents 2260e3c + ac3aee3 commit 15ad941

15 files changed

Lines changed: 7500 additions & 161 deletions

File tree

harness-engineering-bench/swe-bench-pro/README.md

Lines changed: 117 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,103 @@
1-
# SWE-bench-Pro (scaffold)
1+
# SWE-bench-Pro
22

33
This benchmark optimizes a code-editing agent on SWE-bench-Pro tasks. Each task
4-
checks a real project out at `/app/repo` and describes a bug fix or feature. The
4+
checks a real project out at `/app` and describes a bug fix or feature. The
55
editable agent (`baseline/target/src/swebench_pro_agent/agent.py`) edits the
66
repository in place; the **task-source verifier** applies the resulting repo state
77
and runs the task's hidden test suite for the reward. The agent does not
88
self-grade and writes no answer file: reward comes entirely from the suite.
99

10-
## Status: this is a SCAFFOLD, not a runnable benchmark
11-
12-
Everything except the actual task data is in place: a robust Harbor-native agent,
13-
a `build.yaml`, partition scaffolding, a split script, and this README. It will
14-
**not run yet** because the real SWE-bench-Pro task dataset must come from a Harbor
15-
task source that is not committed here.
16-
17-
### DONE (working skeleton)
18-
19-
- `baseline/target/src/swebench_pro_agent/agent.py`: a tool-using code-editing
20-
agent on the OpenAI Responses API (`run_shell`, `read_file`, `write_file`,
21-
`apply_patch`, `run_tests`, `submit`), `MAX_TURNS = 50`. The
22-
`self._client.responses.create(...)` call is wrapped in a retry-with-backoff
23-
helper from the start (the GAIA baseline scored 0.0 because an unguarded call
24-
crashed on a transient error; that retry was the optimizer's winning fix).
25-
- `baseline/build.yaml`: the full VeRO/Harbor optimization config (agent import
26-
path, inference gateway, partitions wiring, timeouts, secrets, W&B).
27-
- `baseline/target/pyproject.toml`, smoke test, `secrets.env.example`, `.gitignore`.
28-
- `scripts/partition_swe_bench_pro.py`: a deterministic, sha256-keyed stratified
29-
split with a `--check` mode, modeled on `gaia/scripts/partition_gaia.py`.
30-
31-
### STUBBED (must be completed before it runs)
32-
33-
Two things must be finished:
34-
35-
1. **Pin the real `task_source`.** `baseline/build.yaml` carries a clearly-marked
36-
placeholder:
37-
38-
```
39-
task_source: scale-ai/swe-bench-pro@sha256:REPLACE_WITH_REAL_DIGEST
40-
```
41-
42-
SWE-bench-Pro is a Scale benchmark. Find the real pinned task package in the
43-
Harbor task registry (ask the DEX-harness / Harbor team if it is not obvious).
44-
The baseline in this directory provides only the **agent + config**; the task
45-
package provides the **repos, tests, gold patches, and grading**. Replace the
46-
placeholder digest here and the `DATASET_DIGEST` constant in
47-
`scripts/partition_swe_bench_pro.py`.
48-
49-
2. **Regenerate the partitions from the real task list.** The committed
50-
`partitions/{development,validation,test}.json` are empty placeholders and
51-
`partitions/manifest.json` is a stub (`"_stub": true`). Once the task source is
52-
pinned, set `TOTAL_TASKS`/`TARGET_COUNTS` and confirm `_read_tasks` against the
53-
real `task.toml` layout in `scripts/partition_swe_bench_pro.py`, then generate
54-
and verify the split:
55-
56-
```bash
57-
uv run --python 3.12 \
58-
harness-engineering-bench/swe-bench-pro/scripts/partition_swe_bench_pro.py \
59-
--tasks-dir /path/to/exported/swe-bench-pro \
60-
--fetch-registry
61-
62-
uv run --python 3.12 \
63-
harness-engineering-bench/swe-bench-pro/scripts/partition_swe_bench_pro.py \
64-
--tasks-dir /path/to/exported/swe-bench-pro \
65-
--check
66-
```
67-
68-
Also update the placeholder `total_cases` under `agent_access` in
69-
`baseline/build.yaml` to real disclosure counts, and run `uv lock` in
70-
`baseline/target/` so the compiled task pins an exact resolution.
10+
## Task source
11+
12+
SWE-bench-Pro ships as the **`swebenchpro` dataset in the default Harbor
13+
registry**, version `1.0`, 731 instances across 11 upstream projects. It is a
14+
*registry* dataset, not an `<org>/<name>@sha256:<digest>` package like
15+
swe-atlas-qna or tau3, so the pin is a bare `name@version`:
16+
17+
```
18+
task_source: swebenchpro@1.0
19+
```
20+
21+
Its tasks resolve to git-backed task ids under
22+
`laude-institute/harbor-datasets` at commit
23+
`c8e8f3fac7097accaacf261d74c3d6f441de45b1`, path
24+
`datasets/swebenchpro/instance_<owner>__<repo>-<sha>`. Each task ships an
25+
`environment/Dockerfile` that `FROM`s a public prebuilt DockerHub image
26+
(`jefzda/sweap-images:<instance>`, 0.5-4.8 GB), resets the repo to the base
27+
commit, and clears `ENTRYPOINT` (so harbor's default keepalive works and no
28+
`--ek keepalive` override is needed, unlike swe-atlas-qna).
29+
30+
Grading is entirely offline: `tests/test.sh` checks out the gold test files,
31+
runs the official `run_script.sh`, parses results with the official `parser.py`,
32+
and writes `1` to `/logs/verifier/reward.txt` only when every test in
33+
`fail_to_pass` and `pass_to_pass` passed. **No judge model, so no verifier
34+
credentials are needed** (`--ve` is unnecessary for this benchmark).
35+
36+
Two consequences of being a registry rather than a package dataset:
37+
38+
- `agent_access[development].expose_case_resources` must be `false`. VeRO
39+
materializes case resources through `PackageDatasetClient`, which only parses
40+
`<org>/<name>` refs and rejects a bare `swebenchpro@1.0`.
41+
- The recorded per-task `ref` in `partitions/manifest.json` is
42+
`<git_commit>:<path>` rather than a `sha256:` content hash.
7143

7244
## Split design
7345

74-
The committed split is intended to be deterministic and stratified by source
75-
repository (so each represented codebase appears across all three partitions):
46+
The committed split is deterministic and stratified by source repository (so each
47+
represented codebase appears across all three partitions):
48+
49+
- development: 146 (20%, full result disclosure to the optimizer)
50+
- validation: 292 (40%, aggregate-only; used to select candidates)
51+
- test: 293 (40%, held out until Harbor grades the completed outer task)
52+
53+
731 does not divide evenly: the exact ratios are 146.2/292.4/292.4, so the one
54+
leftover case is assigned by largest remainder, and the .4/.4 tie between
55+
validation and test breaks towards test. That matches how the sibling benchmarks
56+
resolved the same tie (officeqa 246 -> 49/98/99, swe-atlas-qna 124 -> 25/49/50).
57+
58+
Regenerate and verify the split with:
59+
60+
```bash
61+
harbor download dataset swebenchpro@1.0 --output-dir /tmp/swebenchpro # or a
62+
# sparse checkout of laude-institute/harbor-datasets at the pinned commit
63+
64+
uv run --python 3.12 \
65+
harness-engineering-bench/swe-bench-pro/scripts/partition_swe_bench_pro.py \
66+
--tasks-dir /tmp/swebenchpro --fetch-registry
7667

77-
- development: 20% (full result disclosure to the optimizer)
78-
- validation: 40% (aggregate-only; used to select candidates)
79-
- test: 40% (held out until Harbor grades the completed outer task)
68+
uv run --python 3.12 \
69+
harness-engineering-bench/swe-bench-pro/scripts/partition_swe_bench_pro.py \
70+
--tasks-dir /tmp/swebenchpro --check
71+
```
8072

81-
Exact counts are TODO until the task source is pinned.
73+
## Target model: which models the seed agent can actually run on
74+
75+
The seed agent drives the **OpenAI Responses API** and chains turns with
76+
`previous_response_id`. Measured against the shared LiteLLM proxy
77+
(`heb-litellm-proxy`), that shape constrains the usable target models:
78+
79+
| model | turn 1 | chained turn (`previous_response_id`) |
80+
|---|---|---|
81+
| gpt-4o | OK (with the reasoning gate) | OK |
82+
| gpt-5.4-mini-2026-03-17 | OK | OK |
83+
| gpt-5.6-sol | OK | OK |
84+
| deepseek-v4-flash | OK | OK |
85+
| gpt-oss-120b | OK | OK |
86+
| **qwen-3.6-27b** | OK | **fails, deterministically** |
87+
| gpt-4.1 | 400 on `reasoning` | n/a |
88+
| gpt-5.3-codex | 404 on the proxy's Responses route | n/a |
89+
90+
`qwen-3.6-27b` answers the first turn but every chained call returns
91+
`litellm.BadRequestError: Fireworks_aiException ... invalid_request_error`
92+
(3/3 reproductions, plus an in-harbor trial). The same conversation works on
93+
`/chat/completions`, so the fault is LiteLLM's Responses-to-ChatCompletions
94+
bridge replaying a shape Fireworks rejects, not the model. Switching the agent
95+
to a stateless full-history `input` list also works on qwen, but that changes
96+
the seed harness being measured, so it has not been done here.
97+
98+
`reasoning: {"effort": ...}` is gated on `_is_reasoning_model()` (the same
99+
capability predicate the other five benchmark agents use): sending it to gpt-4o
100+
or gpt-4.1 is a hard 400 on the very first turn.
82101

83102
## Build the outer Harbor task
84103

@@ -94,8 +113,35 @@ VERO_SKIP_SECRET_CHECK=1 uv run vero harbor build \
94113
Omit `VERO_SKIP_SECRET_CHECK=1` for a real build so VeRO verifies that the OpenAI
95114
and Modal credentials declared in `build.yaml` are present. Set `OPENAI_BASE_URL`
96115
to your OpenAI-compatible endpoint. The `compiled/` directory is generated and
97-
intentionally ignored. (This build will fail to resolve tasks until the
98-
placeholder `task_source` above is replaced with the real digest.)
116+
intentionally ignored.
117+
118+
## Measure the held-out baseline
119+
120+
A K=3 baseline is three independent single-attempt rounds over the 293-case
121+
`test` partition, scored by harbor's own
122+
`stats.evals.*.metrics[0].mean` (an errored trial counts as a zero). Each round
123+
is a plain `harbor run` against the registry dataset, with
124+
`--agent-timeout-multiplier 0.6` (`case_timeout_seconds` 1800 over the task's
125+
declared `[agent] timeout_sec` 3000):
126+
127+
```bash
128+
harbor run \
129+
-a swebench_pro_agent.agent:SweBenchProAgent \
130+
-m <target-model> -e modal \
131+
-d swebenchpro@1.0 \
132+
$(python3 -c "import json;print(' '.join('-i '+t for t in json.load(open('../../partitions/test.json'))))") \
133+
--n-attempts 1 --max-retries 3 -n 5 --yes \
134+
--ek app_name=harness-engineering-bench --ek sandbox_idle_timeout_secs=3600 \
135+
--agent-timeout-multiplier 0.6 \
136+
--env-file baseline/secrets.env \
137+
-o ../../../runs/baseline-swe-bench-pro/roundN
138+
```
139+
140+
Run it three times into `round1/`, `round2/`, `round3/`; the pinned
141+
`baseline_reward` is the mean of the three round means and the `±` is the
142+
population stdev across them. Concurrency matters: `-n 12` against the shared
143+
Azure gpt-4o deployment produced 45 `RateLimitError` retries in 15 minutes,
144+
while `-n 5` produced none.
99145

100146
## Run the optimization
101147

harness-engineering-bench/swe-bench-pro/baseline/build.yaml

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ description: >-
44
interface. The target must edit a checked-out repository so the task's hidden
55
test suite passes; the task-source verifier runs the suite for the reward.
66
agent_repo: target
7-
# TODO: pin the real SWE-bench-Pro Harbor task source (see README). This is a
8-
# clearly-marked placeholder, NOT a real digest, and will fail to resolve until
9-
# replaced with the actual `scale-ai/swe-bench-pro@sha256:<digest>` from the
10-
# Harbor task registry.
11-
task_source: scale-ai/swe-bench-pro@sha256:REPLACE_WITH_REAL_DIGEST # TODO: pin the real SWE-bench-Pro Harbor task source (see README)
7+
# SWE-bench-Pro ships as the `swebenchpro` dataset in the DEFAULT Harbor registry
8+
# (731 instances), not as an `<org>/<name>@sha256:<digest>` package like
9+
# swe-atlas-qna or tau3. Its tasks resolve to git-backed task ids under
10+
# laude-institute/harbor-datasets at commit c8e8f3fac7097accaacf261d74c3d6f441de45b1,
11+
# so the version pin is the registry version rather than a content digest.
12+
task_source: swebenchpro@1.0
1213
task_manifest: ../partitions/manifest.json
1314
agent_import_path: swebench_pro_agent.agent:SweBenchProAgent
1415
harbor_requirement: harbor[modal]==0.20.0
@@ -18,18 +19,21 @@ partition_files:
1819
validation: ../partitions/validation.json
1920
test: ../partitions/test.json
2021

21-
# TODO: set real disclosure counts once the partitions are regenerated from the
22-
# pinned task list. total_cases below are placeholders scaled to the stub sizes.
2322
agent_access:
2423
- partition: development
2524
disclosure: full
26-
expose_case_resources: true
27-
total_cases: 0
25+
# false, unlike the sibling benchmarks: VeRO materializes case resources via
26+
# PackageDatasetClient, which only accepts `<org>/<name>` package refs. A
27+
# registry dataset such as swebenchpro@1.0 cannot be exposed that way.
28+
expose_case_resources: false
29+
total_runs: 100
30+
total_cases: 146
2831
- partition: validation
2932
disclosure: aggregate
3033
expose_case_resources: false
3134
min_aggregate_cases: 5
32-
total_cases: 0
35+
total_runs: 100
36+
total_cases: 292
3337

3438
selection_partition: validation
3539
targets:
@@ -65,9 +69,12 @@ expose_attempt_detail: false
6569
# Timeouts are bumped well above the GAIA baseline: SWE-bench-Pro tasks build a
6670
# real repository and run its (often slow) test suite, so both the per-case and
6771
# the verifier budgets need substantially more headroom than a short-answer task.
72+
# task_agent_timeout_seconds mirrors the task package's own `[agent] timeout_sec
73+
# = 3000`; case_timeout_seconds is the tighter budget VeRO enforces on top, so
74+
# the baseline runner's --agent-timeout-multiplier is 1800/3000 = 0.6.
6875
timeout_seconds: 28800
6976
case_timeout_seconds: 1800
70-
task_agent_timeout_seconds: 3600
77+
task_agent_timeout_seconds: 3000
7178
max_concurrency: 8
7279
error_rate_threshold: 0.1
7380
verifier_timeout_seconds: 28800

harness-engineering-bench/swe-bench-pro/baseline/target/pyproject.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
name = "swebench-pro-agent"
33
version = "0.1.0"
44
description = "Editable Harbor-native SWE-bench-Pro baseline for VeRO"
5-
# Cap below 3.14: an uncapped ">=3.11" lets uv resolve to 3.14, whose litellm/pyo3
6-
# build fails. Keep this bounded until the toolchain supports 3.14.
7-
requires-python = ">=3.11,<3.14"
5+
# Floor at 3.12 (harbor 0.20.0 requires it; ">=3.11" made the package's own
6+
# `uv run pytest` unresolvable). Cap below 3.14: an uncapped range lets uv
7+
# resolve to 3.14, whose litellm/pyo3 build fails.
8+
requires-python = ">=3.12,<3.14"
89
dependencies = [
910
"harbor==0.20.0",
1011
"openai==2.46.0",

0 commit comments

Comments
 (0)