From 8891f36458c3d41718ac0826de3291b927800e52 Mon Sep 17 00:00:00 2001 From: John Yang Date: Mon, 6 Jul 2026 19:34:18 +0000 Subject: [PATCH 01/19] Add lock for image construction --- codeclash/arenas/arena.py | 63 ++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/codeclash/arenas/arena.py b/codeclash/arenas/arena.py index 5076a9f9..174cee17 100644 --- a/codeclash/arenas/arena.py +++ b/codeclash/arenas/arena.py @@ -2,6 +2,7 @@ import os import random import subprocess +import threading import time from abc import ABC, abstractmethod from pathlib import Path @@ -75,6 +76,10 @@ class CodeArena(ABC): default_args: dict = {} submission: str + # Serializes image builds across concurrent pairs (e.g. `ladder make --workers N`), so + # worker threads don't all race `docker build` on a cold start and fail with "already exists". + _build_lock = threading.Lock() + def __init__(self, config: dict, *, tournament_id: str, local_output_dir: Path, keep_containers: bool = False): """The CodeArena class is responsible for running games, i.e., taking a list of code from different agents/players and running them against each other. @@ -127,36 +132,38 @@ def build_image(self): if is_running_in_aws_batch(): pull_game_container_aws_ecr(game_name=self.name, image_name=self.image_name, logger=self.logger) - # Check if container exists using subprocess - self.logger.debug(f"Checking if container {self.image_name} exists") - result = subprocess.run( - f"docker images -q {self.image_name}", - shell=True, - capture_output=True, - text=True, - ) - if result.stdout.strip(): - self.logger.debug(f"Container {self.image_name} exists") - return + # Hold the lock across check-and-build so concurrent pairs don't race: the first thread + # builds while the rest wait, then find the image already present and skip. + with CodeArena._build_lock: + self.logger.debug(f"Checking if container {self.image_name} exists") + result = subprocess.run( + f"docker images -q {self.image_name}", + shell=True, + capture_output=True, + text=True, + ) + if result.stdout.strip(): + self.logger.debug(f"Container {self.image_name} exists") + return - self.logger.info( - f"Building Docker image {self.image_name}. This may take 1-5 minutes and only work on Linux for some games." - ) + self.logger.info( + f"Building Docker image {self.image_name}. This may take 1-5 minutes and only work on Linux for some games." + ) - # NOTE: Assuming Dockerfile is declared in same directory as the arena. - arena_file = Path(inspect.getfile(self.__class__)) - folder_path = arena_file.parent - result = subprocess.run( - f"docker build --no-cache -t {self.image_name} -f {folder_path}/{self.name}.Dockerfile .", - shell=True, - capture_output=True, - text=True, - ) - if result.returncode == 0: - self.logger.info(f"✅ Built Docker image {self.image_name}") - else: - self.logger.error(f"❌ Failed to build Docker image: {result.stderr}\n{result.stdout}{result.stderr}") - raise RuntimeError(f"Failed to build Docker image: {result.stderr}") + # NOTE: Assuming Dockerfile is declared in same directory as the arena. + arena_file = Path(inspect.getfile(self.__class__)) + folder_path = arena_file.parent + result = subprocess.run( + f"docker build --no-cache -t {self.image_name} -f {folder_path}/{self.name}.Dockerfile .", + shell=True, + capture_output=True, + text=True, + ) + if result.returncode == 0: + self.logger.info(f"✅ Built Docker image {self.image_name}") + else: + self.logger.error(f"❌ Failed to build Docker image: {result.stderr}\n{result.stdout}{result.stderr}") + raise RuntimeError(f"Failed to build Docker image: {result.stderr}") def copy_logs_from_env(self, round_num: int) -> None: """Copy logs from the game's environment to the local machine.""" From 9906f6a2b06178059b8086e7c8471e012b915385 Mon Sep 17 00:00:00 2001 From: John Yang Date: Mon, 6 Jul 2026 23:50:13 +0000 Subject: [PATCH 02/19] Update win conditions --- codeclash/cli/ladder.py | 115 ++++++++++++------ configs/ablations/ladder/README.md | 12 +- configs/ablations/ladder/battlesnake.yaml | 4 +- .../ladder/battlesnake__gemini_3_5_flash.yaml | 4 +- .../ladder/battlesnake__gpt_5_5.yaml | 4 +- .../ladder/battlesnake__opus_4_7.yaml | 4 +- .../ladder/battlesnake__opus_4_8.yaml | 4 +- .../ladder/battlesnake__sonnet_5.yaml | 4 +- .../ladder/battlesnake_llama_smoke.yaml | 4 +- configs/ablations/ladder/corewar.yaml | 4 +- .../ladder/corewar__gemini_3_5_flash.yaml | 4 +- .../ablations/ladder/corewar__gpt_5_5.yaml | 4 +- .../ablations/ladder/corewar__opus_4_7.yaml | 4 +- .../ablations/ladder/corewar__opus_4_8.yaml | 4 +- .../ablations/ladder/corewar__sonnet_5.yaml | 4 +- configs/ablations/ladder/robotrumble.yaml | 4 +- .../ladder/robotrumble__gemini_3_5_flash.yaml | 4 +- .../ladder/robotrumble__gpt_5_5.yaml | 4 +- .../ladder/robotrumble__opus_4_7.yaml | 4 +- .../ladder/robotrumble__opus_4_8.yaml | 4 +- .../ladder/robotrumble__sonnet_5.yaml | 4 +- 21 files changed, 126 insertions(+), 77 deletions(-) diff --git a/codeclash/cli/ladder.py b/codeclash/cli/ladder.py index 040505ea..7fd2c129 100644 --- a/codeclash/cli/ladder.py +++ b/codeclash/cli/ladder.py @@ -2,6 +2,7 @@ import copy import getpass +import json import time from concurrent.futures import ThreadPoolExecutor, as_completed from pathlib import Path @@ -18,43 +19,55 @@ logger = get_logger("ladder") -def _resolve_ladder_rules(ladder_rules: dict, rounds: int) -> tuple[float, int]: - """Validate the optional ``ladder_rules`` block and return ``(min_round_win_fraction, win_last_k)``. +def _resolve_ladder_rules(ladder_rules: dict, rounds: int) -> tuple[int, int]: + """Validate the required ``ladder_rules`` block and return ``(min_round_wins, win_last_k)``. - Defaults: win at least ``min_round_win_fraction`` (0.4) of the *agent* rounds AND win the last - ``win_last_k`` (1) round(s). The baseline round 0 (identical, un-edited codebases) is excluded - from this count — it reflects game variance, not the agent — so the fraction is taken over the - ``rounds`` rounds the agent actually edits. + Both keys must be specified explicitly in the config (no defaults): + - ``min_round_wins``: the whole number of *agent* rounds the player must win to advance + (a ``>=`` threshold). Must be ``1 <= min_round_wins <= rounds``. + - ``win_last_k``: the player must win the last ``win_last_k`` round(s). ``1`` means just the final + round; ``0`` disables the trailing-rounds requirement entirely. Must be ``<= min_round_wins``. + + The baseline round 0 (identical, un-edited codebases) is excluded from the count — it reflects + game variance, not the agent — so wins are counted over the ``rounds`` rounds the agent actually + edits (rounds 1..``rounds``). """ - min_round_win_fraction = ladder_rules.get("min_round_win_fraction", 0.4) - win_last_k = ladder_rules.get("win_last_k", 1) + if "min_round_wins" not in ladder_rules: + typer.echo("ladder_rules.min_round_wins is required; specify it explicitly in the config.") + raise typer.Exit(1) + if "win_last_k" not in ladder_rules: + typer.echo("ladder_rules.win_last_k is required; specify it explicitly in the config.") + raise typer.Exit(1) + min_round_wins = ladder_rules["min_round_wins"] + win_last_k = ladder_rules["win_last_k"] - # win_last_k: number of trailing rounds the player must win (1 == just the final round). - if isinstance(win_last_k, bool) or not isinstance(win_last_k, int): - typer.echo(f"ladder_rules.win_last_k must be an integer, got {win_last_k!r}.") + # min_round_wins: whole number of agent rounds the player must win (round 0 excluded). + if isinstance(min_round_wins, bool) or not isinstance(min_round_wins, int): + typer.echo(f"ladder_rules.min_round_wins must be an integer, got {min_round_wins!r}.") raise typer.Exit(1) - if win_last_k < 1: + if not 1 <= min_round_wins <= rounds: typer.echo( - f"ladder_rules.win_last_k must be >= 1, got {win_last_k}. Use 1 to require winning only the final round." + f"ladder_rules.min_round_wins must be in [1, {rounds}] (tournament.rounds), got {min_round_wins}." ) raise typer.Exit(1) - if win_last_k > rounds: - typer.echo(f"ladder_rules.win_last_k ({win_last_k}) cannot exceed tournament.rounds ({rounds}).") - raise typer.Exit(1) - # min_round_win_fraction: player must win >= this fraction of the agent rounds (round 0 excluded). - if isinstance(min_round_win_fraction, bool) or not isinstance(min_round_win_fraction, (int, float)): - typer.echo(f"ladder_rules.min_round_win_fraction must be a number, got {min_round_win_fraction!r}.") + # win_last_k: number of trailing rounds the player must win (1 == just the final round, 0 == disabled). + if isinstance(win_last_k, bool) or not isinstance(win_last_k, int): + typer.echo(f"ladder_rules.win_last_k must be an integer, got {win_last_k!r}.") + raise typer.Exit(1) + if win_last_k < 0: + typer.echo( + f"ladder_rules.win_last_k must be >= 0, got {win_last_k}. " + "Use 0 to disable the trailing-rounds requirement, or 1 to require winning only the final round." + ) raise typer.Exit(1) - if not 0 <= min_round_win_fraction <= 1: + if win_last_k > min_round_wins: typer.echo( - f"ladder_rules.min_round_win_fraction must be in [0, 1], got {min_round_win_fraction}. " - "The player must win >= this fraction of the agent rounds; 1 requires winning all of them, " - "0 drops the fraction requirement." + f"ladder_rules.win_last_k ({win_last_k}) cannot exceed ladder_rules.min_round_wins ({min_round_wins})." ) raise typer.Exit(1) - return float(min_round_win_fraction), win_last_k + return min_round_wins, win_last_k ladder_app = typer.Typer( @@ -141,20 +154,24 @@ def run( config["tournament"]["rounds"], config["game"]["sims_per_round"], ) - min_round_win_fraction, win_last_k = _resolve_ladder_rules(config.get("ladder_rules", {}), rounds) + min_round_wins, win_last_k = _resolve_ladder_rules(config.get("ladder_rules", {}), rounds) timestamp = time.strftime("%y%m%d%H%M%S") del config["player"] del config["ladder"] config.pop("ladder_rules", None) - print( - f"Ladder advancement rule: win >= {min_round_win_fraction:.0%} of {rounds} agent rounds " - f"(baseline round 0 excluded) and win the last {win_last_k} round(s)." + last_k_rule = "disabled" if win_last_k == 0 else f"win the last {win_last_k} round(s)" + advancement_rule = ( + f"Ladder advancement rule: win >= {min_round_wins} of {rounds} agent rounds " + f"(baseline round 0 excluded) and {last_k_rule}." ) + logger.info(advancement_rule) ladder_folder = f"LadderTournament.{config['game']['name']}.r{rounds}.s{sims}.{player['name']}.{timestamp}" player["branch"] = ladder_folder parent_dir = LOCAL_LOG_DIR / getpass.getuser() / ladder_folder + rungs_cleared = 0 + advanced = False for idx, opponent in enumerate(ladder): opponent_rank = len(ladder) - idx opponent["name"] = opponent["branch_init"].replace("human/", "").replace("/", "_") @@ -190,24 +207,37 @@ def run( metadata = yaml.safe_load(f) round_winners = [r["winner"] for k, r in metadata["round_stats"].items() if int(k) != 0] - # Advancement rule (configurable via `ladder_rules`): win at least - # `min_round_win_fraction` of the agent rounds AND win the last `win_last_k` rounds. + # Advancement rule (required via `ladder_rules`): win at least `min_round_wins` of the + # agent rounds AND win the last `win_last_k` rounds. win_last_k == 0 disables the + # trailing-rounds requirement. player_wins = sum(1 for w in round_winners if w == player["name"]) - won_majority = player_wins >= len(round_winners) * min_round_win_fraction - won_last_k = all(w == player["name"] for w in round_winners[-win_last_k:]) + won_majority = player_wins >= min_round_wins + won_last_k = win_last_k == 0 or all(w == player["name"] for w in round_winners[-win_last_k:]) + advanced = won_majority and won_last_k - if not won_majority or not won_last_k: + # Record this rung's outcome in its metadata.json (durable gameplay log). The rule itself + # (min_round_wins, win_last_k) is constant across the run and lives in the ladder summary. + metadata["ladder_advancement"] = { + "player_wins": player_wins, + "won_last_k": won_last_k, + "cleared": advanced, + } + with open(metadata_path, "w") as f: + json.dump(metadata, f, indent=2) + + if not advanced: # Player failed the advancement rule; the ladder challenge ends here. print("=" * 10) print( f"{player['name']} did not clear {opponent['name']} " f"(rank {opponent_rank}/{len(ladder)}): won {player_wins}/{len(round_winners)} agent rounds " - f"(needed >= {min_round_win_fraction:.0%}), last {win_last_k} round(s) won: {won_last_k}.\n" + f"(needed >= {min_round_wins}), last {win_last_k} round(s) won: {won_last_k}.\n" "Ladder challenge ends." ) print("=" * 10) break + rungs_cleared += 1 print("=" * 10) print( f"{player['name']} successfully beat {opponent['name']} (rank {opponent_rank}/{len(ladder)}) " @@ -216,5 +246,22 @@ def run( ) print("=" * 10) + # Persist the overall climb result to a ladder-level metadata.json in the run's parent dir. + ladder_summary = { + "player": player["name"], + "game": config["game"]["name"], + "rounds": rounds, + "min_round_wins": min_round_wins, + "win_last_k": win_last_k, + "ladder_size": len(ladder), + "rungs_cleared": rungs_cleared, + "final_opponent": opponent["name"], + "final_opponent_rank": opponent_rank, + "cleared_ladder": rungs_cleared == len(ladder), + } + parent_dir.mkdir(parents=True, exist_ok=True) + with open(parent_dir / "metadata.json", "w") as f: + json.dump(ladder_summary, f, indent=2) + print(f"Ladder tournament complete. Logs saved to {parent_dir}") print(f"Final opponent faced: {opponent['name']} (rank {opponent_rank}/{len(ladder)} in ladder)") diff --git a/configs/ablations/ladder/README.md b/configs/ablations/ladder/README.md index 99d5e6c4..8745d1f2 100644 --- a/configs/ablations/ladder/README.md +++ b/configs/ablations/ladder/README.md @@ -27,11 +27,13 @@ Each run config carries a `ladder_rules` block controlling what it takes to clea ```yaml ladder_rules: - min_round_win_fraction: 0.5 # must win strictly more than this fraction of rounds - win_last_k: 1 # ...and must win the last K rounds (1 == just the final round) + min_round_wins: 2 # must win >= this many of the agent rounds to advance (round 0 excluded) + win_last_k: 0 # ...and must win the last K rounds (1 == just the final round, 0 == disabled) ``` -The defaults shown above reproduce the historical behavior (strict majority of rounds **and** win the final round); the block is optional and falls back to these values if omitted. Validation: +Both keys are **required** — there are no defaults; a config that omits either one errors out. `min_round_wins` is a whole number: the player advances when `player_wins >= min_round_wins`. The baseline round 0 (identical, un-edited codebases) is excluded, so with `tournament.rounds: 5` there are 5 scored agent rounds (rounds 1–5). Validation: -- `win_last_k` must be an integer with `1 <= win_last_k <= tournament.rounds`. -- `min_round_win_fraction` must be a number in `[0, 1)`; `0` drops the majority requirement (e.g. `min_round_win_fraction: 0` + `win_last_k: 1` means "just win the final round"). +- `min_round_wins` must be an integer with `1 <= min_round_wins <= tournament.rounds`. +- `win_last_k` must be an integer with `0 <= win_last_k <= min_round_wins`. `0` **disables** the trailing-rounds requirement; `1` means "just win the final round". + +The per-rung outcome (`player_wins`, `won_last_k`, `cleared`) is persisted under `ladder_advancement` in each rung's `metadata.json`. The overall climb result (`rungs_cleared`, `final_opponent`, `cleared_ladder`, …) is written to a ladder-level `metadata.json` in the run's parent dir. diff --git a/configs/ablations/ladder/battlesnake.yaml b/configs/ablations/ladder/battlesnake.yaml index 689a5d68..d47d23af 100644 --- a/configs/ablations/ladder/battlesnake.yaml +++ b/configs/ablations/ladder/battlesnake.yaml @@ -5,8 +5,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml b/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml index f5f2eca2..bfde759f 100644 --- a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml b/configs/ablations/ladder/battlesnake__gpt_5_5.yaml index 44c02b13..93cc2193 100644 --- a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml +++ b/configs/ablations/ladder/battlesnake__gpt_5_5.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__opus_4_7.yaml b/configs/ablations/ladder/battlesnake__opus_4_7.yaml index 7bca867e..9c6f53a2 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_7.yaml +++ b/configs/ablations/ladder/battlesnake__opus_4_7.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__opus_4_8.yaml b/configs/ablations/ladder/battlesnake__opus_4_8.yaml index 9c4e8d76..52e7a4cc 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_8.yaml +++ b/configs/ablations/ladder/battlesnake__opus_4_8.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__sonnet_5.yaml b/configs/ablations/ladder/battlesnake__sonnet_5.yaml index 63c50e89..706e5206 100644 --- a/configs/ablations/ladder/battlesnake__sonnet_5.yaml +++ b/configs/ablations/ladder/battlesnake__sonnet_5.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake_llama_smoke.yaml b/configs/ablations/ladder/battlesnake_llama_smoke.yaml index b206b0e8..7237a764 100644 --- a/configs/ablations/ladder/battlesnake_llama_smoke.yaml +++ b/configs/ablations/ladder/battlesnake_llama_smoke.yaml @@ -6,8 +6,8 @@ tournament: rounds: 2 ladder_rules: - min_round_win_fraction: 0.5 # win >= half the agent rounds (round 0 excluded) - win_last_k: 1 # ...and win the last K rounds (K=1 == the final round) + min_round_wins: 1 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: BattleSnake sims_per_round: 10 diff --git a/configs/ablations/ladder/corewar.yaml b/configs/ablations/ladder/corewar.yaml index 864e50aa..7d601e02 100644 --- a/configs/ablations/ladder/corewar.yaml +++ b/configs/ablations/ladder/corewar.yaml @@ -1,8 +1,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml b/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml index ef5f1220..4a31bff2 100644 --- a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__gpt_5_5.yaml b/configs/ablations/ladder/corewar__gpt_5_5.yaml index ee3c5186..2a0fe41c 100644 --- a/configs/ablations/ladder/corewar__gpt_5_5.yaml +++ b/configs/ablations/ladder/corewar__gpt_5_5.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__opus_4_7.yaml b/configs/ablations/ladder/corewar__opus_4_7.yaml index a3991526..8ff22594 100644 --- a/configs/ablations/ladder/corewar__opus_4_7.yaml +++ b/configs/ablations/ladder/corewar__opus_4_7.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__opus_4_8.yaml b/configs/ablations/ladder/corewar__opus_4_8.yaml index dc0ef353..135973a9 100644 --- a/configs/ablations/ladder/corewar__opus_4_8.yaml +++ b/configs/ablations/ladder/corewar__opus_4_8.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__sonnet_5.yaml b/configs/ablations/ladder/corewar__sonnet_5.yaml index a429c6b5..0344dd40 100644 --- a/configs/ablations/ladder/corewar__sonnet_5.yaml +++ b/configs/ablations/ladder/corewar__sonnet_5.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/robotrumble.yaml b/configs/ablations/ladder/robotrumble.yaml index 52298a69..2163107e 100644 --- a/configs/ablations/ladder/robotrumble.yaml +++ b/configs/ablations/ladder/robotrumble.yaml @@ -1,8 +1,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml b/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml index 673edb08..f3346cfc 100644 --- a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml b/configs/ablations/ladder/robotrumble__gpt_5_5.yaml index cb0e0eb5..ef4ef8b9 100644 --- a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml +++ b/configs/ablations/ladder/robotrumble__gpt_5_5.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__opus_4_7.yaml b/configs/ablations/ladder/robotrumble__opus_4_7.yaml index 54e73ba6..518c8022 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_7.yaml +++ b/configs/ablations/ladder/robotrumble__opus_4_7.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__opus_4_8.yaml b/configs/ablations/ladder/robotrumble__opus_4_8.yaml index 83a49437..4d26ba7f 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_8.yaml +++ b/configs/ablations/ladder/robotrumble__opus_4_8.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__sonnet_5.yaml b/configs/ablations/ladder/robotrumble__sonnet_5.yaml index 79cf31e0..5632555d 100644 --- a/configs/ablations/ladder/robotrumble__sonnet_5.yaml +++ b/configs/ablations/ladder/robotrumble__sonnet_5.yaml @@ -3,8 +3,8 @@ tournament: rounds: 5 ladder_rules: - min_round_win_fraction: 0.5 # advance only on a strict majority of rounds - win_last_k: 1 # ...and win the last K rounds (K=1 == just the final round) + min_round_wins: 2 # rounds to win to advance (1..total rounds) + win_last_k: 0 # must win last K (0 = off, <= min_round_wins) game: name: RobotRumble sims_per_round: 250 From 16d9ef327e14940d4e5a8054ec9035ae1e170ba4 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:29:49 +0000 Subject: [PATCH 03/19] Surface per-step budget in agent observations Add a global observation_template in configs/mini/default.yaml with a [Step n/limit used - k left] banner, and thread it onto the model via a ClashAgentConfig field pushed in ClashAgent.__init__. Applies to every model backend, tournament type, and arena; models otherwise learn the step limit only once at round start with no running counter. Co-Authored-By: Claude Opus 4.8 (1M context) --- codeclash/agents/minisweagent.py | 16 +++++++++++++++- configs/mini/default.yaml | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/codeclash/agents/minisweagent.py b/codeclash/agents/minisweagent.py index 965e3459..d37fa38f 100644 --- a/codeclash/agents/minisweagent.py +++ b/codeclash/agents/minisweagent.py @@ -18,6 +18,16 @@ ) +class ClashAgentConfig(AgentConfig): + """`AgentConfig` plus an optional global observation-format override. + + `observation_template` is a model-side field in mini-swe-agent, so putting it in the shared + agent config (`configs/mini/default.yaml`) doesn't reach the model on its own. Declaring it + here lets the one global config drive it; `ClashAgent` pushes it onto the model at init.""" + + observation_template: str | None = None + + class ClashAgent(DefaultAgent): """`DefaultAgent` from mini-SWE-agent (https://github.com/SWE-agent/mini-swe-agent) with per-player debug logging.""" @@ -28,11 +38,15 @@ def __init__( env: DockerEnvironment, *, logger: logging.Logger, - config_class: Callable = AgentConfig, + config_class: Callable = ClashAgentConfig, **kwargs, ): super().__init__(model, env, config_class=config_class, **kwargs) self.logger = logger + # Honor the global observation_template (agent config) by pushing it onto the model, + # which is what actually renders observations. Applies to every backend uniformly. + if getattr(self.config, "observation_template", None): + self.model.config.observation_template = self.config.observation_template def add_messages(self, *messages: dict) -> list[dict]: result = super().add_messages(*messages) diff --git a/configs/mini/default.yaml b/configs/mini/default.yaml index 5cb1fe19..604057ff 100644 --- a/configs/mini/default.yaml +++ b/configs/mini/default.yaml @@ -102,3 +102,7 @@ instance_template: | You cannot continue working in any way on this task after submitting. step_limit: 30 cost_limit: 0 +# Global observation format for every model/tournament/arena. ClashAgent pushes this onto the +# model config (mini-swe-agent renders observations model-side). The leading banner surfaces the +# per-round step budget so the model can pace itself; the rest is mini's default observation body. +observation_template: "[Step {{n_model_calls}}/{{step_limit}} used - {{step_limit - n_model_calls}} left]\n{% if output.exception_info %}{{output.exception_info}}\n{% endif %}{{output.returncode}}\n\n{{output.output}}" From b5fa030765b536efa340200d05c85a22cd774db8 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:29:49 +0000 Subject: [PATCH 04/19] Reject BattleSnake submissions missing a server entrypoint validate_code was a pure function-def check, so a main.py that drops the 'if __name__ == "__main__": run_server(...)' block passed validation but failed to start at runtime (forfeit). Require the entrypoint statically. Co-Authored-By: Claude Opus 4.8 (1M context) --- codeclash/arenas/battlesnake/battlesnake.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/codeclash/arenas/battlesnake/battlesnake.py b/codeclash/arenas/battlesnake/battlesnake.py index 36639ec6..3e1b75a1 100644 --- a/codeclash/arenas/battlesnake/battlesnake.py +++ b/codeclash/arenas/battlesnake/battlesnake.py @@ -203,4 +203,11 @@ def validate_code(self, agent: Player) -> tuple[bool, str | None]: error_msg.append(f"There should be a `{func}` function implemented in `{self.submission}`") if len(error_msg) > 0: return False, "\n".join(error_msg + ["Don't change the function signatures!"]) + + # `python main.py` boots the server via the __main__ entrypoint. + if "__main__" not in bot_content or "run_server" not in bot_content: + return False, ( + f"`{self.submission}` must keep its server entrypoint so the bot starts: the " + '`if __name__ == "__main__": run_server(...)` block at the bottom of the file.' + ) return True, None From 8852260a9e7e965a14d219f4027d97160b4ae1f6 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:29:49 +0000 Subject: [PATCH 05/19] Centralize ladder win condition in shared ladder_rules.yaml Every ladder run config duplicated the same ladder_rules block. Extract it to configs/ablations/ladder/ladder_rules.yaml (min_round_wins: 2, win_last_k: 0) and include it from all run configs so the win condition lives in one place. Co-Authored-By: Claude Opus 4.8 (1M context) --- configs/ablations/ladder/battlesnake.yaml | 4 +--- .../ablations/ladder/battlesnake__gemini_3_5_flash.yaml | 4 +--- configs/ablations/ladder/battlesnake__gpt_5_5.yaml | 4 +--- configs/ablations/ladder/battlesnake__opus_4_7.yaml | 4 +--- configs/ablations/ladder/battlesnake__opus_4_8.yaml | 4 +--- configs/ablations/ladder/battlesnake__sonnet_5.yaml | 4 +--- configs/ablations/ladder/battlesnake_llama_smoke.yaml | 4 +--- configs/ablations/ladder/corewar.yaml | 4 +--- configs/ablations/ladder/corewar__gemini_3_5_flash.yaml | 4 +--- configs/ablations/ladder/corewar__gpt_5_5.yaml | 4 +--- configs/ablations/ladder/corewar__opus_4_7.yaml | 4 +--- configs/ablations/ladder/corewar__opus_4_8.yaml | 4 +--- configs/ablations/ladder/corewar__sonnet_5.yaml | 4 +--- configs/ablations/ladder/ladder_rules.yaml | 8 ++++++++ configs/ablations/ladder/robotrumble.yaml | 4 +--- .../ablations/ladder/robotrumble__gemini_3_5_flash.yaml | 4 +--- configs/ablations/ladder/robotrumble__gpt_5_5.yaml | 4 +--- configs/ablations/ladder/robotrumble__opus_4_7.yaml | 4 +--- configs/ablations/ladder/robotrumble__opus_4_8.yaml | 4 +--- configs/ablations/ladder/robotrumble__sonnet_5.yaml | 4 +--- 20 files changed, 27 insertions(+), 57 deletions(-) create mode 100644 configs/ablations/ladder/ladder_rules.yaml diff --git a/configs/ablations/ladder/battlesnake.yaml b/configs/ablations/ladder/battlesnake.yaml index d47d23af..a5886a1c 100644 --- a/configs/ablations/ladder/battlesnake.yaml +++ b/configs/ablations/ladder/battlesnake.yaml @@ -4,9 +4,7 @@ # rung until it loses. Run: uv run codeclash ladder run configs/ablations/ladder/battlesnake.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml b/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml index bfde759f..ede4311f 100644 --- a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml b/configs/ablations/ladder/battlesnake__gpt_5_5.yaml index 93cc2193..d31e0240 100644 --- a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml +++ b/configs/ablations/ladder/battlesnake__gpt_5_5.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/battlesnake__gpt_5_5.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__opus_4_7.yaml b/configs/ablations/ladder/battlesnake__opus_4_7.yaml index 9c6f53a2..61d2cc48 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_7.yaml +++ b/configs/ablations/ladder/battlesnake__opus_4_7.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/battlesnake__opus_4_7.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__opus_4_8.yaml b/configs/ablations/ladder/battlesnake__opus_4_8.yaml index 52e7a4cc..515440a1 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_8.yaml +++ b/configs/ablations/ladder/battlesnake__opus_4_8.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/battlesnake__opus_4_8.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake__sonnet_5.yaml b/configs/ablations/ladder/battlesnake__sonnet_5.yaml index 706e5206..d36a9682 100644 --- a/configs/ablations/ladder/battlesnake__sonnet_5.yaml +++ b/configs/ablations/ladder/battlesnake__sonnet_5.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/battlesnake__sonnet_5.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 diff --git a/configs/ablations/ladder/battlesnake_llama_smoke.yaml b/configs/ablations/ladder/battlesnake_llama_smoke.yaml index 7237a764..3183f844 100644 --- a/configs/ablations/ladder/battlesnake_llama_smoke.yaml +++ b/configs/ablations/ladder/battlesnake_llama_smoke.yaml @@ -5,9 +5,7 @@ # uv run codeclash ladder run configs/ablations/ladder/battlesnake_llama_smoke.yaml -c tournament: rounds: 2 -ladder_rules: - min_round_wins: 1 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 10 diff --git a/configs/ablations/ladder/corewar.yaml b/configs/ablations/ladder/corewar.yaml index 7d601e02..e4c9b980 100644 --- a/configs/ablations/ladder/corewar.yaml +++ b/configs/ablations/ladder/corewar.yaml @@ -1,8 +1,6 @@ tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml b/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml index 4a31bff2..197da02a 100644 --- a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/corewar__gemini_3_5_flash.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__gpt_5_5.yaml b/configs/ablations/ladder/corewar__gpt_5_5.yaml index 2a0fe41c..0e9ae90d 100644 --- a/configs/ablations/ladder/corewar__gpt_5_5.yaml +++ b/configs/ablations/ladder/corewar__gpt_5_5.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/corewar__gpt_5_5.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__opus_4_7.yaml b/configs/ablations/ladder/corewar__opus_4_7.yaml index 8ff22594..f6b66817 100644 --- a/configs/ablations/ladder/corewar__opus_4_7.yaml +++ b/configs/ablations/ladder/corewar__opus_4_7.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/corewar__opus_4_7.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__opus_4_8.yaml b/configs/ablations/ladder/corewar__opus_4_8.yaml index 135973a9..eee2d50f 100644 --- a/configs/ablations/ladder/corewar__opus_4_8.yaml +++ b/configs/ablations/ladder/corewar__opus_4_8.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/corewar__opus_4_8.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/corewar__sonnet_5.yaml b/configs/ablations/ladder/corewar__sonnet_5.yaml index 0344dd40..c06b95ef 100644 --- a/configs/ablations/ladder/corewar__sonnet_5.yaml +++ b/configs/ablations/ladder/corewar__sonnet_5.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/corewar__sonnet_5.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 diff --git a/configs/ablations/ladder/ladder_rules.yaml b/configs/ablations/ladder/ladder_rules.yaml new file mode 100644 index 00000000..41eb9478 --- /dev/null +++ b/configs/ablations/ladder/ladder_rules.yaml @@ -0,0 +1,8 @@ +# Shared advancement rule for every CC:Ladder run config. Each [__].yaml pulls +# this in on its `ladder_rules:` line, so the win condition stays consistent across all +# arenas/models in one place. (The make_*.yaml ladder-build configs don't advance a climber, +# so they intentionally carry no ladder_rules.) +# NOTE: keep the include-directive token out of these comments — the resolver matches it on any +# line, comments included, and would try to resolve it recursively. +min_round_wins: 2 # whole number of agent rounds to win to advance (1..tournament.rounds) +win_last_k: 0 # must win the last K rounds (0 = off; must be <= min_round_wins) diff --git a/configs/ablations/ladder/robotrumble.yaml b/configs/ablations/ladder/robotrumble.yaml index 2163107e..abf47930 100644 --- a/configs/ablations/ladder/robotrumble.yaml +++ b/configs/ablations/ladder/robotrumble.yaml @@ -1,8 +1,6 @@ tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml b/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml index f3346cfc..7ce917e2 100644 --- a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml b/configs/ablations/ladder/robotrumble__gpt_5_5.yaml index ef4ef8b9..81005c0c 100644 --- a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml +++ b/configs/ablations/ladder/robotrumble__gpt_5_5.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/robotrumble__gpt_5_5.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__opus_4_7.yaml b/configs/ablations/ladder/robotrumble__opus_4_7.yaml index 518c8022..df94ac56 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_7.yaml +++ b/configs/ablations/ladder/robotrumble__opus_4_7.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/robotrumble__opus_4_7.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__opus_4_8.yaml b/configs/ablations/ladder/robotrumble__opus_4_8.yaml index 4d26ba7f..44c2b7d0 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_8.yaml +++ b/configs/ablations/ladder/robotrumble__opus_4_8.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/robotrumble__opus_4_8.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 diff --git a/configs/ablations/ladder/robotrumble__sonnet_5.yaml b/configs/ablations/ladder/robotrumble__sonnet_5.yaml index 5632555d..b0931cb8 100644 --- a/configs/ablations/ladder/robotrumble__sonnet_5.yaml +++ b/configs/ablations/ladder/robotrumble__sonnet_5.yaml @@ -2,9 +2,7 @@ # uv run codeclash ladder run configs/ablations/ladder/robotrumble__sonnet_5.yaml tournament: rounds: 5 -ladder_rules: - min_round_wins: 2 # rounds to win to advance (1..total rounds) - win_last_k: 0 # must win last K (0 = off, <= min_round_wins) +ladder_rules: !include ablations/ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 From 800b1c27027f9485da11e2ecfa528f1e79377187 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:29:49 +0000 Subject: [PATCH 06/19] Add matplotlib to dev dependencies Required by codeclash.analysis (elo plots + ranking). Co-Authored-By: Claude Opus 4.8 (1M context) --- pyproject.toml | 1 + uv.lock | 406 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 407 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 1a420f81..4f77404b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ dev = [ "Werkzeug", "frozen-flask", "anthropic", + "matplotlib", # analysis plots + elo ranking (codeclash.analysis) ] aws = [ "boto3", diff --git a/uv.lock b/uv.lock index c7d039ac..a84ea9e3 100644 --- a/uv.lock +++ b/uv.lock @@ -393,6 +393,7 @@ aws = [ dev = [ { name = "anthropic" }, { name = "frozen-flask" }, + { name = "matplotlib" }, { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-cov" }, @@ -418,6 +419,7 @@ requires-dist = [ { name = "jinja2" }, { name = "litellm" }, { name = "markupsafe" }, + { name = "matplotlib", marker = "extra == 'dev'" }, { name = "mini-swe-agent", specifier = ">=2.4,<3" }, { name = "mkdocs-glightbox", marker = "extra == 'docs'" }, { name = "mkdocs-include-markdown-plugin", marker = "extra == 'docs'" }, @@ -447,6 +449,88 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, +] + [[package]] name = "coverage" version = "7.13.0" @@ -539,6 +623,15 @@ toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + [[package]] name = "datasets" version = "5.0.0" @@ -699,6 +792,55 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/f9/7f9263c5695f4bd0023734af91bedb2ff8209e8de6ead162f35d8dc762fd/flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c", size = 103308, upload-time = "2025-08-19T21:03:19.499Z" }, ] +[[package]] +name = "fonttools" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/2b/a7f1545bdf5da69c4bda0cea2a5781f0ad2a6623e0277267672db43c5fe6/fonttools-4.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f", size = 2881793, upload-time = "2026-05-14T12:02:56.645Z" }, + { url = "https://files.pythonhosted.org/packages/49/50/965308c703f085f225db2886813b27e015b8b3438c350b22dd65b52c2a2c/fonttools-4.63.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9", size = 2428130, upload-time = "2026-05-14T12:02:58.891Z" }, + { url = "https://files.pythonhosted.org/packages/d8/38/6937fbd7f2dc3a6b48725851bc2c15ec949b9af14d9bbcb5fe83cdf9bdf9/fonttools-4.63.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b", size = 5111952, upload-time = "2026-05-14T12:03:01.263Z" }, + { url = "https://files.pythonhosted.org/packages/0b/43/a81f20050a3115b57d62c8e781446949512eac36690dc384ccea65ff4cc1/fonttools-4.63.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18", size = 5082308, upload-time = "2026-05-14T12:03:03.211Z" }, + { url = "https://files.pythonhosted.org/packages/67/00/cdd9d4944ca6ae280d01e69cc37bde3bf663630b837a6fc6d2cd65d80e0e/fonttools-4.63.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0", size = 5087932, upload-time = "2026-05-14T12:03:05.147Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f1/0aa0dbea778c75adbef223c42019fd47d22262b905974d62d829545d485f/fonttools-4.63.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007", size = 5213271, upload-time = "2026-05-14T12:03:07.238Z" }, + { url = "https://files.pythonhosted.org/packages/a8/99/253e4056e1f0e67b9390125a154b73b5eb73ad521bece95c004858fdeec2/fonttools-4.63.0-cp311-cp311-win32.whl", hash = "sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb", size = 2304473, upload-time = "2026-05-14T12:03:09.271Z" }, + { url = "https://files.pythonhosted.org/packages/08/60/defa5e69641db890a63be281f41345f4c33b157824eaf0b9fad3e08b0dcb/fonttools-4.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c", size = 2356389, upload-time = "2026-05-14T12:03:11.53Z" }, + { url = "https://files.pythonhosted.org/packages/08/ef/b3c6b9b5be2f82416d73fe2ed2e96e2793cd80e7510bd6a17ca79cdd88ec/fonttools-4.63.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02", size = 2881131, upload-time = "2026-05-14T12:03:13.386Z" }, + { url = "https://files.pythonhosted.org/packages/44/a0/c815bea63117fa63e4e1c01f8a1110d2112fa003f838e6467094ec2432ce/fonttools-4.63.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0", size = 2426704, upload-time = "2026-05-14T12:03:15.801Z" }, + { url = "https://files.pythonhosted.org/packages/44/04/0b91d8e916e92ad1fac9e4624760baf0fd5ff2ead614c2f68fb21373f03f/fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af", size = 5044298, upload-time = "2026-05-14T12:03:18.085Z" }, + { url = "https://files.pythonhosted.org/packages/77/c7/2342da9830e3e9d4870305ca5d2091d2a83284f2953079b7bdd3b5e029d8/fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8", size = 4999800, upload-time = "2026-05-14T12:03:20.161Z" }, + { url = "https://files.pythonhosted.org/packages/e6/6d/67fe16c48d7ce050979b33f47e0d28a318f02da030602e944c34f7a16ef3/fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b", size = 4982666, upload-time = "2026-05-14T12:03:22.87Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/3bbab338c07c71fa56269953845e92c951a61457bbbb0f1022551ea266d9/fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78", size = 5133598, upload-time = "2026-05-14T12:03:25.168Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/aa27c7f98db5b064883dadcc5283947e81e034de42e22a33675878d98b54/fonttools-4.63.0-cp312-cp312-win32.whl", hash = "sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263", size = 2292575, upload-time = "2026-05-14T12:03:27.496Z" }, + { url = "https://files.pythonhosted.org/packages/87/36/cccb9bc2a6ab63d1b2980374f0dca72ce95ae267c9b4cfe77455bb70d0d4/fonttools-4.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272", size = 2343211, upload-time = "2026-05-14T12:03:30.057Z" }, + { url = "https://files.pythonhosted.org/packages/0f/8d/d8fec3dcde2963f8c908fb315e5ff2cd0ac34f82394bbbf73a2aa5145ce3/fonttools-4.63.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd", size = 2876062, upload-time = "2026-05-14T12:03:32.554Z" }, + { url = "https://files.pythonhosted.org/packages/ef/71/d935dc54e4ff121bfdd11e08702db63a7e6f25af21d8a3d7b7212df53641/fonttools-4.63.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59", size = 2424594, upload-time = "2026-05-14T12:03:34.86Z" }, + { url = "https://files.pythonhosted.org/packages/8e/40/e76320afa1df918e146155ef239b1719ee266092e96f5423bfd075affba1/fonttools-4.63.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d", size = 5024840, upload-time = "2026-05-14T12:03:36.745Z" }, + { url = "https://files.pythonhosted.org/packages/ce/36/0b805d8c485f872f65a509cbe3b58a5d0d17bee855333b54a150c79d3061/fonttools-4.63.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68", size = 4975801, upload-time = "2026-05-14T12:03:38.833Z" }, + { url = "https://files.pythonhosted.org/packages/c8/26/2cee03d0aa083ab022da5c07aff9ed3f689da1defb81ad6917c9627896da/fonttools-4.63.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be", size = 4965009, upload-time = "2026-05-14T12:03:41.494Z" }, + { url = "https://files.pythonhosted.org/packages/7e/48/cc4b66d9058c0d0982c833fad10127c4b0e9324606aafa41382295ca4102/fonttools-4.63.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27", size = 5105892, upload-time = "2026-05-14T12:03:43.525Z" }, + { url = "https://files.pythonhosted.org/packages/d8/1f/a98a30a814b9ddef3a2e706025f90b9e0bc94890e6cb15254bc86547d11a/fonttools-4.63.0-cp313-cp313-win32.whl", hash = "sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380", size = 2291313, upload-time = "2026-05-14T12:03:45.594Z" }, + { url = "https://files.pythonhosted.org/packages/92/46/5177b01f3b4abfdd4409f31cca4ab279c9343a26efbe9ec78c97fc612e02/fonttools-4.63.0-cp313-cp313-win_amd64.whl", hash = "sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b", size = 2342299, upload-time = "2026-05-14T12:03:47.414Z" }, + { url = "https://files.pythonhosted.org/packages/27/d2/23d25e3f247b328be58d04a4c9f894178a0d1eda7d42867cfb388adaf416/fonttools-4.63.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745", size = 2875338, upload-time = "2026-05-14T12:03:50.052Z" }, + { url = "https://files.pythonhosted.org/packages/cd/58/7dfa0c761cb3b2964e2a84c4dc986c926a87de0cb9fb60d5b28ded3f2914/fonttools-4.63.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03", size = 2422661, upload-time = "2026-05-14T12:03:52.154Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/64cfa18a7a1621d17b7f4502b2b0ed8a135a90c3db51ea590ee99043e76b/fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49", size = 5010526, upload-time = "2026-05-14T12:03:54.647Z" }, + { url = "https://files.pythonhosted.org/packages/36/e1/a8933a72c45a87177fbde2696e0d0755c8c9062f8c077a961c6215fa27b1/fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b", size = 4923946, upload-time = "2026-05-14T12:03:56.984Z" }, + { url = "https://files.pythonhosted.org/packages/27/60/872e6e233b8c5e8b41413796ff18b7fe479661bd40147e071b450dfad7a1/fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6", size = 4962489, upload-time = "2026-05-14T12:03:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/30/c4/83c24f2ec38b90cfda84bf4b1a1f49df80e84a1db4e7ac6e0d41bf23bc39/fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4", size = 5071870, upload-time = "2026-05-14T12:04:02.122Z" }, + { url = "https://files.pythonhosted.org/packages/de/40/3ae22b60ff1d41ce0bd044b31238cdc72cef99f28b976f1e128ebd618c9b/fonttools-4.63.0-cp314-cp314-win32.whl", hash = "sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616", size = 2295026, upload-time = "2026-05-14T12:04:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d4/98078064ccc76b45cb0f6c002452011e93c4bd26f6850344f0951cc1fe89/fonttools-4.63.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5", size = 2347454, upload-time = "2026-05-14T12:04:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/49/4e/652d1580c5f4e39f7d103b0c793e4773129ad633dce4addd0cf4dfebde02/fonttools-4.63.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001", size = 2958152, upload-time = "2026-05-14T12:04:08.706Z" }, + { url = "https://files.pythonhosted.org/packages/0e/55/ad864c9a9b219f552eb46b32cd7906c466e5a578ba0c3abfcc0fe7413eb6/fonttools-4.63.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e", size = 2460809, upload-time = "2026-05-14T12:04:10.783Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2b/0aa8db70f18cf52e49b4ed5ecec68547f981160bf5ded3b5aed6faa0a6f9/fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096", size = 5148649, upload-time = "2026-05-14T12:04:12.747Z" }, + { url = "https://files.pythonhosted.org/packages/7f/63/18e4369c25043096f1048e0c9915951adc4f842bd81c6b18155824d6fa99/fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f", size = 4932147, upload-time = "2026-05-14T12:04:14.806Z" }, + { url = "https://files.pythonhosted.org/packages/a1/3f/67f3eac2ffd8a98446c5022f8ed3864eac878a5ff7af8df4c8286dba16cc/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40", size = 5027237, upload-time = "2026-05-14T12:04:17.675Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ba/4e6214cb38a7b04779e97bb7636de9a5c7f20af7018d03dee0b64c08510a/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196", size = 5053933, upload-time = "2026-05-14T12:04:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/34/3b/214dcc19ee31d3d38fb5ad2755c11ef0514e5dc300bbaf41c0b69f393799/fonttools-4.63.0-cp314-cp314t-win32.whl", hash = "sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8", size = 2359326, upload-time = "2026-05-14T12:04:24.22Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/3ff1a9b523058c2eeb6a9d50f5574e2a738200d0d94107d5bc4105e8da3f/fonttools-4.63.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419", size = 2425829, upload-time = "2026-05-14T12:04:26.829Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + [[package]] name = "frozen-flask" version = "1.0.2" @@ -1170,6 +1312,112 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/dd/a495a9c104be1c476f0386e714252caf2b7eca883915422a64c50b88c6f5/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c", size = 122798, upload-time = "2026-03-09T13:12:58.963Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/37b4047a2af0cf5ef6d8b4b26e91829ae6fc6a2d1f74524bcb0e7cd28a32/kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb", size = 66216, upload-time = "2026-03-09T13:13:00.155Z" }, + { url = "https://files.pythonhosted.org/packages/0a/aa/510dc933d87767584abfe03efa445889996c70c2990f6f87c3ebaa0a18c5/kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac", size = 63911, upload-time = "2026-03-09T13:13:01.671Z" }, + { url = "https://files.pythonhosted.org/packages/80/46/bddc13df6c2a40741e0cc7865bb1c9ed4796b6760bd04ce5fae3928ef917/kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27", size = 1438209, upload-time = "2026-03-09T13:13:03.385Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d6/76621246f5165e5372f02f5e6f3f48ea336a8f9e96e43997d45b240ed8cd/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398", size = 1248888, upload-time = "2026-03-09T13:13:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c1/31559ec6fb39a5b48035ce29bb63ade628f321785f38c384dee3e2c08bc1/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db", size = 1266304, upload-time = "2026-03-09T13:13:06.743Z" }, + { url = "https://files.pythonhosted.org/packages/5e/ef/1cb8276f2d29cc6a41e0a042f27946ca347d3a4a75acf85d0a16aa6dcc82/kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc", size = 1319650, upload-time = "2026-03-09T13:13:08.607Z" }, + { url = "https://files.pythonhosted.org/packages/4c/e4/5ba3cecd7ce6236ae4a80f67e5d5531287337d0e1f076ca87a5abe4cd5d0/kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679", size = 970949, upload-time = "2026-03-09T13:13:10.299Z" }, + { url = "https://files.pythonhosted.org/packages/5a/69/dc61f7ae9a2f071f26004ced87f078235b5507ab6e5acd78f40365655034/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309", size = 2199125, upload-time = "2026-03-09T13:13:11.841Z" }, + { url = "https://files.pythonhosted.org/packages/e5/7b/abbe0f1b5afa85f8d084b73e90e5f801c0939eba16ac2e49af7c61a6c28d/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2", size = 2293783, upload-time = "2026-03-09T13:13:14.399Z" }, + { url = "https://files.pythonhosted.org/packages/8a/80/5908ae149d96d81580d604c7f8aefd0e98f4fd728cf172f477e9f2a81744/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c", size = 1960726, upload-time = "2026-03-09T13:13:16.047Z" }, + { url = "https://files.pythonhosted.org/packages/84/08/a78cb776f8c085b7143142ce479859cfec086bd09ee638a317040b6ef420/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08", size = 2464738, upload-time = "2026-03-09T13:13:17.897Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e1/65584da5356ed6cb12c63791a10b208860ac40a83de165cb6a6751a686e3/kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4", size = 2270718, upload-time = "2026-03-09T13:13:19.421Z" }, + { url = "https://files.pythonhosted.org/packages/be/6c/28f17390b62b8f2f520e2915095b3c94d88681ecf0041e75389d9667f202/kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b", size = 73480, upload-time = "2026-03-09T13:13:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/d8/0e/2ee5debc4f77a625778fec5501ff3e8036fe361b7ee28ae402a485bb9694/kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac", size = 64930, upload-time = "2026-03-09T13:13:21.997Z" }, + { url = "https://files.pythonhosted.org/packages/4d/b2/818b74ebea34dabe6d0c51cb1c572e046730e64844da6ed646d5298c40ce/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9", size = 123158, upload-time = "2026-03-09T13:13:23.127Z" }, + { url = "https://files.pythonhosted.org/packages/bf/d9/405320f8077e8e1c5c4bd6adc45e1e6edf6d727b6da7f2e2533cf58bff71/kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588", size = 66388, upload-time = "2026-03-09T13:13:24.765Z" }, + { url = "https://files.pythonhosted.org/packages/99/9f/795fedf35634f746151ca8839d05681ceb6287fbed6cc1c9bf235f7887c2/kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819", size = 64068, upload-time = "2026-03-09T13:13:25.878Z" }, + { url = "https://files.pythonhosted.org/packages/c4/13/680c54afe3e65767bed7ec1a15571e1a2f1257128733851ade24abcefbcc/kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f", size = 1477934, upload-time = "2026-03-09T13:13:27.166Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2f/cebfcdb60fd6a9b0f6b47a9337198bcbad6fbe15e68189b7011fd914911f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf", size = 1278537, upload-time = "2026-03-09T13:13:28.707Z" }, + { url = "https://files.pythonhosted.org/packages/f2/0d/9b782923aada3fafb1d6b84e13121954515c669b18af0c26e7d21f579855/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d", size = 1296685, upload-time = "2026-03-09T13:13:30.528Z" }, + { url = "https://files.pythonhosted.org/packages/27/70/83241b6634b04fe44e892688d5208332bde130f38e610c0418f9ede47ded/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083", size = 1346024, upload-time = "2026-03-09T13:13:32.818Z" }, + { url = "https://files.pythonhosted.org/packages/e4/db/30ed226fb271ae1a6431fc0fe0edffb2efe23cadb01e798caeb9f2ceae8f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6", size = 987241, upload-time = "2026-03-09T13:13:34.435Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bd/c314595208e4c9587652d50959ead9e461995389664e490f4dce7ff0f782/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1", size = 2227742, upload-time = "2026-03-09T13:13:36.4Z" }, + { url = "https://files.pythonhosted.org/packages/c1/43/0499cec932d935229b5543d073c2b87c9c22846aab48881e9d8d6e742a2d/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0", size = 2323966, upload-time = "2026-03-09T13:13:38.204Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6f/79b0d760907965acfd9d61826a3d41f8f093c538f55cd2633d3f0db269f6/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15", size = 1977417, upload-time = "2026-03-09T13:13:39.966Z" }, + { url = "https://files.pythonhosted.org/packages/ab/31/01d0537c41cb75a551a438c3c7a80d0c60d60b81f694dac83dd436aec0d0/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314", size = 2491238, upload-time = "2026-03-09T13:13:41.698Z" }, + { url = "https://files.pythonhosted.org/packages/e4/34/8aefdd0be9cfd00a44509251ba864f5caf2991e36772e61c408007e7f417/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9", size = 2294947, upload-time = "2026-03-09T13:13:43.343Z" }, + { url = "https://files.pythonhosted.org/packages/ad/cf/0348374369ca588f8fe9c338fae49fa4e16eeb10ffb3d012f23a54578a9e/kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384", size = 73569, upload-time = "2026-03-09T13:13:45.792Z" }, + { url = "https://files.pythonhosted.org/packages/28/26/192b26196e2316e2bd29deef67e37cdf9870d9af8e085e521afff0fed526/kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7", size = 64997, upload-time = "2026-03-09T13:13:46.878Z" }, + { url = "https://files.pythonhosted.org/packages/9d/69/024d6711d5ba575aa65d5538042e99964104e97fa153a9f10bc369182bc2/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09", size = 123166, upload-time = "2026-03-09T13:13:48.032Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/adbb40df306f587054a348831220812b9b1d787aff714cfbc8556e38fccd/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3", size = 66395, upload-time = "2026-03-09T13:13:49.365Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd", size = 64065, upload-time = "2026-03-09T13:13:50.562Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3", size = 1477903, upload-time = "2026-03-09T13:13:52.084Z" }, + { url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96", size = 1278751, upload-time = "2026-03-09T13:13:54.673Z" }, + { url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099", size = 1296793, upload-time = "2026-03-09T13:13:56.287Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8", size = 1346041, upload-time = "2026-03-09T13:13:58.269Z" }, + { url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87", size = 987292, upload-time = "2026-03-09T13:13:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23", size = 2227865, upload-time = "2026-03-09T13:14:01.401Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859", size = 2324369, upload-time = "2026-03-09T13:14:02.972Z" }, + { url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902", size = 1977989, upload-time = "2026-03-09T13:14:04.503Z" }, + { url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167", size = 2491645, upload-time = "2026-03-09T13:14:06.106Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0", size = 2295237, upload-time = "2026-03-09T13:14:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276", size = 73573, upload-time = "2026-03-09T13:14:12.327Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d2/64be2e429eb4fca7f7e1c52a91b12663aeaf25de3895e5cca0f47ef2a8d0/kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c", size = 64998, upload-time = "2026-03-09T13:14:13.469Z" }, + { url = "https://files.pythonhosted.org/packages/b0/69/ce68dd0c85755ae2de490bf015b62f2cea5f6b14ff00a463f9d0774449ff/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1", size = 125700, upload-time = "2026-03-09T13:14:14.636Z" }, + { url = "https://files.pythonhosted.org/packages/74/aa/937aac021cf9d4349990d47eb319309a51355ed1dbdc9c077cdc9224cb11/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e", size = 67537, upload-time = "2026-03-09T13:14:15.808Z" }, + { url = "https://files.pythonhosted.org/packages/ee/20/3a87fbece2c40ad0f6f0aefa93542559159c5f99831d596050e8afae7a9f/kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7", size = 65514, upload-time = "2026-03-09T13:14:18.035Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c", size = 1584848, upload-time = "2026-03-09T13:14:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368", size = 1391542, upload-time = "2026-03-09T13:14:21.54Z" }, + { url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489", size = 1404447, upload-time = "2026-03-09T13:14:23.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1", size = 1455918, upload-time = "2026-03-09T13:14:24.74Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3", size = 1072856, upload-time = "2026-03-09T13:14:26.597Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18", size = 2333580, upload-time = "2026-03-09T13:14:28.237Z" }, + { url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021", size = 2423018, upload-time = "2026-03-09T13:14:30.018Z" }, + { url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310", size = 2062804, upload-time = "2026-03-09T13:14:32.888Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3", size = 2597482, upload-time = "2026-03-09T13:14:34.971Z" }, + { url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2", size = 2394328, upload-time = "2026-03-09T13:14:36.816Z" }, + { url = "https://files.pythonhosted.org/packages/47/84/6a6d5e5bb8273756c27b7d810d47f7ef2f1f9b9fd23c9ee9a3f8c75c9cef/kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53", size = 68410, upload-time = "2026-03-09T13:14:38.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615", size = 123231, upload-time = "2026-03-09T13:14:41.323Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02", size = 66489, upload-time = "2026-03-09T13:14:42.534Z" }, + { url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e", size = 64063, upload-time = "2026-03-09T13:14:44.759Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913, upload-time = "2026-03-09T13:14:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782, upload-time = "2026-03-09T13:14:48.458Z" }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815, upload-time = "2026-03-09T13:14:50.721Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925, upload-time = "2026-03-09T13:14:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322, upload-time = "2026-03-09T13:14:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857, upload-time = "2026-03-09T13:14:56.471Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376, upload-time = "2026-03-09T13:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549, upload-time = "2026-03-09T13:14:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680, upload-time = "2026-03-09T13:15:01.364Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905, upload-time = "2026-03-09T13:15:03.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e", size = 75086, upload-time = "2026-03-09T13:15:07.775Z" }, + { url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df", size = 66577, upload-time = "2026-03-09T13:15:09.139Z" }, + { url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e", size = 125794, upload-time = "2026-03-09T13:15:10.525Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4", size = 67646, upload-time = "2026-03-09T13:15:12.016Z" }, + { url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028", size = 65511, upload-time = "2026-03-09T13:15:13.311Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858, upload-time = "2026-03-09T13:15:15.103Z" }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539, upload-time = "2026-03-09T13:15:16.661Z" }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310, upload-time = "2026-03-09T13:15:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244, upload-time = "2026-03-09T13:15:20.444Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154, upload-time = "2026-03-09T13:15:22.039Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377, upload-time = "2026-03-09T13:15:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288, upload-time = "2026-03-09T13:15:25.789Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158, upload-time = "2026-03-09T13:15:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260, upload-time = "2026-03-09T13:15:29.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403, upload-time = "2026-03-09T13:15:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681", size = 79687, upload-time = "2026-03-09T13:15:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57", size = 70032, upload-time = "2026-03-09T13:15:34.411Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fa/2910df836372d8761bb6eff7d8bdcb1613b5c2e03f260efe7abe34d388a7/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797", size = 130262, upload-time = "2026-03-09T13:15:35.629Z" }, + { url = "https://files.pythonhosted.org/packages/0f/41/c5f71f9f00aabcc71fee8b7475e3f64747282580c2fe748961ba29b18385/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203", size = 138036, upload-time = "2026-03-09T13:15:36.894Z" }, + { url = "https://files.pythonhosted.org/packages/fa/06/7399a607f434119c6e1fdc8ec89a8d51ccccadf3341dee4ead6bd14caaf5/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7", size = 194295, upload-time = "2026-03-09T13:15:38.22Z" }, + { url = "https://files.pythonhosted.org/packages/b5/91/53255615acd2a1eaca307ede3c90eb550bae9c94581f8c00081b6b1c8f44/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57", size = 75987, upload-time = "2026-03-09T13:15:39.65Z" }, + { url = "https://files.pythonhosted.org/packages/e9/eb/5fcbbbf9a0e2c3a35effb88831a483345326bbc3a030a3b5b69aee647f84/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232", size = 59532, upload-time = "2026-03-09T13:15:47.047Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9b/e17104555bb4db148fd52327feea1e96be4b88e8e008b029002c281a21ab/kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a", size = 57420, upload-time = "2026-03-09T13:15:48.199Z" }, + { url = "https://files.pythonhosted.org/packages/48/44/2b5b95b7aa39fb2d8d9d956e0f3d5d45aef2ae1d942d4c3ffac2f9cfed1a/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737", size = 79892, upload-time = "2026-03-09T13:15:49.694Z" }, + { url = "https://files.pythonhosted.org/packages/52/7d/7157f9bba6b455cfb4632ed411e199fc8b8977642c2b12082e1bd9e6d173/kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16", size = 77603, upload-time = "2026-03-09T13:15:50.945Z" }, + { url = "https://files.pythonhosted.org/packages/0a/dd/8050c947d435c8d4bc94e3252f4d8bb8a76cfb424f043a8680be637a57f1/kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1", size = 73558, upload-time = "2026-03-09T13:15:52.112Z" }, +] + [[package]] name = "linkify-it-py" version = "2.0.3" @@ -1306,6 +1554,70 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] +[[package]] +name = "matplotlib" +version = "3.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/24/080c99d223d158d3a8902769269ab6da5b50f7a0e6e072513907e02b7a6c/matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57", size = 33251176, upload-time = "2026-06-12T02:29:15.508Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/a2/78f662f1b18968531f67d3fcde1b7ea8496920bacd4f16ddb5b79d112e46/matplotlib-3.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f857524b442f0f36e641868ce2171aafa88cb0bc0644f4e1d8a5df9b32649fef", size = 9436261, upload-time = "2026-06-12T02:27:34.161Z" }, + { url = "https://files.pythonhosted.org/packages/5e/92/044f1de43901310202f4c79acf4f141be53b2ca8d8380e2fcefb3d523a75/matplotlib-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:57baa92fdc82948ed716eae6d2579d4d6f40965cd8d2f416755b4a72580a3233", size = 9264669, upload-time = "2026-06-12T02:27:37.413Z" }, + { url = "https://files.pythonhosted.org/packages/53/f4/f0b4f9ba7ec14a7af8151f3ad71ecfe3561e6ba38cfab1db3681ba4ca112/matplotlib-3.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:630eee0e67d35cce2019a0e670719f4816e3b86aff0fa72729f6c69786fceb45", size = 10021076, upload-time = "2026-06-12T02:27:39.926Z" }, + { url = "https://files.pythonhosted.org/packages/d7/33/4d679c6dcd594a156542080ac907ddccf7b09ca11655c4b28eca8e9ee5da/matplotlib-3.11.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5106c444d0bf966eee2853548c03772af4ab7199118e086c62fbac8ccb07c055", size = 10828999, upload-time = "2026-06-12T02:27:42.433Z" }, + { url = "https://files.pythonhosted.org/packages/07/74/0a3683802037d8cd013144d77c247219b47f2aabace6fdde74faa12bacf7/matplotlib-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d7aea652b58e686444079be3376ef546bffa1eee9b9bb9c472b9fcf6cf410d3", size = 10913103, upload-time = "2026-06-12T02:27:44.827Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9f/970fcbf381e82ec66fdf5da8ea76e2e9240f61a24011ce9fd1d42c37ac2d/matplotlib-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:70a5b3e9a5dab708c0f039709ae7c68d5b4d254e291ef76492cdba230c8bb5e4", size = 9310945, upload-time = "2026-06-12T02:27:46.867Z" }, + { url = "https://files.pythonhosted.org/packages/14/4e/6e7cfed23611265ded53806852343b5c59339e506e84c474a9b5afc3b249/matplotlib-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:3d68266213e73823ac3be90615bab0cf31f88851e114cdb1dd25dacf3b01e1a7", size = 8999304, upload-time = "2026-06-12T02:27:48.798Z" }, + { url = "https://files.pythonhosted.org/packages/da/17/f5276b496c61477a6c4fc5e7401f4bfe1c2e5ef7c6cd67896f2ade3809cb/matplotlib-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06b5872e9cf11adc8f589ded3ce11bc3e1061ad498259664fabc1f6615beb918", size = 9449976, upload-time = "2026-06-12T02:27:50.989Z" }, + { url = "https://files.pythonhosted.org/packages/82/34/bdd77418adb2178a1d59f044bd67bfebb115896e91b840b8a197eb3f4f4e/matplotlib-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0515d495124be3124340e59f164d901ed4484e2246a5b74cfa483cac3b80bd97", size = 9279307, upload-time = "2026-06-12T02:27:53.247Z" }, + { url = "https://files.pythonhosted.org/packages/94/95/7f522393c88313336b20d70fc849555757b2e5febc22b83b3a3f0fd4bce9/matplotlib-3.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be5f93a1d21981bfb802ded0d77a0caa92d4342a47d45754fac77e314a506344", size = 10031353, upload-time = "2026-06-12T02:27:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/87/ce/8f25a0e3186aefd61913e7467d1b999465bcd0d0c03ac695c1b26ca559b7/matplotlib-3.11.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41635d7909d19e52e924a521dde6d8f670b0f53ab1d0e8c331fa831554f681d1", size = 10839232, upload-time = "2026-06-12T02:27:57.746Z" }, + { url = "https://files.pythonhosted.org/packages/85/c2/db15da2bbdf9e3ca66df7db8e2c33a1dfed67be24a24d2c878efaaff01d6/matplotlib-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:94f5000f67ca9faa300863ea17f8bce9175cb67b88bec4bc7780502d53dd7c9e", size = 10923899, upload-time = "2026-06-12T02:28:00.223Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2f/a58a4443a4d052a4ea77557478336aefc26c7981f6408d37adba763aa758/matplotlib-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ac6f1ef39f3d0f9e2463303013094992cdbe0f85f43bc54155bc472b2042768e", size = 9329528, upload-time = "2026-06-12T02:28:02.27Z" }, + { url = "https://files.pythonhosted.org/packages/61/0f/4b669589d47733b97ab9df4b58d6fc1e68acb5ea42a928dc7cbdd6bf5871/matplotlib-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:9dd11fb612ce7bc60b1de5b4fc87ff959d22317b5de42aabf392f66f97af22eb", size = 9003413, upload-time = "2026-06-12T02:28:04.49Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/aa47f156b061d14c98b906f76c428507397708ec63ff94f410ae1752b426/matplotlib-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce3b839b34ae1f430b4616893a2945a2999debaa7e94e7e29a2a8bbf286f7b5", size = 9450532, upload-time = "2026-06-12T02:28:06.769Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4f/5a9eb0375e81413953febf8af7b012a6b6357f53438a15c4f5ad86c6bbb5/matplotlib-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:373db8f91214e8ccaf35ac833cc1dd59dd961e148bbd55dd027141591dde1313", size = 9279760, upload-time = "2026-06-12T02:28:09.152Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c0/1117d53077e3ac3152503a84e9cf7a5c239576805ee71276e80c2aaa7471/matplotlib-3.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be152b7570324dc8d01574cc9474dd2d803237acf528bcbb5b211fa347461a09", size = 10031623, upload-time = "2026-06-12T02:28:11.26Z" }, + { url = "https://files.pythonhosted.org/packages/92/7e/e937138daffad65b71bf831a377809dcbc830fb4f31a31e067dc1faa2575/matplotlib-3.11.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:126f256df600652d7e4b394cf3164ff75210a00038f287c95a012a6f58d0e83f", size = 10839372, upload-time = "2026-06-12T02:28:14.102Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c2/438ecc197ffb8023b6b9922915542f2172f5fd45b76703b0b4fc47322243/matplotlib-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:03acfeddf87b0dddb11b081ef7740ad445a3ca8bcb6b8e3011b08f2cf802b75c", size = 10924099, upload-time = "2026-06-12T02:28:16.383Z" }, + { url = "https://files.pythonhosted.org/packages/40/2e/395883da416f378b3ed2c9f3e843ac477eae1ce731b671b79adaa6f0bacd/matplotlib-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:ab3722f04f3ff34c23b5012c5873d2894174e06c3822fcdac3610965a5ac7d06", size = 9329727, upload-time = "2026-06-12T02:28:18.581Z" }, + { url = "https://files.pythonhosted.org/packages/61/82/2c388956abf8bf392dfb5b8917c502f1082df6a941b781ab8c8e5ba2474b/matplotlib-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c945824670fb8915b4ac879e5e61f3c58e0913022f70a0de4c082b17372f8771", size = 9003506, upload-time = "2026-06-12T02:28:20.474Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c1/34454baa44da7975ada82e9aea37105ec47059514dc967d3be14426ba8dc/matplotlib-3.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3489c3dc487669b4a980bc3068f87856de7a1564248d3f6c629efb2a58b03f24", size = 9499838, upload-time = "2026-06-12T02:28:22.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c3/98fe79a398cf232219f090163a7fa7e6766e9f2e0ad26df54d6f8934d8ee/matplotlib-3.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6a98f5476ce784a50ce09998f4ae1e6a9f25043cef8a480c98949902eda74620", size = 9332298, upload-time = "2026-06-12T02:28:24.796Z" }, + { url = "https://files.pythonhosted.org/packages/95/e4/b4b7c33151e74e5c802f3cde1ba807ebfc38401e329b44e215a5888dd76d/matplotlib-3.11.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:565af866fd63e4bd3f987d580afe27c44c2552a3b3305f4ecbb85133601ea6f3", size = 10045491, upload-time = "2026-06-12T02:28:27.141Z" }, + { url = "https://files.pythonhosted.org/packages/71/28/394548efd68354110c1a1be11fe6b6e559e06d1a23da35908a0e316c55a9/matplotlib-3.11.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6b3e64dea5062c570f04358e2711859f3531b459f29516274fbad889079e4f3", size = 10857059, upload-time = "2026-06-12T02:28:29.222Z" }, + { url = "https://files.pythonhosted.org/packages/c8/44/e7922e6e2a4d63bdfbc9dc4a53e3850ab438d46cf42e6779bb15ec92c948/matplotlib-3.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:942b37c5db1899610bd1543ce8e13e4ecff9a4633e7f63bb6aa9205d2644ebd1", size = 10939576, upload-time = "2026-06-12T02:28:31.66Z" }, + { url = "https://files.pythonhosted.org/packages/3d/be/b1ca96003a441d619b727fee21d671fdff7a5ce2f1bb797b2521aa2f679a/matplotlib-3.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:c08e649a6313e1291e713623b97a38e5bb4aa580b2a100a94a3309bc6b9c8eb3", size = 9379519, upload-time = "2026-06-12T02:28:33.888Z" }, + { url = "https://files.pythonhosted.org/packages/e3/72/4bf3b91821c34596dd6a7bdac5836d94f744144c8208939ef49d8ec43f7e/matplotlib-3.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2746cd2c113742ff6ce37a864c5ac5fd7aa644568f445e66166e457ac78e40e0", size = 9055456, upload-time = "2026-06-12T02:28:35.878Z" }, + { url = "https://files.pythonhosted.org/packages/57/52/a94102ac99eb78e2fe9b826674f9ef9ee23327110ea6ab4776c1b4eb6209/matplotlib-3.11.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3338e3e3de128cf50d0d2fb92a122815daf9c755bd882a474343c05f8fd7ec79", size = 9452137, upload-time = "2026-06-12T02:28:37.93Z" }, + { url = "https://files.pythonhosted.org/packages/7c/03/b8cdb625a21f710dfa11bbca1f48fb4057d2c0286975f8b415bf80942c99/matplotlib-3.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:25c2e5455efd8d99f41fb79871a31feb7d301569642e332ec58d72cfe9282bc3", size = 9281514, upload-time = "2026-06-12T02:28:40.028Z" }, + { url = "https://files.pythonhosted.org/packages/b7/2d/4e1240ea82ee197dfb3851e71f71c87eeeb975f1753b56a0588e4e80739a/matplotlib-3.11.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9695457a467ff86d23f35037a43deb6f1134dd6d3e2ac8ce1e2087cff09ffb9", size = 10843005, upload-time = "2026-06-12T02:28:42.39Z" }, + { url = "https://files.pythonhosted.org/packages/29/dc/6377ecfaa5fef79430f74a1a16638b4e2aa30d4692bae2c19f9d76fe3b01/matplotlib-3.11.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19c16c61dea63b3582918503e6b294193961261d9daa806d4ae2151f1ad05430", size = 11127459, upload-time = "2026-06-12T02:28:44.483Z" }, + { url = "https://files.pythonhosted.org/packages/6f/41/795c405aa7560443a3b01309424cde4a1113b85c90b8a63417444a749617/matplotlib-3.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2d72ea8b7924f3cb955e61518d21e43b3df1e6c8a793b480a0c1214f185d30ba", size = 10925160, upload-time = "2026-06-12T02:28:46.564Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f7/3a9e6389a7cfaeff76c56e40c2dabcb13110e21e82f837228c834ebe748c/matplotlib-3.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:1c02da0a629dfa9debf52725ea06866b74c1fb70a895bae05e4493d34074f9f2", size = 9485186, upload-time = "2026-06-12T02:28:49.344Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c0/396478ee7cf2091d182db8b4a8695f6a37f1ddb978989cf9dbb84cd5c123/matplotlib-3.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aa55d73b3117d4b07f959cd9eb6f69b375d8df3414139c479388e551aa5d999d", size = 9160349, upload-time = "2026-06-12T02:28:51.382Z" }, + { url = "https://files.pythonhosted.org/packages/c5/6f/1c3bd51bb2b34eaacdcf3c3d859dbb357f952fc8020c617dc118ad7c9e38/matplotlib-3.11.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a9d8c6e7cd2f0ddf11d8d92e520dd1d9d2abb0cf6ac8831e338666c81e905847", size = 9500921, upload-time = "2026-06-12T02:28:53.443Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/4d861d0121840cb1a3fd4a10deb211efd6fccd481ed23e553f31f4f4da4a/matplotlib-3.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:be050fcf32f729eda99f7f75a80bf67612ce16ab9ac1c23a387dcaede95cb70e", size = 9332190, upload-time = "2026-06-12T02:28:55.623Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/22f6bc35711a0b5639a784e74e653e77c86210bd4304449dd399a482f74e/matplotlib-3.11.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfabef0230d0697aa0d717385194dd41162e00207a68bf4abf94c2bf4c27dca0", size = 10854181, upload-time = "2026-06-12T02:28:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/3f/7e/9a9eaca731a2939589da520f0ebe8fd8753d0f51fca98c7d20af6dbe261a/matplotlib-3.11.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1644db30e759199443493ac5e5caec24fdb775a8f6123021f85ba47c4133c3cb", size = 11137715, upload-time = "2026-06-12T02:29:00.555Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f9/9b030b6088354acb0296871bb624b25befc1c42509d3c6cd17420c83a5b8/matplotlib-3.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15b0d160079cb10699a0e98b5989c70677b2df7cacdc62af67c30f2facec46d9", size = 10939427, upload-time = "2026-06-12T02:29:02.527Z" }, + { url = "https://files.pythonhosted.org/packages/59/94/6b273eaee4ee250863567d100865da61a5c1527fa67f527b7ed22e0dd29c/matplotlib-3.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:446307e6b04b57b1f1239e228a1ec2af0d589a1008cebc3dfa3f5441d095cfb6", size = 9535809, upload-time = "2026-06-12T02:29:04.994Z" }, + { url = "https://files.pythonhosted.org/packages/60/95/1d36bddf2b7e2692c1540e78a6e5bc88bc1496b137e3e35a611f91b65ac3/matplotlib-3.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:652fb5696271d4c50f196d22a5ff4f8e4444c74f847423570d7dc0aa2bbd0159", size = 9209226, upload-time = "2026-06-12T02:29:07.033Z" }, + { url = "https://files.pythonhosted.org/packages/0f/c2/f5da6cd37ed6871f5c9b3c0507ddb69f14d6c36fac4541e4e0c60cb8cdfc/matplotlib-3.11.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:81ae77077a1e16d37a5b61096ccb07c8d90a99b518fa8256b8f21578932f2f62", size = 9434094, upload-time = "2026-06-12T02:29:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/f8/07/56f66906e0f87a0c6d0d0acbd34dbc9432b1931d8f26ef618bd6f92932a9/matplotlib-3.11.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ddef37840695f5eef65f9f070fe2d2f510f584c2156203f9f622a5b0584efffd", size = 9262183, upload-time = "2026-06-12T02:29:11.283Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d8/c4ecab06b7ea36a570c4f3bd2d48d1799fd5d9174470e45c2194199431e7/matplotlib-3.11.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf662e5ac5707658cb931e19972c4bd99f7b4f8b7bf79d3c821d239fa6b71e64", size = 10015653, upload-time = "2026-06-12T02:29:13.251Z" }, +] + [[package]] name = "mdit-py-plugins" version = "0.5.0" @@ -1838,6 +2150,91 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, +] + [[package]] name = "platformdirs" version = "4.5.1" @@ -2167,6 +2564,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/a4/aa2bada4a2fd648f40f19affa55d2c01dc7ff5ea9cffd3dfdeb6114951db/pymdown_extensions-10.18-py3-none-any.whl", hash = "sha256:090bca72be43f7d3186374e23c782899dbef9dc153ef24c59dcd3c346f9ffcae", size = 266703, upload-time = "2025-12-07T17:22:11.22Z" }, ] +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + [[package]] name = "pytest" version = "9.0.2" From c7f7e5a2992d419b747a2b8df68f233ab35f40ed Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:35:28 +0000 Subject: [PATCH 07/19] Print ladder advancement rule to console Unify with scml-ladder's behavior: echo the advancement rule to stdout (in addition to logging it) at the start of a ladder run. Co-Authored-By: Claude Opus 4.8 (1M context) --- codeclash/cli/ladder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/codeclash/cli/ladder.py b/codeclash/cli/ladder.py index 7fd2c129..edd1c7e6 100644 --- a/codeclash/cli/ladder.py +++ b/codeclash/cli/ladder.py @@ -165,6 +165,7 @@ def run( f"Ladder advancement rule: win >= {min_round_wins} of {rounds} agent rounds " f"(baseline round 0 excluded) and {last_k_rule}." ) + print(advancement_rule) logger.info(advancement_rule) ladder_folder = f"LadderTournament.{config['game']['name']}.r{rounds}.s{sims}.{player['name']}.{timestamp}" player["branch"] = ladder_folder From 8cf8f2cf1196d6062b7024b64bc52cebe5acc85f Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:46:43 +0000 Subject: [PATCH 08/19] reduce ocmments --- configs/ablations/ladder/ladder_rules.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/configs/ablations/ladder/ladder_rules.yaml b/configs/ablations/ladder/ladder_rules.yaml index 41eb9478..b34226c3 100644 --- a/configs/ablations/ladder/ladder_rules.yaml +++ b/configs/ablations/ladder/ladder_rules.yaml @@ -1,8 +1,5 @@ # Shared advancement rule for every CC:Ladder run config. Each [__].yaml pulls # this in on its `ladder_rules:` line, so the win condition stays consistent across all -# arenas/models in one place. (The make_*.yaml ladder-build configs don't advance a climber, -# so they intentionally carry no ladder_rules.) -# NOTE: keep the include-directive token out of these comments — the resolver matches it on any -# line, comments included, and would try to resolve it recursively. +# arenas/models in one place. min_round_wins: 2 # whole number of agent rounds to win to advance (1..tournament.rounds) win_last_k: 0 # must win the last K rounds (0 = off; must be <= min_round_wins) From 57830cc6423fcb29d75a35e75cd9216b0305ee09 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:47:37 +0000 Subject: [PATCH 09/19] nit --- configs/ablations/ladder/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/configs/ablations/ladder/README.md b/configs/ablations/ladder/README.md index 8745d1f2..02b37976 100644 --- a/configs/ablations/ladder/README.md +++ b/configs/ablations/ladder/README.md @@ -35,5 +35,3 @@ Both keys are **required** — there are no defaults; a config that omits either - `min_round_wins` must be an integer with `1 <= min_round_wins <= tournament.rounds`. - `win_last_k` must be an integer with `0 <= win_last_k <= min_round_wins`. `0` **disables** the trailing-rounds requirement; `1` means "just win the final round". - -The per-rung outcome (`player_wins`, `won_last_k`, `cleared`) is persisted under `ladder_advancement` in each rung's `metadata.json`. The overall climb result (`rungs_cleared`, `final_opponent`, `cleared_ladder`, …) is written to a ladder-level `metadata.json` in the run's parent dir. From 8c597b77f2c02aedc8d1ec4daad31467209307f6 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:49:14 +0000 Subject: [PATCH 10/19] reduce comments --- codeclash/agents/minisweagent.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/codeclash/agents/minisweagent.py b/codeclash/agents/minisweagent.py index d37fa38f..320e94bc 100644 --- a/codeclash/agents/minisweagent.py +++ b/codeclash/agents/minisweagent.py @@ -19,12 +19,7 @@ class ClashAgentConfig(AgentConfig): - """`AgentConfig` plus an optional global observation-format override. - - `observation_template` is a model-side field in mini-swe-agent, so putting it in the shared - agent config (`configs/mini/default.yaml`) doesn't reach the model on its own. Declaring it - here lets the one global config drive it; `ClashAgent` pushes it onto the model at init.""" - + """`AgentConfig` plus an optional global observation-format override.""" observation_template: str | None = None @@ -43,8 +38,6 @@ def __init__( ): super().__init__(model, env, config_class=config_class, **kwargs) self.logger = logger - # Honor the global observation_template (agent config) by pushing it onto the model, - # which is what actually renders observations. Applies to every backend uniformly. if getattr(self.config, "observation_template", None): self.model.config.observation_template = self.config.observation_template From f838b81129092f52b64eecaa5d835364e60429f9 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 02:54:16 +0000 Subject: [PATCH 11/19] Give ladder climbers an adversarial task prompt Ladder run configs only set game_description to e.g. 'BattleSnake ladder', so a climbing model was never told it's writing code to defeat an opponent (the shared instance template even frames rounds as a cooperative relay). Add a shared ladder_prompt.yaml with an arena-agnostic prompt that states the adversarial task and pulls in arena specifics via a new {{arena_description}} template var (exposed from the arena's static description through GameContext). All 19 run configs include it; make_* build configs are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) --- codeclash/agents/utils.py | 3 +++ codeclash/tournaments/pvp.py | 1 + configs/ablations/ladder/battlesnake.yaml | 4 +--- .../ladder/battlesnake__gemini_3_5_flash.yaml | 4 +--- .../ablations/ladder/battlesnake__gpt_5_5.yaml | 4 +--- .../ablations/ladder/battlesnake__opus_4_7.yaml | 4 +--- .../ablations/ladder/battlesnake__opus_4_8.yaml | 4 +--- .../ablations/ladder/battlesnake__sonnet_5.yaml | 4 +--- .../ladder/battlesnake_llama_smoke.yaml | 3 +-- configs/ablations/ladder/corewar.yaml | 4 +--- .../ladder/corewar__gemini_3_5_flash.yaml | 4 +--- configs/ablations/ladder/corewar__gpt_5_5.yaml | 4 +--- configs/ablations/ladder/corewar__opus_4_7.yaml | 4 +--- configs/ablations/ladder/corewar__opus_4_8.yaml | 4 +--- configs/ablations/ladder/corewar__sonnet_5.yaml | 4 +--- configs/ablations/ladder/ladder_prompt.yaml | 17 +++++++++++++++++ configs/ablations/ladder/robotrumble.yaml | 4 +--- .../ladder/robotrumble__gemini_3_5_flash.yaml | 4 +--- .../ablations/ladder/robotrumble__gpt_5_5.yaml | 4 +--- .../ablations/ladder/robotrumble__opus_4_7.yaml | 4 +--- .../ablations/ladder/robotrumble__opus_4_8.yaml | 4 +--- .../ablations/ladder/robotrumble__sonnet_5.yaml | 4 +--- 22 files changed, 40 insertions(+), 56 deletions(-) create mode 100644 configs/ablations/ladder/ladder_prompt.yaml diff --git a/codeclash/agents/utils.py b/codeclash/agents/utils.py index 81c2c9dd..080d2d03 100644 --- a/codeclash/agents/utils.py +++ b/codeclash/agents/utils.py @@ -26,6 +26,9 @@ class GameContext(BaseModel): round: int rounds: int working_dir: str + # Arena's static description (CodeArena.description), exposed to prompt templates as + # {{arena_description}}. Optional so non-pvp GameContext construction sites keep working. + arena_description: str = "" def _render_prompt_templates(self) -> dict: context = self.model_dump() diff --git a/codeclash/tournaments/pvp.py b/codeclash/tournaments/pvp.py index 65c4e1d0..e8274c72 100644 --- a/codeclash/tournaments/pvp.py +++ b/codeclash/tournaments/pvp.py @@ -79,6 +79,7 @@ def get_agent(self, agent_config: dict, prompts: dict) -> Player: round=1, rounds=self.rounds, working_dir=str(DIR_WORK), + arena_description=self.game.description, ) return get_agent(agent_config, game_context, environment) diff --git a/configs/ablations/ladder/battlesnake.yaml b/configs/ablations/ladder/battlesnake.yaml index a5886a1c..75a30c90 100644 --- a/configs/ablations/ladder/battlesnake.yaml +++ b/configs/ablations/ladder/battlesnake.yaml @@ -24,7 +24,5 @@ player: temperature: 0.2 max_tokens: 4096 push: True -prompts: - game_description: |- - BattleSnake ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml b/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml index ede4311f..1c59336f 100644 --- a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml @@ -18,7 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gemini_3_5_flash.yaml push: True -prompts: - game_description: |- - BattleSnake ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml b/configs/ablations/ladder/battlesnake__gpt_5_5.yaml index d31e0240..2aef4961 100644 --- a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml +++ b/configs/ablations/ladder/battlesnake__gpt_5_5.yaml @@ -18,7 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gpt_5_5.yaml push: True -prompts: - game_description: |- - BattleSnake ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__opus_4_7.yaml b/configs/ablations/ladder/battlesnake__opus_4_7.yaml index 61d2cc48..194b5671 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_7.yaml +++ b/configs/ablations/ladder/battlesnake__opus_4_7.yaml @@ -18,7 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_7.yaml push: True -prompts: - game_description: |- - BattleSnake ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__opus_4_8.yaml b/configs/ablations/ladder/battlesnake__opus_4_8.yaml index 515440a1..897209fa 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_8.yaml +++ b/configs/ablations/ladder/battlesnake__opus_4_8.yaml @@ -18,7 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: - game_description: |- - BattleSnake ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__sonnet_5.yaml b/configs/ablations/ladder/battlesnake__sonnet_5.yaml index d36a9682..87388a53 100644 --- a/configs/ablations/ladder/battlesnake__sonnet_5.yaml +++ b/configs/ablations/ladder/battlesnake__sonnet_5.yaml @@ -18,7 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_sonnet_5.yaml push: True -prompts: - game_description: |- - BattleSnake ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake_llama_smoke.yaml b/configs/ablations/ladder/battlesnake_llama_smoke.yaml index 3183f844..564f75e9 100644 --- a/configs/ablations/ladder/battlesnake_llama_smoke.yaml +++ b/configs/ablations/ladder/battlesnake_llama_smoke.yaml @@ -23,8 +23,7 @@ player: step_limit: 10 # smoke override: stop after 10 steps (cost cap disabled in default.yaml) model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: - game_description: "BattleSnake ladder smoke over the llama endpoint." +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: - {agent: dummy, name: pinky, branch_init: human/moxuz/pinky-snek} # simple heuristic (port) - {agent: dummy, name: tr8r, branch_init: human/noahspriggs/tr-8r} # 2016 winner (port) diff --git a/configs/ablations/ladder/corewar.yaml b/configs/ablations/ladder/corewar.yaml index e4c9b980..14e3150e 100644 --- a/configs/ablations/ladder/corewar.yaml +++ b/configs/ablations/ladder/corewar.yaml @@ -16,7 +16,5 @@ player: temperature: 0.2 max_tokens: 4096 push: True -prompts: - game_description: |- - Core War ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml b/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml index 197da02a..bda7379a 100644 --- a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml @@ -14,7 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gemini_3_5_flash.yaml push: True -prompts: - game_description: |- - Core War ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__gpt_5_5.yaml b/configs/ablations/ladder/corewar__gpt_5_5.yaml index 0e9ae90d..80e012c6 100644 --- a/configs/ablations/ladder/corewar__gpt_5_5.yaml +++ b/configs/ablations/ladder/corewar__gpt_5_5.yaml @@ -14,7 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gpt_5_5.yaml push: True -prompts: - game_description: |- - Core War ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__opus_4_7.yaml b/configs/ablations/ladder/corewar__opus_4_7.yaml index f6b66817..e332b216 100644 --- a/configs/ablations/ladder/corewar__opus_4_7.yaml +++ b/configs/ablations/ladder/corewar__opus_4_7.yaml @@ -14,7 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_7.yaml push: True -prompts: - game_description: |- - Core War ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__opus_4_8.yaml b/configs/ablations/ladder/corewar__opus_4_8.yaml index eee2d50f..3023294f 100644 --- a/configs/ablations/ladder/corewar__opus_4_8.yaml +++ b/configs/ablations/ladder/corewar__opus_4_8.yaml @@ -14,7 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: - game_description: |- - Core War ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__sonnet_5.yaml b/configs/ablations/ladder/corewar__sonnet_5.yaml index c06b95ef..0d20d4cf 100644 --- a/configs/ablations/ladder/corewar__sonnet_5.yaml +++ b/configs/ablations/ladder/corewar__sonnet_5.yaml @@ -14,7 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_sonnet_5.yaml push: True -prompts: - game_description: |- - Core War ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/ladder_prompt.yaml b/configs/ablations/ladder/ladder_prompt.yaml new file mode 100644 index 00000000..9883acb2 --- /dev/null +++ b/configs/ablations/ladder/ladder_prompt.yaml @@ -0,0 +1,17 @@ +# Shared task instructions for a model climbing a CC:Ladder run (all arenas). Each ladder run +# config pulls this in on its `prompts:` line, so the framing lives in one place. Uses vars the +# ladder already provides: player_id, arena_description, rounds, round, working_dir. +# Deliberately says nothing about ladders/rungs/advancement — just: write code to beat one opponent. +# NOTE: keep the include-directive token out of these comments; the resolver matches it on any line. +game_description: |- + You are a software developer ({{player_id}}) competing in a coding game. You are matched against a + single opponent, and your job is to write and improve the code for your bot so that it defeats theirs. + + {{arena_description}} + + You face this opponent over {{rounds}} rounds. Each round you edit your bot's code in {{working_dir}}; + when you submit, the two bots play a full match and the result is recorded. This is round {{round}} — + review how earlier rounds went (past match logs are in `/logs/`) and make your bot stronger. + + Your goal is to beat the opponent. The game's rules and your bot's entry point are documented in the + codebase (`docs/`). diff --git a/configs/ablations/ladder/robotrumble.yaml b/configs/ablations/ladder/robotrumble.yaml index abf47930..2adef24a 100644 --- a/configs/ablations/ladder/robotrumble.yaml +++ b/configs/ablations/ladder/robotrumble.yaml @@ -18,7 +18,5 @@ player: temperature: 0.2 max_tokens: 4096 push: True -prompts: - game_description: |- - RobotRumble ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml b/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml index 7ce917e2..bf379e8b 100644 --- a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml +++ b/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml @@ -16,7 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gemini_3_5_flash.yaml push: True -prompts: - game_description: |- - RobotRumble ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml b/configs/ablations/ladder/robotrumble__gpt_5_5.yaml index 81005c0c..25e26abd 100644 --- a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml +++ b/configs/ablations/ladder/robotrumble__gpt_5_5.yaml @@ -16,7 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gpt_5_5.yaml push: True -prompts: - game_description: |- - RobotRumble ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__opus_4_7.yaml b/configs/ablations/ladder/robotrumble__opus_4_7.yaml index df94ac56..6aeb422f 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_7.yaml +++ b/configs/ablations/ladder/robotrumble__opus_4_7.yaml @@ -16,7 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_7.yaml push: True -prompts: - game_description: |- - RobotRumble ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__opus_4_8.yaml b/configs/ablations/ladder/robotrumble__opus_4_8.yaml index 44c2b7d0..fef17c96 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_8.yaml +++ b/configs/ablations/ladder/robotrumble__opus_4_8.yaml @@ -16,7 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: - game_description: |- - RobotRumble ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__sonnet_5.yaml b/configs/ablations/ladder/robotrumble__sonnet_5.yaml index b0931cb8..b0a96049 100644 --- a/configs/ablations/ladder/robotrumble__sonnet_5.yaml +++ b/configs/ablations/ladder/robotrumble__sonnet_5.yaml @@ -16,7 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_sonnet_5.yaml push: True -prompts: - game_description: |- - RobotRumble ladder +prompts: !include ablations/ladder/ladder_prompt.yaml ladder: !include ablations/ladder/rungs/robotrumble.yaml From 067378e337a2d5c0acd23daeda71084677568be9 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 03:00:57 +0000 Subject: [PATCH 12/19] Strip explanatory comments from ladder/agent config additions --- codeclash/agents/utils.py | 2 -- codeclash/arenas/battlesnake/battlesnake.py | 2 -- configs/ablations/ladder/ladder_prompt.yaml | 5 ----- configs/ablations/ladder/ladder_rules.yaml | 7 ++----- configs/mini/default.yaml | 3 --- 5 files changed, 2 insertions(+), 17 deletions(-) diff --git a/codeclash/agents/utils.py b/codeclash/agents/utils.py index 080d2d03..2f2aef7a 100644 --- a/codeclash/agents/utils.py +++ b/codeclash/agents/utils.py @@ -26,8 +26,6 @@ class GameContext(BaseModel): round: int rounds: int working_dir: str - # Arena's static description (CodeArena.description), exposed to prompt templates as - # {{arena_description}}. Optional so non-pvp GameContext construction sites keep working. arena_description: str = "" def _render_prompt_templates(self) -> dict: diff --git a/codeclash/arenas/battlesnake/battlesnake.py b/codeclash/arenas/battlesnake/battlesnake.py index 3e1b75a1..91ac964a 100644 --- a/codeclash/arenas/battlesnake/battlesnake.py +++ b/codeclash/arenas/battlesnake/battlesnake.py @@ -203,8 +203,6 @@ def validate_code(self, agent: Player) -> tuple[bool, str | None]: error_msg.append(f"There should be a `{func}` function implemented in `{self.submission}`") if len(error_msg) > 0: return False, "\n".join(error_msg + ["Don't change the function signatures!"]) - - # `python main.py` boots the server via the __main__ entrypoint. if "__main__" not in bot_content or "run_server" not in bot_content: return False, ( f"`{self.submission}` must keep its server entrypoint so the bot starts: the " diff --git a/configs/ablations/ladder/ladder_prompt.yaml b/configs/ablations/ladder/ladder_prompt.yaml index 9883acb2..e1442060 100644 --- a/configs/ablations/ladder/ladder_prompt.yaml +++ b/configs/ablations/ladder/ladder_prompt.yaml @@ -1,8 +1,3 @@ -# Shared task instructions for a model climbing a CC:Ladder run (all arenas). Each ladder run -# config pulls this in on its `prompts:` line, so the framing lives in one place. Uses vars the -# ladder already provides: player_id, arena_description, rounds, round, working_dir. -# Deliberately says nothing about ladders/rungs/advancement — just: write code to beat one opponent. -# NOTE: keep the include-directive token out of these comments; the resolver matches it on any line. game_description: |- You are a software developer ({{player_id}}) competing in a coding game. You are matched against a single opponent, and your job is to write and improve the code for your bot so that it defeats theirs. diff --git a/configs/ablations/ladder/ladder_rules.yaml b/configs/ablations/ladder/ladder_rules.yaml index b34226c3..eed3f2e9 100644 --- a/configs/ablations/ladder/ladder_rules.yaml +++ b/configs/ablations/ladder/ladder_rules.yaml @@ -1,5 +1,2 @@ -# Shared advancement rule for every CC:Ladder run config. Each [__].yaml pulls -# this in on its `ladder_rules:` line, so the win condition stays consistent across all -# arenas/models in one place. -min_round_wins: 2 # whole number of agent rounds to win to advance (1..tournament.rounds) -win_last_k: 0 # must win the last K rounds (0 = off; must be <= min_round_wins) +min_round_wins: 2 +win_last_k: 0 diff --git a/configs/mini/default.yaml b/configs/mini/default.yaml index 604057ff..24420ed0 100644 --- a/configs/mini/default.yaml +++ b/configs/mini/default.yaml @@ -102,7 +102,4 @@ instance_template: | You cannot continue working in any way on this task after submitting. step_limit: 30 cost_limit: 0 -# Global observation format for every model/tournament/arena. ClashAgent pushes this onto the -# model config (mini-swe-agent renders observations model-side). The leading banner surfaces the -# per-round step budget so the model can pace itself; the rest is mini's default observation body. observation_template: "[Step {{n_model_calls}}/{{step_limit}} used - {{step_limit - n_model_calls}} left]\n{% if output.exception_info %}{{output.exception_info}}\n{% endif %}{{output.returncode}}\n\n{{output.output}}" From 4cebcdc750e6bbaa56c0e6a19a7326d679cb2506 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 03:05:09 +0000 Subject: [PATCH 13/19] Fix pre-commit --- codeclash/agents/minisweagent.py | 1 + codeclash/cli/ladder.py | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/codeclash/agents/minisweagent.py b/codeclash/agents/minisweagent.py index 320e94bc..fd3d8d79 100644 --- a/codeclash/agents/minisweagent.py +++ b/codeclash/agents/minisweagent.py @@ -20,6 +20,7 @@ class ClashAgentConfig(AgentConfig): """`AgentConfig` plus an optional global observation-format override.""" + observation_template: str | None = None diff --git a/codeclash/cli/ladder.py b/codeclash/cli/ladder.py index edd1c7e6..77df7ff2 100644 --- a/codeclash/cli/ladder.py +++ b/codeclash/cli/ladder.py @@ -46,9 +46,7 @@ def _resolve_ladder_rules(ladder_rules: dict, rounds: int) -> tuple[int, int]: typer.echo(f"ladder_rules.min_round_wins must be an integer, got {min_round_wins!r}.") raise typer.Exit(1) if not 1 <= min_round_wins <= rounds: - typer.echo( - f"ladder_rules.min_round_wins must be in [1, {rounds}] (tournament.rounds), got {min_round_wins}." - ) + typer.echo(f"ladder_rules.min_round_wins must be in [1, {rounds}] (tournament.rounds), got {min_round_wins}.") raise typer.Exit(1) # win_last_k: number of trailing rounds the player must win (1 == just the final round, 0 == disabled). From e7889bd94ca8ccce0f543602d2589701e051c243 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 03:15:09 +0000 Subject: [PATCH 14/19] Move observation_template from agent config into model configs --- configs/mini/default.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/mini/default.yaml b/configs/mini/default.yaml index 24420ed0..5cb1fe19 100644 --- a/configs/mini/default.yaml +++ b/configs/mini/default.yaml @@ -102,4 +102,3 @@ instance_template: | You cannot continue working in any way on this task after submitting. step_limit: 30 cost_limit: 0 -observation_template: "[Step {{n_model_calls}}/{{step_limit}} used - {{step_limit - n_model_calls}} left]\n{% if output.exception_info %}{{output.exception_info}}\n{% endif %}{{output.returncode}}\n\n{{output.output}}" From 2a071b17e23f5f413d519e369c3c47e3afddff75 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 03:49:39 +0000 Subject: [PATCH 15/19] Reorganize configs: main->pvp, ladder out of ablations, models.yaml->mini/model_roster.yaml --- codeclash/agents/mini_anthropic_model.py | 2 +- codeclash/analysis/code_evolve/main.py | 2 +- codeclash/cli/ladder.py | 2 +- codeclash/utils/generate_confs.py | 8 ++++---- codeclash/viewer/static/js/picker.js | 2 +- configs/{ablations => }/ladder/README.md | 4 ++-- configs/{ablations => }/ladder/battlesnake.yaml | 8 ++++---- .../ladder/battlesnake__gemini_3_5_flash.yaml | 8 ++++---- configs/{ablations => }/ladder/battlesnake__gpt_5_5.yaml | 8 ++++---- configs/{ablations => }/ladder/battlesnake__opus_4_7.yaml | 8 ++++---- configs/{ablations => }/ladder/battlesnake__opus_4_8.yaml | 8 ++++---- configs/{ablations => }/ladder/battlesnake__sonnet_5.yaml | 8 ++++---- .../{ablations => }/ladder/battlesnake_llama_smoke.yaml | 6 +++--- configs/{ablations => }/ladder/corewar.yaml | 6 +++--- .../{ablations => }/ladder/corewar__gemini_3_5_flash.yaml | 8 ++++---- configs/{ablations => }/ladder/corewar__gpt_5_5.yaml | 8 ++++---- configs/{ablations => }/ladder/corewar__opus_4_7.yaml | 8 ++++---- configs/{ablations => }/ladder/corewar__opus_4_8.yaml | 8 ++++---- configs/{ablations => }/ladder/corewar__sonnet_5.yaml | 8 ++++---- configs/{ablations => }/ladder/ladder_prompt.yaml | 0 configs/{ablations => }/ladder/ladder_rules.yaml | 0 configs/{ablations => }/ladder/make_battlesnake.yaml | 2 +- configs/{ablations => }/ladder/make_corewar.yaml | 0 configs/{ablations => }/ladder/make_robotrumble.yaml | 0 configs/{ablations => }/ladder/robotrumble.yaml | 6 +++--- .../ladder/robotrumble__gemini_3_5_flash.yaml | 8 ++++---- configs/{ablations => }/ladder/robotrumble__gpt_5_5.yaml | 8 ++++---- configs/{ablations => }/ladder/robotrumble__opus_4_7.yaml | 8 ++++---- configs/{ablations => }/ladder/robotrumble__opus_4_8.yaml | 8 ++++---- configs/{ablations => }/ladder/robotrumble__sonnet_5.yaml | 8 ++++---- configs/{ablations => }/ladder/rungs/battlesnake.yaml | 0 configs/{ablations => }/ladder/rungs/corewar.yaml | 0 configs/{ablations => }/ladder/rungs/robotrumble.yaml | 0 configs/{models.yaml => mini/model_roster.yaml} | 0 ...-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml | 0 ...ude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml | 0 ..._claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml | 0 ...nake__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml | 0 ...e-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml | 0 ...leSnake__claude-sonnet-4-20250514__o3__r15__s1000.yaml | 0 ...20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...e-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml | 0 ...laude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml | 0 ...ke__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml | 0 ...sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml | 0 ...Snake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml | 0 ...20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...ttleSnake__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml | 0 .../BattleSnake__gemini-2.5-pro__gpt-5__r15__s1000.yaml | 0 ...ake__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml | 0 .../BattleSnake__gemini-2.5-pro__o3__r15__s1000.yaml | 0 ...-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...leSnake__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml | 0 .../BattleSnake__gpt-5-mini__o3__r15__s1000.yaml | 0 ...t-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 .../BattleSnake__gpt-5__gpt-5-mini__r15__s1000.yaml | 0 .../BattleSnake__gpt-5__grok-code-fast-1__r15__s1000.yaml | 0 .../{main => pvp}/BattleSnake__gpt-5__o3__r15__s1000.yaml | 0 ...e__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 .../BattleSnake__grok-code-fast-1__o3__r15__s1000.yaml | 0 ...e-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...nake__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml | 0 ...ude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml | 0 ..._claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml | 0 ...eWar__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml | 0 ...e-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml | 0 ...CoreWar__claude-sonnet-4-20250514__o3__r15__s1000.yaml | 0 ...20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...e-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml | 0 ...laude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml | 0 ...ar__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml | 0 ...sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml | 0 ...reWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml | 0 ...20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 .../CoreWar__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml | 0 .../CoreWar__gemini-2.5-pro__gpt-5__r15__s1000.yaml | 0 ...War__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml | 0 .../CoreWar__gemini-2.5-pro__o3__r15__s1000.yaml | 0 ...-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...CoreWar__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml | 0 .../CoreWar__gpt-5-mini__o3__r15__s1000.yaml | 0 ...t-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 .../CoreWar__gpt-5__gpt-5-mini__r15__s1000.yaml | 0 .../CoreWar__gpt-5__grok-code-fast-1__r15__s1000.yaml | 0 configs/{main => pvp}/CoreWar__gpt-5__o3__r15__s1000.yaml | 0 ...r__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 .../CoreWar__grok-code-fast-1__o3__r15__s1000.yaml | 0 ...e-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...eWar__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml | 0 ...4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml | 0 ...aude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml | 0 ...__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml | 0 ...alite__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml | 0 ...de-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml | 0 .../Halite__claude-sonnet-4-20250514__o3__r15__s250.yaml | 0 ...-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...de-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml | 0 ...claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml | 0 ...ite__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml | 0 ...-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml | 0 ...Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml | 0 ...-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../Halite__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml | 0 .../Halite__gemini-2.5-pro__gpt-5__r15__s250.yaml | 0 ...lite__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml | 0 .../Halite__gemini-2.5-pro__o3__r15__s250.yaml | 0 ...i-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../Halite__gpt-5-mini__grok-code-fast-1__r15__s250.yaml | 0 .../{main => pvp}/Halite__gpt-5-mini__o3__r15__s250.yaml | 0 ...pt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../Halite__gpt-5__gpt-5-mini__r15__s250.yaml | 0 .../Halite__gpt-5__grok-code-fast-1__r15__s250.yaml | 0 configs/{main => pvp}/Halite__gpt-5__o3__r15__s250.yaml | 0 ...te__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../Halite__grok-code-fast-1__o3__r15__s250.yaml | 0 ...de-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...alite__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...4-20250514__claude-sonnet-4-5-20250929__r15__s100.yaml | 0 ...aude-sonnet-4-20250514__gemini-2.5-pro__r15__s100.yaml | 0 ...__claude-sonnet-4-20250514__gpt-5-mini__r15__s100.yaml | 0 ...Bench__claude-sonnet-4-20250514__gpt-5__r15__s100.yaml | 0 ...de-sonnet-4-20250514__grok-code-fast-1__r15__s100.yaml | 0 ...skyBench__claude-sonnet-4-20250514__o3__r15__s100.yaml | 0 ...-20250514__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 ...de-sonnet-4-5-20250929__gemini-2.5-pro__r15__s100.yaml | 0 ...claude-sonnet-4-5-20250929__gpt-5-mini__r15__s100.yaml | 0 ...nch__claude-sonnet-4-5-20250929__gpt-5__r15__s100.yaml | 0 ...-sonnet-4-5-20250929__grok-code-fast-1__r15__s100.yaml | 0 ...yBench__claude-sonnet-4-5-20250929__o3__r15__s100.yaml | 0 ...-20250929__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 ...HuskyBench__gemini-2.5-pro__gpt-5-mini__r15__s100.yaml | 0 .../HuskyBench__gemini-2.5-pro__gpt-5__r15__s100.yaml | 0 ...ench__gemini-2.5-pro__grok-code-fast-1__r15__s100.yaml | 0 .../HuskyBench__gemini-2.5-pro__o3__r15__s100.yaml | 0 ...i-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 ...skyBench__gpt-5-mini__grok-code-fast-1__r15__s100.yaml | 0 .../HuskyBench__gpt-5-mini__o3__r15__s100.yaml | 0 ...pt-5-mini__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 .../HuskyBench__gpt-5__gpt-5-mini__r15__s100.yaml | 0 .../HuskyBench__gpt-5__grok-code-fast-1__r15__s100.yaml | 0 .../{main => pvp}/HuskyBench__gpt-5__o3__r15__s100.yaml | 0 ...ch__gpt-5__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 .../HuskyBench__grok-code-fast-1__o3__r15__s100.yaml | 0 ...de-fast-1__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 ...Bench__o3__qwen3-coder-plus-2025-09-23__r15__s100.yaml | 0 ...4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml | 0 ...aude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml | 0 ...__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml | 0 ...oCode__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml | 0 ...de-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml | 0 ...RoboCode__claude-sonnet-4-20250514__o3__r15__s250.yaml | 0 ...-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...de-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml | 0 ...claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml | 0 ...ode__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml | 0 ...-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml | 0 ...boCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml | 0 ...-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../RoboCode__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml | 0 .../RoboCode__gemini-2.5-pro__gpt-5__r15__s250.yaml | 0 ...Code__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml | 0 .../RoboCode__gemini-2.5-pro__o3__r15__s250.yaml | 0 ...i-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...RoboCode__gpt-5-mini__grok-code-fast-1__r15__s250.yaml | 0 .../RoboCode__gpt-5-mini__o3__r15__s250.yaml | 0 ...pt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../RoboCode__gpt-5__gpt-5-mini__r15__s250.yaml | 0 .../RoboCode__gpt-5__grok-code-fast-1__r15__s250.yaml | 0 configs/{main => pvp}/RoboCode__gpt-5__o3__r15__s250.yaml | 0 ...de__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../RoboCode__grok-code-fast-1__o3__r15__s250.yaml | 0 ...de-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...oCode__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml | 0 ...aude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml | 0 ...__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml | 0 ...umble__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml | 0 ...de-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml | 0 ...otRumble__claude-sonnet-4-20250514__o3__r15__s250.yaml | 0 ...-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...de-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml | 0 ...claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml | 0 ...ble__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml | 0 ...-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml | 0 ...Rumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml | 0 ...-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...obotRumble__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml | 0 .../RobotRumble__gemini-2.5-pro__gpt-5__r15__s250.yaml | 0 ...mble__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml | 0 .../RobotRumble__gemini-2.5-pro__o3__r15__s250.yaml | 0 ...i-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...otRumble__gpt-5-mini__grok-code-fast-1__r15__s250.yaml | 0 .../RobotRumble__gpt-5-mini__o3__r15__s250.yaml | 0 ...pt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../RobotRumble__gpt-5__gpt-5-mini__r15__s250.yaml | 0 .../RobotRumble__gpt-5__grok-code-fast-1__r15__s250.yaml | 0 .../{main => pvp}/RobotRumble__gpt-5__o3__r15__s250.yaml | 0 ...le__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 .../RobotRumble__grok-code-fast-1__o3__r15__s250.yaml | 0 ...de-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 ...umble__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml | 0 docs/quickstart.md | 4 ++-- docs/usage/tournaments.md | 6 +++--- scripts/run_multiple_pvp.sh | 2 +- 205 files changed, 90 insertions(+), 90 deletions(-) rename configs/{ablations => }/ladder/README.md (91%) rename configs/{ablations => }/ladder/battlesnake.yaml (78%) rename configs/{ablations => }/ladder/battlesnake__gemini_3_5_flash.yaml (61%) rename configs/{ablations => }/ladder/battlesnake__gpt_5_5.yaml (61%) rename configs/{ablations => }/ladder/battlesnake__opus_4_7.yaml (61%) rename configs/{ablations => }/ladder/battlesnake__opus_4_8.yaml (61%) rename configs/{ablations => }/ladder/battlesnake__sonnet_5.yaml (61%) rename configs/{ablations => }/ladder/battlesnake_llama_smoke.yaml (82%) rename configs/{ablations => }/ladder/corewar.yaml (68%) rename configs/{ablations => }/ladder/corewar__gemini_3_5_flash.yaml (57%) rename configs/{ablations => }/ladder/corewar__gpt_5_5.yaml (56%) rename configs/{ablations => }/ladder/corewar__opus_4_7.yaml (56%) rename configs/{ablations => }/ladder/corewar__opus_4_8.yaml (56%) rename configs/{ablations => }/ladder/corewar__sonnet_5.yaml (56%) rename configs/{ablations => }/ladder/ladder_prompt.yaml (100%) rename configs/{ablations => }/ladder/ladder_rules.yaml (100%) rename configs/{ablations => }/ladder/make_battlesnake.yaml (97%) rename configs/{ablations => }/ladder/make_corewar.yaml (100%) rename configs/{ablations => }/ladder/make_robotrumble.yaml (100%) rename configs/{ablations => }/ladder/robotrumble.yaml (69%) rename configs/{ablations => }/ladder/robotrumble__gemini_3_5_flash.yaml (59%) rename configs/{ablations => }/ladder/robotrumble__gpt_5_5.yaml (58%) rename configs/{ablations => }/ladder/robotrumble__opus_4_7.yaml (58%) rename configs/{ablations => }/ladder/robotrumble__opus_4_8.yaml (58%) rename configs/{ablations => }/ladder/robotrumble__sonnet_5.yaml (58%) rename configs/{ablations => }/ladder/rungs/battlesnake.yaml (100%) rename configs/{ablations => }/ladder/rungs/corewar.yaml (100%) rename configs/{ablations => }/ladder/rungs/robotrumble.yaml (100%) rename configs/{models.yaml => mini/model_roster.yaml} (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gemini-2.5-pro__gpt-5__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gemini-2.5-pro__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5-mini__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__grok-code-fast-1__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/BattleSnake__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gemini-2.5-pro__gpt-5__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gemini-2.5-pro__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5-mini__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5__gpt-5-mini__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5__grok-code-fast-1__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__grok-code-fast-1__o3__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/CoreWar__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gemini-2.5-pro__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gemini-2.5-pro__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5-mini__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5-mini__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__grok-code-fast-1__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/Halite__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__gpt-5-mini__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__gpt-5__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__grok-code-fast-1__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__o3__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-5-20250929__gpt-5__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-5-20250929__o3__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gemini-2.5-pro__gpt-5-mini__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gemini-2.5-pro__gpt-5__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gemini-2.5-pro__grok-code-fast-1__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gemini-2.5-pro__o3__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5-mini__grok-code-fast-1__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5-mini__o3__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5__gpt-5-mini__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5__grok-code-fast-1__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5__o3__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__gpt-5__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__grok-code-fast-1__o3__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/HuskyBench__o3__qwen3-coder-plus-2025-09-23__r15__s100.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gemini-2.5-pro__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gemini-2.5-pro__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5-mini__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5-mini__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__grok-code-fast-1__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RoboCode__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gemini-2.5-pro__gpt-5__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gemini-2.5-pro__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5-mini__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5-mini__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5__gpt-5-mini__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5__grok-code-fast-1__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__grok-code-fast-1__o3__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) rename configs/{main => pvp}/RobotRumble__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml (100%) diff --git a/codeclash/agents/mini_anthropic_model.py b/codeclash/agents/mini_anthropic_model.py index 9e6432f9..554fa984 100644 --- a/codeclash/agents/mini_anthropic_model.py +++ b/codeclash/agents/mini_anthropic_model.py @@ -11,7 +11,7 @@ `model_class: codeclash.agents.mini_anthropic_model.AnthropicModel` and provide the API key, base URL, and model name (see the `*_env` config fields, which keep endpoint-specific values in the environment rather than in committed configs). Requires the optional `anthropic` dependency -(`uv pip install -e '.[llama]'`). See configs/ablations/ladder/robotrumble_llama.yaml. +(`uv pip install -e '.[llama]'`). See configs/ladder/robotrumble_llama.yaml. """ import json diff --git a/codeclash/analysis/code_evolve/main.py b/codeclash/analysis/code_evolve/main.py index b749acd2..5504e389 100644 --- a/codeclash/analysis/code_evolve/main.py +++ b/codeclash/analysis/code_evolve/main.py @@ -18,7 +18,7 @@ from codeclash.arenas import ARENAS from codeclash.constants import LOCAL_LOG_DIR -MODELS_PATH = Path("configs/models.yaml") +MODELS_PATH = Path("configs/mini/model_roster.yaml") TARGET_ROUNDS = [1, 15, 5, 10] diff --git a/codeclash/cli/ladder.py b/codeclash/cli/ladder.py index 77df7ff2..e4807827 100644 --- a/codeclash/cli/ladder.py +++ b/codeclash/cli/ladder.py @@ -85,7 +85,7 @@ def make( ): """Build a ladder: run PvP tournaments across all pairs of players (for ranking). - [dim]• codeclash ladder make configs/ablations/ladder/make_battlesnake.yaml[/dim] + [dim]• codeclash ladder make configs/ladder/make_battlesnake.yaml[/dim] """ yaml_content = config_path.read_text() preprocessed_yaml = resolve_includes(yaml_content, base_dir=CONFIG_DIR) diff --git a/codeclash/utils/generate_confs.py b/codeclash/utils/generate_confs.py index 6cc2b109..3fb9544c 100644 --- a/codeclash/utils/generate_confs.py +++ b/codeclash/utils/generate_confs.py @@ -3,14 +3,14 @@ Each configuration file specifies a tournament between two models in a given arena, including the number of rounds and simulations per round. The configurations are saved -as YAML files in the specified output directory (default: configs/main/). +as YAML files in the specified output directory (default: configs/pvp/). Also generates a tracking JSON file at configs/tracker.json to keep track of the number of tournaments and rounds played for each pair of models in each arena. Usage: -python codeclash/utils/generate_confs.py -m configs/models.yaml -r 15 -s 1000 +python codeclash/utils/generate_confs.py -m configs/mini/model_roster.yaml -r 15 -s 1000 """ import argparse @@ -184,7 +184,7 @@ def main(models, arenas, rounds: int, simulations: int, record_ratio: float, out "-m", "--models", type=str, - default="configs/models.yaml", + default="configs/mini/model_roster.yaml", help="Path to model configurations.", ) parser.add_argument( @@ -218,7 +218,7 @@ def main(models, arenas, rounds: int, simulations: int, record_ratio: float, out "-o", "--output", type=Path, - default=Path("configs/main/"), + default=Path("configs/pvp/"), help="Output directory for configuration files (default: main/).", ) args = parser.parse_args() diff --git a/codeclash/viewer/static/js/picker.js b/codeclash/viewer/static/js/picker.js index 25ada9bc..1aaff0c5 100644 --- a/codeclash/viewer/static/js/picker.js +++ b/codeclash/viewer/static/js/picker.js @@ -503,7 +503,7 @@ async function fillTextareaWithAWSSubmitCommands() { // Format output as AWS submit commands const commands = successfulResults.map( (result) => - `aws/run_job.py -- aws/docker_and_sync.sh codeclash run configs/main/${result.config_name}`, + `aws/run_job.py -- aws/docker_and_sync.sh codeclash run configs/pvp/${result.config_name}`, ); textarea.value = commands.join("\n"); diff --git a/configs/ablations/ladder/README.md b/configs/ladder/README.md similarity index 91% rename from configs/ablations/ladder/README.md rename to configs/ladder/README.md index 02b37976..48895252 100644 --- a/configs/ablations/ladder/README.md +++ b/configs/ladder/README.md @@ -5,7 +5,7 @@ For a more static and hill-climb-able version of CodeClash, we introduce CC:Ladd For instance, for RobotRumble, we created a ladder by doing the following steps: 1. From the online [leaderboard](https://robotrumble.org/boards/2), we manually crawled all open source, published bots and pushed them as branches to the [CC:RobotRumble](https://github.com/CodeClash-ai/RobotRumble) repository. 2. We then created the `robotrumble.yaml` file in this folder. -3. Next, from the repository root, we run `uv run codeclash ladder run configs/ablations/ladder/robotrumble.yaml`, which runs PvP Tournaments against all pairs of branches. +3. Next, from the repository root, we run `uv run codeclash ladder run configs/ladder/robotrumble.yaml`, which runs PvP Tournaments against all pairs of branches. 4. From these logs, we then calculate win rate to rank all models. You can follow these steps to create your own "CC:" ladder. @@ -19,7 +19,7 @@ Each arena has a few kinds of config in this folder: - `make_.yaml` — the round-robin used to **build** the ladder (`ladder make`), running PvP tournaments across all pairs of human bots to rank them. - `.yaml` — the **run** config (`ladder run`): a climber ascends the ranked ladder rung by rung until it loses. - `__.yaml` — per-model run configs (e.g. `battlesnake__opus_4_8.yaml`) that swap in a specific model via `model: !include mini/models/llama_.yaml`. -- `rungs/.yaml` — the ranked opponent list (worst first, strongest last), shared by both `.yaml` and every `__.yaml` through `ladder: !include ablations/ladder/rungs/.yaml`. Edit the ladder in this one file and every config for that arena picks it up. +- `rungs/.yaml` — the ranked opponent list (worst first, strongest last), shared by both `.yaml` and every `__.yaml` through `ladder: !include ladder/rungs/.yaml`. Edit the ladder in this one file and every config for that arena picks it up. ## Ladder advancement rule (`ladder_rules`) diff --git a/configs/ablations/ladder/battlesnake.yaml b/configs/ladder/battlesnake.yaml similarity index 78% rename from configs/ablations/ladder/battlesnake.yaml rename to configs/ladder/battlesnake.yaml index 75a30c90..7468756b 100644 --- a/configs/ablations/ladder/battlesnake.yaml +++ b/configs/ladder/battlesnake.yaml @@ -1,10 +1,10 @@ # CC:Ladder for BattleSnake — the ranked ladder of human bots (worst opponent first, # strongest last), derived from the round-robin in make_battlesnake.yaml # (Bradley-Terry/Elo over 1225 pairwise tournaments). An LM climber ascends rung by -# rung until it loses. Run: uv run codeclash ladder run configs/ablations/ladder/battlesnake.yaml +# rung until it loses. Run: uv run codeclash ladder run configs/ladder/battlesnake.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 @@ -24,5 +24,5 @@ player: temperature: 0.2 max_tokens: 4096 push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/battlesnake.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml b/configs/ladder/battlesnake__gemini_3_5_flash.yaml similarity index 61% rename from configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml rename to configs/ladder/battlesnake__gemini_3_5_flash.yaml index 1c59336f..4f3cdd3d 100644 --- a/configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml +++ b/configs/ladder/battlesnake__gemini_3_5_flash.yaml @@ -1,8 +1,8 @@ # BattleSnake ladder climbed by gemini-3-5-flash. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/battlesnake__gemini_3_5_flash.yaml +# uv run codeclash ladder run configs/ladder/battlesnake__gemini_3_5_flash.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 @@ -18,5 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gemini_3_5_flash.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/battlesnake.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml b/configs/ladder/battlesnake__gpt_5_5.yaml similarity index 61% rename from configs/ablations/ladder/battlesnake__gpt_5_5.yaml rename to configs/ladder/battlesnake__gpt_5_5.yaml index 2aef4961..b18970ff 100644 --- a/configs/ablations/ladder/battlesnake__gpt_5_5.yaml +++ b/configs/ladder/battlesnake__gpt_5_5.yaml @@ -1,8 +1,8 @@ # BattleSnake ladder climbed by gpt-5-5. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/battlesnake__gpt_5_5.yaml +# uv run codeclash ladder run configs/ladder/battlesnake__gpt_5_5.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 @@ -18,5 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gpt_5_5.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/battlesnake.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__opus_4_7.yaml b/configs/ladder/battlesnake__opus_4_7.yaml similarity index 61% rename from configs/ablations/ladder/battlesnake__opus_4_7.yaml rename to configs/ladder/battlesnake__opus_4_7.yaml index 194b5671..f3161f5c 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_7.yaml +++ b/configs/ladder/battlesnake__opus_4_7.yaml @@ -1,8 +1,8 @@ # BattleSnake ladder climbed by opus-4-7. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/battlesnake__opus_4_7.yaml +# uv run codeclash ladder run configs/ladder/battlesnake__opus_4_7.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 @@ -18,5 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_7.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/battlesnake.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__opus_4_8.yaml b/configs/ladder/battlesnake__opus_4_8.yaml similarity index 61% rename from configs/ablations/ladder/battlesnake__opus_4_8.yaml rename to configs/ladder/battlesnake__opus_4_8.yaml index 897209fa..1f6d5c35 100644 --- a/configs/ablations/ladder/battlesnake__opus_4_8.yaml +++ b/configs/ladder/battlesnake__opus_4_8.yaml @@ -1,8 +1,8 @@ # BattleSnake ladder climbed by opus-4-8. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/battlesnake__opus_4_8.yaml +# uv run codeclash ladder run configs/ladder/battlesnake__opus_4_8.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 @@ -18,5 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/battlesnake.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake__sonnet_5.yaml b/configs/ladder/battlesnake__sonnet_5.yaml similarity index 61% rename from configs/ablations/ladder/battlesnake__sonnet_5.yaml rename to configs/ladder/battlesnake__sonnet_5.yaml index 87388a53..648475fe 100644 --- a/configs/ablations/ladder/battlesnake__sonnet_5.yaml +++ b/configs/ladder/battlesnake__sonnet_5.yaml @@ -1,8 +1,8 @@ # BattleSnake ladder climbed by sonnet-5. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/battlesnake__sonnet_5.yaml +# uv run codeclash ladder run configs/ladder/battlesnake__sonnet_5.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 250 @@ -18,5 +18,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_sonnet_5.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/battlesnake.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/battlesnake_llama_smoke.yaml b/configs/ladder/battlesnake_llama_smoke.yaml similarity index 82% rename from configs/ablations/ladder/battlesnake_llama_smoke.yaml rename to configs/ladder/battlesnake_llama_smoke.yaml index 564f75e9..d5f9db56 100644 --- a/configs/ablations/ladder/battlesnake_llama_smoke.yaml +++ b/configs/ladder/battlesnake_llama_smoke.yaml @@ -2,10 +2,10 @@ # Opus 4.8 (native Anthropic API via AnthropicModel) climbs a 2-rung BattleSnake ladder. # 2 rounds, 10 sims — just enough to confirm the model authenticates, caches, and edits code. # Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/battlesnake_llama_smoke.yaml -c +# uv run codeclash ladder run configs/ladder/battlesnake_llama_smoke.yaml -c tournament: rounds: 2 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: BattleSnake sims_per_round: 10 @@ -23,7 +23,7 @@ player: step_limit: 10 # smoke override: stop after 10 steps (cost cap disabled in default.yaml) model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml +prompts: !include ladder/ladder_prompt.yaml ladder: - {agent: dummy, name: pinky, branch_init: human/moxuz/pinky-snek} # simple heuristic (port) - {agent: dummy, name: tr8r, branch_init: human/noahspriggs/tr-8r} # 2016 winner (port) diff --git a/configs/ablations/ladder/corewar.yaml b/configs/ladder/corewar.yaml similarity index 68% rename from configs/ablations/ladder/corewar.yaml rename to configs/ladder/corewar.yaml index 14e3150e..ae6760c1 100644 --- a/configs/ablations/ladder/corewar.yaml +++ b/configs/ladder/corewar.yaml @@ -1,6 +1,6 @@ tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 @@ -16,5 +16,5 @@ player: temperature: 0.2 max_tokens: 4096 push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/corewar.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml b/configs/ladder/corewar__gemini_3_5_flash.yaml similarity index 57% rename from configs/ablations/ladder/corewar__gemini_3_5_flash.yaml rename to configs/ladder/corewar__gemini_3_5_flash.yaml index bda7379a..3a53078c 100644 --- a/configs/ablations/ladder/corewar__gemini_3_5_flash.yaml +++ b/configs/ladder/corewar__gemini_3_5_flash.yaml @@ -1,8 +1,8 @@ # CoreWar ladder climbed by gemini-3-5-flash. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/corewar__gemini_3_5_flash.yaml +# uv run codeclash ladder run configs/ladder/corewar__gemini_3_5_flash.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 @@ -14,5 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gemini_3_5_flash.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/corewar.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__gpt_5_5.yaml b/configs/ladder/corewar__gpt_5_5.yaml similarity index 56% rename from configs/ablations/ladder/corewar__gpt_5_5.yaml rename to configs/ladder/corewar__gpt_5_5.yaml index 80e012c6..673fefdc 100644 --- a/configs/ablations/ladder/corewar__gpt_5_5.yaml +++ b/configs/ladder/corewar__gpt_5_5.yaml @@ -1,8 +1,8 @@ # CoreWar ladder climbed by gpt-5-5. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/corewar__gpt_5_5.yaml +# uv run codeclash ladder run configs/ladder/corewar__gpt_5_5.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 @@ -14,5 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gpt_5_5.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/corewar.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__opus_4_7.yaml b/configs/ladder/corewar__opus_4_7.yaml similarity index 56% rename from configs/ablations/ladder/corewar__opus_4_7.yaml rename to configs/ladder/corewar__opus_4_7.yaml index e332b216..82c362c7 100644 --- a/configs/ablations/ladder/corewar__opus_4_7.yaml +++ b/configs/ladder/corewar__opus_4_7.yaml @@ -1,8 +1,8 @@ # CoreWar ladder climbed by opus-4-7. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/corewar__opus_4_7.yaml +# uv run codeclash ladder run configs/ladder/corewar__opus_4_7.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 @@ -14,5 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_7.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/corewar.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__opus_4_8.yaml b/configs/ladder/corewar__opus_4_8.yaml similarity index 56% rename from configs/ablations/ladder/corewar__opus_4_8.yaml rename to configs/ladder/corewar__opus_4_8.yaml index 3023294f..3a4fc8ec 100644 --- a/configs/ablations/ladder/corewar__opus_4_8.yaml +++ b/configs/ladder/corewar__opus_4_8.yaml @@ -1,8 +1,8 @@ # CoreWar ladder climbed by opus-4-8. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/corewar__opus_4_8.yaml +# uv run codeclash ladder run configs/ladder/corewar__opus_4_8.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 @@ -14,5 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/corewar.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/corewar__sonnet_5.yaml b/configs/ladder/corewar__sonnet_5.yaml similarity index 56% rename from configs/ablations/ladder/corewar__sonnet_5.yaml rename to configs/ladder/corewar__sonnet_5.yaml index 0d20d4cf..30183f26 100644 --- a/configs/ablations/ladder/corewar__sonnet_5.yaml +++ b/configs/ladder/corewar__sonnet_5.yaml @@ -1,8 +1,8 @@ # CoreWar ladder climbed by sonnet-5. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/corewar__sonnet_5.yaml +# uv run codeclash ladder run configs/ladder/corewar__sonnet_5.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: CoreWar sims_per_round: 2000 @@ -14,5 +14,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_sonnet_5.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/corewar.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/ladder_prompt.yaml b/configs/ladder/ladder_prompt.yaml similarity index 100% rename from configs/ablations/ladder/ladder_prompt.yaml rename to configs/ladder/ladder_prompt.yaml diff --git a/configs/ablations/ladder/ladder_rules.yaml b/configs/ladder/ladder_rules.yaml similarity index 100% rename from configs/ablations/ladder/ladder_rules.yaml rename to configs/ladder/ladder_rules.yaml diff --git a/configs/ablations/ladder/make_battlesnake.yaml b/configs/ladder/make_battlesnake.yaml similarity index 97% rename from configs/ablations/ladder/make_battlesnake.yaml rename to configs/ladder/make_battlesnake.yaml index d71901ff..a8ba3b87 100644 --- a/configs/ablations/ladder/make_battlesnake.yaml +++ b/configs/ladder/make_battlesnake.yaml @@ -6,7 +6,7 @@ # 50 bots -> 50*49/2 = 1225 pairwise tournaments. # Excludes 4 compiled-language bots that can't build in-arena (snork/hettie/esproso/bobby-witt) # and bountysnake2017 (unreliable server). All bots live on CodeClash-ai/BattleSnake; Docker required. -# Run: uv run codeclash ladder make configs/ablations/ladder/make_battlesnake.yaml --workers 3 +# Run: uv run codeclash ladder make configs/ladder/make_battlesnake.yaml --workers 3 tournament: rounds: 0 diff --git a/configs/ablations/ladder/make_corewar.yaml b/configs/ladder/make_corewar.yaml similarity index 100% rename from configs/ablations/ladder/make_corewar.yaml rename to configs/ladder/make_corewar.yaml diff --git a/configs/ablations/ladder/make_robotrumble.yaml b/configs/ladder/make_robotrumble.yaml similarity index 100% rename from configs/ablations/ladder/make_robotrumble.yaml rename to configs/ladder/make_robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble.yaml b/configs/ladder/robotrumble.yaml similarity index 69% rename from configs/ablations/ladder/robotrumble.yaml rename to configs/ladder/robotrumble.yaml index 2adef24a..05f5a31e 100644 --- a/configs/ablations/ladder/robotrumble.yaml +++ b/configs/ladder/robotrumble.yaml @@ -1,6 +1,6 @@ tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 @@ -18,5 +18,5 @@ player: temperature: 0.2 max_tokens: 4096 push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/robotrumble.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml b/configs/ladder/robotrumble__gemini_3_5_flash.yaml similarity index 59% rename from configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml rename to configs/ladder/robotrumble__gemini_3_5_flash.yaml index bf379e8b..880427bb 100644 --- a/configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml +++ b/configs/ladder/robotrumble__gemini_3_5_flash.yaml @@ -1,8 +1,8 @@ # RobotRumble ladder climbed by gemini-3-5-flash. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/robotrumble__gemini_3_5_flash.yaml +# uv run codeclash ladder run configs/ladder/robotrumble__gemini_3_5_flash.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 @@ -16,5 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gemini_3_5_flash.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/robotrumble.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml b/configs/ladder/robotrumble__gpt_5_5.yaml similarity index 58% rename from configs/ablations/ladder/robotrumble__gpt_5_5.yaml rename to configs/ladder/robotrumble__gpt_5_5.yaml index 25e26abd..093412f7 100644 --- a/configs/ablations/ladder/robotrumble__gpt_5_5.yaml +++ b/configs/ladder/robotrumble__gpt_5_5.yaml @@ -1,8 +1,8 @@ # RobotRumble ladder climbed by gpt-5-5. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/robotrumble__gpt_5_5.yaml +# uv run codeclash ladder run configs/ladder/robotrumble__gpt_5_5.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 @@ -16,5 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_gpt_5_5.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/robotrumble.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__opus_4_7.yaml b/configs/ladder/robotrumble__opus_4_7.yaml similarity index 58% rename from configs/ablations/ladder/robotrumble__opus_4_7.yaml rename to configs/ladder/robotrumble__opus_4_7.yaml index 6aeb422f..73173368 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_7.yaml +++ b/configs/ladder/robotrumble__opus_4_7.yaml @@ -1,8 +1,8 @@ # RobotRumble ladder climbed by opus-4-7. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/robotrumble__opus_4_7.yaml +# uv run codeclash ladder run configs/ladder/robotrumble__opus_4_7.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 @@ -16,5 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_7.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/robotrumble.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__opus_4_8.yaml b/configs/ladder/robotrumble__opus_4_8.yaml similarity index 58% rename from configs/ablations/ladder/robotrumble__opus_4_8.yaml rename to configs/ladder/robotrumble__opus_4_8.yaml index fef17c96..41a6e0d6 100644 --- a/configs/ablations/ladder/robotrumble__opus_4_8.yaml +++ b/configs/ladder/robotrumble__opus_4_8.yaml @@ -1,8 +1,8 @@ # RobotRumble ladder climbed by opus-4-8. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/robotrumble__opus_4_8.yaml +# uv run codeclash ladder run configs/ladder/robotrumble__opus_4_8.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 @@ -16,5 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_opus_4_8.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/robotrumble.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/robotrumble__sonnet_5.yaml b/configs/ladder/robotrumble__sonnet_5.yaml similarity index 58% rename from configs/ablations/ladder/robotrumble__sonnet_5.yaml rename to configs/ladder/robotrumble__sonnet_5.yaml index b0a96049..1d08a2d1 100644 --- a/configs/ablations/ladder/robotrumble__sonnet_5.yaml +++ b/configs/ladder/robotrumble__sonnet_5.yaml @@ -1,8 +1,8 @@ # RobotRumble ladder climbed by sonnet-5. Requires LLAMA_API_KEY in .env. -# uv run codeclash ladder run configs/ablations/ladder/robotrumble__sonnet_5.yaml +# uv run codeclash ladder run configs/ladder/robotrumble__sonnet_5.yaml tournament: rounds: 5 -ladder_rules: !include ablations/ladder/ladder_rules.yaml +ladder_rules: !include ladder/ladder_rules.yaml game: name: RobotRumble sims_per_round: 250 @@ -16,5 +16,5 @@ player: agent: !include mini/default.yaml model: !include mini/models/llama_sonnet_5.yaml push: True -prompts: !include ablations/ladder/ladder_prompt.yaml -ladder: !include ablations/ladder/rungs/robotrumble.yaml +prompts: !include ladder/ladder_prompt.yaml +ladder: !include ladder/rungs/robotrumble.yaml diff --git a/configs/ablations/ladder/rungs/battlesnake.yaml b/configs/ladder/rungs/battlesnake.yaml similarity index 100% rename from configs/ablations/ladder/rungs/battlesnake.yaml rename to configs/ladder/rungs/battlesnake.yaml diff --git a/configs/ablations/ladder/rungs/corewar.yaml b/configs/ladder/rungs/corewar.yaml similarity index 100% rename from configs/ablations/ladder/rungs/corewar.yaml rename to configs/ladder/rungs/corewar.yaml diff --git a/configs/ablations/ladder/rungs/robotrumble.yaml b/configs/ladder/rungs/robotrumble.yaml similarity index 100% rename from configs/ablations/ladder/rungs/robotrumble.yaml rename to configs/ladder/rungs/robotrumble.yaml diff --git a/configs/models.yaml b/configs/mini/model_roster.yaml similarity index 100% rename from configs/models.yaml rename to configs/mini/model_roster.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__o3__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__o3__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__o3__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__o3__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml diff --git a/configs/main/BattleSnake__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml b/configs/pvp/BattleSnake__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/BattleSnake__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gemini-2.5-pro__gpt-5__r15__s1000.yaml b/configs/pvp/BattleSnake__gemini-2.5-pro__gpt-5__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gemini-2.5-pro__gpt-5__r15__s1000.yaml rename to configs/pvp/BattleSnake__gemini-2.5-pro__gpt-5__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/BattleSnake__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/BattleSnake__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gemini-2.5-pro__o3__r15__s1000.yaml b/configs/pvp/BattleSnake__gemini-2.5-pro__o3__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gemini-2.5-pro__o3__r15__s1000.yaml rename to configs/pvp/BattleSnake__gemini-2.5-pro__o3__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5-mini__o3__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5-mini__o3__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5-mini__o3__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5-mini__o3__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5__gpt-5-mini__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5__o3__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5__o3__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5__o3__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5__o3__r15__s1000.yaml diff --git a/configs/main/BattleSnake__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/BattleSnake__grok-code-fast-1__o3__r15__s1000.yaml b/configs/pvp/BattleSnake__grok-code-fast-1__o3__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__grok-code-fast-1__o3__r15__s1000.yaml rename to configs/pvp/BattleSnake__grok-code-fast-1__o3__r15__s1000.yaml diff --git a/configs/main/BattleSnake__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/BattleSnake__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/BattleSnake__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/BattleSnake__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/BattleSnake__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__gpt-5__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__o3__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__o3__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__o3__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__o3__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-5-20250929__gpt-5__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml diff --git a/configs/main/CoreWar__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml b/configs/pvp/CoreWar__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/CoreWar__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/CoreWar__gemini-2.5-pro__gpt-5__r15__s1000.yaml b/configs/pvp/CoreWar__gemini-2.5-pro__gpt-5__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gemini-2.5-pro__gpt-5__r15__s1000.yaml rename to configs/pvp/CoreWar__gemini-2.5-pro__gpt-5__r15__s1000.yaml diff --git a/configs/main/CoreWar__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/CoreWar__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/CoreWar__gemini-2.5-pro__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/CoreWar__gemini-2.5-pro__o3__r15__s1000.yaml b/configs/pvp/CoreWar__gemini-2.5-pro__o3__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gemini-2.5-pro__o3__r15__s1000.yaml rename to configs/pvp/CoreWar__gemini-2.5-pro__o3__r15__s1000.yaml diff --git a/configs/main/CoreWar__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5-mini__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5-mini__o3__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5-mini__o3__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5-mini__o3__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5-mini__o3__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5__gpt-5-mini__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5__gpt-5-mini__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5__gpt-5-mini__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5__gpt-5-mini__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5__grok-code-fast-1__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5__grok-code-fast-1__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5__grok-code-fast-1__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5__grok-code-fast-1__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5__o3__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5__o3__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5__o3__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5__o3__r15__s1000.yaml diff --git a/configs/main/CoreWar__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__gpt-5__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__grok-code-fast-1__o3__r15__s1000.yaml b/configs/pvp/CoreWar__grok-code-fast-1__o3__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__grok-code-fast-1__o3__r15__s1000.yaml rename to configs/pvp/CoreWar__grok-code-fast-1__o3__r15__s1000.yaml diff --git a/configs/main/CoreWar__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/CoreWar__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml b/configs/pvp/CoreWar__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml similarity index 100% rename from configs/main/CoreWar__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml rename to configs/pvp/CoreWar__o3__qwen3-coder-plus-2025-09-23__r15__s1000.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__o3__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__o3__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__o3__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__o3__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml diff --git a/configs/main/Halite__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/Halite__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml b/configs/pvp/Halite__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml rename to configs/pvp/Halite__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/Halite__gemini-2.5-pro__gpt-5__r15__s250.yaml b/configs/pvp/Halite__gemini-2.5-pro__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gemini-2.5-pro__gpt-5__r15__s250.yaml rename to configs/pvp/Halite__gemini-2.5-pro__gpt-5__r15__s250.yaml diff --git a/configs/main/Halite__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml b/configs/pvp/Halite__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/Halite__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/Halite__gemini-2.5-pro__o3__r15__s250.yaml b/configs/pvp/Halite__gemini-2.5-pro__o3__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gemini-2.5-pro__o3__r15__s250.yaml rename to configs/pvp/Halite__gemini-2.5-pro__o3__r15__s250.yaml diff --git a/configs/main/Halite__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5-mini__grok-code-fast-1__r15__s250.yaml b/configs/pvp/Halite__gpt-5-mini__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5-mini__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/Halite__gpt-5-mini__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5-mini__o3__r15__s250.yaml b/configs/pvp/Halite__gpt-5-mini__o3__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5-mini__o3__r15__s250.yaml rename to configs/pvp/Halite__gpt-5-mini__o3__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5__gpt-5-mini__r15__s250.yaml b/configs/pvp/Halite__gpt-5__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5__gpt-5-mini__r15__s250.yaml rename to configs/pvp/Halite__gpt-5__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5__grok-code-fast-1__r15__s250.yaml b/configs/pvp/Halite__gpt-5__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/Halite__gpt-5__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5__o3__r15__s250.yaml b/configs/pvp/Halite__gpt-5__o3__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5__o3__r15__s250.yaml rename to configs/pvp/Halite__gpt-5__o3__r15__s250.yaml diff --git a/configs/main/Halite__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/Halite__grok-code-fast-1__o3__r15__s250.yaml b/configs/pvp/Halite__grok-code-fast-1__o3__r15__s250.yaml similarity index 100% rename from configs/main/Halite__grok-code-fast-1__o3__r15__s250.yaml rename to configs/pvp/Halite__grok-code-fast-1__o3__r15__s250.yaml diff --git a/configs/main/Halite__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/Halite__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/Halite__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/Halite__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/Halite__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__gpt-5-mini__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__gpt-5-mini__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__gpt-5-mini__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__gpt-5-mini__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__gpt-5__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__gpt-5__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__gpt-5__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__gpt-5__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__grok-code-fast-1__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__grok-code-fast-1__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__grok-code-fast-1__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__grok-code-fast-1__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__o3__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__o3__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__o3__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__o3__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-5-20250929__gpt-5__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__gpt-5__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-5-20250929__gpt-5__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__gpt-5__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-5-20250929__o3__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__o3__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-5-20250929__o3__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__o3__r15__s100.yaml diff --git a/configs/main/HuskyBench__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/HuskyBench__gemini-2.5-pro__gpt-5-mini__r15__s100.yaml b/configs/pvp/HuskyBench__gemini-2.5-pro__gpt-5-mini__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gemini-2.5-pro__gpt-5-mini__r15__s100.yaml rename to configs/pvp/HuskyBench__gemini-2.5-pro__gpt-5-mini__r15__s100.yaml diff --git a/configs/main/HuskyBench__gemini-2.5-pro__gpt-5__r15__s100.yaml b/configs/pvp/HuskyBench__gemini-2.5-pro__gpt-5__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gemini-2.5-pro__gpt-5__r15__s100.yaml rename to configs/pvp/HuskyBench__gemini-2.5-pro__gpt-5__r15__s100.yaml diff --git a/configs/main/HuskyBench__gemini-2.5-pro__grok-code-fast-1__r15__s100.yaml b/configs/pvp/HuskyBench__gemini-2.5-pro__grok-code-fast-1__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gemini-2.5-pro__grok-code-fast-1__r15__s100.yaml rename to configs/pvp/HuskyBench__gemini-2.5-pro__grok-code-fast-1__r15__s100.yaml diff --git a/configs/main/HuskyBench__gemini-2.5-pro__o3__r15__s100.yaml b/configs/pvp/HuskyBench__gemini-2.5-pro__o3__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gemini-2.5-pro__o3__r15__s100.yaml rename to configs/pvp/HuskyBench__gemini-2.5-pro__o3__r15__s100.yaml diff --git a/configs/main/HuskyBench__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5-mini__grok-code-fast-1__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5-mini__grok-code-fast-1__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5-mini__grok-code-fast-1__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5-mini__grok-code-fast-1__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5-mini__o3__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5-mini__o3__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5-mini__o3__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5-mini__o3__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5__gpt-5-mini__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5__gpt-5-mini__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5__gpt-5-mini__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5__gpt-5-mini__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5__grok-code-fast-1__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5__grok-code-fast-1__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5__grok-code-fast-1__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5__grok-code-fast-1__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5__o3__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5__o3__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5__o3__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5__o3__r15__s100.yaml diff --git a/configs/main/HuskyBench__gpt-5__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__gpt-5__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__gpt-5__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__gpt-5__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/HuskyBench__grok-code-fast-1__o3__r15__s100.yaml b/configs/pvp/HuskyBench__grok-code-fast-1__o3__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__grok-code-fast-1__o3__r15__s100.yaml rename to configs/pvp/HuskyBench__grok-code-fast-1__o3__r15__s100.yaml diff --git a/configs/main/HuskyBench__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/HuskyBench__o3__qwen3-coder-plus-2025-09-23__r15__s100.yaml b/configs/pvp/HuskyBench__o3__qwen3-coder-plus-2025-09-23__r15__s100.yaml similarity index 100% rename from configs/main/HuskyBench__o3__qwen3-coder-plus-2025-09-23__r15__s100.yaml rename to configs/pvp/HuskyBench__o3__qwen3-coder-plus-2025-09-23__r15__s100.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__o3__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__o3__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__o3__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__o3__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml diff --git a/configs/main/RoboCode__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RoboCode__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml b/configs/pvp/RoboCode__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RoboCode__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RoboCode__gemini-2.5-pro__gpt-5__r15__s250.yaml b/configs/pvp/RoboCode__gemini-2.5-pro__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gemini-2.5-pro__gpt-5__r15__s250.yaml rename to configs/pvp/RoboCode__gemini-2.5-pro__gpt-5__r15__s250.yaml diff --git a/configs/main/RoboCode__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RoboCode__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RoboCode__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RoboCode__gemini-2.5-pro__o3__r15__s250.yaml b/configs/pvp/RoboCode__gemini-2.5-pro__o3__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gemini-2.5-pro__o3__r15__s250.yaml rename to configs/pvp/RoboCode__gemini-2.5-pro__o3__r15__s250.yaml diff --git a/configs/main/RoboCode__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5-mini__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5-mini__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5-mini__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5-mini__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5-mini__o3__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5-mini__o3__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5-mini__o3__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5-mini__o3__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5__gpt-5-mini__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5__o3__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5__o3__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5__o3__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5__o3__r15__s250.yaml diff --git a/configs/main/RoboCode__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RoboCode__grok-code-fast-1__o3__r15__s250.yaml b/configs/pvp/RoboCode__grok-code-fast-1__o3__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__grok-code-fast-1__o3__r15__s250.yaml rename to configs/pvp/RoboCode__grok-code-fast-1__o3__r15__s250.yaml diff --git a/configs/main/RoboCode__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RoboCode__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RoboCode__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RoboCode__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RoboCode__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__claude-sonnet-4-5-20250929__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__gemini-2.5-pro__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__gpt-5__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__o3__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__o3__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__o3__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__o3__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-20250514__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__gemini-2.5-pro__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__gpt-5__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml diff --git a/configs/main/RobotRumble__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml b/configs/pvp/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RobotRumble__gemini-2.5-pro__gpt-5__r15__s250.yaml b/configs/pvp/RobotRumble__gemini-2.5-pro__gpt-5__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gemini-2.5-pro__gpt-5__r15__s250.yaml rename to configs/pvp/RobotRumble__gemini-2.5-pro__gpt-5__r15__s250.yaml diff --git a/configs/main/RobotRumble__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RobotRumble__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RobotRumble__gemini-2.5-pro__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RobotRumble__gemini-2.5-pro__o3__r15__s250.yaml b/configs/pvp/RobotRumble__gemini-2.5-pro__o3__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gemini-2.5-pro__o3__r15__s250.yaml rename to configs/pvp/RobotRumble__gemini-2.5-pro__o3__r15__s250.yaml diff --git a/configs/main/RobotRumble__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__gemini-2.5-pro__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5-mini__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5-mini__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5-mini__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5-mini__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5-mini__o3__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5-mini__o3__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5-mini__o3__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5-mini__o3__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5-mini__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5__gpt-5-mini__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5__gpt-5-mini__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5__gpt-5-mini__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5__gpt-5-mini__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5__grok-code-fast-1__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5__grok-code-fast-1__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5__grok-code-fast-1__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5__grok-code-fast-1__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5__o3__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5__o3__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5__o3__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5__o3__r15__s250.yaml diff --git a/configs/main/RobotRumble__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__gpt-5__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__grok-code-fast-1__o3__r15__s250.yaml b/configs/pvp/RobotRumble__grok-code-fast-1__o3__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__grok-code-fast-1__o3__r15__s250.yaml rename to configs/pvp/RobotRumble__grok-code-fast-1__o3__r15__s250.yaml diff --git a/configs/main/RobotRumble__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__grok-code-fast-1__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/configs/main/RobotRumble__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml b/configs/pvp/RobotRumble__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml similarity index 100% rename from configs/main/RobotRumble__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml rename to configs/pvp/RobotRumble__o3__qwen3-coder-plus-2025-09-23__r15__s250.yaml diff --git a/docs/quickstart.md b/docs/quickstart.md index 4d25859b..105054b8 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -111,7 +111,7 @@ CodeClash configs are organized into tiers: |-----------|---------|----------|----------| | `configs/test/` | Smoke tests with dummy agents | Free | Verifying setup works | | `configs/examples/` | Short tournaments (5 rounds) | Low | Learning, quick experiments | -| `configs/main/` | Full benchmark runs (15 rounds) | High | Reproducing paper results | +| `configs/pvp/` | Full benchmark runs (15 rounds) | High | Reproducing paper results | | `configs/ablations/` | Specialized experiments | Varies | Research ablations | ### Test Configs (Free) @@ -142,7 +142,7 @@ Full 15-round tournaments used in the paper: ```bash # Full BattleSnake tournament -uv run codeclash run configs/main/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml ``` !!! warning "Cost Warning" diff --git a/docs/usage/tournaments.md b/docs/usage/tournaments.md index 03e10931..5d318924 100644 --- a/docs/usage/tournaments.md +++ b/docs/usage/tournaments.md @@ -260,14 +260,14 @@ Example: `PvpTournament.BattleSnake.r5.s1000.p2.claude-sonnet-4-5.o3.24121014302 ```bash # BattleSnake: Claude Sonnet 4.5 vs o3 (15 rounds) -uv run codeclash run configs/main/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml ``` ### Run all arenas for a matchup ```bash for arena in BattleSnake CoreWar Halite RoboCode RobotRumble; do - uv run codeclash run "configs/main/${arena}__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml" + uv run codeclash run "configs/pvp/${arena}__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml" done ``` @@ -299,7 +299,7 @@ uv run codeclash run configs/my_config_b.yaml -s variantB #!/bin/bash models=("claude-sonnet-4-5-20250929" "gpt-5" "gemini-2.5-pro") for model in "${models[@]}"; do - config="configs/main/BattleSnake__${model}__o3__r15__s1000.yaml" + config="configs/pvp/BattleSnake__${model}__o3__r15__s1000.yaml" if [ -f "$config" ]; then uv run codeclash run "$config" fi diff --git a/scripts/run_multiple_pvp.sh b/scripts/run_multiple_pvp.sh index 33c10165..50352f51 100755 --- a/scripts/run_multiple_pvp.sh +++ b/scripts/run_multiple_pvp.sh @@ -3,7 +3,7 @@ # Check if argument is provided if [ $# -eq 0 ]; then echo "Usage: $0 " - echo "Example: $0 configs/main/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml" + echo "Example: $0 configs/pvp/RobotRumble__gemini-2.5-pro__gpt-5-mini__r15__s1000.yaml" exit 1 fi From f9bb262a23ce95e615c0c254a54f06b3370b290e Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 03:52:57 +0000 Subject: [PATCH 16/19] Remove unreferenced example configs (stale Bridge/haiku, duplicate HuskyBench) --- .../Bridge__claude-3-5-haiku__r2__s10.yaml | 74 ------------------- ...ude-sonnet-4-5-20250929__o3__r5__s100.yaml | 36 --------- 2 files changed, 110 deletions(-) delete mode 100644 configs/examples/Bridge__claude-3-5-haiku__r2__s10.yaml delete mode 100644 configs/examples/HuskyBench__claude-sonnet-4-5-20250929__o3__r5__s100.yaml diff --git a/configs/examples/Bridge__claude-3-5-haiku__r2__s10.yaml b/configs/examples/Bridge__claude-3-5-haiku__r2__s10.yaml deleted file mode 100644 index 0853e30b..00000000 --- a/configs/examples/Bridge__claude-3-5-haiku__r2__s10.yaml +++ /dev/null @@ -1,74 +0,0 @@ -tournament: - rounds: 2 -game: - name: Bridge - sims_per_round: 10 -players: -- agent: mini - name: north - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-3-5-haiku-20241022' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: east - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-3-5-haiku-20241022' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: south - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-3-5-haiku-20241022' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: west - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-3-5-haiku-20241022' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called Bridge. - Bridge is a 4-player trick-taking card game played in partnerships: North/South vs East/West. - - Your position: {{player_id}} (North=0, East=1, South=2, West=3) - Teams: North/South (positions 0/2) vs East/West (positions 1/3) - - The game is played in {{total_rounds}} rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After everyone finishes editing their codebases, the game is run automatically. - - Your task: improve the bot in `bridge_agent.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. - All of your commands will be executed in the {{working_dir}} directory. - - Your bot must implement two functions: - - get_bid(game_state) -> str: Make bidding decisions during the auction - - play_card(game_state) -> str: Play a card during the play phase - - game_state contains: - - position: Your seat (0-3) - - hand: Your cards (e.g., ["AS", "KH", "7D", "TC"]) - - legal_bids/legal_cards: Valid moves you can make - - bids: Previous bids in the auction - - current_trick: Cards played in current trick - - contract: The final contract (after bidding) - - tricks_won: Tricks won by each team - - Card notation: where rank is A,K,Q,J,T,9,8,7,6,5,4,3,2 and suit is S,H,D,C - Bid notation: "PASS" or level(1-7) + strain(C,D,H,S,NT) like "1H", "3NT", "7S" - - Check examples/random_agent.py in the workspace for a starting template. diff --git a/configs/examples/HuskyBench__claude-sonnet-4-5-20250929__o3__r5__s100.yaml b/configs/examples/HuskyBench__claude-sonnet-4-5-20250929__o3__r5__s100.yaml deleted file mode 100644 index 6b383dd5..00000000 --- a/configs/examples/HuskyBench__claude-sonnet-4-5-20250929__o3__r5__s100.yaml +++ /dev/null @@ -1,36 +0,0 @@ -tournament: - rounds: 5 -game: - name: HuskyBench - sims_per_round: 100 - args: {} -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-sonnet-4-5-20250929' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: o3 - config: - agent: !include mini/default.yaml - model: - model_name: 'openai/o3' -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called HuskyBench. - In this game, you will write code to control a poker-playing bot, aiming to outsmart your opponents and win chips. - Victory comes from crafting clever strategies—bluffing, reading opponents, and managing your chip stack effectively. - Be mindful of your bot's efficiency - your code should complete a simulation within 10 seconds to avoid forfeiting the round. - You can use run_game.sh to check if your bot runs in time. - - The game is played in 15 rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `client/player.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your both and supporting assets. - All of your commands will be executed in the {{working_dir}} directory (see notes below). From 7eb5f582f71629c033c58b2691b4eee05193128d Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 03:57:43 +0000 Subject: [PATCH 17/19] Point docs at pvp configs; drop r5 example duplicates and vs_human ablation --- README.md | 2 +- configs/ablations/vs_human/README.md | 17 ------- ...0250514__vs__seven-of-nine__r15__s250.yaml | 33 -------------- ...4-5-20250929__vs__gigachad__r15__s250.yaml | 31 ------------- ...0250929__vs__seven-of-nine__r15__s250.yaml | 33 -------------- ...2.5-pro__vs__seven-of-nine__r15__s250.yaml | 32 ------------- ...-5-mini__vs__seven-of-nine__r15__s250.yaml | 30 ------------- ...__gpt-5__vs__seven-of-nine__r15__s250.yaml | 30 ------------- ...-fast-1__vs__seven-of-nine__r15__s250.yaml | 33 -------------- ...ble__o3__vs__seven-of-nine__r15__s250.yaml | 30 ------------- ...5-09-23__vs__seven-of-nine__r15__s250.yaml | 31 ------------- ...de-sonnet-4-5-20250929__o3__r5__s1000.yaml | 37 --------------- ...de-sonnet-4-5-20250929__o3__r5__s1000.yaml | 34 -------------- ...ude-sonnet-4-5-20250929__o3__r5__s250.yaml | 45 ------------------- ...ude-sonnet-4-5-20250929__o3__r5__s250.yaml | 39 ---------------- ...ude-sonnet-4-5-20250929__o3__r5__s250.yaml | 36 --------------- docs/quickstart.md | 39 +++++++--------- docs/usage/codebase-tour.md | 2 +- docs/usage/tournaments.md | 6 +-- 19 files changed, 20 insertions(+), 520 deletions(-) delete mode 100644 configs/ablations/vs_human/README.md delete mode 100644 configs/ablations/vs_human/RobotRumble__claude-sonnet-4-20250514__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__gigachad__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__gemini-2.5-pro__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__gpt-5-mini__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__gpt-5__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__grok-code-fast-1__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__o3__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/ablations/vs_human/RobotRumble__qwen3-coder-plus-2025-09-23__vs__seven-of-nine__r15__s250.yaml delete mode 100644 configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml delete mode 100644 configs/examples/CoreWar__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml delete mode 100644 configs/examples/Halite__claude-sonnet-4-5-20250929__o3__r5__s250.yaml delete mode 100644 configs/examples/RoboCode__claude-sonnet-4-5-20250929__o3__r5__s250.yaml delete mode 100644 configs/examples/RobotRumble__claude-sonnet-4-5-20250929__o3__r5__s250.yaml diff --git a/README.md b/README.md index cf867207..fea15b1f 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ codeclash run configs/test/battlesnake.yaml Once this works, you should be set up to run a real tournament! To run *Claude Sonnet 4.5* against *o3* in a *BattleSnake* tournament with *5 rounds* and *1000 competition simulations* per round, run: ```bash -uv run codeclash run configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml ``` ## ⚔️ How It Works diff --git a/configs/ablations/vs_human/README.md b/configs/ablations/vs_human/README.md deleted file mode 100644 index d1f5cebf..00000000 --- a/configs/ablations/vs_human/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# vs. Human - -These set of configurations correspond to Section 4.1 of the original paper, specifically the subsection *On RobotRumble, models trail substantially behind expert human programmers*. - -Each configuration pits a model against an open source codebase written by a human expert for a particular arena. Across a tournament spanning 15 rounds, the model is allowed the evolve the codebase as it sees fit to beat the human expert's solution. The human's solution is *not* changing for the duration of the tournament. - -To make models compete against static human solutions, do the following two steps. - -1. Make sure the human solution is working and pushed as a branch to the corresponding arena. E.g. [gigachad](https://github.com/CodeClash-ai/RobotRumble/tree/human/entropicdrifter/gigachad) for RobotRumble. -2. Then, in your configuration, simply specify one of the players as a `dummy` agent, with `branch_init` set to the branch name, such as: - -```yaml -players: -- agent: dummy - branch_init: human/entropicdrifter/gigachad - name: gigachad -``` diff --git a/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-20250514__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-20250514__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index e7e91d4e..00000000 --- a/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-20250514__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,33 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: claude-sonnet-4-20250514 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@anthropic/claude-sonnet-4-20250514' - model_class: portkey - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__gigachad__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__gigachad__r15__s250.yaml deleted file mode 100644 index fe803313..00000000 --- a/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__gigachad__r15__s250.yaml +++ /dev/null @@ -1,31 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@anthropic/claude-sonnet-4-5-20250929' - model_class: portkey - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: dummy - name: gigachad - branch_init: human/entropicdrifter/gigachad -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index 119179d0..00000000 --- a/configs/ablations/vs_human/RobotRumble__claude-sonnet-4-5-20250929__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,33 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@anthropic/claude-sonnet-4-5-20250929' - model_class: portkey - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__gemini-2.5-pro__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__gemini-2.5-pro__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index 03730af0..00000000 --- a/configs/ablations/vs_human/RobotRumble__gemini-2.5-pro__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,32 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: gemini-2.5-pro - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@google/gemini-2.5-pro' - model_class: portkey - model_kwargs: - temperature: 0.2 -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__gpt-5-mini__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__gpt-5-mini__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index 5eb43c50..00000000 --- a/configs/ablations/vs_human/RobotRumble__gpt-5-mini__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,30 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: gpt-5-mini - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@openai/gpt-5-mini' - model_class: portkey -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__gpt-5__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__gpt-5__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index c14a2536..00000000 --- a/configs/ablations/vs_human/RobotRumble__gpt-5__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,30 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: gpt-5 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@openai/gpt-5' - model_class: portkey -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__grok-code-fast-1__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__grok-code-fast-1__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index 03a11585..00000000 --- a/configs/ablations/vs_human/RobotRumble__grok-code-fast-1__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,33 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: grok-code-fast-1 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@x-ai/grok-code-fast-1' - model_class: portkey - litellm_model_name_override: xai/grok-code-fast-1 - model_kwargs: - temperature: 0.2 -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__o3__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__o3__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index 3e95b5e1..00000000 --- a/configs/ablations/vs_human/RobotRumble__o3__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,30 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: o3 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: '@openai/o3' - model_class: portkey -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/ablations/vs_human/RobotRumble__qwen3-coder-plus-2025-09-23__vs__seven-of-nine__r15__s250.yaml b/configs/ablations/vs_human/RobotRumble__qwen3-coder-plus-2025-09-23__vs__seven-of-nine__r15__s250.yaml deleted file mode 100644 index 4b7f1caf..00000000 --- a/configs/ablations/vs_human/RobotRumble__qwen3-coder-plus-2025-09-23__vs__seven-of-nine__r15__s250.yaml +++ /dev/null @@ -1,31 +0,0 @@ -tournament: - rounds: 15 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: qwen3-coder-plus-2025-09-23 - branch_init: starter/python - config: - agent: !include mini/default.yaml - model: - model_name: dashscope/qwen3-coder-plus-2025-09-23 - model_kwargs: - temperature: 0.2 -- agent: dummy - name: seven-of-nine - branch_init: human/entropicdrifter/seven-of-nine -prompts: - game_description: | - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - - The game is played in {{rounds}} rounds. For every round, you (and your competitor) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your bot and supporting assets. diff --git a/configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml b/configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml deleted file mode 100644 index 58413752..00000000 --- a/configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +++ /dev/null @@ -1,37 +0,0 @@ -tournament: - rounds: 5 -game: - name: BattleSnake - sims_per_round: 1000 - args: - width: 11 - height: 11 - browser: false -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-sonnet-4-5-20250929' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: o3 - config: - agent: !include mini/default.yaml - model: - model_name: 'openai/o3' -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called BattleSnake. - Your bot (`main.py`) controls a snake on a grid-based board. - Snakes collect food, avoid collisions, and try to outlast their opponents. - - The game is played in 15 rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `main.py`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your both and supporting assets. - All of your commands will be executed in the {{working_dir}} directory (see notes below). diff --git a/configs/examples/CoreWar__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml b/configs/examples/CoreWar__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml deleted file mode 100644 index 615f339d..00000000 --- a/configs/examples/CoreWar__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +++ /dev/null @@ -1,34 +0,0 @@ -tournament: - rounds: 5 -game: - name: CoreWar - sims_per_round: 1000 - args: {} -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-sonnet-4-5-20250929' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: o3 - config: - agent: !include mini/default.yaml - model: - model_name: 'openai/o3' -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called CoreWar. - CoreWar is a programming battle where you write "warriors" in an assembly-like language called Redcode to compete within a virtual machine (MARS), aiming to eliminate your rivals by making their code self-terminate. - Victory comes from crafting clever tactics—replicators, scanners, bombers—that exploit memory layout and instruction timing to control the core. - - The game is played in 15 rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `warrior.red`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your both and supporting assets. - All of your commands will be executed in the {{working_dir}} directory (see notes below). diff --git a/configs/examples/Halite__claude-sonnet-4-5-20250929__o3__r5__s250.yaml b/configs/examples/Halite__claude-sonnet-4-5-20250929__o3__r5__s250.yaml deleted file mode 100644 index 6f484b0e..00000000 --- a/configs/examples/Halite__claude-sonnet-4-5-20250929__o3__r5__s250.yaml +++ /dev/null @@ -1,45 +0,0 @@ -tournament: - rounds: 5 -game: - name: Halite - sims_per_round: 250 - args: {} -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-sonnet-4-5-20250929' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: o3 - config: - agent: !include mini/default.yaml - model: - model_name: 'openai/o3' -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called Halite. - Halite is a multi-player turn-based strategy game where bots compete on a rectangular grid to capture territory and accumulate strength. - Players control pieces that can move across the map to conquer neutral and enemy territory, with each cell providing production that increases the strength of pieces occupying it. - The goal is to control the most territory by the end of the game through strategic expansion, consolidation of forces, and tactical combat decisions. - - You have the choice of writing your Halite bot in one of four programming languages: C, C++, OCaml, or Rust. - Example implementations can be found under the `airesources/` folder. - Your submission should be stored in the `submission/` folder. This folder currently contains an example C bot, but feel free to use any of the supported languages. - Please make sure your main file is named `main.`, where `` is the appropriate file extension for your chosen programming language. - You may include additional files as needed, but please ensure: - 1. The `submission/` folder contains only files relevant to your bot. - 2. The `submission/` folder ONLY contains a single bot (no multiple bots in one submission). - 3. Your bot can be compiled. See `runGame.sh` under the corresponding `submission//` folder to see how we will compile and run your bot. - - - The game is played in 15 rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `submission`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your both and supporting assets. - All of your commands will be executed in the {{working_dir}} directory (see notes below). diff --git a/configs/examples/RoboCode__claude-sonnet-4-5-20250929__o3__r5__s250.yaml b/configs/examples/RoboCode__claude-sonnet-4-5-20250929__o3__r5__s250.yaml deleted file mode 100644 index 20742e5c..00000000 --- a/configs/examples/RoboCode__claude-sonnet-4-5-20250929__o3__r5__s250.yaml +++ /dev/null @@ -1,39 +0,0 @@ -tournament: - rounds: 5 -game: - name: RoboCode - sims_per_round: 250 - args: - nodisplay: true - nosound: true - record_ratio: 0.2 -players: -- agent: mini - name: claudesonnet4520250929 - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-sonnet-4-5-20250929' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: o3 - config: - agent: !include mini/default.yaml - model: - model_name: 'openai/o3' -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called RoboCode. - Robocode (Tank Royale) is a programming game where your code is the tank: each turn your bot sends intents—speed plus body/gun/radar turn rates and firepower—based on the game state it perceives via radar. - Your program decides how to move, aim, and fire in a deterministic, turn-based arena to outlast other bots. - Your bot logic must be written in Java and located in the `robots/custom/` directory. - Keep the main bot class named `MyTank.java`, but you can include additional Java files if you'd like. - - The game is played in 15 rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robots/custom/`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your both and supporting assets. - All of your commands will be executed in the {{working_dir}} directory (see notes below). diff --git a/configs/examples/RobotRumble__claude-sonnet-4-5-20250929__o3__r5__s250.yaml b/configs/examples/RobotRumble__claude-sonnet-4-5-20250929__o3__r5__s250.yaml deleted file mode 100644 index 45a0a795..00000000 --- a/configs/examples/RobotRumble__claude-sonnet-4-5-20250929__o3__r5__s250.yaml +++ /dev/null @@ -1,36 +0,0 @@ -tournament: - rounds: 5 -game: - name: RobotRumble - sims_per_round: 250 - args: - raw: true -players: -- agent: mini - name: claude-sonnet-4-5-20250929 - config: - agent: !include mini/default.yaml - model: - model_name: 'anthropic/claude-sonnet-4-5-20250929' - model_kwargs: - temperature: 0.2 - max_tokens: 4096 -- agent: mini - name: o3 - config: - agent: !include mini/default.yaml - model: - model_name: 'openai/o3' -prompts: - game_description: |- - You are a software developer ({{player_id}}) competing in a coding game called RobotRumble. - RobotRumble is a turn-based coding battle where you program a team of robots in Python to move, attack, and outmaneuver your opponent on a grid. - Every decision is driven by your code, and victory comes from crafting logic that positions robots smartly, times attacks well, and adapts over the 100-turn match. - NOTE: Please ensure that your code runs efficiently (under 60 seconds). Code that exceeds this run time will automatically forfeit the round. - - The game is played in 15 rounds. For every round, you (and your competitors) edit program code that controls your bot. This is round {{round}}. - After you and your competitor finish editing your codebases, the game is run automatically. - - Your task: improve the bot in `robot.js`, located in {{working_dir}}. - {{working_dir}} is your codebase, which contains both your both and supporting assets. - All of your commands will be executed in the {{working_dir}} directory (see notes below). diff --git a/docs/quickstart.md b/docs/quickstart.md index 105054b8..748ad743 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -110,7 +110,7 @@ CodeClash configs are organized into tiers: | Directory | Purpose | LLM Cost | Use When | |-----------|---------|----------|----------| | `configs/test/` | Smoke tests with dummy agents | Free | Verifying setup works | -| `configs/examples/` | Short tournaments (5 rounds) | Low | Learning, quick experiments | +| `configs/examples/` | Single-player & minimal per-arena samples | Low | Trying one arena or mode | | `configs/pvp/` | Full benchmark runs (15 rounds) | High | Reproducing paper results | | `configs/ablations/` | Specialized experiments | Varies | Research ablations | @@ -122,31 +122,22 @@ No LLM API calls - uses dummy agents that make no changes: uv run codeclash run configs/test/battlesnake.yaml ``` -### Example Configs (Quick Experiments) +### PvP Configs (Full Benchmarks) -Short 5-round tournaments for learning and experimentation: +Full 15-round model-vs-model tournaments, as used in the paper: ```bash -# Claude Sonnet 4.5 vs o3 in BattleSnake (5 rounds) -uv run codeclash run configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +# Claude Sonnet 4.5 vs o3 in BattleSnake +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml # Same matchup in other arenas -uv run codeclash run configs/examples/CoreWar__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml -uv run codeclash run configs/examples/Halite__claude-sonnet-4-5-20250929__o3__r5__s250.yaml -uv run codeclash run configs/examples/RoboCode__claude-sonnet-4-5-20250929__o3__r5__s250.yaml -``` - -### Main Configs (Full Benchmarks) - -Full 15-round tournaments used in the paper: - -```bash -# Full BattleSnake tournament -uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml +uv run codeclash run configs/pvp/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml +uv run codeclash run configs/pvp/Halite__claude-sonnet-4-5-20250929__o3__r15__s250.yaml +uv run codeclash run configs/pvp/RoboCode__claude-sonnet-4-5-20250929__o3__r15__s250.yaml ``` !!! warning "Cost Warning" - Main configs run 15 rounds with real LLM agents. Expect significant API costs depending on your model choices. + PvP configs run 15 rounds with real LLM agents. Expect significant API costs depending on your model choices. ## Viewing Results @@ -175,8 +166,8 @@ The viewer shows: ```bash # 1. Make sure you have API keys in .env -# 2. Run a short example tournament -uv run codeclash run configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +# 2. Run a tournament +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml # 3. View results uv run python scripts/run_viewer.py @@ -186,18 +177,18 @@ uv run python scripts/run_viewer.py ```bash # CoreWar - Assembly-like programming battle -uv run codeclash run configs/examples/CoreWar__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +uv run codeclash run configs/pvp/CoreWar__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml # RobotRumble - Multi-robot combat -uv run codeclash run configs/examples/RobotRumble__claude-sonnet-4-5-20250929__o3__r5__s250.yaml +uv run codeclash run configs/pvp/RobotRumble__claude-sonnet-4-5-20250929__o3__r15__s250.yaml ``` ### Create a custom matchup -Copy an example config and modify: +Copy a config and modify: ```bash -cp configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml configs/my_tournament.yaml +cp configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml configs/my_tournament.yaml # Edit configs/my_tournament.yaml to change models, rounds, etc. uv run codeclash run configs/my_tournament.yaml ``` diff --git a/docs/usage/codebase-tour.md b/docs/usage/codebase-tour.md index fe6eabfc..8d8fbada 100644 --- a/docs/usage/codebase-tour.md +++ b/docs/usage/codebase-tour.md @@ -248,7 +248,7 @@ Shared helper functions: 5. **Create example configs:** - `configs/test/myarena.yaml` (dummy agents) - - `configs/examples/MyArena__model1__model2__r5__s100.yaml` + - `configs/pvp/MyArena__model1__model2__r15__s100.yaml` ### Adding a New Agent Type diff --git a/docs/usage/tournaments.md b/docs/usage/tournaments.md index 5d318924..9f27f79f 100644 --- a/docs/usage/tournaments.md +++ b/docs/usage/tournaments.md @@ -28,18 +28,18 @@ uv run codeclash run [options] ```bash # Basic run -uv run codeclash run configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml # Keep containers for debugging uv run codeclash run configs/test/battlesnake.yaml -k # Custom output directory with suffix -uv run codeclash run configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml \ +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml \ -o ./my_experiments \ -s experiment1 # Push final codebases to GitHub -uv run codeclash run configs/examples/BattleSnake__claude-sonnet-4-5-20250929__o3__r5__s1000.yaml -p +uv run codeclash run configs/pvp/BattleSnake__claude-sonnet-4-5-20250929__o3__r15__s1000.yaml -p ``` ## Configuration Anatomy From 7f84dfa3da3061411b5b3e36485f33a16d49adb8 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 04:04:25 +0000 Subject: [PATCH 18/19] Fix battlesnake entrypoint check to accept any server start; fix single_player doc ref --- codeclash/arenas/battlesnake/battlesnake.py | 6 +++--- docs/reference/tournament/single_player.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/codeclash/arenas/battlesnake/battlesnake.py b/codeclash/arenas/battlesnake/battlesnake.py index 91ac964a..6f6eece3 100644 --- a/codeclash/arenas/battlesnake/battlesnake.py +++ b/codeclash/arenas/battlesnake/battlesnake.py @@ -203,9 +203,9 @@ def validate_code(self, agent: Player) -> tuple[bool, str | None]: error_msg.append(f"There should be a `{func}` function implemented in `{self.submission}`") if len(error_msg) > 0: return False, "\n".join(error_msg + ["Don't change the function signatures!"]) - if "__main__" not in bot_content or "run_server" not in bot_content: + if "__main__" not in bot_content: return False, ( - f"`{self.submission}` must keep its server entrypoint so the bot starts: the " - '`if __name__ == "__main__": run_server(...)` block at the bottom of the file.' + f'`{self.submission}` must keep its `if __name__ == "__main__"` block that starts ' + "the server, or the bot fails to launch." ) return True, None diff --git a/docs/reference/tournament/single_player.md b/docs/reference/tournament/single_player.md index 1cdeadff..d52398db 100644 --- a/docs/reference/tournament/single_player.md +++ b/docs/reference/tournament/single_player.md @@ -30,7 +30,7 @@ players: ## Running a SinglePlayer Tournament ```bash -python main_single_player.py configs/examples/battlesnake_single_player.yaml +uv run python scripts/main_single_player.py configs/examples/BattleSnake_single_player.yaml ``` ## Implementation From 80ca42eefb4f6969dea1cbb35f538c7e13e37fc5 Mon Sep 17 00:00:00 2001 From: John Yang Date: Tue, 7 Jul 2026 04:06:44 +0000 Subject: [PATCH 19/19] Remove unused ClashAgentConfig now that observation_template lives in model configs --- codeclash/agents/minisweagent.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/codeclash/agents/minisweagent.py b/codeclash/agents/minisweagent.py index fd3d8d79..965e3459 100644 --- a/codeclash/agents/minisweagent.py +++ b/codeclash/agents/minisweagent.py @@ -18,12 +18,6 @@ ) -class ClashAgentConfig(AgentConfig): - """`AgentConfig` plus an optional global observation-format override.""" - - observation_template: str | None = None - - class ClashAgent(DefaultAgent): """`DefaultAgent` from mini-SWE-agent (https://github.com/SWE-agent/mini-swe-agent) with per-player debug logging.""" @@ -34,13 +28,11 @@ def __init__( env: DockerEnvironment, *, logger: logging.Logger, - config_class: Callable = ClashAgentConfig, + config_class: Callable = AgentConfig, **kwargs, ): super().__init__(model, env, config_class=config_class, **kwargs) self.logger = logger - if getattr(self.config, "observation_template", None): - self.model.config.observation_template = self.config.observation_template def add_messages(self, *messages: dict) -> list[dict]: result = super().add_messages(*messages)