1- # SWE-bench-Pro (scaffold)
1+ # SWE-bench-Pro
22
33This 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
55editable agent (` baseline/target/src/swebench_pro_agent/agent.py ` ) edits the
66repository in place; the ** task-source verifier** applies the resulting repo state
77and runs the task's hidden test suite for the reward. The agent does not
88self-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 \
94113Omit ` VERO_SKIP_SECRET_CHECK=1 ` for a real build so VeRO verifies that the OpenAI
95114and Modal credentials declared in ` build.yaml ` are present. Set ` OPENAI_BASE_URL `
96115to 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
0 commit comments