sora 370953729b Fix perf stats (wrong import path), per-repeat checkpoints, README
- perf_stats aggregator lives in eval/, not model/: the import failed
  silently and EVERY perf column was empty (not just ttft). Now warns
  on stderr instead of swallowing.
- repeats > 1 get their own checkpoint key (:rep2, :rep3, ...): repeat 2
  previously restored repeat 1's predictions and finished instantly with
  identical scores. rep1 keeps the legacy key (existing checkpoints still
  resume).
- repeats summary: report the MEAN score and aggregate time/tokens over
  ALL runs (was: last run only).
- README: six-benchmark command as the primary example.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-11 13:38:04 +00:00

32 lines
1019 B
Python

"""Run-lifecycle hooks: plugins that observe/extend a run without touching
its logic. Register with @register_hook('on_benchmark_failed') etc.; the CLI
fires them at the matching points. Multiple hooks per event all run.
from evalharness.hooks import register_hook
@register_hook('on_benchmark_failed')
def notify(name, error, **ctx):
requests.post(webhook, json={'bench': name, 'error': str(error)})
"""
from typing import Callable, Dict, List
_HOOKS: Dict[str, List[Callable]] = {}
def register_hook(event: str):
def decorator(fn):
_HOOKS.setdefault(event, []).append(fn)
return fn
return decorator
def fire(event: str, **ctx) -> None:
"""Invoke every hook registered for the event; hook errors are printed
and swallowed -- observability must never break the run."""
for fn in _HOOKS.get(event, []):
try:
fn(**ctx)
except Exception as e:
print(f'hook {fn.__name__!r} failed: {type(e).__name__}: {e}', flush=True)