mirror of
https://github.com/razzant/ouroboros.git
synced 2026-08-06 00:59:46 +00:00
Commit 3/3 of the bench post-mortem sprint (plan smooth-skipping-charm; commits 1-2 = bf8bde7 v6.54.3, ef786bb v6.54.4). Minor bump per plan. Shared bench-template scaffold defaults, disclosed in the benchmarks index and per-bench METHODOLOGY files: OUROBOROS_MAX_WORKERS=4 (same-model decomposition slots within one task, never best-of-N; TB 2->4, GAIA --max-workers default 1->4 with explicit 1 as the strict-baseline ablation and the quality-profile silent 1->5 bump removed, SWE-pro 5->4), OUROBOROS_SAFETY_MODE=light (disposable jails; deterministic guards stay), RUNTIME_MODE=pro for container benches (GAIA deliberately stays light: its solver runs unisolated against a live repo), and claude_code_edit disabled in every bench solve task (single-model harness measurement). TB raises _DEADLINE_SAFETY_SEC 30->105 from measured finalization overhead, mirrors the registry _WEB_TOOLS denylist (youtube_transcript drift fixed, pinned by a sync test), and the README pins why --all-model keeps review single-model. ProgramBench e2e runner ported from the colleague's tree, adapted to our APIs: metadata.budget_profile onto the v6.54.4 contract (footer keys dropped, reserve pct unit-fixed 0.15->15), solve-model preflight through migrate_model_value (fail-fast on direct-route legacy ids), atomic per-instance checkpoints with honored reattach (client poll timeout leaves the executor alive; the next run skips seed/start and reattaches), explicit payload-status terminal detection, denominator-preserving ledgers (skipped_existing rows; skipped = successful for exit code), source-only submissions (both root binaries excluded by name), idempotent workspace normalization shared by the prepare-only flow. New continual_learning/ launcher wraps the EXTERNAL CL-Bench runner (nothing vendored; fails loudly with obtain instructions), strict-sequential guard (parallel opt-in is exclusively-stateless-bridge only), standard-path pointer rows keep the ledger denominator, fidelity gaps of the pinned external adapter recorded and warned. OSWorld aligned to the official 2.0 protocol (pinned OSWorld-V2@c261cb57, 500-step default, show_result.py layout, official traj rows), bridge-level final_answer capture with VM-state-only prompting, preflight verifies the target server's effective scaffold settings via /api/settings (env cannot configure a --url server) and refuses the live desktop URL without an explicit flag. LifelongAgentBench documented as blocked (its 100% run was a no-gold-oracle artifact). Carriers synced to 6.55.0. Review: 6 triad+scope rounds to a fully clean verdict (16 confirmed criticals fixed, each with a regression test); gemini/opus clean in all rounds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
125 lines
4.5 KiB
Python
125 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Copy ProgramBench submissions into a separate run dir for targeted eval.
|
|
|
|
Creates a minimal ``programbench eval``-compatible tree::
|
|
|
|
<dest_run>/<instance_id>/submission.tar.gz
|
|
|
|
Only instances with a non-empty ``submission.tar.gz`` in the source run are copied.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import pathlib
|
|
import shutil
|
|
import sys
|
|
|
|
if __package__ in {None, ""}:
|
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[3]))
|
|
|
|
from devtools.benchmarks.common.manifests import write_json
|
|
from devtools.benchmarks.common.run_roots import ensure_outside_repo, run_root, safe_join_under
|
|
from devtools.benchmarks.programbench.run_programbench_e2e import _load_instances
|
|
|
|
|
|
def _parse_instance_ids(raw: str) -> list[str]:
|
|
return [part.strip() for part in str(raw or "").split(",") if part.strip()]
|
|
|
|
|
|
def export_submissions(
|
|
*,
|
|
source_run: pathlib.Path,
|
|
dest_run: pathlib.Path,
|
|
instance_ids: list[str],
|
|
overwrite: bool,
|
|
) -> dict[str, str]:
|
|
copied: dict[str, str] = {}
|
|
skipped: list[str] = []
|
|
missing: list[str] = []
|
|
|
|
for instance_id in instance_ids:
|
|
src_sub = safe_join_under(source_run, instance_id) / "submission.tar.gz"
|
|
if not src_sub.is_file() or src_sub.stat().st_size <= 0:
|
|
missing.append(instance_id)
|
|
continue
|
|
dest_dir = safe_join_under(dest_run, instance_id)
|
|
dest_sub = dest_dir / "submission.tar.gz"
|
|
if dest_sub.is_file() and dest_sub.stat().st_size > 0 and not overwrite:
|
|
skipped.append(instance_id)
|
|
continue
|
|
dest_dir.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(src_sub, dest_sub)
|
|
copied[instance_id] = str(dest_sub)
|
|
|
|
return {
|
|
"source_run": str(source_run),
|
|
"dest_run": str(dest_run),
|
|
"requested": len(instance_ids),
|
|
"copied": len(copied),
|
|
"skipped_existing": len(skipped),
|
|
"missing_submission": len(missing),
|
|
"copied_ids": sorted(copied.keys()),
|
|
"skipped_ids": sorted(skipped),
|
|
"missing_ids": sorted(missing),
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Export ProgramBench submissions to a separate run dir")
|
|
parser.add_argument("--repo-dir", default=str(pathlib.Path(__file__).resolve().parents[3]))
|
|
parser.add_argument("--source-run-id", required=True, help="existing run under bench_runs/programbench/")
|
|
parser.add_argument("--dest-run-id", required=True, help="export run id (created under bench_runs/programbench/)")
|
|
parser.add_argument("--instance-id", action="append", default=[], help="repeatable instance id filter")
|
|
parser.add_argument("--instance-ids", default="", help="comma-separated instance ids")
|
|
parser.add_argument("--shuffle", action="store_true")
|
|
parser.add_argument("--slice", default="", dest="slice_spec", help="e.g. 0:25 or 50:65")
|
|
parser.add_argument("--filter", default="", dest="filter_spec")
|
|
parser.add_argument("--overwrite", action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
repo_dir = pathlib.Path(args.repo_dir).expanduser().resolve(strict=False)
|
|
source_run = ensure_outside_repo(run_root("programbench", args.source_run_id), repo_dir)
|
|
dest_run = ensure_outside_repo(run_root("programbench", args.dest_run_id), repo_dir)
|
|
|
|
explicit = list(args.instance_id or []) + _parse_instance_ids(args.instance_ids)
|
|
if explicit:
|
|
instance_ids = explicit
|
|
else:
|
|
instances = _load_instances(
|
|
difficulty="",
|
|
filter_spec=str(args.filter_spec or ""),
|
|
slice_spec=str(args.slice_spec or ""),
|
|
instance_id="",
|
|
shuffle=bool(args.shuffle),
|
|
)
|
|
instance_ids = [str(item["instance_id"]) for item in instances]
|
|
|
|
if not instance_ids:
|
|
raise SystemExit("no instance ids selected")
|
|
|
|
summary = export_submissions(
|
|
source_run=source_run,
|
|
dest_run=dest_run,
|
|
instance_ids=instance_ids,
|
|
overwrite=bool(args.overwrite),
|
|
)
|
|
write_json(dest_run / "export_manifest.json", summary)
|
|
write_json(
|
|
dest_run / "instance_order.json",
|
|
{
|
|
"count": len(instance_ids),
|
|
"shuffle": bool(args.shuffle),
|
|
"shuffle_seed": 42 if args.shuffle else None,
|
|
"instance_ids": instance_ids,
|
|
"exported_from": str(source_run),
|
|
},
|
|
)
|
|
print(json.dumps(summary, indent=2))
|
|
print(dest_run)
|
|
return 0 if summary["copied"] or summary["skipped_existing"] else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|