feat(olympics): agent Olympics benchmark — multi-language arena, results ledger, model-aware budgets

Fourth benchmark axis: teams of LLM agents deliberate in a room, implement
code in an isolated VM, and are scored deterministically on correctness/speed.

- Multi-language adapter (python/js/go/rust/bash) via MultiPL-E continuation mode
- Append-only JSONL ledger with status tracking (ok/dnf/killed/error) so
  budget-exhausted or crashed runs still record a row (fixes selection bias)
- Model-aware wall-clock scaling (U-shaped by param count; 3x for reasoning)
- Self-owned SIGALRM/SIGTERM watchdog (RunTimeout: BaseException so broad
  except Exception handlers in the infer/completion path can't swallow it)
- Seed forwarded to Ollama sampler + markdown-fence stripping in completion.py
This commit is contained in:
leetcrypt
2026-06-27 10:17:23 -07:00
parent 7fb3911550
commit df8f1881d8
19 changed files with 2962 additions and 2 deletions
+250
View File
@@ -0,0 +1,250 @@
"""Append-only results ledger — the research record for Olympics runs.
Each event already writes a ``score.json``/``transcript.json`` under a
``<team>__<challenge>`` directory, but that directory is *overwritten* on rerun,
so it cannot answer "how did this team trend over time?". The ledger fixes that:
one flat JSON line per run, appended forever, keyed by a unique ``run_id`` and
stamped with the wall-clock time + git commit so a result is reproducible.
JSONL is chosen on purpose — it is append-safe under concurrency, streamable,
and loads in one line from pandas (``pd.read_json(path, lines=True)``), jq, or
plain ``json.loads`` per line. ``leaderboard()`` aggregates it without re-running
any model (same philosophy as re-scoring a transcript under a new profile).
"""
from __future__ import annotations
import json
import os
import socket
import subprocess
import time
import uuid
from pathlib import Path
from statistics import median
DEFAULT_PATH = Path.home() / ".cache" / "hh-bench" / "olympics" / "ledger.jsonl"
# Stable column order so the JSONL is human-diffable and schema-clear.
FIELDS = (
"run_id", "ts", "status", "team", "topology", "framing", "models",
"language", "suite", "challenge", "mode", "room", "runtime", "profile",
"seed", "code_model", "correct", "submitted", "composite", "pass@1",
"rounds", "rounds_to_green", "wall_clock_s", "wall_clock_budget",
"budget_scale", "total_tokens", "tokens_in", "tokens_out",
"cost_normalized", "defect_class", "model_baseline_correct",
"n_penalties", "error", "git", "host", "transcript",
)
# A completed-and-graded run vs the ways a run can fail to produce a grade.
STATUS_OK = "ok" # ran to a hidden-test verdict
STATUS_DNF = "dnf" # graceful budget exhaustion (soft wall-clock/token cap)
STATUS_KILLED = "killed" # hard deadline / external SIGTERM / watchdog
STATUS_ERROR = "error" # uncaught exception mid-run
def _git_sha() -> str:
try:
out = subprocess.run(["git", "rev-parse", "--short", "HEAD"],
capture_output=True, text=True, timeout=5)
return out.stdout.strip() if out.returncode == 0 else ""
except Exception: # noqa: BLE001
return ""
def _path(path: str | os.PathLike | None) -> Path:
return Path(path) if path else DEFAULT_PATH
def row_from_score(score: dict, *, team, challenge, mode: str, room: str,
runtime: str, seed: int, suite: str = "mbpp",
code_model: str | None = None,
wall_clock_budget: float | None = None,
budget_scale: float | None = None) -> dict:
"""Flatten a score dict + run context into one ledger row."""
tok = score.get("tokens", {}) or {}
return {
"run_id": uuid.uuid4().hex[:12],
"ts": time.strftime("%Y-%m-%dT%H:%M:%S"),
"status": STATUS_OK,
"team": team.id,
"topology": team.topology,
"framing": team.framing,
"models": team.models,
"language": challenge.language,
"suite": suite,
"challenge": challenge.id,
"mode": mode,
"room": score.get("room_substrate", room),
"runtime": runtime,
"profile": score.get("profile"),
"seed": seed,
"code_model": code_model,
"correct": bool(score.get("correct")),
"submitted": bool(score.get("submitted")),
"composite": score.get("composite"),
"pass@1": score.get("pass@1"),
"rounds": score.get("rounds"),
"rounds_to_green": score.get("rounds_to_green"),
"wall_clock_s": score.get("wall_clock_s"),
"wall_clock_budget": wall_clock_budget,
"budget_scale": budget_scale,
"total_tokens": score.get("total_tokens"),
"tokens_in": tok.get("in", 0),
"tokens_out": tok.get("out", 0),
"cost_normalized": score.get("cost_normalized"),
"defect_class": score.get("defect_class"),
"model_baseline_correct": score.get("model_baseline_correct"),
"n_penalties": len(score.get("penalties", []) or []),
"error": "",
"git": _git_sha(),
"host": socket.gethostname(),
"transcript": score.get("transcript"),
}
def _write(row: dict, path: str | os.PathLike | None) -> dict:
p = _path(path)
p.parent.mkdir(parents=True, exist_ok=True)
with open(p, "a") as f:
f.write(json.dumps({k: row.get(k) for k in FIELDS}) + "\n")
return row
def append(score: dict, *, team, challenge, mode: str, room: str,
runtime: str, seed: int, suite: str = "mbpp",
code_model: str | None = None,
wall_clock_budget: float | None = None,
budget_scale: float | None = None,
path: str | os.PathLike | None = None) -> dict:
"""Append one completed run to the ledger and return the row written."""
row = row_from_score(score, team=team, challenge=challenge, mode=mode,
room=room, runtime=runtime, seed=seed, suite=suite,
code_model=code_model,
wall_clock_budget=wall_clock_budget,
budget_scale=budget_scale)
return _write(row, path)
def append_incomplete(*, team, challenge, mode: str, room: str, runtime: str,
seed: int, status: str, error: str = "",
suite: str = "mbpp", code_model: str | None = None,
wall_clock_budget: float | None = None,
budget_scale: float | None = None,
path: str | os.PathLike | None = None) -> dict:
"""Append a run that never produced a hidden-test verdict (killed / errored
/ hard-DNF). Keeps the research record complete so the ledger isn't biased
toward runs that happened to finish (the selection-bias fix)."""
row = {k: None for k in FIELDS}
row.update({
"run_id": uuid.uuid4().hex[:12],
"ts": time.strftime("%Y-%m-%dT%H:%M:%S"),
"status": status,
"team": team.id, "topology": team.topology, "framing": team.framing,
"models": team.models, "language": challenge.language, "suite": suite,
"challenge": challenge.id, "mode": mode, "room": room,
"runtime": runtime, "seed": seed, "code_model": code_model,
"correct": False, "submitted": False, "n_penalties": 0,
"wall_clock_budget": wall_clock_budget, "budget_scale": budget_scale,
"error": error[:200], "git": _git_sha(), "host": socket.gethostname(),
})
return _write(row, path)
def load(path: str | os.PathLike | None = None) -> list[dict]:
p = _path(path)
if not p.exists():
return []
rows = []
for line in p.read_text().splitlines():
line = line.strip()
if line:
try:
rows.append(json.loads(line))
except json.JSONDecodeError:
continue
return rows
def _matches(row: dict, filters: dict) -> bool:
for k, v in filters.items():
if v is None:
continue
rv = row.get(k)
if k == "models": # substring match against any model in the team
if not any(v in m for m in (rv or [])):
return False
elif k == "since":
if (row.get("ts") or "") < v:
return False
elif rv != v:
return False
return True
def leaderboard(rows: list[dict], *, by: str = "team",
filters: dict | None = None) -> list[dict]:
"""Aggregate rows into a leaderboard grouped by ``by`` (any row field, or a
'+'-joined composite like 'team+language'). Ranked by solve rate."""
filters = filters or {}
keys = by.split("+")
def group_key(r):
parts = []
for k in keys:
v = r.get(k)
if isinstance(v, list):
# collapse a same-model team to one tag; keep mixed teams joined.
uniq = list(dict.fromkeys(v))
parts.append("/".join(uniq))
else:
parts.append(str(v))
return " · ".join(parts)
groups: dict[str, list[dict]] = {}
for r in rows:
if _matches(r, filters):
groups.setdefault(group_key(r), []).append(r)
out = []
for g, rs in groups.items():
attempted = len(rs)
# solve_rate is computed over *completed* runs only (status == ok) so an
# infra kill never masquerades as a capability failure; killed/errored
# runs are surfaced separately as a reliability signal.
done = [r for r in rs if (r.get("status") or "ok") == STATUS_OK]
incomplete = attempted - len(done)
solved = [r for r in done if r.get("correct")]
greens = [r["rounds_to_green"] for r in solved
if r.get("rounds_to_green") is not None]
secs = [r["wall_clock_s"] for r in done if r.get("wall_clock_s") is not None]
toks = [r["total_tokens"] for r in done if r.get("total_tokens") is not None]
out.append({
"group": g, "n": attempted, "completed": len(done),
"incomplete": incomplete, "solved": len(solved),
"solve_rate": round(len(solved) / len(done), 3) if done else None,
"median_green": median(greens) if greens else None,
"median_s": round(median(secs), 1) if secs else None,
"median_tokens": int(median(toks)) if toks else None,
})
out.sort(key=lambda d: (d["solve_rate"] if d["solve_rate"] is not None
else -1.0, d["completed"]), reverse=True)
return out
def print_leaderboard(agg: list[dict], by: str) -> None:
print("=" * 80)
print(f"olympics leaderboard · by={by} · groups={len(agg)}")
print("-" * 80)
print(f"{'group':<30}{'done':>5}{'dnf':>5}{'solved':>7}{'rate':>7}"
f"{'med_grn':>8}{'med_s':>8}{'med_tok':>9}")
print("-" * 80)
for d in agg:
g = d["group"] if len(d["group"]) <= 29 else d["group"][:28] + ""
rate = "" if d["solve_rate"] is None else f"{d['solve_rate']:.3f}"
print(f"{g:<30}{d['completed']:>5}{d['incomplete']:>5}{d['solved']:>7}"
f"{rate:>7}"
f"{('' if d['median_green'] is None else d['median_green']):>8}"
f"{('' if d['median_s'] is None else d['median_s']):>8}"
f"{('' if d['median_tokens'] is None else d['median_tokens']):>9}")
print("=" * 80)