Skip to content

Commit 971f386

Browse files
authored
Merge pull request #21 from BrunoV21/process-patch
Process patch
2 parents e02d306 + 1372c7b commit 971f386

File tree

7 files changed

+47
-38
lines changed

7 files changed

+47
-38
lines changed

codetide/agents/tide/agent.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def pass_custom_logger_fn(self)->Self:
6262
def approve(self):
6363
self._has_patch = False
6464
if os.path.exists(self.patch_path):
65-
changed_paths = process_patch(self.patch_path, open_file, write_file, remove_file, file_exists)
65+
changed_paths = process_patch(self.patch_path, open_file, write_file, remove_file, file_exists, root_path=self.tide.rootpath)
6666
self.changed_paths.extend(changed_paths)
6767

6868
previous_response = self.history[-1]
@@ -81,10 +81,10 @@ def reject(self, feedback :str):
8181

8282
@property
8383
def patch_path(self)->Path:
84-
if not os.path.exists(DEFAULT_STORAGE_PATH):
85-
os.makedirs(DEFAULT_STORAGE_PATH, exist_ok=True)
84+
if not os.path.exists(self.tide.rootpath / DEFAULT_STORAGE_PATH):
85+
os.makedirs(self.tide.rootpath / DEFAULT_STORAGE_PATH, exist_ok=True)
8686

87-
return DEFAULT_STORAGE_PATH / f"{self.session_id}.bash"
87+
return self.tide.rootpath / DEFAULT_STORAGE_PATH / f"{self.session_id}.bash"
8888

8989
@staticmethod
9090
def trim_messages(messages, tokenizer_fn, max_tokens :Optional[int]=None):
@@ -220,12 +220,12 @@ def commit(self, message :str):
220220
"""
221221
try:
222222
# Open the repository
223-
repo = self.repo
223+
repo = self.tide.repo
224224

225225
# Get author and committer information
226226
config = repo.config
227-
author_name = config.get('user.name', 'Unknown Author')
228-
author_email = config.get('user.email', 'unknown@example.com')
227+
author_name = config._get('user.name')[1].value or 'Unknown Author'
228+
author_email = config._get('user.email')[1].value or 'unknown@example.com'
229229

230230
author = pygit2.Signature(author_name, author_email)
231231
committer = author # Typically same as author

codetide/agents/tide/prompts.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@
327327
"""
328328

329329
CMD_TRIGGER_PLANNING_STEPS = """
330-
330+
You must operate in a multi-step planning and execution mode: first outline the plan step by step in a sequential way, then ask for my revision.
331+
Do not start implementing the steps without my approval.
331332
"""
332333

333334
CMD_WRITE_TESTS_PROMPT = """

codetide/core/defaults.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989

9090
BREAKLINE = "\n"
9191

92+
DEFAULT_BYTES_CONTENT_PLACEHOLDERS = "< suppressed bytes content >"
93+
9294
CODETIDE_ASCII_ART = """
9395
9496
███████╗ ██████╗ ██████╗ ███████╗████████╗██╗██████╗ ███████╗

codetide/mcp/tools/patch_code/__init__.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .parser import Parser, patch_to_commit
44
# from ....core.common import writeFile
55

6-
from typing import Dict, Tuple, List, Callable
6+
from typing import Dict, Optional, Tuple, List, Callable, Union
77
import pathlib
88
import os
99

@@ -108,18 +108,24 @@ def process_patch(
108108
open_fn: Callable[[str], str],
109109
write_fn: Callable[[str, str], None],
110110
remove_fn: Callable[[str], None],
111-
exists_fn: Callable[[str], bool]
111+
exists_fn: Callable[[str], bool],
112+
root_path: Optional[Union[str, pathlib.Path]]=None
112113
) -> List[str]:
113114
"""The main entrypoint function to process a patch from text to filesystem."""
114115
if not os.path.exists(patch_path):
115116
raise DiffError("Patch path {patch_path} does not exist.")
116117

118+
if root_path is not None:
119+
root_path = pathlib.Path(root_path)
120+
117121
# Normalize line endings before processing
118122
text = open_fn(patch_path)
119123

120124
# FIX: Check for existence of files to be added before parsing.
121125
paths_to_add = identify_files_added(text)
122126
for p in paths_to_add:
127+
if root_path is not None:
128+
p = str(root_path / p)
123129
if exists_fn(p):
124130
raise DiffError(f"Add File Error - file already exists: {p}")
125131

