Skip to content

Fix agentic SWE-bench eval dispatch: dedicated agentic_evals bucket + sweep job / 修复 agentic SWE-bench 评估调度:新增 agentic_evals 独立分桶与扫描任务#2267

Merged
Oseltamivir merged 4 commits into
mainfrom
fix/agentic-eval-bucket-dispatch
Jul 18, 2026
Merged

Fix agentic SWE-bench eval dispatch: dedicated agentic_evals bucket + sweep job / 修复 agentic SWE-bench 评估调度:新增 agentic_evals 独立分桶与扫描任务#2267
Oseltamivir merged 4 commits into
mainfrom
fix/agentic-eval-bucket-dispatch

Conversation

@Oseltamivir

@Oseltamivir Oseltamivir commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

Since #1947, generate_sweep_configs --evals-only marks the top-concurrency agentic arm of each config as a SWE-bench eval row, but two downstream consumers were never taught about agentic eval rows, so any PR touching a single-node agentic-coding config fails its sweep (first seen on #2258):

  1. Schema layerChangelogMatrixEntry.evals is typed list[SingleNodeMatrixEntry] (fixed-seq-len only), so process_changelog.py's final model_validate rejects the agentic eval row with 8 errors (missing isl/osl/max-model-len/disagg, forbidden kv-offloading/total-cpu-dram-gb/duration/scenario-type). check-changelog fails before any GPU work: example run.
  2. Dispatch layer — even with the schema widened (attempted on agentx/dsv4-v300-vllm-mtp), sweep-evals dispatches every eval row with fixed-seq-len inputs: ISL/OSL/MAX_MODEL_LEN come out empty, scenario-type defaults to fixed-seq-len, and the launcher runs the fixed_seq_len benchmark script, which exits at check_env_vars: example run.

Fix

