Skip to content

Commit 1299ead

Browse files
committed
Ref: Avoid circular dependency Game <> Player
Closes #18
1 parent f382cbc commit 1299ead

5 files changed

Lines changed: 34 additions & 30 deletions

File tree

codeclash/agents/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ def get_agent(config: dict, game: CodeGame) -> Player:
1111
}.get(config["agent"])
1212
if agents is None:
1313
raise ValueError(f"Unknown agent type: {config['agent']}")
14-
return agents(config, game)
14+
environment = game.get_environment()
15+
format_vars = {
16+
"game_id": game.game_id,
17+
"rounds": game.rounds,
18+
"round": game.round,
19+
}
20+
return agents(config, environment, format_vars)

codeclash/agents/abstract.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,35 @@
33

44
from dotenv import load_dotenv
55
from ghapi.all import GhApi
6+
from minisweagent import Environment
67

78
from codeclash.constants import GH_ORG
8-
from codeclash.games.abstract import CodeGame
99

1010
load_dotenv()
1111

1212

1313
class Player(ABC):
14-
def __init__(self, config: dict, game: CodeGame):
14+
def __init__(
15+
self,
16+
config: dict,
17+
environment: Environment,
18+
format_vars: dict,
19+
):
1520
self.config = config
16-
self.name = f"{game.game_id}_{config['name']}"
17-
self.container = game.get_environment()
18-
self.game = game
21+
self.name = f"{format_vars['game_id']}_{config['name']}"
22+
self.environment = environment
23+
self.round = format_vars["round"]
24+
self.format_vars = format_vars
1925

2026
def commit(self):
2127
"""Commit changes to the agent's codebase."""
28+
rounds = self.format_vars["rounds"]
2229
for cmd in [
2330
"git add -A",
24-
f"git commit --allow-empty -m 'Round {self.game.round}/{self.game.rounds} Update'",
31+
f"git commit --allow-empty -m 'Round {self.round}/{rounds} Update'",
2532
]:
26-
self.container.execute(cmd)
27-
print(
28-
f"Committed changes for {self.name} for round {self.game.round}/{self.game.rounds}"
29-
)
33+
self.environment.execute(cmd)
34+
print(f"Committed changes for {self.name} for round {self.round}/{rounds}")
3035

3136
def push(self):
3237
"""Push codebase to a new repository."""
@@ -41,7 +46,7 @@ def push(self):
4146
f"git remote add origin https://x-access-token:{token}@github.com/{GH_ORG}/{self.name}.git",
4247
"git push -u origin main",
4348
]:
44-
self.container.execute(cmd)
49+
self.environment.execute(cmd)
4550

4651
@abstractmethod
4752
def run(self):

codeclash/agents/dummy.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,5 @@
44
class Dummy(Player):
55
"""A dummy player that does nothing. Mainly for testing purposes."""
66

7-
def __init__(self, config: dict, game):
8-
super().__init__(config, game)
9-
107
def run(self):
118
self.commit()

codeclash/agents/minisweagent.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
from codeclash.agents.abstract import Player
1717
from codeclash.agents.utils import resolve_api_key
18-
from codeclash.games.abstract import CodeGame
1918

2019

2120
class ClashAgent(DefaultAgent):
@@ -29,14 +28,14 @@ def __init__(
2928
model: Model,
3029
env: Environment,
3130
name: str,
32-
game: CodeGame,
31+
format_vars: dict,
3332
*,
3433
config_class: Callable = AgentConfig,
3534
**kwargs,
3635
):
3736
super().__init__(model, env, config_class=config_class, **kwargs)
3837
self.name = name
39-
self.game = game
38+
self.format_vars = format_vars
4039
self.console = Console()
4140

4241
def add_message(self, role: str, content: str, **kwargs):
@@ -52,10 +51,7 @@ def render_template(self, template: str, **kwargs) -> str:
5251
| asdict(self.env.config)
5352
| asdict(self.model.config)
5453
| platform.uname()._asdict()
55-
| {
56-
"rounds": self.game.rounds,
57-
"round": self.game.round,
58-
}
54+
| self.format_vars
5955
)
6056
return Template(template).render(**kwargs, **cs, **os.environ)
6157

@@ -68,16 +64,16 @@ def run(self) -> tuple[str, str]:
6864
class MiniSWEAgent(Player):
6965
"""Player with agentic code editing capabilities"""
7066

71-
def __init__(self, config: dict, game: CodeGame):
72-
super().__init__(config, game)
67+
def __init__(self, config: dict, environment: Environment, format_vars: dict):
68+
super().__init__(config, environment=environment, format_vars=format_vars)
7369
self.agent = ClashAgent(
7470
LitellmModel(
7571
model_name=config["model"],
7672
model_kwargs={"api_key": resolve_api_key(config["model"])},
7773
),
78-
self.container,
74+
self.environment,
7975
self.name,
80-
game,
76+
format_vars,
8177
**yaml.safe_load(Path(config["config"]).read_text())["agent"],
8278
)
8379

@@ -94,7 +90,7 @@ def run(self):
9490
finally:
9591
save_traj(
9692
self.agent, # type: ignore
97-
Path(f"{self.name}_r{self.game.round}.traj.json"),
93+
Path(f"{self.name}_r{self.format_vars['round']}.traj.json"),
9894
exit_status=exit_status,
9995
result=result,
10096
)

codeclash/games/abstract.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def _pre_round_setup(self, agents: list[Any]):
100100
# Copy agent codebases into game's container
101101
for agent in agents:
102102
copy_between_containers(
103-
src_container=agent.container,
103+
src_container=agent.environment,
104104
dest_container=self.environment,
105105
src_path=DIR_WORK,
106106
dest_path=f"/{agent.name}",
@@ -124,9 +124,9 @@ def _post_round_setup(self, agents: list[Any]):
124124
for agent in agents:
125125
copy_between_containers(
126126
self.environment,
127-
agent.container,
127+
agent.environment,
128128
self.round_log_path,
129-
f"{agent.container.config.cwd}/logs/round_{self.round}.log",
129+
f"{agent.environment.config.cwd}/logs/round_{self.round}.log",
130130
)
131131
print(f"Copied round log to {agent.name}'s container.")
132132
print(f"Round {self.round} completed.")

0 commit comments

Comments
 (0)