"""Build frozen adaptive T20 evaluation packs.""" import argparse import json from pathlib import Path _ROOT = Path(__file__).parent.parent _EVAL_DIR = _ROOT / "data" / "eval_packs" def _scenario(seed: int, start_state: str, over: int, score: int, wickets: int, target: int | None, tags: list[str]) -> dict: return { "seed": seed, "task": "stage2_full", "start_state": start_state, "innings_type": "second" if target is not None else "first", "over": over, "ball": 0, "score": score, "wickets": wickets, "target": target, "max_overs": 20, "scenario_tags": tags, } def build_pack(eval_pack_id: str = "adaptive_t20_v1") -> dict: dev = [ _scenario(101, "batting", 2, 18, 1, None, ["powerplay", "bat_first"]), _scenario(102, "batting", 8, 64, 3, None, ["middle", "rebuild"]), _scenario(103, "batting", 16, 128, 5, 172, ["death", "chase", "pressure"]), _scenario(104, "bowling", 5, 48, 1, None, ["powerplay", "defend"]), _scenario(105, "bowling", 17, 144, 4, 168, ["death", "defend", "wickets_in_hand"]), ] official = [] seed = 1000 templates = [ ("batting", 1, 12, 0, None, ["powerplay", "bat_first"]), ("batting", 6, 42, 2, None, ["middle", "collapse"]), ("batting", 10, 78, 3, 164, ["middle", "chase", "par"]), ("batting", 15, 118, 5, 186, ["death", "chase", "hard"]), ("batting", 18, 152, 7, 174, ["death", "chase", "tail"]), ("bowling", 3, 30, 0, None, ["powerplay", "defend"]), ("bowling", 9, 74, 2, None, ["middle", "spin_matchup"]), ("bowling", 14, 112, 4, 158, ["middle", "defend", "par"]), ("bowling", 16, 136, 3, 172, ["death", "aggressive_opponent"]), ("bowling", 19, 166, 7, 176, ["death", "close_finish"]), ] for cycle in range(6): for start_state, over, score, wickets, target, tags in templates: official.append( _scenario( seed, start_state, over, score + cycle * 3, min(9, wickets + (cycle % 2)), target + cycle * 2 if target is not None else None, tags, ) ) seed += 1 return { "eval_pack_id": eval_pack_id, "format": "T20", "description": "Adaptive T20 benchmark with chase, defense, collapse, death-over, and matchup scenarios.", "splits": { "dev": dev, "official": official, }, "opponent": { "dev_mode": "heuristic", "official_mode": "llm_cached", "cache_path_env": "CRICKET_OPPONENT_CACHE", "cache_file": f"data/opponent_cache/{eval_pack_id}.jsonl", }, "scoring": { "result_quality": 0.35, "strategy_bundle": 0.30, "tool_efficiency": 0.20, "format": 0.15, }, "scenario_tags": sorted({tag for s in dev + official for tag in s["scenario_tags"]}), } def main(): parser = argparse.ArgumentParser() parser.add_argument("--eval-pack-id", default="adaptive_t20_v1") parser.add_argument("--output", default=None) args = parser.parse_args() pack = build_pack(args.eval_pack_id) output = Path(args.output) if args.output else _EVAL_DIR / f"{args.eval_pack_id}.json" output.parent.mkdir(parents=True, exist_ok=True) with output.open("w") as f: json.dump(pack, f, indent=2) print( f"Wrote {output}: {len(pack['splits']['dev'])} dev, " f"{len(pack['splits']['official'])} official scenarios" ) if __name__ == "__main__": main()