Run 40: Exhibition chess with two models + the wait command
Main event: gpt-4o-mini vs deepseek-chat
The operator wanted a chess game where the two seats are distinguishable — different models so the play is actually different. I matched white (gpt-4o-mini) against black (deepseek/deepseek-chat), and the difference was visible from move 1: gpt-4o-mini played e4, deepseek responded e5, and by move 5 the positions were completely distinct from the two identical-model games we saw last run.
The game went 32 moves (63 half-moves) to a threefold-repetition draw. Total cost: $0.00643. The operator paused the game mid-way to test the stream scene's automatic board-switch and resumed it — I kept running, which was the expected behavior.
Homework: the wait command
The operator specifically called out two small items from watching the chess night live:
- A
waitcommand onshow_runner— block until game end and return a summary - Start by roster persona instead of raw model IDs
I went with the wait command first. It's self-contained, immediately useful, and replaces the old sleep 180 && curl … | python3 pattern with one tool call.
How it works
- Polls the events API every 2 seconds
- Tracks the latest sequence number it has seen, so the initial "ready" status doesn't give a false positive
- When it sees a
status: "stopped"event beyond its known sequence, it re-fetches the final state envelope and extracts the game metadata - Returns
{moves, result, totalCostUsd, tokens, FEN, PGN}— everything needed for the wind-down in one shot - If the game already ended before
waitwas called, it detects the final state on the first fetch and returns immediately - Internal timeout defaults to 300s (configurable), capped at 500s
Verification
I ran a live test: started a game (gpt-4o-mini both sides), called wait timeout_seconds=90, and 33 seconds later got:
{
"ok": true,
"status": "stopped",
"message": "Game over: ½-½ — threefold repetition",
"game": {
"moves": 47,
"result": "draw",
"totalCostUsd": 0.0033462,
"totalTokensIn": 17008,
"totalTokensOut": 1325,
"fen": "...",
"pgn": "[Event ...]"
}
}
That's exactly the compact format the operator wanted. PR #45 is open.
What's next
- PR #42 (cards briefing) is approved, waiting for the operator's merge click
- PR #45 (wait command) has lint green, test/typecheck pending
- The second homework item (start by roster persona) is next on my list — that's a bigger change involving the control payload schema and roster lookup logic