feat: add scaleswe v1 taskset + per-task setup/workdir hooks - #1616
Conversation
scaleswe-v1 ports the v0 ComposableEnv Scale-SWE taskset to v1: each row carries its per-task image + workdir, runs its pre_commands in setup() before the agent, and scores with a single `solved` reward that restores the test files to base, applies the f2p test, and runs the merged F2P+P2P pytest ids through a self-contained scorer (1.0 iff every expected id passes). Two small, general framework hooks enable it: - Task.workdir, injected into the runtime config (symmetric with Task.image), so the agent and scoring run in the row's repo dir. - Taskset.setup(task, runtime), run by the rollout after runtime.start() and before the harness, for per-task runtime prep. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- add Taskset.NEEDS_CONTAINER ClassVar; the Environment refuses the subprocess runtime for a taskset that sets it. scaleswe-v1 sets NEEDS_CONTAINER = True. - drop scaleswe's dataset_name/split knobs (hardcode AweAI-Team/Scale-SWE train); the taskset uses the base TasksetConfig. - drop the pre_commands guard — all 20181 Scale-SWE rows carry pre_commands. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The prime sandbox pulls the raw Docker Hub image (aweaiteam/scaleswe:<tag>) directly — verified in a smoke — so the us-central1 prod-sandbox prefix the v0 env prepended is unnecessary. Use the row's image_url as-is. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
runtime_for injected task.workdir unconditionally, overriding a user-set --harness.runtime.workdir. Apply the task's workdir only when the runtime config's is still the default — matching the "cli/toml > task > default" precedence the resources loop already uses. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Needs human review This PR introduces new v1 framework features (per-task setup hooks, workdir injection, container validation) and a substantial new taskset. These are new capabilities affecting runtime behavior, not minor changes. Additionally, two unresolved review comments identify potential logic issues in the taskset implementation. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6818779. Configure here.
| if result.exit_code != 0: | ||
| raise vf.ProgramError( | ||
| f"scaleswe setup failed ({task.name}): {result.stderr.strip()[-500:]}" | ||
| ) |
There was a problem hiding this comment.
Missing pre_commands validation
Medium Severity
setup runs pre_commands without checking they are non-empty after normalization, so a row with missing or whitespace-only pre_commands still passes setup. The v0 Scale-SWE taskset raises in that case; here the repo may never be reset before the agent runs.
Reviewed by Cursor Bugbot for commit 6818779. Configure here.
| test_ids = task.fail_to_pass + task.pass_to_pass | ||
| if not test_ids: | ||
| return 0.0 | ||
| await runtime.run(["sh", "-c", RESTORE], {**ENV, "base": task.base_commit}) |
There was a problem hiding this comment.
Missing base commit check
Medium Severity
The solved reward runs the RESTORE script with an empty base when base_commit is missing, instead of failing fast. The v0 taskset rejects rows without parent_commit/base_commit before restoring tests.
Reviewed by Cursor Bugbot for commit 6818779. Configure here.
| """Working directory the harness and scoring run in — the Environment injects it into | ||
| the runtime config's `workdir` (where the runtime supports one). For a containerized | ||
| task whose image puts the working tree at a non-default path (e.g. a SWE row's | ||
| `/workspace/<repo>`).""" |
There was a problem hiding this comment.
Undocumented v1 framework hooks
Medium Severity
This PR adds user-facing v1 APIs (Task.workdir, Taskset.setup, Taskset.NEEDS_CONTAINER, and related env/rollout wiring) but does not update the project docs that describe v1 authoring and evaluation. Authors need that behavior documented to use SWE-style tasksets correctly.
Additional Locations (2)
Triggered by project rule: BugBot Instructions
Reviewed by Cursor Bugbot for commit 6818779. Configure here.
…tellect-ai#1616) * feat(v1): add scaleswe taskset + per-task setup/workdir hooks scaleswe-v1 ports the v0 ComposableEnv Scale-SWE taskset to v1: each row carries its per-task image + workdir, runs its pre_commands in setup() before the agent, and scores with a single `solved` reward that restores the test files to base, applies the f2p test, and runs the merged F2P+P2P pytest ids through a self-contained scorer (1.0 iff every expected id passes). Two small, general framework hooks enable it: - Task.workdir, injected into the runtime config (symmetric with Task.image), so the agent and scoring run in the row's repo dir. - Taskset.setup(task, runtime), run by the rollout after runtime.start() and before the harness, for per-task runtime prep. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: rename scaleswe _scorer.py -> score.py Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(v1): NEEDS_CONTAINER taskset flag; trim scaleswe config - add Taskset.NEEDS_CONTAINER ClassVar; the Environment refuses the subprocess runtime for a taskset that sets it. scaleswe-v1 sets NEEDS_CONTAINER = True. - drop scaleswe's dataset_name/split knobs (hardcode AweAI-Team/Scale-SWE train); the taskset uses the base TasksetConfig. - drop the pre_commands guard — all 20181 Scale-SWE rows carry pre_commands. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: drop the GCP registry prefix from scaleswe images The prime sandbox pulls the raw Docker Hub image (aweaiteam/scaleswe:<tag>) directly — verified in a smoke — so the us-central1 prod-sandbox prefix the v0 env prepended is unnecessary. Use the row's image_url as-is. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(v1): honor cli/toml workdir over the task's runtime_for injected task.workdir unconditionally, overriding a user-set --harness.runtime.workdir. Apply the task's workdir only when the runtime config's is still the default — matching the "cli/toml > task > default" precedence the resources loop already uses. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: drop redundant comment on workdir precedence Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>


