diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 349a88418..1cdc392d4 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -13,7 +13,7 @@ import git import openai import requests from openai.error import APIError, RateLimitError, ServiceUnavailableError -from rich.console import Console +from rich.console import Console, Text from rich.live import Live from rich.markdown import Markdown @@ -491,6 +491,9 @@ class Coder: if add_rel_files_message: return add_rel_files_message + def update_cur_messages(self, content, edited): + self.cur_messages += [dict(role="assistant", content=content)] + def auto_commit(self): res = self.commit(history=self.cur_messages, prefix="aider: ") if res: @@ -646,6 +649,8 @@ class Coder: show_resp = self.render_incremental_response(True) if self.pretty: show_resp = Markdown(show_resp, style=self.assistant_output_color, code_theme="default") + else: + show_resp = Text(show_resp) self.io.console.print(show_resp) self.io.console.print(tokens) diff --git a/aider/coders/editblock_func_coder.py b/aider/coders/editblock_func_coder.py index a4b25af3c..53d52d8e6 100644 --- a/aider/coders/editblock_func_coder.py +++ b/aider/coders/editblock_func_coder.py @@ -1,9 +1,11 @@ +import json import os from aider import diffs from ..dump import dump # noqa: F401 from .base_coder import Coder +from .editblock_coder import do_replace from .editblock_func_prompts import EditBlockFunctionPrompts @@ -56,92 +58,44 @@ class EditBlockFunctionCoder(Coder): self.gpt_prompts = EditBlockFunctionPrompts() super().__init__(*args, **kwargs) - def update_cur_messages(self, content, edited): - if edited: - self.cur_messages += [ - dict(role="assistant", content=self.gpt_prompts.redacted_edit_message) - ] - else: - self.cur_messages += [dict(role="assistant", content=content)] - - def get_context_from_history(self, history): - context = "" - if history: - context += "# Context:\n" - for msg in history: - if msg["role"] == "user": - context += msg["role"].upper() + ": " + msg["content"] + "\n" - return context - def render_incremental_response(self, final=False): if self.partial_response_content: return self.partial_response_content args = self.parse_partial_args() - - if not args: - return - - explanation = args.get("explanation") - files = args.get("files", []) - - res = "" - if explanation: - res += f"{explanation}\n\n" - - for i, file_upd in enumerate(files): - path = file_upd.get("path") - if not path: - continue - content = file_upd.get("content") - if not content: - continue - - this_final = (i < len(files) - 1) or final - res += self.live_diffs(path, content, this_final) - - return res - - def live_diffs(self, fname, content, final): - lines = content.splitlines(keepends=True) - - # ending an existing block - full_path = os.path.abspath(os.path.join(self.root, fname)) - - with open(full_path, "r") as f: - orig_lines = f.readlines() - - show_diff = diffs.diff_partial_update( - orig_lines, - lines, - final, - fname=fname, - ).splitlines() - - return "\n".join(show_diff) + res = json.dumps(args, indent=4) + return "```\n" + res + "\n```\n" def update_files(self): name = self.partial_response_function_call.get("name") + if name and name != "replace_lines": - raise ValueError(f'Unknown function_call name="{name}", use name="write_file"') + raise ValueError(f'Unknown function_call name="{name}", use name="replace_lines"') args = self.parse_partial_args() if not args: return - files = args.get("files", []) + edits = args.get("edits", []) edited = set() - for file_upd in files: - path = file_upd.get("path") - if not path: - raise ValueError(f"Missing path parameter: {file_upd}") + for edit in edits: + path = get_arg(edit, "path") + original = get_arg(edit, "original_lines") + updated = get_arg(edit, "updated_lines") - content = file_upd.get("content") - if not content: - raise ValueError(f"Missing content parameter: {file_upd}") - - if self.allowed_to_edit(path, content): + full_path = self.allowed_to_edit(path) + if not full_path: + continue + if do_replace(full_path, original, updated, self.dry_run): edited.add(path) + continue + self.io.tool_error(f"Failed to apply edit to {path}") return edited + + +def get_arg(edit, arg): + if arg not in edit: + raise ValueError(f"Missing `{arg}` parameter: {edit}") + return edit[arg]