Files

104 lines
4.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Preview or execute at most eight paid diagnostic samples; never change key limits.
Run from the repository root. Preview is the default; --execute starts the eval.
Use a NEW output directory for a changed configuration. Identical invocations resume
through Inspect eval_set. These are development runs, not confirmatory results.
"""
from __future__ import annotations
import argparse
import hashlib
import json
import subprocess
from pathlib import Path
def parser() -> argparse.ArgumentParser:
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("--split", choices=["original", "conflicting"], default="conflicting")
p.add_argument("--ids", nargs="+", default=["lcbhard_0", "lcbhard_1"])
p.add_argument("--model", default="openrouter/z-ai/glm-5.3-flash")
p.add_argument("--messages", type=int, choices=[30, 60], default=30)
p.add_argument("--sample-seconds", type=int, default=1200)
p.add_argument("--tokens", type=int, default=200000,
help="Per-sample total token limit, including repeated input; not a dollar cap")
p.add_argument("--seed-file", type=Path, action="append", default=[])
p.add_argument("--exposure", choices=["available", "inspect"], default="available")
p.add_argument("--out", type=Path, required=True)
p.add_argument("--execute", action="store_true")
return p
def configuration(args: argparse.Namespace) -> tuple[dict, dict[str, str]]:
import messageboardbench.task as task_module
import impossiblebench.livecodebench_scorers as upstream_scorer
from messageboardbench.task import validate_seed_files
if not 1 <= len(args.ids) <= 8 or len(set(args.ids)) != len(args.ids):
raise ValueError("Choose 1–8 distinct sample IDs for diagnostics")
if not 1 <= args.sample_seconds <= 1800 or not 1 <= args.tokens <= 400000:
raise ValueError("Diagnostics require 1–1800 seconds and 1–400000 tokens per sample")
seeds = {p.name: p.read_text() for p in args.seed_file}
if len(seeds) != len(args.seed_file):
raise ValueError("Seed filenames must be unique")
validate_seed_files(seeds)
config = {
"purpose": "development-only", "split": args.split, "ids": args.ids,
"model": args.model, "message_limit": args.messages,
"time_limit": args.sample_seconds, "token_limit": args.tokens,
"exposure": args.exposure, "max_attempts": 3, "concurrency": 2,
"timeout": 300, "max_retries": 1, "retry_attempts": 1,
"source_sha256": {str(Path(p).resolve()): hashlib.sha256(Path(p).read_bytes()).hexdigest()
for p in (__file__, task_module.__file__, upstream_scorer.__file__)},
"seed_files": {p.name: {"source": str(p.resolve()),
"sha256": hashlib.sha256(seeds[p.name].encode()).hexdigest()}
for p in args.seed_file},
}
return config, seeds
def main() -> None:
args = parser().parse_args()
config, seeds = configuration(args)
print(json.dumps(config, indent=2))
if not args.execute:
print("Preview only. Add --execute to run; no model request has been sent.")
return
# Refuse before loading credentials or making a model request if Docker is down.
subprocess.run(["docker", "info", "--format", "{{.ServerVersion}}"], check=True,
timeout=15, capture_output=True)
from dotenv import load_dotenv
from inspect_ai import eval_set
from messageboardbench.analysis import rows, summarise, write_csv
from messageboardbench.task import scratch_livecodebench
args.out.mkdir(parents=True, exist_ok=True)
manifest = args.out / "manifest.json"
if manifest.exists() and json.loads(manifest.read_text()) != config:
raise ValueError("Configuration changed; use a new --out directory")
manifest.write_text(json.dumps(config, indent=2) + "\n")
load_dotenv()
task = scratch_livecodebench(split=args.split, message_limit=args.messages,
seed_files=seeds, exposure=args.exposure)
missing = set(args.ids) - {str(sample.id) for sample in task.dataset}
if missing:
raise ValueError(f"Unknown task IDs: {sorted(missing)}")
success, logs = eval_set(
task,
log_dir=str(args.out / "evals"), model=args.model, sample_id=args.ids,
max_connections=2, max_sandboxes=2, max_samples=2,
max_retries=1, retry_attempts=1, timeout=300,
time_limit=args.sample_seconds, token_limit=args.tokens,
fail_on_error=False,
)
table = rows(s for log in logs for s in (log.samples or []))
write_csv(table, args.out / "samples.csv")
summary = {"eval_set_success": success, **summarise(table)}
(args.out / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
print(json.dumps(summary, indent=2))
if not success:
raise SystemExit(1)
if __name__ == "__main__":
main()