Summary
Adds the
scaleswe-v1taskset (a v1 port of the v0 ComposableEnv Scale-SWE taskset) plus three small, general framework hooks that agentic/SWE tasksets need.scaleswe-v1 (
examples/tasksets/scaleswe_v1)Scale-SWE (
AweAI-Team/Scale-SWE) rows ship a per-task Docker image with the repo,pre_commandsthat reset it to the base commit on a cleanscaleswebranch, F2P/P2P pytest ids, and an optionalf2p_patch/f2p_scriptcarrying the failing test.ScaleSWETaskcarrying itsimage+workdirand the SWE metadata.setup(task, runtime)runs the row'spre_commandsin the live runtime before the agent.solvedreward restores the test files to base (the agent only fixes the source), applies the f2p test, and runs the merged F2P+P2P ids through a self-containedscore.py(run by the testbed python) — 1.0 iff every expected id passes. Host-side reward stays tiny; the pytest run + JUnit matching live inscore.py.AweAI-Team/Scale-SWE, train); the row'simage_urlis used as-is (the prime sandbox pulls the raw Docker Hub image — no registry prefix needed).Framework hooks (general)
Task.workdir— injected into the runtime config'sworkdir(symmetric withTask.image), so the agent and scoring run in the row's repo dir, not the default/app.Taskset.setup(task, runtime)— no-op by default; run by the rollout afterruntime.start()and before the harness, for per-task runtime prep.Taskset.NEEDS_CONTAINER— ClassVar; the Environment refuses the subprocess runtime for a taskset that sets it (scaleswe-v1 sets itTrue).Validation
100-rollout eval on
glm-5.1(rlm harness, prime runtime, uncapped):avg_reward=0.490; 51.6% among cleanly-completed (5 rollouts hit rlm/sandbox infra failures —harness exited 1/prime exec failed— none in the taskset or scorer).setup()pre_commands, and the f2p/P2P pytest scorer all produce correct 0/1 rewards at scale.ruff check --isolated/ruff format --isolated --checkclean.Note
Cursor Bugbot is generating a summary for commit 46da6d1. Configure here.
Note
Add ScaleSWE v1 taskset with per-task setup and workdir hooks
scaleswe_v1taskset that loads tasks from theAweAI-Team/Scale-SWEdataset, runs pre-commands to prepare the repo, applies optional fail-to-pass patches/scripts, and scores results via pytest JUnit XML output.score.pyCLI scorer that normalizes test IDs, parses JUnit XML, and emits1.0or0.0based on whether all expected tests passed.Tasksetwith aNEEDS_CONTAINERclass variable and an asyncsetuphook;Rollout.runnow callssetupbefore starting tools.Taskwith an optionalworkdirfield;Environment.__init__propagates it to the runtime config when supported.Environmentnow raisesValueErrorat construction time if a container-required taskset is paired with aSubprocessConfigruntime.Macroscope summarized 46da6d1.