Route agentic eval rows into their own bucket, mirroring how the repo already separates agentic benchmark rows (single_node['agentic'] → dedicated sweep-agentic job with a static, correct input block):

  • validation.py: ChangelogMatrixEntry.agentic_evals: list[SingleNodeAgenticMatrixEntry]; the agentic model accepts optional run-eval/eval-only (carried by eval rows; exclude_none keeps benchmark-row output byte-identical, preserving artifact-reuse row shapes). evals stays fixed-seq-len-only, so an agentic row reaching the fixed-seq-len dispatch is now structurally impossible — it fails check-changelog instead.
  • process_changelog.py: split single-node eval rows by scenario-type into evals / agentic_evals.
  • run-sweep.yml: new sweep-agentic-evals job cloned from sweep-agentic's input block (forwards scenario-type, kv-offloading, kv-offload-backend(+metadata), total-cpu-dram-gb, duration, stubs isl/osl/max-model-len to '0') plus run-eval: true / eval-only: true; wired into collect-evals. This satisfies the agentic scripts' check_env_vars gate and routes the launcher to benchmarks/single_node/agentic/, whose EVAL_ONLY=true branch runs the SWE-bench run_eval path from [WIP] add SWE-bench Lite accuracy eval / 添加 SWE-bench Lite 准确率评估 #1947.
  • recover_failed_ingest.py: count agentic_evals in eval_jobs (uses .get, so pre-existing reuse artifacts without the key still work; on the workflow side a missing key yields null, which the job's != 'null' condition skips).
  • Tests: existing process_changelog tests mock subprocess.run with stdout="[]", so no realistic row ever hit the schema — CI was the first place this could fail. Added an end-to-end split test with realistic fixed + agentic eval rows flowing through the real ChangelogMatrixEntry.model_validate, plus ChangelogMatrixEntry bucket tests (including a guard that evals still rejects agentic rows, and that benchmark-row dumps don't gain eval flags).

python -m pytest utils/ -q: 543 passed; the 2 failures in utils/evals/test_run_eval_dispatch.py are pre-existing on main (environment-dependent, they shell out to mini-swe-agent) and unrelated.

Non-goal: trigger-ingest / trigger-agentic-ingest gating is unchanged; whether a main-push run with only agentic evals (agentic evals-only entry) should route to the agentic ingest is left as a follow-up.

After merge, agentx/dsv4-v300-vllm-mtp (#2258) should rebase onto main and drop its validation.py union commit.

中文说明

问题

#1947 起,generate_sweep_configs --evals-only 会将每个配置中并发度最高的 agentic 条目标记为 SWE-bench 评估行,但下游两个消费方并不认识 agentic 评估行,导致任何涉及单节点 agentic-coding 配置的 PR 扫描失败(最早出现在 #2258):

  1. Schema 层ChangelogMatrixEntry.evals 的类型是 list[SingleNodeMatrixEntry](仅固定序列长度),process_changelog.py 最终的 model_validate 会以 8 个校验错误拒绝 agentic 评估行,check-changelog 在任何 GPU 任务开始前即失败。
  2. 调度层 — 即便放宽 schema(agentx/dsv4-v300-vllm-mtp 分支曾尝试),sweep-evals 仍按固定序列长度的输入派发所有评估行:ISL/OSL/MAX_MODEL_LEN 为空、scenario-type 回落为 fixed-seq-len,启动器因此运行 fixed_seq_len 目录下的基准测试脚本,并在 check_env_vars 处退出。

修复

将 agentic 评估行放入独立分桶,与仓库现有的 agentic 基准测试行设计一致(single_node['agentic'] → 专用 sweep-agentic 任务):

  • validation.py:新增 ChangelogMatrixEntry.agentic_evals;agentic 模型接受可选的 run-eval/eval-onlyexclude_none 保证基准测试行输出逐字节不变,不影响产物复用)。evals 仍仅接受固定序列长度条目,agentic 行进入固定序列长度调度路径从结构上不再可能。
  • process_changelog.py:按 scenario-type 将单节点评估行拆分到 evals / agentic_evals
  • run-sweep.yml:新增 sweep-agentic-evals 任务,输入块复制自 sweep-agentic(转发 scenario-typekv-offloadingkv-offload-backend(+metadata)total-cpu-dram-gbdurationisl/osl/max-model-len 置为 '0'),并附加 run-eval: true / eval-only: true;同时接入 collect-evals
  • recover_failed_ingest.pyeval_jobs 统计计入 agentic_evals(使用 .get,兼容旧的复用产物)。
  • 测试:现有测试用 stdout="[]" 模拟子进程,真实行形状从未经过 schema 校验,CI 成了第一道防线。本 PR 新增端到端拆分测试(真实的固定 + agentic 评估行经过真实的 model_validate)及 ChangelogMatrixEntry 分桶测试(含 evals 拒绝 agentic 行的守卫测试)。

python -m pytest utils/ -q:543 通过;utils/evals/test_run_eval_dispatch.py 的 2 个失败在 main 上即存在(依赖本地 mini-swe-agent 环境),与本 PR 无关。

非目标:trigger-ingest / trigger-agentic-ingest 的触发条件未改动;仅含 agentic 评估的 main 推送应走哪条 ingest 路径留作后续跟进。

合并后,agentx/dsv4-v300-vllm-mtp#2258)应 rebase 到 main 并移除其 validation.py 的 union 提交。

Validation run / 验证运行

This PR carries an eval-only, agentic-scoped changelog entry for the existing dsv4-fp4-b300-vllm-agentic config, so the sweep itself proves the fix (the same eval-only dispatch that failed on #2258/#2259): run 29633097900check-changelog passes (previously 8 schema errors), the fixed-seq-len eval / job is skipped, and the new agentic eval / job dispatches the DEP8 conc-224 SWE-bench eval with agentic inputs (previously died in 7s on check_env_vars: ISL/OSL/MAX_MODEL_LEN). After merge, the same entry re-runs through the on: push main sweep, confirming the push path too.

中文:本 PR 附带一条针对现有 dsv4-fp4-b300-vllm-agentic 配置的 evals-only、仅 agentic 场景的 changelog 条目,使扫描本身即可验证修复(与 #2258/#2259 失败的 eval-only 调度路径完全一致):见 run 29633097900 —— check-changelog 通过(此前报 8 个 schema 校验错误),固定序列长度的 eval / 任务被正确跳过,新的 agentic eval / 任务以 agentic 输入派发 DEP8 conc-224 的 SWE-bench 评估(此前在 7 秒内因 check_env_vars: ISL/OSL/MAX_MODEL_LEN 退出)。合并后,同一条目会经由 main 分支的 on: push 扫描再次运行,同时验证 push 路径。

…sweep job

Since #1947, generate_sweep_configs --evals-only marks the top-concurrency
agentic arm of each config as a SWE-bench eval row, but two consumers were
never taught about agentic eval rows, so any PR touching a single-node
agentic-coding config failed its sweep:

1. Schema: ChangelogMatrixEntry.evals only accepted SingleNodeMatrixEntry
   (fixed-seq-len), so process_changelog.py's final model_validate rejected
   the agentic row and check-changelog failed before any GPU work.
2. Dispatch: even with the schema widened, run-sweep.yml's sweep-evals job
   dispatches every eval row with fixed-seq-len inputs; an agentic row gets
   empty ISL/OSL/MAX_MODEL_LEN and scenario-type defaults to fixed-seq-len,
   so the launcher runs the fixed_seq_len benchmark script, which exits on
   check_env_vars.

Fix: route agentic eval rows into a new agentic_evals bucket (mirroring the
single_node['agentic'] design) dispatched by a new sweep-agentic-evals job
cloned from sweep-agentic's input block plus run-eval/eval-only, so an
agentic row can never reach the fixed-seq-len eval dispatch. The agentic
model accepts optional run-eval/eval-only carried by eval rows;
exclude_none keeps benchmark row output byte-identical.

中文:自 #1947 起,generate_sweep_configs --evals-only 会将每个配置中并发度最高的
agentic 搜索空间条目标记为 SWE-bench 评估行,但下游两个消费方并不认识 agentic
评估行,导致任何涉及单节点 agentic-coding 配置的 PR 扫描失败:其一,schema 层
ChangelogMatrixEntry.evals 仅接受固定序列长度条目,check-changelog 直接报错;
其二,调度层 sweep-evals 以固定序列长度的输入派发评估行,ISL/OSL/MAX_MODEL_LEN
为空且 scenario-type 回落为 fixed-seq-len,启动器因此运行错误的基准测试脚本并
在 check_env_vars 处退出。本修复新增 agentic_evals 独立分桶(与
single_node['agentic'] 设计一致),由新的 sweep-agentic-evals 任务按
sweep-agentic 的输入派发并附加 run-eval/eval-only,使 agentic 评估行不可能进入
固定序列长度的评估调度路径;基准测试行的输出保持逐字节不变。

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — this correctly plugs the agentic SWE-bench eval dispatch gap by mirroring the existing single_node['agentic'] → sweep-agentic pattern.

Extended reasoning...

Overview

The PR adds a new agentic_evals bucket (schema in validation.py, split logic in process_changelog.py) and a dedicated sweep-agentic-evals job in run-sweep.yml to fix a real bug: single-node agentic-coding eval rows previously had no valid path through ChangelogMatrixEntry and, once schema-widened, would have been dispatched with fixed-seq-len inputs (empty ISL/OSL/MAX_MODEL_LEN), launching the wrong benchmark script. recover_failed_ingest.py is updated to count the new bucket in its eval_jobs stat.

Security risks

None. This is CI/workflow orchestration and Pydantic schema code with no user-facing surface, auth, or secrets handling.

Level of scrutiny

Moderate — this is CI-critical infrastructure (a broken change would block all PRs touching agentic configs, as the linked incident shows), but the change is well-contained: it adds a new parallel bucket/job rather than modifying existing dispatch paths, and the risk of the existing fixed-seq-len path being broken is essentially nil (the evals bucket still explicitly rejects agentic rows, verified by a new guard test).

Other factors

I independently verified the change is properly scoped: generate_sweep_configs.py's mark_eval_entries/mark_all_eval_entries only ever mark single-node agentic rows as eval rows (multi-node agentic eval is explicitly commented as unsupported), so the new agentic_evals bucket and sweep-agentic-evals job cover the entire reachable case — there's no multi-node agentic eval row that would still hit the old broken path. Tests exercise the real model_validate (not mocked), which is exactly what was missing before and what let this bug reach CI in the first place. The trigger-ingest/trigger-agentic-ingest non-goal called out in the PR description is accurate — it's a pre-existing gating condition left untouched, not a regression from this change.

Collapse fixtures into module constants, merge the accept/reject checks
into one test, and drop redundant cases; added test lines go from 212 to
100 with the two core guards kept (agentic rows validate only in
agentic_evals; realistic rows split end-to-end through the real schema).

中文:精简 agentic 评估分桶测试——fixture 合并为模块常量,接受/拒绝检查合并
为单个测试并移除冗余用例,新增测试行数从 212 降至 100,保留两项核心守卫
(agentic 行仅能通过 agentic_evals 校验;真实行形状端到端经过真实 schema
拆分)。
Eval-only, agentic-coding-scoped entry for dsv4-fp4-b300-vllm-agentic so
the PR sweep (and the on-push main sweep after merge) runs exactly one
job: the DEP8 top-concurrency SWE-bench eval through the new
sweep-agentic-evals dispatch, confirming the fix for the eval-only
failures first seen on #2258/#2259.

中文:新增 changelog 条目以端到端验证 agentic 评估调度——针对
dsv4-fp4-b300-vllm-agentic 的 evals-only、仅 agentic-coding 场景条目,使
PR 扫描(及合并后 main 分支的 push 触发扫描)只运行一个任务:DEP8 最高并发
的 SWE-bench 评估经由新的 sweep-agentic-evals 调度执行,确认对 #2258/#2259
上首次出现的 eval-only 失败的修复。
@github-actions

Copy link
Copy Markdown
Contributor

@Oseltamivir

Copy link
Copy Markdown
Collaborator Author

@Oseltamivir
Oseltamivir merged commit 476d0d2 into main Jul 18, 2026
3 checks passed
@Oseltamivir
Oseltamivir deleted the fix/agentic-eval-bucket-dispatch branch July 18, 2026 08:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

1 participant