AI models play cooperative Codenames against the deck, in two modes:
- classic (primary): ONE key. Model A is the spymaster (sees the key, gives clues); model B guesses blind with up to N+1 guesses per clue. 9 agents, 3 assassins, 9 clues max. Every ordered (giver, guesser) pairing is a cell in the standings matrix — including a model cluing for itself.
- duet: faithful Codenames Duet — two overlapping keys, 15 shared agents, guesses judged on the giver's key, both partners clue.
Every clue, guess, prompted "thinking", native reasoning trace, and per-call cost is recorded.
Live UI: main.ts endpoint (standings → tap a team → tap a game → full replay
with collapsed chain-of-thought). Wears the house style (quatro direction),
importing pen.tsx/directions.ts from
dcm31/house-style.
- 25 words from the official 400-word list; official Duet key card overlap (9 green / 3 assassin / 13 neutral per side; 3 shared greens; 15 unique agents; 1 double assassin; 1 green-for-you-assassin-for-them each way).
- 9 total clue turns shared by the team. Givers alternate, except a giver with no remaining greens hands the pen over (Duet allows clues in any order).
- Guesses judged against the giver's key. Green → keep guessing (or stop); neutral → turn ends, word marked against that key; assassin → instant loss.
- Simplifications: no sudden-death phase; 8-guess safety cap per turn; a model that can't produce a valid clue/guess in 2 attempts forfeits that action.
Guess Efficiency Score (GES), 0-100%: raw = successful guesses (0-9), plus a win bonus of (10 - clues used); GES = raw / 18. Wins always outrank losses (win floor 56% vs loss ceiling 44%); the perfect game — all 9 words on the first clue — is 100%. Leaderboard shows each model's average GES combined and split by role. Per-game data also keeps win/loss, words found, clues used, full transcript, and OpenRouter usage cost.
Rendering mermaid diagram...
- Edit
runner/config.ts: pickSEED_MODE("classic" or "duet"),SEED_KEYS(model keys),SEED_TIER(a fresh tier name — seeding is guarded per tier),GAMES_PER_PAIRING. Classic seeds ORDERED pairs (model_a gives, model_b guesses); duet seeds unordered pairs. - Run
runner/seed.ts. The cron drains the queue automatically (~1 game/2–4 min, 3 concurrent).runner/run-next.tsadvances it manually. - When done benchmarking, pause the worker: set
runner/cron.tsback to a long interval or change its file type toscript(it's a cheap no-op when idle, but still).
runner/validate-models.ts checks ids + pricing; runner/check-credits.ts
shows key limits/balance; runner/test-engine.ts is the offline engine test.
- free —
:freeOpenRouter models ($0): Nemotron 550B/120B/30B + GPT-OSS 20B. - cheap / premium — configured (Haiku 4.5, GPT-5 mini, Gemini 2.5 Flash, DeepSeek V3.1 / Sonnet 4.5, GPT-5.1) but need OpenRouter credits topped up.
Env: OPENROUTER_API_KEY.
Word list note: the 400 base words as shipped by open-source Codenames clones — lists of individual common words aren't subject to copyright; used here for a personal benchmark.