Skip to content

Commit 72a95f7

Browse files
committed
Include full files that agent modified
1 parent 0c55329 commit 72a95f7

2 files changed

Lines changed: 73 additions & 4 deletions

File tree

codeclash/agents/player.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from codeclash.agents.utils import GameContext
1010
from codeclash.constants import GH_ORG
11-
from codeclash.tournaments.utils.git_utils import filter_git_diff
11+
from codeclash.tournaments.utils.git_utils import extract_modified_code_file_paths_from_diff, filter_git_diff
1212
from codeclash.utils.environment import assert_zero_exit_code, create_file_in_container
1313
from codeclash.utils.log import get_logger
1414

@@ -40,6 +40,7 @@ def __init__(
4040
"player_unique_id": self._player_unique_id,
4141
"diff": {0: ""}, # mapping round -> diff
4242
"incremental_diff": {0: ""}, # mapping round -> diff
43+
"modified_files": {0: {}}, # mapping round -> {file_path: file_content}
4344
"created_timestamp": int(time.time()),
4445
"config": self.config,
4546
"initial_commit_hash": self._get_commit_hash(),
@@ -67,8 +68,11 @@ def pre_run_hook(self, *, new_round: int) -> None:
6768
def post_run_hook(self, *, round: int) -> None:
6869
"""Should be called after we called the run method."""
6970
self._commit()
70-
self._metadata["diff"][round] = self._get_round_diff(round)
71+
raw_diff = self._get_round_diff(round)
72+
filtered_diff = filter_git_diff(raw_diff)
73+
self._metadata["diff"][round] = raw_diff
7174
self._metadata["incremental_diff"][round] = self._get_round_diff(round, incremental=True)
75+
self._metadata["modified_files"][round] = self._extract_modified_files_from_diff(filtered_diff)
7276
if self.push:
7377
for cmd in [
7478
f"git push origin {self._branch_name}",
@@ -151,6 +155,23 @@ def _commit(self) -> None:
151155
self._tag_round(r)
152156
self.logger.info(f"Committed changes for {self.name} for round {r}")
153157

158+
def _extract_modified_files_from_diff(self, diff: str) -> dict[str, str]:
159+
"""Extract modified file paths from a git diff and get their full content.
160+
Returns a dict mapping file path to full file content.
161+
Only includes common code file extensions.
162+
"""
163+
file_paths = extract_modified_code_file_paths_from_diff(diff)
164+
165+
file_contents = {}
166+
for file_path in file_paths:
167+
out = assert_zero_exit_code(
168+
self.environment.execute(f"cat '{file_path}'"),
169+
logger=self.logger,
170+
)
171+
file_contents[file_path] = out["output"]
172+
173+
return file_contents
174+
154175
def _get_round_diff(self, round: int, *, incremental: bool = False) -> str:
155176
"""Get the diff between the round and initial version (round 0).
156177
If incremental is True, get the diff between the round and the previous round.

codeclash/tournaments/utils/git_utils.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import re
2+
13
from codeclash.utils.log import get_logger
24

35

4-
def filter_git_diff(text: str) -> str:
6+
def filter_git_diff(diff: str) -> str:
57
"""Return a git diff with any file sections mentioning binary content removed."""
68
logger = get_logger(__name__)
7-
lines = text.splitlines(keepends=True)
9+
lines = diff.splitlines(keepends=True)
810
out: list[str] = []
911
block: list[str] = []
1012
in_block = False
@@ -56,3 +58,49 @@ def extract_file_path_from_block(bl: list[str]) -> str:
5658
out.extend(block)
5759

5860
return "".join(out)
61+
62+
63+
def extract_modified_code_file_paths_from_diff(diff: str) -> list[str]:
64+
"""Extract modified file paths from a git diff.
65+
66+
Args:
67+
diff: Git diff text
68+
69+
Returns:
70+
List of file paths that were modified
71+
"""
72+
include_extensions = [
73+
".py",
74+
".js",
75+
".ts",
76+
".java",
77+
".cpp",
78+
".c",
79+
".h",
80+
".hpp",
81+
".php",
82+
".rb",
83+
".go",
84+
".rs",
85+
".kt",
86+
".swift",
87+
".md",
88+
".txt",
89+
".sh",
90+
]
91+
92+
file_paths = []
93+
lines = diff.splitlines()
94+
95+
for line in lines:
96+
if line.startswith("diff --git "):
97+
# Format: "diff --git a/path/to/file b/path/to/file"
98+
match = re.match(r"diff --git a/(.+) b/(.+)", line)
99+
if match:
100+
file_path = match.group(2) # Use the "b/" path (after changes)
101+
102+
# Check if file has an included extension
103+
if any(file_path.endswith(ext) for ext in include_extensions):
104+
file_paths.append(file_path)
105+
106+
return file_paths

0 commit comments

Comments
 (0)