@@ -128,6 +134,8 @@ def process_patch(
128134
# Load files with normalized line endings
129135
orig_files = {}
130136
for path in paths_needed:
137+
if root_path is not None:
138+
path = str(root_path / path)
131139
orig_files[path] = open_fn(path)
132140

133141
patch, _fuzz = text_to_patch(text, orig_files)

codetide/parsers/generic_parser.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from ..core.models import CodeBase, CodeFileModel, ImportStatement
2+
from ..core.defaults import DEFAULT_BYTES_CONTENT_PLACEHOLDERS
23
from ..parsers.base_parser import BaseParser
34
from ..core.common import readFile
45

@@ -54,10 +55,10 @@ async def parse_file(self, file_path: Union[str, Path], root_path: Optional[Unio
5455

5556
return codeFile
5657

57-
def parse_code(self, file_path :Path, code :str):
58+
def parse_code(self, file_path :Path, code :Optional[str]=None):
5859
codeFile = CodeFileModel(
5960
file_path=str(file_path),
60-
raw=code
61+
raw=code if not isinstance(code, bytes) else DEFAULT_BYTES_CONTENT_PLACEHOLDERS
6162
)
6263
return codeFile
6364

examples/hf_demo_space/app.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from aicore.llm import Llm, LlmConfig
1919
from aicore.config import Config
2020

21-
from git_utils import push_new_branch, validate_git_url, checkout_new_branch
21+
from git_utils import commit_and_push_changes, validate_git_url, checkout_new_branch
2222
from chainlit.cli import run_chainlit
2323
from typing import Optional
2424
from pathlib import Path
@@ -153,6 +153,7 @@ async def start_chatr():
153153

154154
agent_tide_ui.agent_tide.llm = Llm.from_config(config.llm)
155155
agent_tide_ui.agent_tide.llm.provider.session_id = agent_tide_ui.agent_tide.session_id
156+
agent_tide_ui.agent_tide.pass_custom_logger_fn()
156157

157158
session_dir_path = DEFAULT_SESSIONS_WORKSPACE / session_id
158159
if not os.path.exists(session_dir_path):
@@ -260,10 +261,9 @@ async def on_stop_steps(action :cl.Action):
260261
@cl.action_callback("checkout_commit_push")
261262
async def on_checkout_commit_push(action :cl.Action):
262263
agent_tide_ui: AgentTideUi = cl.user_session.get("AgentTideUi")
263-
await agent_tide_ui.agent_tide.prepare_commit()
264-
agent_tide_ui.agent_tide.commit("AgentTide - add all and push")
265-
266-
push_new_branch(agent_tide_ui.agent_tide.tide.repo, branch_name=cl.user_session.get("current_branch_name"))
264+
# await agent_tide_ui.agent_tide.prepare_commit()
265+
# agent_tide_ui.agent_tide.commit("AgentTide - add all and push")
266+
await commit_and_push_changes(agent_tide_ui.agent_tide.tide.rootpath, branch_name=cl.user_session.get("current_branch_name"), commit_message="AgentTide - add all and push", checkout=False)
267267

268268
@cl.action_callback("inspect_code_context")
269269
async def on_inspect_context(action :cl.Action):

examples/hf_demo_space/git_utils.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async def validate_git_url(url) -> None:
4141
except subprocess.CalledProcessError as e:
4242
raise ValueError(f"Invalid Git repository URL: {url}. Error: {e.stderr}") from e
4343

44-
async def commit_and_push_changes(repo_path: Path, branch_name: str = None, commit_message: str = "Auto-commit: Save changes") -> None:
44+
async def commit_and_push_changes(repo_path: Path, branch_name: str = None, commit_message: str = "Auto-commit: Save changes", checkout :bool=True) -> None:
4545
"""Add all changes, commit with default message, and push to remote."""
4646

4747
repo_path_str = str(repo_path)
@@ -51,27 +51,26 @@ async def commit_and_push_changes(repo_path: Path, branch_name: str = None, comm
5151
if not branch_name:
5252
branch_name = f"agent-tide-{ulid()}"
5353

54-
# Create and checkout new branch
55-
process = await asyncio.create_subprocess_exec(
56-
"git", "checkout", "-b", branch_name,
57-
cwd=repo_path_str,
58-
stdout=asyncio.subprocess.PIPE,
59-
stderr=asyncio.subprocess.PIPE,
60-
text=True
61-
)
62-
63-
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=10)
64-
65-
if process.returncode != 0:
66-
raise subprocess.CalledProcessError(process.returncode, ["git", "checkout", "-b", branch_name], stdout, stderr)
67-
54+
if checkout:
55+
# Create and checkout new branch
56+
process = await asyncio.create_subprocess_exec(
57+
"git", "checkout", "-b", branch_name,
58+
cwd=repo_path_str,
59+
stdout=asyncio.subprocess.PIPE,
60+
stderr=asyncio.subprocess.PIPE
61+
)
62+
63+
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=10)
64+
65+
if process.returncode != 0:
66+
raise subprocess.CalledProcessError(process.returncode, ["git", "checkout", "-b", branch_name], stdout, stderr)
67+
6868
# Add all changes
6969
process = await asyncio.create_subprocess_exec(
7070
"git", "add", ".",
7171
cwd=repo_path_str,
7272
stdout=asyncio.subprocess.PIPE,
73-
stderr=asyncio.subprocess.PIPE,
74-
text=True
73+
stderr=asyncio.subprocess.PIPE
7574
)
7675

7776
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=30)
@@ -84,8 +83,7 @@ async def commit_and_push_changes(repo_path: Path, branch_name: str = None, comm
8483
"git", "commit", "-m", commit_message,
8584
cwd=repo_path_str,
8685
stdout=asyncio.subprocess.PIPE,
87-
stderr=asyncio.subprocess.PIPE,
88-
text=True
86+
stderr=asyncio.subprocess.PIPE
8987
)
9088

9189
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=30)
@@ -101,8 +99,7 @@ async def commit_and_push_changes(repo_path: Path, branch_name: str = None, comm
10199
"git", "push", "origin", branch_name,
102100
cwd=repo_path_str,
103101
stdout=asyncio.subprocess.PIPE,
104-
stderr=asyncio.subprocess.PIPE,
105-
text=True
102+
stderr=asyncio.subprocess.PIPE
106103
)
107104

108105
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=60)

0 commit comments

Comments
 (0)