Skip to content

Commit 7e030e3

Browse files
committed
Get rid of games/utils.py; copy traj to environment
1 parent b6f32b7 commit 7e030e3

5 files changed

Lines changed: 117 additions & 106 deletions

File tree

codeclash/agents/minisweagent.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from codeclash.agents.abstract import Player
1818
from codeclash.agents.utils import GameContext, resolve_api_key
1919
from codeclash.constants import DIR_LOGS
20+
from codeclash.utils.environment import copy_file_to_container
2021

2122

2223
class ClashAgent(DefaultAgent):
@@ -95,11 +96,16 @@ def run(self):
9596
result = exc_message
9697
print(exc_message)
9798
finally:
99+
traj_path = (
100+
DIR_LOGS
101+
/ self.game_context.id
102+
/ f"{self.name}_r{self.game_context.round}.traj.json"
103+
)
98104
save_traj(
99105
self.agent, # type: ignore
100-
DIR_LOGS
101-
/ f"{self.game_context.id}/{self.name}_r{self.game_context.round}.traj.json",
106+
traj_path,
102107
exit_status=exit_status,
103108
result=result,
104109
)
110+
copy_file_to_container(self.environment, traj_path, traj_path)
105111
self.commit()

codeclash/games/abstract.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111

1212
from codeclash.agents.abstract import Player
1313
from codeclash.constants import DIR_LOGS, DIR_WORK, GH_ORG
14-
from codeclash.games.utils import copy_between_containers, copy_file_from_container
15-
from codeclash.utils.environment import assert_zero_exit_code
14+
from codeclash.utils.environment import (
15+
assert_zero_exit_code,
16+
copy_between_containers,
17+
copy_file_from_container,
18+
)
1619
from codeclash.utils.log import get_logger
1720

1821

codeclash/games/robocode/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from codeclash.agents.abstract import Player
44
from codeclash.games.abstract import CodeGame
5-
from codeclash.games.utils import copy_file_to_container
5+
from codeclash.utils.environment import copy_file_to_container
66

77

88
class RoboCodeGame(CodeGame):

codeclash/games/utils.py

Lines changed: 0 additions & 101 deletions
This file was deleted.

codeclash/utils/environment.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import logging
2+
import subprocess
3+
import tempfile
4+
from pathlib import Path
5+
6+
from minisweagent.environments.docker import DockerEnvironment
27

38

49
def assert_zero_exit_code(
@@ -10,3 +15,101 @@ def assert_zero_exit_code(
1015
logger.error(msg)
1116
raise RuntimeError(msg)
1217
return result
18+
19+
20+
def copy_between_containers(
21+
src_container: DockerEnvironment,
22+
dest_container: DockerEnvironment,
23+
src_path: str | Path,
24+
dest_path: str | Path,
25+
):
26+
"""
27+
Copy files from one Docker container to another via a temporary local directory.
28+
"""
29+
with tempfile.TemporaryDirectory() as temp_dir:
30+
temp_path = Path(temp_dir) / Path(src_path).name
31+
32+
# Copy from source container to temporary local directory
33+
cmd_src = [
34+
"docker",
35+
"cp",
36+
f"{src_container.container_id}:{src_path}",
37+
str(temp_path),
38+
]
39+
result_src = subprocess.run(
40+
cmd_src, check=False, capture_output=True, text=True
41+
)
42+
if result_src.returncode != 0:
43+
raise RuntimeError(
44+
f"Failed to copy from {src_container.container_id} to local temp: {result_src.stdout}{result_src.stderr}"
45+
)
46+
47+
# Ensure destination folder exists
48+
assert_zero_exit_code(
49+
dest_container.execute(f"mkdir -p {Path(dest_path).parent}")
50+
)
51+
52+
# Copy from temporary local directory to destination container
53+
cmd_dest = [
54+
"docker",
55+
"cp",
56+
str(temp_path),
57+
f"{dest_container.container_id}:{dest_path}",
58+
]
59+
result_dest = subprocess.run(
60+
cmd_dest, check=False, capture_output=True, text=True
61+
)
62+
if result_dest.returncode != 0:
63+
raise RuntimeError(
64+
f"Failed to copy from local temp to {dest_container.container_id}: {result_dest.stdout}{result_dest.stderr}"
65+
)
66+
67+
68+
def copy_file_to_container(
69+
container: DockerEnvironment,
70+
src_path: str | Path,
71+
dest_path: str | Path,
72+
):
73+
"""
74+
Copy a file from the local filesystem to a Docker container.
75+
"""
76+
if not str(dest_path).startswith("/"):
77+
# If not an absolute path, assume relative to container's cwd
78+
dest_path = f"{container.config.cwd}/{dest_path}"
79+
cmd = [
80+
"docker",
81+
"cp",
82+
str(src_path),
83+
f"{container.container_id}:{dest_path}",
84+
]
85+
# Ensure destination folder exists
86+
assert_zero_exit_code(container.execute(f"mkdir -p {Path(dest_path).parent}"))
87+
result = subprocess.run(cmd, check=False, capture_output=True, text=True)
88+
if result.returncode != 0:
89+
raise RuntimeError(
90+
f"Failed to copy {src_path} to {container.container_id}:{dest_path}: {result.stdout}{result.stderr}"
91+
)
92+
return result
93+
94+
95+
def copy_file_from_container(
96+
container: DockerEnvironment,
97+
src_path: str | Path,
98+
dest_path: str | Path,
99+
):
100+
"""
101+
Copy a file from a Docker container to the local filesystem.
102+
"""
103+
cmd = [
104+
"docker",
105+
"cp",
106+
f"{container.container_id}:{src_path}",
107+
str(dest_path),
108+
]
109+
Path(dest_path).parent.mkdir(parents=True, exist_ok=True)
110+
result = subprocess.run(cmd, check=False, capture_output=True, text=True)
111+
if result.returncode != 0:
112+
raise RuntimeError(
113+
f"Failed to copy {container.container_id}:{src_path} to {dest_path}: {result.stdout}{result.stderr}"
114+
)
115+
return result

0 commit comments

Comments
 (0)