dispatch_arena_v0 / scripts /build_catalog.py
Freakdivi's picture
Upload folder using huggingface_hub
c71bf62 verified
"""Build the dispatch arena scenario catalog.
Usage:
.venv/bin/python -m dispatch_arena.scripts.build_catalog
.venv/bin/python -m dispatch_arena.scripts.build_catalog --backend llm
.venv/bin/python -m dispatch_arena.scripts.build_catalog --easy 30 --medium 40 --hard 30 --out catalog.json
Backends:
anchor (default): deterministic, no API key needed
llm : uses Claude (anthropic SDK, requires ANTHROPIC_API_KEY).
Falls back per-scenario to anchors if the LLM trips.
"""
from __future__ import annotations
import argparse
import logging
import sys
from pathlib import Path
from dispatch_arena.catalog.builder import (
AnchorScenarioBuilder,
LLMScenarioBuilder,
save_catalog,
)
def parse_args(argv=None):
parser = argparse.ArgumentParser(description="Generate the Dispatch Arena scenario catalog.")
parser.add_argument("--backend", choices=["anchor", "llm"], default="anchor")
parser.add_argument("--easy", type=int, default=30)
parser.add_argument("--medium", type=int, default=40)
parser.add_argument("--hard", type=int, default=30)
parser.add_argument("--seed", type=int, default=0, help="master RNG seed for determinism")
parser.add_argument(
"--out",
type=Path,
default=Path(__file__).resolve().parents[1] / "catalog" / "catalog.json",
)
parser.add_argument("--verbose", action="store_true")
return parser.parse_args(argv)
def main(argv=None) -> int:
args = parse_args(argv)
logging.basicConfig(
level=logging.INFO if args.verbose else logging.WARNING,
format="%(levelname)s %(name)s: %(message)s",
)
counts = {"easy": args.easy, "medium": args.medium, "hard": args.hard}
total = sum(counts.values())
if args.backend == "llm":
builder = LLMScenarioBuilder(master_seed=args.seed)
else:
builder = AnchorScenarioBuilder(master_seed=args.seed)
print(f"Building {total} scenarios via {args.backend} backend ({counts}) -> {args.out}")
specs = builder.build_batch(counts)
args.out.parent.mkdir(parents=True, exist_ok=True)
save_catalog(specs, args.out)
# Summary
by_diff = {}
by_skill = {}
for s in specs:
by_diff[s.difficulty] = by_diff.get(s.difficulty, 0) + 1
for t in s.skill_focus:
by_skill[t] = by_skill.get(t, 0) + 1
print(f"\n=== CATALOG WRITTEN: {len(specs)} scenarios ===")
print(f"By difficulty: {by_diff}")
print(f"By skill_focus tag: {dict(sorted(by_skill.items(), key=lambda kv: -kv[1]))}")
print(f"Output: {args.out}")
return 0
if __name__ == "__main__":
sys.exit(main())