Jev-like decision models (TypeSafe Jev, and open models that serve POST /v1/systemone) play games against each
other, so their abilities can be compared by results. The current game is 4-player UNO.
A survey of the models is in docs/jev_models.md; JevBench public-item results for 28 small
open models are in runs/jevbench-public-20260929/, and the items
themselves in data/jevbench-public/. The site's /arenas/bench/items/ page shows every item (state, question,
options, correct answer) with the answer and the probability each model gave.
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]' # the platform needs trueskill and tokenizers; tests use pytest
.venv/bin/python -m pytest # rules engine, prompt building, client, tournament
# sanity check without models: 1 heuristic player against 3 random players, 1000 games in a few seconds
.venv/bin/python -m arena run configs/sanity.toml
# 4 local 0.8B models at one table
servers/setup.sh # one venv per model (their dependencies conflict); run once
servers/start.sh # start the servers: kev 8101 · decider 8102 · jevstyle 8103 · openthai 8104
.venv/bin/python servers/check.py # send one test request to each server
.venv/bin/python -m arena run configs/local4.toml # 250 deals x 4 seat rotations = 1000 games
servers/stop.sh
# results and replays
.venv/bin/python -m arena viz runs/<dir> # http://127.0.0.1:8200
.venv/bin/python -m arena viz runs/<dir> --export view.html # one self-contained HTML file (replays of the first 3 deals)
.venv/bin/python -m arena prompt --seed 3 --step 30 # the request a model receives at some point of a game
The server environments (venvs, third-party sources, weight revisions) are described in
servers/envs/README.md; each model's start command is in servers/models/<name>.toml.
export HF_HUB_CACHE=~/.cache/huggingface/hub # weight cache (the model files refer to this variable)
export ARENA_GPUS=0,1,2,3,4,5,6,7 # several GPUs: models are spread over them by name (not needed for one GPU)
python3 servers/launch.py start && python3 servers/launch.py wait
.venv/bin/python -m arena swiss configs/swiss.toml > runs/swiss.log 2>&1 & # results go to runs/<time>_swiss/
configs/swiss.toml: 4-player games, Wild Draw Four challenge, hand listed in a shuffled
order, must-play (a house rule: without it, weak models that keep drawing stall games forever), 1000 games per
model, a maximum lead of 40 games, at most 1000 decisions per game..venv/bin/python -m arena swiss configs/swiss.toml --resume runs/<run>.runs/<run>/hold.txt, wait until status.json no longer lists it
under busy, run servers/launch.py stop/start/wait, then remove it from hold.txt.python3 bench/pack_runs.py pack runs/<run> (the jsonl files become xz, split above 45 MB; the raw
jsonl files are not committed), then commit runs/<run>/.git pull, python3 bench/pack_runs.py unpack runs/<run>, then start the
site with .venv/bin/python -m arena site --uno-run latest --port 8200 (the UNO page uses the newest *_swiss run).python3 servers/launch.py start kev-0.8b decider-0.8b && python3 servers/launch.py wait kev-0.8b decider-0.8b
.venv/bin/python -m arena c4 kev-0.8b decider-0.8b # 7 openings x both colors = 14 games
.venv/bin/python -m arena c4 kev-0.8b heuristic --openings 49 # 98 games; players: model names, random, heuristic
.venv/bin/python -m arena c4-show runs/<dir> --game G03-ab # replay a game in the terminal
arena/connect4/.runs/<time>_c4-<a>-vs-<b>/ with games.jsonl, decisions.jsonl (options, probabilities, latency per
move) and summary.md..venv/bin/python -m arena c4-league plays every pair of running model servers, every opening with both
colors (378 pairs x 14 games = 5292 games for 28 models); standings by points (win 1, draw 0.5) with TrueSkill;
--resume runs/<run> continues a stopped league. --hint defend appends a defence hint to the instructions (an
experiment: with 4 models it changed neither the blocking rate nor the probability on the blocking column)..venv/bin/python -m arena site serves /arenas/connect4/ with every match in runs/: the
summary, the games, and each game move by move (board, the probability of each column, the columns that would
win at once or had to be blocked, and the request sent, rebuilt from the game's seed)..venv/bin/python -m arena c4-puzzles-make # data/c4-puzzles/: 1000 puzzles, verified by the engine and the solver
.venv/bin/python -m arena c4-puzzles-run # every running model server, each puzzle in 3 option orders
data/c4-puzzles/README.md.runs/<time>_c4-puzzles/<model>/results.jsonl and summary.json; the site shows them at
/arenas/c4puzzles/ with a puzzle browser. The results are committed as results.jsonl.xz
(python3 bench/pack_runs.py pack|unpack runs/<run>).| File | Purpose |
|---|---|
arena/uno/cards.py | the classic 108-card deck |
arena/uno/engine.py | rules engine (official rules; optional Wild Draw Four challenge and must-play house rule); accepts legal actions only |
arena/uno/render.py | renders the position as a plain-text state and builds the questions; rules templates A/B/C, history_rounds rounds of history |
arena/players.py | random, heuristic and System One players; asks for the card first and for the color after a wild, one request per question |
arena/systemone.py | /v1/systemone client |
arena/match.py, tournament.py | one game, fixed schedules with seat rotations, parallel execution, logging |
arena/swiss.py | Swiss tournament over all model servers, rated with TrueSkill (resume, hold, maximum lead) |
arena/stats.py, leaderboard.py | win rates with Wilson 95% intervals, points, diagnostics, the leaderboard |
arena/connect4/ | Connect Four: engine, prompts, players, two-player matches and leagues, solver, decision puzzles |
arena/replay.py, viz.py, viewer.html | replays: re-simulate a game from its seed and logged actions, and rebuild the requests sent to the models |
arena/site.py, arena/static/ | the site: home, leaderboard, JevBench results, the UNO viewer and Connect Four replays under /arenas/ |
servers/ | model servers: launcher, adapters, one file per model, environment manifests |
bench/ | model registry with measured sizes, JevBench runner, deployment reports, run packing |
probabilities, not confidence (servers define
confidence differently).runs/<time>_<name>/:
games.jsonl: one line per game, with all events and the starting hands;decisions.jsonl: one line per decision, with the option probabilities, latency, token counts and diagnostic flags;summary.md: the summary.Jev-like decision models (TypeSafe Jev, and open models that serve POST /v1/systemone) play games against each
other, so their abilities can be compared by results. The current game is 4-player UNO.
A survey of the models is in docs/jev_models.md; JevBench public-item results for 28 small
open models are in runs/jevbench-public-20260929/, and the items
themselves in data/jevbench-public/. The site's /arenas/bench/items/ page shows every item (state, question,
options, correct answer) with the answer and the probability each model gave.
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]' # the platform needs trueskill and tokenizers; tests use pytest
.venv/bin/python -m pytest # rules engine, prompt building, client, tournament
# sanity check without models: 1 heuristic player against 3 random players, 1000 games in a few seconds
.venv/bin/python -m arena run configs/sanity.toml
# 4 local 0.8B models at one table
servers/setup.sh # one venv per model (their dependencies conflict); run once
servers/start.sh # start the servers: kev 8101 · decider 8102 · jevstyle 8103 · openthai 8104
.venv/bin/python servers/check.py # send one test request to each server
.venv/bin/python -m arena run configs/local4.toml # 250 deals x 4 seat rotations = 1000 games
servers/stop.sh
# results and replays
.venv/bin/python -m arena viz runs/<dir> # http://127.0.0.1:8200
.venv/bin/python -m arena viz runs/<dir> --export view.html # one self-contained HTML file (replays of the first 3 deals)
.venv/bin/python -m arena prompt --seed 3 --step 30 # the request a model receives at some point of a game
The server environments (venvs, third-party sources, weight revisions) are described in
servers/envs/README.md; each model's start command is in servers/models/<name>.toml.
export HF_HUB_CACHE=~/.cache/huggingface/hub # weight cache (the model files refer to this variable)
export ARENA_GPUS=0,1,2,3,4,5,6,7 # several GPUs: models are spread over them by name (not needed for one GPU)
python3 servers/launch.py start && python3 servers/launch.py wait
.venv/bin/python -m arena swiss configs/swiss.toml > runs/swiss.log 2>&1 & # results go to runs/<time>_swiss/
configs/swiss.toml: 4-player games, Wild Draw Four challenge, hand listed in a shuffled
order, must-play (a house rule: without it, weak models that keep drawing stall games forever), 1000 games per
model, a maximum lead of 40 games, at most 1000 decisions per game..venv/bin/python -m arena swiss configs/swiss.toml --resume runs/<run>.runs/<run>/hold.txt, wait until status.json no longer lists it
under busy, run servers/launch.py stop/start/wait, then remove it from hold.txt.python3 bench/pack_runs.py pack runs/<run> (the jsonl files become xz, split above 45 MB; the raw
jsonl files are not committed), then commit runs/<run>/.git pull, python3 bench/pack_runs.py unpack runs/<run>, then start the
site with .venv/bin/python -m arena site --uno-run latest --port 8200 (the UNO page uses the newest *_swiss run).python3 servers/launch.py start kev-0.8b decider-0.8b && python3 servers/launch.py wait kev-0.8b decider-0.8b
.venv/bin/python -m arena c4 kev-0.8b decider-0.8b # 7 openings x both colors = 14 games
.venv/bin/python -m arena c4 kev-0.8b heuristic --openings 49 # 98 games; players: model names, random, heuristic
.venv/bin/python -m arena c4-show runs/<dir> --game G03-ab # replay a game in the terminal
arena/connect4/.runs/<time>_c4-<a>-vs-<b>/ with games.jsonl, decisions.jsonl (options, probabilities, latency per
move) and summary.md..venv/bin/python -m arena c4-league plays every pair of running model servers, every opening with both
colors (378 pairs x 14 games = 5292 games for 28 models); standings by points (win 1, draw 0.5) with TrueSkill;
--resume runs/<run> continues a stopped league. --hint defend appends a defence hint to the instructions (an
experiment: with 4 models it changed neither the blocking rate nor the probability on the blocking column)..venv/bin/python -m arena site serves /arenas/connect4/ with every match in runs/: the
summary, the games, and each game move by move (board, the probability of each column, the columns that would
win at once or had to be blocked, and the request sent, rebuilt from the game's seed)..venv/bin/python -m arena c4-puzzles-make # data/c4-puzzles/: 1000 puzzles, verified by the engine and the solver
.venv/bin/python -m arena c4-puzzles-run # every running model server, each puzzle in 3 option orders
data/c4-puzzles/README.md.runs/<time>_c4-puzzles/<model>/results.jsonl and summary.json; the site shows them at
/arenas/c4puzzles/ with a puzzle browser. The results are committed as results.jsonl.xz
(python3 bench/pack_runs.py pack|unpack runs/<run>).| File | Purpose |
|---|---|
arena/uno/cards.py | the classic 108-card deck |
arena/uno/engine.py | rules engine (official rules; optional Wild Draw Four challenge and must-play house rule); accepts legal actions only |
arena/uno/render.py | renders the position as a plain-text state and builds the questions; rules templates A/B/C, history_rounds rounds of history |
arena/players.py | random, heuristic and System One players; asks for the card first and for the color after a wild, one request per question |
arena/systemone.py | /v1/systemone client |
arena/match.py, tournament.py | one game, fixed schedules with seat rotations, parallel execution, logging |
arena/swiss.py | Swiss tournament over all model servers, rated with TrueSkill (resume, hold, maximum lead) |
arena/stats.py, leaderboard.py | win rates with Wilson 95% intervals, points, diagnostics, the leaderboard |
arena/connect4/ | Connect Four: engine, prompts, players, two-player matches and leagues, solver, decision puzzles |
arena/replay.py, viz.py, viewer.html | replays: re-simulate a game from its seed and logged actions, and rebuild the requests sent to the models |
arena/site.py, arena/static/ | the site: home, leaderboard, JevBench results, the UNO viewer and Connect Four replays under /arenas/ |
servers/ | model servers: launcher, adapters, one file per model, environment manifests |
bench/ | model registry with measured sizes, JevBench runner, deployment reports, run packing |
probabilities, not confidence (servers define
confidence differently).runs/<time>_<name>/:
games.jsonl: one line per game, with all events and the starting hands;decisions.jsonl: one line per decision, with the option probabilities, latency, token counts and diagnostic flags;summary.md: the summary.