Feature/n agent support - #75
Open
Raandom wants to merge 9 commits into
Open
Conversation
Raandom
marked this pull request as ready for review
July 2, 2026 20:19
… env leakage
- Add dataset/gold_conflict_report_4tuples.json (full 4-tuple scan)
- Add dataset/subsets/team4_clean.json (5 conflict-free 4-tuples)
- Add dataset/subsets/team4_slight.json (50 slight-conflict 4-tuples)
- Fix test_model_name_propagated_via_env_in_invocation: mock
resolve_endpoint_overrides to {} so ambient ANTHROPIC_AUTH_TOKEN
in the test runner environment doesn't trigger preserve_model_name=True
Team was the only setting with end-to-end N>2 support; solo and coop silently evaluated only the first two features, and GCP batch skipped N>2 team runs. This completes the matrix: - sandbox: add test_solo_n (one patch vs N feature suites) with the same features/all_passed schema as test_merged_n and legacy feature1/feature2/both_passed dual-written at N=2 - evaluate: route solo N>2 to test_solo_n and coop N>2 through test_merged_n; N=2 keeps the exact legacy test_solo/test_merged paths. Fix _run_with_progress counting a passing N>2 team eval as a failure (only checked both_passed) - gcp: N-generic EvalTask/EvalResult (feature_ids/patches/ features_passed/all_passed) with __post_init__ normalization for legacy 2-field construction; batch VM script loops downloads and tests over N_FEATURES and fold-merges N agent branches (keeping the per-step union fallback); remove the N>2 skip in _run_gcp_batch and write features_result/all_passed to eval.json - export test_merged_n/test_solo_n from the package Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirror the 2-agent setting's all-pairs convention for N-agent teams: team3_all enumerates every 3-feature combination (29 tasks, 1409 groups) and team4_all every 4-feature combination (28 tasks, 2219 groups), with no mergeability curation. The curated clean/slight subsets remain for stratified analysis. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Brings in main's submission-path and stdin-hang fixes, and formats the three files ruff 0.16.2 reformats (CI resolves latest ruff, which moved past what main was formatted with). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
CooperBench has so far measured how well two agents cooperate on a shared codebase. Many of the questions the benchmark is built for — how coordination overhead scales, how merge complexity compounds, whether teams degrade gracefully — only become visible with N > 2 agents. The runner side (
runner/team.py,runner/coop.py) was already written N-generically, but everything around it assumed exactly two agents: task discovery destructured 2-tuples, the eval harness tested exactly two patches, the GCP batch pipeline hadfeature1/feature2hardwired end to end, and the dataset had no N-tuple task definitions. This PR removes that ceiling across the whole pipeline: dataset → task discovery → evaluation → reporting.What is implemented
Dataset & task discovery
"groups"(N-element feature tuples) alongside the legacy"pairs";discover_tasks()validates whole groups instead of destructuring 2-tuples (runner/tasks.py).scripts/check_gold_conflicts.pygeneralises the pairwise gold-conflict checker to arbitrary group sizes via--group-size N, and fixes two pre-existing Modal bugs (container keep-alive, double-terminate).N-way evaluation (
eval/sandbox.py)test_merged_n(): sets up one git branch per agent, applies each agent's patch, fold-merges them sequentially (agent2 into agent1, then agent3, …), and runs every feature's test suite against the merged tree. Keeps the identical-patch short-circuit and the lead-alone fallback from the 2-agent path.test_solo_n(): one agent's single patch tested against all N feature suites.featuresdict keyed by feature id plusall_passed, and dual-write the legacyfeature1/feature2/both_passedkeys when N = 2.Eval routing (
eval/evaluate.py)team(any N) andcoop/solowith N > 2 route to the N-generic functions; 2-agentcoop/solokeep the exact legacytest_merged()/test_solo()paths, so existing results and eval.json schemas are byte-compatible.both_passedwas checked).GCP batch backend (
eval/backends/gcp.py)EvalTask/EvalResultgain N-generic fields (feature_ids,patches,tests_patches,features_passed,all_passed) with__post_init__normalisation, so legacy 2-field construction keeps working.N_FEATURES; the in-container script builds one branch per agent, fold-merges sequentially (keeping the batch path's per-step union-merge fallback), and runs all N suites. The former "skip team runs with > 2 agents" guard is removed.Reporting —
runner/core.pyand the eval progress display acceptall_passedalongsideboth_passed, and batch eval.json now carriesfeatures_result/all_passedwith legacy keys dual-written at N = 2.Support matrix
test_merged_ntest_merged_ntest_solo_nN = 2 behaviour is unchanged in every cell (legacy code paths and result schemas are preserved exactly).
Benchmarks run with this feature
Gold-patch merge sweeps over the full dataset (via Modal, using the generalised
check_gold_conflicts.py) to characterise N-way conflict structure and curate evaluation subsets:gold_conflict_report_3tuples*.json)gold_conflict_report_4tuples.json)From these sweeps, four curated subsets are checked in for N-agent runs (
dataset/subsets/):team3_clean— 20 groups (all 20 clean-merging 3-tuples) across 4 tasksteam3_slight— 50 lightly-conflicting 3-tuples across 4 tasksteam4_clean— 5 groups (all 5 clean-merging 4-tuples)team4_slight— 50 lightly-conflicting 4-tuples across 3 tasksThe steep drop in clean merges (20/1,409 at N=3, 5/2,219 at N=4) is itself the headline motivation: multi-way integration is drastically harder than pairwise, which is exactly the regime this PR makes measurable with agents.
Caveat: the sweeps check textual mergeability only —
check_gold_conflicts.pyattempts the fold merge but does not run the feature test suites on the merged tree. So "clean merge" means git merged without conflicts, not test-verified compatibility; the*_cleansubsets are curated by mergeability. Semantic verification (running all N suites on the merged gold patches viatest_merged_n) is a pending follow-up — at eval time, however,test_merged_n/test_solo_nalways run every feature's suite on the merged tree, so agent results are test-verified.Agent baseline: Qwen3.5-9B on all four group subsets
Full end-to-end run of the team setting over all 125 groups (430 agent trajectories, ~10h wall clock):
mini_swe_agent_v2,Qwen/Qwen3.5-9B(vLLM on Modal H100, 32k ctx), default team harness with--git, concurrency 3, evaluated with the new N-way docker eval.Reference point: the same model at N=2 (prior internal team run, reduced protocol) passed 23/344 pairs (6.7%). Going from 2 to 3–4 agents collapses group success to zero — the coordination cliff this PR makes measurable. Failure modes, from the trajectories: agents engage the PR flow (242
gh prcalls, 201 pushes across the sweep) but rarely complete open-PR-then-submit within the 100-step budget; leads exhaust steps re-verifying or waiting; 4-agent groups show elevated context-overflow errors at 32k. Best group: 2/3 features passing (llama_index_task/17244, team3_slight). The 0% is the honest headline for a 9B model under the full protocol — a reduced-protocol (--team-no-*) comparison run is a natural follow-up.Testing
tests/eval/test_sandbox.py)_nfunctions for all three settings (tests/eval/test_evaluate.py)_run_gcp_batchwith a mocked evaluator over 3-agent team, 2-agent coop, and 3-feature solo runs (tests/eval/test_gcp_batch.py)groupsdiscovery tests (tests/runner/test_tasks.py)Checklist
🤖 Generated with Claude Code