From 9364ce1f150ca33d2541b7cab7f31fe185db0ce2 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 5 Aug 2024 09:06:00 +0200 Subject: [PATCH 001/135] Fix typos discovered by codespell --- HISTORY.md | 2 +- aider/website/HISTORY.md | 2 +- aider/website/docs/ctags.md | 2 +- aider/website/docs/faq.md | 2 +- aider/website/docs/troubleshooting/edit-errors.md | 2 +- aider/website/examples/README.md | 2 +- requirements/requirements.in | 2 +- tests/basic/test_editblock.py | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index db7a3554f..d30a8759b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -478,7 +478,7 @@ - Added `/git` command to run git from inside aider chats. - Use Meta-ENTER (Esc+ENTER in some environments) to enter multiline chat messages. -- Create a `.gitignore` with `.aider*` to prevent users from accidentaly adding aider files to git. +- Create a `.gitignore` with `.aider*` to prevent users from accidentally adding aider files to git. - Check pypi for newer versions and notify user. - Updated keyboard interrupt logic so that 2 ^C in 2 seconds always forces aider to exit. - Provide GPT with detailed error if it makes a bad edit block, ask for a retry. diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index ee99d10f2..3a75e2f27 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -493,7 +493,7 @@ cog.out(text) - Added `/git` command to run git from inside aider chats. - Use Meta-ENTER (Esc+ENTER in some environments) to enter multiline chat messages. -- Create a `.gitignore` with `.aider*` to prevent users from accidentaly adding aider files to git. +- Create a `.gitignore` with `.aider*` to prevent users from accidentally adding aider files to git. - Check pypi for newer versions and notify user. - Updated keyboard interrupt logic so that 2 ^C in 2 seconds always forces aider to exit. - Provide GPT with detailed error if it makes a bad edit block, ask for a retry. diff --git a/aider/website/docs/ctags.md b/aider/website/docs/ctags.md index b57f8de33..7edebf886 100644 --- a/aider/website/docs/ctags.md +++ b/aider/website/docs/ctags.md @@ -228,7 +228,7 @@ Some possible approaches to reducing the amount of map data are: - Distill the global map, to prioritize important symbols and discard "internal" or otherwise less globally relevant identifiers. Possibly enlist `gpt-3.5-turbo` to perform this distillation in a flexible and language agnostic way. - Provide a mechanism for GPT to start with a distilled subset of the global map, and let it ask to see more detail about subtrees or keywords that it feels are relevant to the current coding task. - - Attempt to analyize the natural language coding task given by the user and predict which subset of the repo map is relevant. Possibly by analysis of prior coding chats within the specific repo. Work on certain files or types of features may require certain somewhat predictable context from elsewhere in the repo. Vector and keyword search against the chat history, repo map or codebase may help here. + - Attempt to analyze the natural language coding task given by the user and predict which subset of the repo map is relevant. Possibly by analysis of prior coding chats within the specific repo. Work on certain files or types of features may require certain somewhat predictable context from elsewhere in the repo. Vector and keyword search against the chat history, repo map or codebase may help here. One key goal is to prefer solutions which are language agnostic or which can be easily deployed against most popular code languages. diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index dbaefa327..853a41584 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -37,7 +37,7 @@ If you still wish to add lots of files to the chat, you can: - Use a wildcard when you launch aider: `aider src/*.py` - Use a wildcard with the in-chat `/add` command: `/add src/*.py` -- Give the `/add` command a directory name and it will recurisvely add every file under that dir: `/add src` +- Give the `/add` command a directory name and it will recursively add every file under that dir: `/add src` ## How can I run aider locally from source code? diff --git a/aider/website/docs/troubleshooting/edit-errors.md b/aider/website/docs/troubleshooting/edit-errors.md index 6fe8978ad..56d213485 100644 --- a/aider/website/docs/troubleshooting/edit-errors.md +++ b/aider/website/docs/troubleshooting/edit-errors.md @@ -34,7 +34,7 @@ so editing errors are probably unavoidable. Many LLM now have very large context windows, but filling them with irrelevant code or conversation -can cofuse the model. +can confuse the model. - Don't add too many files to the chat, *just* add the files you think need to be edited. Aider also sends the LLM a [map of your entire git repo](https://aider.chat/docs/repomap.html), so other relevant code will be included automatically. diff --git a/aider/website/examples/README.md b/aider/website/examples/README.md index 37e7031ae..80843df1d 100644 --- a/aider/website/examples/README.md +++ b/aider/website/examples/README.md @@ -8,7 +8,7 @@ has_toc: false # Example chat transcripts Below are some chat transcripts showing what it's like to code with aider. -In the chats, you'll see a varity of coding tasks like generating new code, editing existing code, debugging, exploring unfamiliar code, etc. +In the chats, you'll see a variety of coding tasks like generating new code, editing existing code, debugging, exploring unfamiliar code, etc. * [**Hello World Flask App**](https://aider.chat/examples/hello-world-flask.html): Start from scratch and have aider create a simple Flask app with various endpoints, such as adding two numbers and calculating the Fibonacci sequence. diff --git a/requirements/requirements.in b/requirements/requirements.in index d9620ffa8..8cdb092e9 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -23,7 +23,7 @@ litellm flake8 importlib_resources -# The proper depdendency is networkx[default], but this brings +# The proper dependency is networkx[default], but this brings # in matplotlib and a bunch of other deps # https://github.com/networkx/networkx/blob/d7132daa8588f653eacac7a5bae1ee85a183fa43/pyproject.toml#L57 # We really only need networkx itself and scipy for the repomap. diff --git a/tests/basic/test_editblock.py b/tests/basic/test_editblock.py index 92083c0b1..56ccd3f52 100644 --- a/tests/basic/test_editblock.py +++ b/tests/basic/test_editblock.py @@ -181,9 +181,9 @@ aider/coder.py aider/coder.py <<<<<<< SEARCH - self.console.print("[red]Skipped commmit.") + self.console.print("[red]Skipped commit.") ======= - self.io.tool_error("Skipped commmit.") + self.io.tool_error("Skipped commit.") >>>>>>> REPLACE""" # Should not raise a ValueError From 1c73e7d43a0a6d73a2353f040959ff3efc7b57fb Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 5 Sep 2024 14:35:34 -0700 Subject: [PATCH 002/135] turn off suggest shell commands during benchmarks --- benchmark/benchmark.py | 1 + 1 file changed, 1 insertion(+) diff --git a/benchmark/benchmark.py b/benchmark/benchmark.py index e77853a69..3d559b9be 100755 --- a/benchmark/benchmark.py +++ b/benchmark/benchmark.py @@ -567,6 +567,7 @@ def run_test_real( verbose=verbose, # auto_lint=False, # disabled for code-in-json experiments cache_prompts=True, + suggest_shell_commands=False, ) coder.max_apply_update_errors = max_apply_update_errors From 8d151a35737691e2eccc355f00621a2801f19554 Mon Sep 17 00:00:00 2001 From: Jun Siang Cheah Date: Thu, 5 Sep 2024 23:04:54 +0100 Subject: [PATCH 003/135] docs: clean up yi-coder model names --- aider/website/_data/edit_leaderboard.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 7c3c5d484..752397c7e 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -950,7 +950,7 @@ - dirname: 2024-09-04-16-08-09--yi-coder-9b-whole test_cases: 133 - model: openai/hf:01-ai/Yi-Coder-9B-Chat + model: Yi Coder 9B Chat edit_format: whole commit_hash: c4e4967 pass_rate_1: 46.6 @@ -974,7 +974,7 @@ - dirname: 2024-09-04-16-17-33--yi-coder-9b-chat-q4_0-whole test_cases: 133 - model: ollama/yi-coder:9b-chat-q4_0 + model: yi-coder:9b-chat-q4_0 edit_format: whole commit_hash: c4e4967 pass_rate_1: 41.4 From 795810ffb8e94536830aed698ef3639be0aafa38 Mon Sep 17 00:00:00 2001 From: fry69 <142489379+fry69@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:44:42 +0200 Subject: [PATCH 004/135] fix: update model configurations --- aider/models.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/aider/models.py b/aider/models.py index 41b3eba93..5fc20df95 100644 --- a/aider/models.py +++ b/aider/models.py @@ -18,7 +18,7 @@ from aider.dump import dump # noqa: F401 from aider.llm import litellm DEFAULT_MODEL_NAME = "gpt-4o" -ANTHROPIC_BETA_HEADER = "max-tokens-3-5-sonnet-2024-07-15,prompt-caching-2024-07-31" +ANTHROPIC_BETA_HEADER = "prompt-caching-2024-07-31" OPENAI_MODELS = """ gpt-4 @@ -306,10 +306,8 @@ MODEL_SETTINGS = [ examples_as_sys_msg=True, accepts_images=True, max_tokens=8192, - extra_headers={ - "anthropic-beta": "max-tokens-3-5-sonnet-2024-07-15", - }, reminder="user", + cache_control=True, ), # Vertex AI Claude models # Does not yet support 8k token @@ -320,6 +318,7 @@ MODEL_SETTINGS = [ use_repo_map=True, examples_as_sys_msg=True, accepts_images=True, + max_tokens=8192, reminder="user", ), ModelSettings( From 2aef59e62492485a4f0b669de53892ab3a6f5c68 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 6 Sep 2024 13:32:15 -0700 Subject: [PATCH 005/135] update name to DeepSeek V2.5 --- aider/website/_data/edit_leaderboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 752397c7e..96bb19950 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -997,7 +997,7 @@ - dirname: 2024-09-05-14-50-11--deepseek-sep5-no-shell test_cases: 133 - model: DeepSeek Chat V2.5 + model: DeepSeek V2.5 edit_format: diff commit_hash: 1279c86 pass_rate_1: 54.9 From e9c0c82e0363fea83747a7be9c314bc087a1cebb Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 6 Sep 2024 13:47:14 -0700 Subject: [PATCH 006/135] added reflection 70b --- aider/website/_data/edit_leaderboard.yml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 96bb19950..217c82142 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1017,4 +1017,26 @@ versions: 0.55.1.dev seconds_per_case: 49.6 total_cost: 0.0998 - \ No newline at end of file + +- dirname: 2024-09-06-19-55-17--reflection-hyperbolic-whole-output2 + test_cases: 133 + model: Reflection-70B + edit_format: whole + commit_hash: 74631ee-dirty, 2aef59e-dirty + pass_rate_1: 33.1 + pass_rate_2: 42.1 + percent_cases_well_formed: 100.0 + error_outputs: 2 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 10 + lazy_comments: 26 + syntax_errors: 1 + indentation_errors: 3 + exhausted_context_windows: 0 + test_timeouts: 3 + command: (not currently supported) + date: 2024-09-06 + versions: 0.55.1.dev + seconds_per_case: 61.6 + total_cost: 0.0000 \ No newline at end of file From 304566a914c6b7d459c7d9deb1da7a219ba268ea Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 6 Sep 2024 13:50:08 -0700 Subject: [PATCH 007/135] added reflection 70b --- aider/website/docs/leaderboards/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/docs/leaderboards/index.md b/aider/website/docs/leaderboards/index.md index 52f26e903..2414539b0 100644 --- a/aider/website/docs/leaderboards/index.md +++ b/aider/website/docs/leaderboards/index.md @@ -321,6 +321,6 @@ mod_dates = [get_last_modified_date(file) for file in files] latest_mod_date = max(mod_dates) cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}") ]]]--> -September 05, 2024. +September 06, 2024.

From 5344052aeb593285fefc984686add2ed32e978ee Mon Sep 17 00:00:00 2001 From: "Jay Alammar (aider)" Date: Fri, 6 Sep 2024 17:06:11 -0400 Subject: [PATCH 008/135] feat: add support for new Cohere models command-r-08-2024 and command-r-plus-08-2024 --- aider/models.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/aider/models.py b/aider/models.py index 5fc20df95..c213273e7 100644 --- a/aider/models.py +++ b/aider/models.py @@ -91,6 +91,19 @@ MODEL_SETTINGS = [ weak_model_name="gpt-4o-mini", reminder="sys", ), + # New Cohere models + ModelSettings( + "command-r-08-2024", + "whole", + weak_model_name="command-r-08-2024", + use_repo_map=True, + ), + ModelSettings( + "command-r-plus-08-2024", + "whole", + weak_model_name="command-r-plus-08-2024", + use_repo_map=True, + ), ModelSettings( "gpt-3.5-turbo-0125", "whole", From 68bd2b75c6ce63d7e38d6e04267490eddc711969 Mon Sep 17 00:00:00 2001 From: "Jay Alammar (aider)" Date: Fri, 6 Sep 2024 17:06:51 -0400 Subject: [PATCH 009/135] refactor: group Cohere models together in the model settings list --- aider/models.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/aider/models.py b/aider/models.py index c213273e7..50d5ffe0e 100644 --- a/aider/models.py +++ b/aider/models.py @@ -91,25 +91,13 @@ MODEL_SETTINGS = [ weak_model_name="gpt-4o-mini", reminder="sys", ), - # New Cohere models - ModelSettings( - "command-r-08-2024", - "whole", - weak_model_name="command-r-08-2024", - use_repo_map=True, - ), - ModelSettings( - "command-r-plus-08-2024", - "whole", - weak_model_name="command-r-plus-08-2024", - use_repo_map=True, - ), ModelSettings( "gpt-3.5-turbo-0125", "whole", weak_model_name="gpt-4o-mini", reminder="sys", ), + ), ModelSettings( "gpt-3.5-turbo-1106", "whole", @@ -352,6 +340,19 @@ MODEL_SETTINGS = [ weak_model_name="command-r-plus", use_repo_map=True, ), + # New Cohere models + ModelSettings( + "command-r-08-2024", + "whole", + weak_model_name="command-r-08-2024", + use_repo_map=True, + ), + ModelSettings( + "command-r-plus-08-2024", + "whole", + weak_model_name="command-r-plus-08-2024", + use_repo_map=True, + ), # Groq llama3 ModelSettings( "groq/llama3-70b-8192", From 74f1ceff9308e7472cf706c68071d9d3f5a0bb14 Mon Sep 17 00:00:00 2001 From: "Jay Alammar (aider)" Date: Fri, 6 Sep 2024 17:07:16 -0400 Subject: [PATCH 010/135] fix: resolve syntax error by removing extra closing parenthesis in model settings list --- aider/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index 50d5ffe0e..d8cba5d32 100644 --- a/aider/models.py +++ b/aider/models.py @@ -90,7 +90,6 @@ MODEL_SETTINGS = [ "whole", weak_model_name="gpt-4o-mini", reminder="sys", - ), ModelSettings( "gpt-3.5-turbo-0125", "whole", From d85979e1fbf5deee8020c0702fb596ce8e762cc9 Mon Sep 17 00:00:00 2001 From: "Jay Alammar (aider)" Date: Fri, 6 Sep 2024 17:07:23 -0400 Subject: [PATCH 011/135] fix: correct syntax error by fixing misplaced parenthesis in ModelSettings entries --- aider/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/models.py b/aider/models.py index d8cba5d32..50d5ffe0e 100644 --- a/aider/models.py +++ b/aider/models.py @@ -90,6 +90,7 @@ MODEL_SETTINGS = [ "whole", weak_model_name="gpt-4o-mini", reminder="sys", + ), ModelSettings( "gpt-3.5-turbo-0125", "whole", From df33498cad037fb3002c55a25852f93c74f7e0df Mon Sep 17 00:00:00 2001 From: "Jay Alammar (aider)" Date: Fri, 6 Sep 2024 17:07:32 -0400 Subject: [PATCH 012/135] fix: correct syntax error by removing extra closing parenthesis in ModelSettings definition --- aider/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index 50d5ffe0e..d8cba5d32 100644 --- a/aider/models.py +++ b/aider/models.py @@ -90,7 +90,6 @@ MODEL_SETTINGS = [ "whole", weak_model_name="gpt-4o-mini", reminder="sys", - ), ModelSettings( "gpt-3.5-turbo-0125", "whole", From 11020c8aee5a888593f78123335ef9b73e2da742 Mon Sep 17 00:00:00 2001 From: Krazer Date: Fri, 6 Sep 2024 17:35:55 -0500 Subject: [PATCH 013/135] send output through InputOutput --- aider/coders/base_coder.py | 19 ++----------------- aider/commands.py | 7 +++---- aider/io.py | 27 +++++++++++++++++++++++++++ aider/main.py | 4 ++-- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index cface7d72..8f433bae8 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -241,8 +241,6 @@ class Coder: dry_run=False, map_tokens=1024, verbose=False, - assistant_output_color="blue", - code_theme="default", stream=True, use_git=True, cur_messages=None, @@ -315,8 +313,6 @@ class Coder: self.auto_commits = auto_commits self.dirty_commits = dirty_commits - self.assistant_output_color = assistant_output_color - self.code_theme = code_theme self.dry_run = dry_run self.pretty = self.io.pretty @@ -1096,11 +1092,7 @@ class Coder: utils.show_messages(messages, functions=self.functions) self.multi_response_content = "" - if self.show_pretty() and self.stream: - mdargs = dict(style=self.assistant_output_color, code_theme=self.code_theme) - self.mdstream = MarkdownStream(mdargs=mdargs) - else: - self.mdstream = None + self.mdstream=self.io.assistant_output("", self.stream) retry_delay = 0.125 @@ -1452,14 +1444,7 @@ class Coder: raise Exception("No data found in LLM response!") show_resp = self.render_incremental_response(True) - if self.show_pretty(): - show_resp = Markdown( - show_resp, style=self.assistant_output_color, code_theme=self.code_theme - ) - else: - show_resp = Text(show_resp or "") - - self.io.console.print(show_resp) + self.io.assistant_output(show_resp) if ( hasattr(completion.choices[0], "finish_reason") diff --git a/aider/commands.py b/aider/commands.py index 6f6fb6acd..71c5316a4 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -562,8 +562,7 @@ class Commands: "HEAD", ) - # don't use io.tool_output() because we don't want to log or further colorize - print(diff) + self.io.print(diff) def quote_fname(self, fname): if " " in fname and '"' not in fname: @@ -1030,9 +1029,9 @@ class Commands: if text: self.io.add_to_input_history(text) - print() + self.io.print() self.io.user_input(text, log_only=False) - print() + self.io.print() return text diff --git a/aider/io.py b/aider/io.py index d756505a2..93182bac5 100644 --- a/aider/io.py +++ b/aider/io.py @@ -18,6 +18,8 @@ from pygments.token import Token from rich.console import Console from rich.style import Style as RichStyle from rich.text import Text +from rich.markdown import Markdown +from aider.mdstream import MarkdownStream from .dump import dump # noqa: F401 from .utils import is_image_file @@ -177,6 +179,8 @@ class InputOutput: tool_output_color=None, tool_error_color="red", tool_warning_color="#FFA500", + assistant_output_color="blue", + code_theme="default", encoding="utf-8", dry_run=False, llm_history_file=None, @@ -191,6 +195,8 @@ class InputOutput: self.tool_output_color = tool_output_color if pretty else None self.tool_error_color = tool_error_color if pretty else None self.tool_warning_color = tool_warning_color if pretty else None + self.assistant_output_color = assistant_output_color + self.code_theme = code_theme self.input = input self.output = output @@ -563,6 +569,27 @@ class InputOutput: style = RichStyle(**style) self.console.print(*messages, style=style) + def assistant_output(self, message, stream=False): + mdStream = None + show_resp = message + + if self.pretty: + if stream: + mdargs = dict(style=self.assistant_output_color, code_theme=self.code_theme) + mdStream = MarkdownStream(mdargs=mdargs) + else: + show_resp = Markdown( + message, style=self.assistant_output_color, code_theme=self.code_theme + ) + else: + show_resp = Text(message or "") + + self.console.print(show_resp) + return mdStream + + def print(self, message): + print(message) + def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True): if blockquote: if strip: diff --git a/aider/main.py b/aider/main.py index aca80da84..fa334a00c 100644 --- a/aider/main.py +++ b/aider/main.py @@ -396,6 +396,8 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F user_input_color=args.user_input_color, tool_output_color=args.tool_output_color, tool_error_color=args.tool_error_color, + assistant_output_color=args.assistant_output_color, + code_theme=args.code_theme, dry_run=args.dry_run, encoding=args.encoding, llm_history_file=args.llm_history_file, @@ -577,8 +579,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F dry_run=args.dry_run, map_tokens=args.map_tokens, verbose=args.verbose, - assistant_output_color=args.assistant_output_color, - code_theme=args.code_theme, stream=args.stream, use_git=args.git, restore_chat_history=args.restore_chat_history, From 9d4316b1d5b6313545a3d7b656bf41ea2218e2d6 Mon Sep 17 00:00:00 2001 From: Krazer Date: Fri, 6 Sep 2024 17:39:22 -0500 Subject: [PATCH 014/135] add default empty message --- aider/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/io.py b/aider/io.py index 93182bac5..c2f82ffd3 100644 --- a/aider/io.py +++ b/aider/io.py @@ -587,7 +587,7 @@ class InputOutput: self.console.print(show_resp) return mdStream - def print(self, message): + def print(self, message=""): print(message) def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True): From 69b9a4510dc81e44629b7e55ac5c37b9cf60293a Mon Sep 17 00:00:00 2001 From: Krazer Date: Fri, 6 Sep 2024 17:40:40 -0500 Subject: [PATCH 015/135] remove unused --- aider/coders/base_coder.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 8f433bae8..41dca7528 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -18,16 +18,12 @@ from datetime import datetime from json.decoder import JSONDecodeError from pathlib import Path -from rich.console import Console, Text -from rich.markdown import Markdown - from aider import __version__, models, prompts, urls, utils from aider.commands import Commands from aider.history import ChatSummary from aider.io import ConfirmGroup, InputOutput from aider.linter import Linter from aider.llm import litellm -from aider.mdstream import MarkdownStream from aider.repo import ANY_GIT_ERROR, GitRepo from aider.repomap import RepoMap from aider.run_cmd import run_cmd From f4853d166fe943ab68d28355ec29aaa06ddc3dbe Mon Sep 17 00:00:00 2001 From: Krazer Date: Fri, 6 Sep 2024 18:08:51 -0500 Subject: [PATCH 016/135] remove console --- aider/coders/base_coder.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 41dca7528..7d92cb57f 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -313,11 +313,6 @@ class Coder: self.dry_run = dry_run self.pretty = self.io.pretty - if self.pretty: - self.console = Console() - else: - self.console = Console(force_terminal=False, no_color=True) - self.main_model = main_model if cache_prompts and self.main_model.cache_control: From 84758c6c8dcf123285fe749cb54ba5b6c1c1f707 Mon Sep 17 00:00:00 2001 From: fry69 <142489379+fry69@users.noreply.github.com> Date: Sat, 7 Sep 2024 16:11:00 +0200 Subject: [PATCH 017/135] Update CONTRIBUTING.md fix link to benchmark data folder --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 22bcece77..441c946fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ See the [benchmark README](https://github.com/paul-gauthier/aider/blob/main/benchmark/README.md) for information on running aider's code editing benchmarks. Submit results by opening a PR with edits to the -[benchmark results data files](https://github.com/paul-gauthier/aider/blob/main/_data/). +[benchmark results data files](https://github.com/paul-gauthier/aider/blob/main/aider/website/_data/). ## Pull Requests From d2379a6d7372fa2ad81cc22f9ff88a1c5c389daa Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sat, 7 Sep 2024 07:17:05 -0700 Subject: [PATCH 018/135] feat: add shell command suggestion toggle and related prompts --- aider/coders/base_coder.py | 11 +++++++++++ aider/coders/base_prompts.py | 5 +++++ aider/coders/editblock_prompts.py | 11 ++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index cface7d72..e66cd6fef 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -923,10 +923,21 @@ class Coder: lazy_prompt = self.gpt_prompts.lazy_prompt if self.main_model.lazy else "" platform_text = self.get_platform_info() + if self.suggest_shell_commands: + shell_cmd_prompt = self.gpt_prompts.shell_cmd_prompt.format(platform=platform_text) + shell_cmd_reminder = self.gpt_prompts.shell_cmd_reminder.format(platform=platform_text) + else: + shell_cmd_prompt = self.gpt_prompts.no_shell_cmd_prompt.format(platform=platform_text) + shell_cmd_reminder = self.gpt_prompts.no_shell_cmd_reminder.format( + platform=platform_text + ) + prompt = prompt.format( fence=self.fence, lazy_prompt=lazy_prompt, platform=platform_text, + shell_cmd_prompt=shell_cmd_prompt, + shell_cmd_reminder=shell_cmd_reminder, ) return prompt diff --git a/aider/coders/base_prompts.py b/aider/coders/base_prompts.py index d4e91b5e0..7e07a4f54 100644 --- a/aider/coders/base_prompts.py +++ b/aider/coders/base_prompts.py @@ -43,3 +43,8 @@ If you need to edit any of these files, ask me to *add them to the chat* first. read_only_files_prefix = """Here are some READ ONLY files, provided for your reference. Do not edit these files! """ + + shell_cmd_prompt = "" + shell_cmd_reminder = "" + no_shell_cmd_prompt = "" + no_shell_cmd_reminder = "" diff --git a/aider/coders/editblock_prompts.py b/aider/coders/editblock_prompts.py index 072e78a24..4d3502521 100644 --- a/aider/coders/editblock_prompts.py +++ b/aider/coders/editblock_prompts.py @@ -27,7 +27,10 @@ You can keep asking if you then decide you need to edit more files. All changes to files must use this *SEARCH/REPLACE block* format. ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*! +{shell_cmd_prompt} +""" + shell_cmd_prompt = """ 4. *Concisely* suggest any shell commands the user might want to run in ```bash blocks. Just suggest shell commands this way, not example code. @@ -36,7 +39,6 @@ Only suggest at most a few shell commands at a time, not more than 1-3. Use the appropriate shell based on the user's system info: {platform} - Examples of when to suggest shell commands: - If you changed a self-contained html file, suggest an OS-appropriate command to open a browser to view it to see the updated content. @@ -47,6 +49,10 @@ Examples of when to suggest shell commands: - Etc. """ + no_shell_cmd_prompt = """ +Keep in mind these details about the user's platform and environment: +{platform} +""" example_messages = [ dict( role="user", @@ -176,7 +182,10 @@ To rename files which have been added to the chat, use shell commands at the end {lazy_prompt} ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*! +{shell_cmd_reminder} +""" + shell_cmd_reminder = """ Examples of when to suggest shell commands: - If you changed a self-contained html file, suggest an OS-appropriate command to open a browser to view it to see the updated content. From e526d2890cc8d617fabc98f03964dcea57a4cfc6 Mon Sep 17 00:00:00 2001 From: fry69 <142489379+fry69@users.noreply.github.com> Date: Sun, 8 Sep 2024 12:47:07 +0200 Subject: [PATCH 019/135] fix: handle OSError when executing lint command --- aider/linter.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/aider/linter.py b/aider/linter.py index 9014c8890..23e0112c7 100644 --- a/aider/linter.py +++ b/aider/linter.py @@ -46,14 +46,18 @@ class Linter: cmd += " " + rel_fname cmd = cmd.split() - process = subprocess.Popen( - cmd, - cwd=self.root, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - encoding=self.encoding, - errors="replace", - ) + try: + process = subprocess.Popen( + cmd, + cwd=self.root, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + encoding=self.encoding, + errors="replace", + ) + except OSError as err: + print(f"Unable to execute lint command: {err}") + return stdout, _ = process.communicate() errors = stdout if process.returncode == 0: From ed7a9c656238ca0768bd81eb569a0682c8c7982e Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Sun, 8 Sep 2024 09:05:37 -0700 Subject: [PATCH 020/135] refactor: extract thread launch for load_slow_imports into function --- aider/main.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/aider/main.py b/aider/main.py index aca80da84..28080e7f1 100644 --- a/aider/main.py +++ b/aider/main.py @@ -686,9 +686,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.exit: return - thread = threading.Thread(target=load_slow_imports) - thread.daemon = True - thread.start() + launch_slow_imports_thread() while True: try: @@ -706,6 +704,12 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F coder.show_announcements() +def launch_slow_imports_thread(): + thread = threading.Thread(target=load_slow_imports) + thread.daemon = True + thread.start() + + def load_slow_imports(): # These imports are deferred in various ways to # improve startup time. From f54b6860dbfb75792515e38f2de04345437ebf16 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Sun, 8 Sep 2024 09:07:19 -0700 Subject: [PATCH 021/135] feat: optimize slow imports loading based on version and executable --- aider/main.py | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/aider/main.py b/aider/main.py index 28080e7f1..9a09a6ac4 100644 --- a/aider/main.py +++ b/aider/main.py @@ -705,24 +705,52 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F def launch_slow_imports_thread(): - thread = threading.Thread(target=load_slow_imports) + thread = threading.Thread(target=check_and_load_imports) thread.daemon = True thread.start() +def check_and_load_imports(): + import json + from pathlib import Path + + installs_file = Path.home() / ".aider" / "installs.json" + key = (__version__, sys.executable) + + try: + if installs_file.exists(): + with open(installs_file, "r") as f: + installs = json.load(f) + else: + installs = {} + + if str(key) not in installs: + load_slow_imports() + installs[str(key)] = True + installs_file.parent.mkdir(parents=True, exist_ok=True) + with open(installs_file, "w") as f: + json.dump(installs, f) + else: + thread = threading.Thread(target=load_slow_imports) + thread.daemon = True + thread.start() + except Exception as e: + print(f"Error in check_and_load_imports: {e}", file=sys.stderr) + + def load_slow_imports(): # These imports are deferred in various ways to # improve startup time. - # This func is called in a thread to load them in the background - # while we wait for the user to type their first message. + # This func is called either synchronously or in a thread + # depending on whether it's been run before for this version and executable. try: import httpx # noqa: F401 import litellm # noqa: F401 import networkx # noqa: F401 import numpy # noqa: F401 - except Exception: - pass + except Exception as e: + print(f"Error in load_slow_imports: {e}", file=sys.stderr) if __name__ == "__main__": From b4389f98fb13109a150f71b1e6447a46214407ef Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 8 Sep 2024 09:11:00 -0700 Subject: [PATCH 022/135] refactor: Synchronize slow imports and improve error handling --- aider/main.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/aider/main.py b/aider/main.py index 9a09a6ac4..aaf022c27 100644 --- a/aider/main.py +++ b/aider/main.py @@ -686,7 +686,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.exit: return - launch_slow_imports_thread() + check_and_load_imports(io) while True: try: @@ -704,15 +704,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F coder.show_announcements() -def launch_slow_imports_thread(): - thread = threading.Thread(target=check_and_load_imports) - thread.daemon = True - thread.start() -def check_and_load_imports(): - import json - from pathlib import Path +def check_and_load_imports(io): installs_file = Path.home() / ".aider" / "installs.json" key = (__version__, sys.executable) @@ -729,13 +723,13 @@ def check_and_load_imports(): installs[str(key)] = True installs_file.parent.mkdir(parents=True, exist_ok=True) with open(installs_file, "w") as f: - json.dump(installs, f) + json.dump(installs, f, indent=4) else: thread = threading.Thread(target=load_slow_imports) thread.daemon = True thread.start() except Exception as e: - print(f"Error in check_and_load_imports: {e}", file=sys.stderr) + io.tool_warning(f"Error in check_and_load_imports: {e}", file=sys.stderr) def load_slow_imports(): From aeea629d173013f9e4a328a5c75da0c7f1172793 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Sun, 8 Sep 2024 09:11:03 -0700 Subject: [PATCH 023/135] feat: add verbose output to check_and_load_imports function --- aider/main.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/aider/main.py b/aider/main.py index aaf022c27..5677284f8 100644 --- a/aider/main.py +++ b/aider/main.py @@ -4,6 +4,7 @@ import os import re import sys import threading +import traceback from pathlib import Path import git @@ -686,7 +687,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.exit: return - check_and_load_imports(io) + check_and_load_imports(io, verbose=args.verbose) while True: try: @@ -706,30 +707,45 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F -def check_and_load_imports(io): - +def check_and_load_imports(io, verbose=False): installs_file = Path.home() / ".aider" / "installs.json" key = (__version__, sys.executable) + if verbose: + io.tool_output(f"Checking imports for version {__version__} and executable {sys.executable}") + io.tool_output(f"Installs file: {installs_file}") + try: if installs_file.exists(): with open(installs_file, "r") as f: installs = json.load(f) + if verbose: + io.tool_output("Installs file exists and loaded") else: installs = {} + if verbose: + io.tool_output("Installs file does not exist, creating new dictionary") if str(key) not in installs: + if verbose: + io.tool_output("First run for this version and executable, loading imports synchronously") load_slow_imports() installs[str(key)] = True installs_file.parent.mkdir(parents=True, exist_ok=True) with open(installs_file, "w") as f: json.dump(installs, f, indent=4) + if verbose: + io.tool_output("Imports loaded and installs file updated") else: + if verbose: + io.tool_output("Not first run, loading imports in background thread") thread = threading.Thread(target=load_slow_imports) thread.daemon = True thread.start() except Exception as e: io.tool_warning(f"Error in check_and_load_imports: {e}", file=sys.stderr) + if verbose: + io.tool_output(f"Full exception details: {traceback.format_exc()}") def load_slow_imports(): From 1e9ff842f3e94de97be6c543f3f5876df3617eab Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Sun, 8 Sep 2024 09:11:08 -0700 Subject: [PATCH 024/135] style: format code with linter --- aider/main.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/aider/main.py b/aider/main.py index 5677284f8..9f5af89fe 100644 --- a/aider/main.py +++ b/aider/main.py @@ -705,14 +705,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F coder.show_announcements() - - def check_and_load_imports(io, verbose=False): installs_file = Path.home() / ".aider" / "installs.json" key = (__version__, sys.executable) if verbose: - io.tool_output(f"Checking imports for version {__version__} and executable {sys.executable}") + io.tool_output( + f"Checking imports for version {__version__} and executable {sys.executable}" + ) io.tool_output(f"Installs file: {installs_file}") try: @@ -728,7 +728,9 @@ def check_and_load_imports(io, verbose=False): if str(key) not in installs: if verbose: - io.tool_output("First run for this version and executable, loading imports synchronously") + io.tool_output( + "First run for this version and executable, loading imports synchronously" + ) load_slow_imports() installs[str(key)] = True installs_file.parent.mkdir(parents=True, exist_ok=True) From 9982f439e4864d29764dd131a1da4d6a33e27bfc Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 8 Sep 2024 09:18:20 -0700 Subject: [PATCH 025/135] feat: improve error handling for import loading --- aider/main.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/aider/main.py b/aider/main.py index 9f5af89fe..ab4950fb3 100644 --- a/aider/main.py +++ b/aider/main.py @@ -731,7 +731,14 @@ def check_and_load_imports(io, verbose=False): io.tool_output( "First run for this version and executable, loading imports synchronously" ) - load_slow_imports() + try: + load_slow_imports(swallow=False) + except Exception as err: + io.tool_error(str(err)) + io.tool_output("Error loading required imports. Did you install aider properly?") + io.tool_output("https://aider.chat/docs/install.html") + sys.exit(1) + installs[str(key)] = True installs_file.parent.mkdir(parents=True, exist_ok=True) with open(installs_file, "w") as f: @@ -745,12 +752,12 @@ def check_and_load_imports(io, verbose=False): thread.daemon = True thread.start() except Exception as e: - io.tool_warning(f"Error in check_and_load_imports: {e}", file=sys.stderr) + io.tool_warning(f"Error in checking imports: {e}") if verbose: io.tool_output(f"Full exception details: {traceback.format_exc()}") -def load_slow_imports(): +def load_slow_imports(swallow=True): # These imports are deferred in various ways to # improve startup time. # This func is called either synchronously or in a thread @@ -762,7 +769,8 @@ def load_slow_imports(): import networkx # noqa: F401 import numpy # noqa: F401 except Exception as e: - print(f"Error in load_slow_imports: {e}", file=sys.stderr) + if not swallow: + raise e if __name__ == "__main__": From e40a07a8a15ce26dcf2d91081315ca55a5cda185 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 8 Sep 2024 09:26:39 -0700 Subject: [PATCH 026/135] refactor: move import check before API key setup --- aider/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/main.py b/aider/main.py index ab4950fb3..d7d9fcac9 100644 --- a/aider/main.py +++ b/aider/main.py @@ -487,6 +487,8 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F cmd_line = scrub_sensitive_info(args, cmd_line) io.tool_output(cmd_line, log_only=True) + check_and_load_imports(io, verbose=args.verbose) + if args.anthropic_api_key: os.environ["ANTHROPIC_API_KEY"] = args.anthropic_api_key @@ -687,8 +689,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.exit: return - check_and_load_imports(io, verbose=args.verbose) - while True: try: coder.run() From cee348614e0f4650676ba7aa9f2ee4db0cf1e369 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sun, 8 Sep 2024 17:07:25 -0700 Subject: [PATCH 027/135] copy --- HISTORY.md | 11 +++++++ aider/main.py | 2 +- aider/website/HISTORY.md | 11 +++++++ aider/website/_includes/replit-pipx.md | 9 ++++++ aider/website/docs/install/pipx.md | 9 +----- aider/website/docs/troubleshooting/imports.md | 31 +++++++++++++++++++ 6 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 aider/website/_includes/replit-pipx.md create mode 100644 aider/website/docs/troubleshooting/imports.md diff --git a/HISTORY.md b/HISTORY.md index d9420866d..c6e4d0b43 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,17 @@ # Release history +### main branch + +- New `/report` command to open your browser with a pre-populated GitHub Issue. +- New `--chat-language` switch to set the spoken language. +- Now `--no-suggest-shell-commands` removes the prompts that ask for shell commands. +- DeepSeek models use 8192 output tokens now. +- Check key imports on launch, provide helpful error message if dependencies aren't available. +- Renamed `--models` to `--list-models`. +- Numerous bug fixes for corner case crashes. +- Aider wrote 70% of the code in this release. + ### Aider v0.55.0 - Only print the pip command when self updating on Windows, without running it. diff --git a/aider/main.py b/aider/main.py index d7d9fcac9..1610d0bc7 100644 --- a/aider/main.py +++ b/aider/main.py @@ -736,7 +736,7 @@ def check_and_load_imports(io, verbose=False): except Exception as err: io.tool_error(str(err)) io.tool_output("Error loading required imports. Did you install aider properly?") - io.tool_output("https://aider.chat/docs/install.html") + io.tool_output("https://aider.chat/docs/install/install.html") sys.exit(1) installs[str(key)] = True diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index fdc5e1f10..e1fdc4873 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -16,6 +16,17 @@ cog.out(text) # Release history +### main branch + +- New `/report` command to open your browser with a pre-populated GitHub Issue. +- New `--chat-language` switch to set the spoken language. +- Now `--no-suggest-shell-commands` removes the prompts that ask for shell commands. +- DeepSeek models use 8192 output tokens now. +- Check key imports on launch, provide helpful error message if dependencies aren't available. +- Renamed `--models` to `--list-models`. +- Numerous bug fixes for corner case crashes. +- Aider wrote 70% of the code in this release. + ### Aider v0.55.0 - Only print the pip command when self updating on Windows, without running it. diff --git a/aider/website/_includes/replit-pipx.md b/aider/website/_includes/replit-pipx.md new file mode 100644 index 000000000..12ca93f11 --- /dev/null +++ b/aider/website/_includes/replit-pipx.md @@ -0,0 +1,9 @@ +To use aider with pipx on replit, you can run these commands in the replit shell: + +``` +pip install pipx +pipx run aider-chat ...normal aider args... +``` + +If you install aider with pipx on replit and try and run it as just `aider` it will crash with a missing `libstdc++.so.6` library. + diff --git a/aider/website/docs/install/pipx.md b/aider/website/docs/install/pipx.md index 71d31fd9c..85cd8abec 100644 --- a/aider/website/docs/install/pipx.md +++ b/aider/website/docs/install/pipx.md @@ -29,12 +29,5 @@ pipx install aider-chat ## pipx on replit -To use aider with pipx on replit, you can run these commands in the replit shell: - -``` -pip install pipx -pipx run aider-chat ...normal aider args... -``` - -If you install aider with pipx on replit and try and run it as just `aider` it will crash with a missing `libstdc++.so.6` library. +{% include replit-pipx.md %} diff --git a/aider/website/docs/troubleshooting/imports.md b/aider/website/docs/troubleshooting/imports.md new file mode 100644 index 000000000..2eba51b82 --- /dev/null +++ b/aider/website/docs/troubleshooting/imports.md @@ -0,0 +1,31 @@ +--- +parent: Troubleshooting +nav_order: 28 +--- + +# Import errors + +Aider expects to be installed via `pip` or `pipx`, which will install +all of its required dependencies. +If aider reports `ImportErrors`, this probably means it has been installed +incorrectly. + + +## Dependency versions + +Aider pins its dependencies and is tested to work with those specific versions. +You should be careful about upgrading or downgrading other python libraries that +aider uses. + +If you need other versions of packages for your project, +consider +[installing aider using pipx](/docs/install/pipx.html). + + + +## Replit + +You can `pip install aider-chat` on replit, or you can install it via +pipx. + +{% include replit-pipx.md %} From 82f8aa5d6a85ed4c45e9f7c8cd1f90344c7adf37 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 10:26:32 -0700 Subject: [PATCH 028/135] copy --- aider/repomap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aider/repomap.py b/aider/repomap.py index 51ae9db0a..857d3c58f 100644 --- a/aider/repomap.py +++ b/aider/repomap.py @@ -316,6 +316,9 @@ class RepoMap: if not file_ok: if fname not in self.warned_files: self.io.tool_warning(f"Repo-map can't include {fname}") + self.io.tool_output( + "Has it been deleted from the file system but not from git?" + ) self.warned_files.add(fname) continue From 73e7d7bd2aa53a8879bcd67a950bda479b03860f Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 12:42:20 -0700 Subject: [PATCH 029/135] fix: handle git errors when listing files in the repository --- aider/repo.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aider/repo.py b/aider/repo.py index 96f0639f1..1ed5f49a6 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -257,6 +257,10 @@ class GitRepo: commit = self.repo.head.commit except ValueError: commit = None + except ANY_GIT_ERROR as err: + self.io.tool_error(f"Unable to list files in git repo: {err}") + self.io.tool_output("Is your git repo corrupted?") + return [] files = set() if commit: From abf6a9db2e9f636e087b661d4017af69192fb41b Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:26:07 -0700 Subject: [PATCH 030/135] fix: Handle additional Git-related errors in GitRepo.list_files --- aider/repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/repo.py b/aider/repo.py index 1ed5f49a6..369761233 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -257,7 +257,7 @@ class GitRepo: commit = self.repo.head.commit except ValueError: commit = None - except ANY_GIT_ERROR as err: + except (OSError,) + ANY_GIT_ERROR as err: self.io.tool_error(f"Unable to list files in git repo: {err}") self.io.tool_output("Is your git repo corrupted?") return [] From 1a6284cb24f40e7840f1abbc157bd5004a4693d4 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:28:04 -0700 Subject: [PATCH 031/135] feat: add error handling for parser loading in basic_lint function --- aider/linter.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/aider/linter.py b/aider/linter.py index 23e0112c7..fe30d0c08 100644 --- a/aider/linter.py +++ b/aider/linter.py @@ -209,7 +209,12 @@ def basic_lint(fname, code): if lang == "typescript": return - parser = get_parser(lang) + try: + parser = get_parser(lang) + except OSError as err: + print(f"Unable to load parser: {err}") + return + tree = parser.parse(bytes(code, "utf-8")) errors = traverse_tree(tree.root_node) From d82d21b8c1f39f24d9f3398254e36aa04ad1de13 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:34:49 -0700 Subject: [PATCH 032/135] refactor: improve error handling for SQLite operations in RepoMap --- aider/repomap.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/aider/repomap.py b/aider/repomap.py index 857d3c58f..05c6c9729 100644 --- a/aider/repomap.py +++ b/aider/repomap.py @@ -27,6 +27,9 @@ from tree_sitter_languages import get_language, get_parser # noqa: E402 Tag = namedtuple("Tag", "rel_fname fname line name kind".split()) +SQLITE_ERRORS = (sqlite3.OperationalError, sqlite3.DatabaseError) + + class RepoMap: CACHE_VERSION = 3 TAGS_CACHE_DIR = f".aider.tags.cache.v{CACHE_VERSION}" @@ -167,7 +170,7 @@ class RepoMap: path = Path(self.root) / self.TAGS_CACHE_DIR try: self.TAGS_CACHE = Cache(path) - except sqlite3.OperationalError: + except SQLITE_ERRORS: self.io.tool_warning(f"Unable to use tags cache, delete {path} to resolve.") self.TAGS_CACHE = dict() @@ -195,8 +198,12 @@ class RepoMap: data = list(self.get_tags_raw(fname, rel_fname)) # Update the cache - self.TAGS_CACHE[cache_key] = {"mtime": file_mtime, "data": data} - self.save_tags_cache() + try: + self.TAGS_CACHE[cache_key] = {"mtime": file_mtime, "data": data} + self.save_tags_cache() + except SQLITE_ERRORS: + pass + return data def get_tags_raw(self, fname, rel_fname): From 3cd6790d9a79e7c500b2a2da7927ec9505476c8d Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:37:24 -0700 Subject: [PATCH 033/135] fix: handle OSError in git repo operations --- aider/repo.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/aider/repo.py b/aider/repo.py index 369761233..ca6c0102f 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -10,7 +10,7 @@ from aider.sendchat import simple_send_with_retries from .dump import dump # noqa: F401 -ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError) +ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError) class GitRepo: @@ -257,7 +257,7 @@ class GitRepo: commit = self.repo.head.commit except ValueError: commit = None - except (OSError,) + ANY_GIT_ERROR as err: + except ANY_GIT_ERROR as err: self.io.tool_error(f"Unable to list files in git repo: {err}") self.io.tool_output("Is your git repo corrupted?") return [] @@ -267,9 +267,14 @@ class GitRepo: if commit in self.tree_files: files = self.tree_files[commit] else: - for blob in commit.tree.traverse(): - if blob.type == "blob": # blob is a file - files.add(blob.path) + try: + for blob in commit.tree.traverse(): + if blob.type == "blob": # blob is a file + files.add(blob.path) + except ANY_GIT_ERROR as err: + self.io.tool_error(f"Unable to list files in git repo: {err}") + self.io.tool_output("Is your git repo corrupted?") + return [] files = set(self.normalize_path(path) for path in files) self.tree_files[commit] = set(files) From 4e63254704fa99142fbf0fd83a445d2c4fa1c966 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:40:56 -0700 Subject: [PATCH 034/135] refactor: Improve error handling in git repository checks --- aider/main.py | 24 ++++++++++++------------ aider/repo.py | 3 +++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/aider/main.py b/aider/main.py index 1610d0bc7..5b0ab6dfa 100644 --- a/aider/main.py +++ b/aider/main.py @@ -302,23 +302,23 @@ def sanity_check_repo(repo, io): try: repo.get_tracked_files() - return True + if not repo.git_repo_error: + return True + error_msg = str(repo.git_repo_error) except ANY_GIT_ERROR as exc: error_msg = str(exc) - if "version in (1, 2)" in error_msg: - io.tool_error("Aider only works with git repos with version number 1 or 2.") - io.tool_output( - "You may be able to convert your repo: git update-index --index-version=2" - ) - io.tool_output("Or run aider --no-git to proceed without using git.") - io.tool_output("https://github.com/paul-gauthier/aider/issues/211") - return False - - io.tool_error("Unable to read git repository, it may be corrupt?") - io.tool_output(error_msg) + if "version in (1, 2)" in error_msg: + io.tool_error("Aider only works with git repos with version number 1 or 2.") + io.tool_output("You may be able to convert your repo: git update-index --index-version=2") + io.tool_output("Or run aider --no-git to proceed without using git.") + io.tool_output("https://github.com/paul-gauthier/aider/issues/211") return False + io.tool_error("Unable to read git repository, it may be corrupt?") + io.tool_output(error_msg) + return False + def main(argv=None, input=None, output=None, force_git_root=None, return_coder=False): report_uncaught_exceptions() diff --git a/aider/repo.py b/aider/repo.py index ca6c0102f..7416c4d40 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -21,6 +21,7 @@ class GitRepo: aider_ignore_last_check = 0 subtree_only = False ignore_file_cache = {} + git_repo_error = None def __init__( self, @@ -258,6 +259,7 @@ class GitRepo: except ValueError: commit = None except ANY_GIT_ERROR as err: + self.git_repo_error = err self.io.tool_error(f"Unable to list files in git repo: {err}") self.io.tool_output("Is your git repo corrupted?") return [] @@ -272,6 +274,7 @@ class GitRepo: if blob.type == "blob": # blob is a file files.add(blob.path) except ANY_GIT_ERROR as err: + self.git_repo_error = err self.io.tool_error(f"Unable to list files in git repo: {err}") self.io.tool_output("Is your git repo corrupted?") return [] From 00f42590c87fc4082f4e7c62efff9abaeec85d58 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:41:28 -0700 Subject: [PATCH 035/135] feat: add AssertionError to ANY_GIT_ERROR tuple --- aider/repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/repo.py b/aider/repo.py index 7416c4d40..69a5a3c52 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -10,7 +10,7 @@ from aider.sendchat import simple_send_with_retries from .dump import dump # noqa: F401 -ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError) +ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError, AssertionError) class GitRepo: From bd21122e6403dfc0104657a8a6ddcf96cdce1ed4 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:44:02 -0700 Subject: [PATCH 036/135] refactor: improve error handling for git version check --- aider/main.py | 6 +++++- aider/repo.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/aider/main.py b/aider/main.py index 5b0ab6dfa..be90d8776 100644 --- a/aider/main.py +++ b/aider/main.py @@ -307,8 +307,12 @@ def sanity_check_repo(repo, io): error_msg = str(repo.git_repo_error) except ANY_GIT_ERROR as exc: error_msg = str(exc) + bad_ver = "version in (1, 2)" in error_msg + except AssertionError as exc: + error_msg = str(exc) + bad_ver = True - if "version in (1, 2)" in error_msg: + if bad_ver: io.tool_error("Aider only works with git repos with version number 1 or 2.") io.tool_output("You may be able to convert your repo: git update-index --index-version=2") io.tool_output("Or run aider --no-git to proceed without using git.") diff --git a/aider/repo.py b/aider/repo.py index 69a5a3c52..7416c4d40 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -10,7 +10,7 @@ from aider.sendchat import simple_send_with_retries from .dump import dump # noqa: F401 -ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError, AssertionError) +ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError) class GitRepo: From eced076602f9cf297d5b1b93557b3913b13bb8e2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:46:03 -0700 Subject: [PATCH 037/135] feat: add IndexError to ANY_GIT_ERROR tuple in repo.py --- aider/repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/repo.py b/aider/repo.py index 7416c4d40..7375cc654 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -10,7 +10,7 @@ from aider.sendchat import simple_send_with_retries from .dump import dump # noqa: F401 -ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError) +ANY_GIT_ERROR = (git.exc.ODBError, git.exc.GitError, OSError, IndexError) class GitRepo: From 964fe7e2dc624184e6c5594fa8b2ed6930b30c86 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 13:56:27 -0700 Subject: [PATCH 038/135] fix: handle UnicodeEncodeError in prompt session --- aider/io.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aider/io.py b/aider/io.py index d756505a2..03eec020a 100644 --- a/aider/io.py +++ b/aider/io.py @@ -345,7 +345,11 @@ class InputOutput: session = PromptSession( key_bindings=kb, editing_mode=self.editingmode, **session_kwargs ) - line = session.prompt() + try: + line = session.prompt() + except UnicodeEncodeError as err: + self.io.tool_error(str(err)) + return "" if line and line[0] == "{" and not multiline_input: multiline_input = True From 3976d4b8f17ea7f800383ec74d89108d63985288 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:37:18 -0700 Subject: [PATCH 039/135] copy --- aider/website/docs/config/adv-model-settings.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/aider/website/docs/config/adv-model-settings.md b/aider/website/docs/config/adv-model-settings.md index e3bba0010..cb7d238a9 100644 --- a/aider/website/docs/config/adv-model-settings.md +++ b/aider/website/docs/config/adv-model-settings.md @@ -89,3 +89,8 @@ The yaml file should be a a list of dictionary objects for each model, as follow examples_as_sys_msg: false ``` +You can look at the `ModelSettings` class in +[models.py](https://github.com/paul-gauthier/aider/blob/main/aider/models.py) +file for details about all of the model setting that aider supports. +That file also contains the settings for many popular models. + From 26c2b2e3edf6e609c306347b1ba365a26d5bbbde Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:43:35 -0700 Subject: [PATCH 040/135] copy --- HISTORY.md | 6 +++--- aider/website/HISTORY.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c6e4d0b43..b21dacf4d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,12 +5,12 @@ - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. -- Now `--no-suggest-shell-commands` removes the prompts that ask for shell commands. -- DeepSeek models use 8192 output tokens now. +- Now `--[no-]suggest-shell-commands` controls both prompting for and offering to execute shell commands. +- DeepSeek models use 8192 output tokens. - Check key imports on launch, provide helpful error message if dependencies aren't available. - Renamed `--models` to `--list-models`. - Numerous bug fixes for corner case crashes. -- Aider wrote 70% of the code in this release. +- Aider wrote 56% of the code in this release. ### Aider v0.55.0 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index e1fdc4873..cdb03c800 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -20,12 +20,12 @@ cog.out(text) - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. -- Now `--no-suggest-shell-commands` removes the prompts that ask for shell commands. -- DeepSeek models use 8192 output tokens now. +- Now `--[no-]suggest-shell-commands` controls both prompting for and offering to execute shell commands. +- DeepSeek models use 8192 output tokens. - Check key imports on launch, provide helpful error message if dependencies aren't available. - Renamed `--models` to `--list-models`. - Numerous bug fixes for corner case crashes. -- Aider wrote 70% of the code in this release. +- Aider wrote 56% of the code in this release. ### Aider v0.55.0 From 6f2b064f53bb5f5e5f4ec0cfa67da45cc8de3fab Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:45:11 -0700 Subject: [PATCH 041/135] version bump to 0.56.0 --- aider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/__init__.py b/aider/__init__.py index e6102716f..d4cebfea5 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1,6 +1,6 @@ try: from aider.__version__ import __version__ except Exception: - __version__ = "0.55.1.dev" + __version__ = "0.56.0" __all__ = [__version__] From 509c880b687ab52b960c1336f3f2db342620a59a Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:46:20 -0700 Subject: [PATCH 042/135] set version to 0.56.1.dev --- aider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/__init__.py b/aider/__init__.py index d4cebfea5..44656e63e 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1,6 +1,6 @@ try: from aider.__version__ import __version__ except Exception: - __version__ = "0.56.0" + __version__ = "0.56.1.dev" __all__ = [__version__] From b216d57107320f1e00e65a2ee4ab8707654660b3 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:47:56 -0700 Subject: [PATCH 043/135] copy --- aider/website/docs/usage/caching.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aider/website/docs/usage/caching.md b/aider/website/docs/usage/caching.md index 4bc51178b..f79bc6d9c 100644 --- a/aider/website/docs/usage/caching.md +++ b/aider/website/docs/usage/caching.md @@ -13,6 +13,13 @@ Aider supports prompt caching for cost savings and faster coding. Currently Anthropic provides caching for Sonnet and Haiku, and DeepSeek provides caching for Coder. +Aider organizes the chat history to try and cache: + +- The system prompt. +- Read only files added with `--read` or `/read-only`. +- The repository map. +- The editable files that have been added to the chat. + ![Prompt caching](/assets/prompt-caching.jpg) From fe2e36afdad0af5ee0fb85435a770aabdcef653c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:51:33 -0700 Subject: [PATCH 044/135] cache ro+repo or just ro if no repo --- aider/coders/chat_chunks.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/aider/coders/chat_chunks.py b/aider/coders/chat_chunks.py index 881e781f2..060099a61 100644 --- a/aider/coders/chat_chunks.py +++ b/aider/coders/chat_chunks.py @@ -31,10 +31,12 @@ class ChatChunks: else: self.add_cache_control(self.system) - if self.readonly_files: - self.add_cache_control(self.readonly_files) - else: + if self.repo: + # this will mark both the readonly_files and repomap chunk as cacheable self.add_cache_control(self.repo) + else: + # otherwise, just cache readonly_files if there are any + self.add_cache_control(self.readonly_files) self.add_cache_control(self.chat_files) From 5420f67b2b9c9794d9f1500654aca7d27ffbab0e Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 14:56:44 -0700 Subject: [PATCH 045/135] copy --- HISTORY.md | 2 +- aider/website/HISTORY.md | 2 +- aider/website/_data/blame.yml | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b21dacf4d..320bc2716 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ # Release history -### main branch +### Aider v0.56.0 - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index cdb03c800..0df516832 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -16,7 +16,7 @@ cog.out(text) # Release history -### main branch +### Aider v0.56.0 - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. diff --git a/aider/website/_data/blame.yml b/aider/website/_data/blame.yml index f00b6c4be..2b702a3ad 100644 --- a/aider/website/_data/blame.yml +++ b/aider/website/_data/blame.yml @@ -2482,3 +2482,52 @@ Paul Gauthier (aider): 811 start_tag: v0.54.0 total_lines: 1533 +- aider_percentage: 55.6 + aider_total: 154 + end_date: '2024-09-09' + end_tag: v0.56.0 + file_counts: + aider/__init__.py: + Paul Gauthier: 1 + aider/args.py: + Paul Gauthier: 2 + Paul Gauthier (aider): 6 + aider/coders/base_coder.py: + Paul Gauthier: 14 + Paul Gauthier (aider): 10 + aider/commands.py: + Paul Gauthier: 8 + Paul Gauthier (aider): 6 + aider/io.py: + Paul Gauthier: 5 + aider/linter.py: + Paul Gauthier: 6 + Paul Gauthier (aider): 4 + fry69: 12 + aider/main.py: + Paul Gauthier: 35 + Paul Gauthier (aider): 48 + aider/models.py: + Paul Gauthier: 2 + fry69: 3 + aider/repo.py: + Paul Gauthier: 16 + aider/repomap.py: + Paul Gauthier: 13 + aider/report.py: + Paul Gauthier: 2 + Paul Gauthier (aider): 20 + benchmark/benchmark.py: + Paul Gauthier: 1 + tests/basic/test_linter.py: + Paul Gauthier: 1 + Paul Gauthier (aider): 51 + tests/basic/test_main.py: + Paul Gauthier: 2 + Paul Gauthier (aider): 9 + grand_total: + Paul Gauthier: 108 + Paul Gauthier (aider): 154 + fry69: 15 + start_tag: v0.55.0 + total_lines: 277 From fb1a9254c794a9ac990e9356ab03e2739cc57f0a Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Mon, 9 Sep 2024 15:00:37 -0700 Subject: [PATCH 046/135] feat: remove aider/__version__.py after version bump --- scripts/versionbump.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/versionbump.py b/scripts/versionbump.py index f0f57e0cd..30277fd52 100755 --- a/scripts/versionbump.py +++ b/scripts/versionbump.py @@ -2,6 +2,7 @@ import argparse import datetime +import os import re import subprocess import sys @@ -150,6 +151,15 @@ def main(): if not dry_run: subprocess.run(cmd, check=True) + # Remove aider/__version__.py if it exists + version_file = "aider/__version__.py" + if os.path.exists(version_file): + print(f"Removing {version_file}") + if not dry_run: + os.remove(version_file) + subprocess.run(["git", "add", version_file], check=True) + subprocess.run(["git", "commit", "-m", f"Remove {version_file}"], check=True) + subprocess.run(["git", "push", "origin", "--no-verify"], check=True) if __name__ == "__main__": main() From de84a089242bd5d53d9c6893320b59091d00907c Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Mon, 9 Sep 2024 15:00:41 -0700 Subject: [PATCH 047/135] style: Apply linter suggestions to versionbump.py --- scripts/versionbump.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/versionbump.py b/scripts/versionbump.py index 30277fd52..243753100 100755 --- a/scripts/versionbump.py +++ b/scripts/versionbump.py @@ -161,5 +161,6 @@ def main(): subprocess.run(["git", "commit", "-m", f"Remove {version_file}"], check=True) subprocess.run(["git", "push", "origin", "--no-verify"], check=True) + if __name__ == "__main__": main() From 6cddc800f15e51eb9fa86030609a1bda445d382c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 15:01:08 -0700 Subject: [PATCH 048/135] docs: update HISTORY.md and remove git operations from versionbump.py --- HISTORY.md | 3 ++- scripts/versionbump.py | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 320bc2716..8d8362348 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,10 +3,11 @@ ### Aider v0.56.0 +- Enables prompt caching for Sonnet via OpenRouter. +- Enables 8k output tokens for Sonnet via VertexAI and DeepSeek V2.5. - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. - Now `--[no-]suggest-shell-commands` controls both prompting for and offering to execute shell commands. -- DeepSeek models use 8192 output tokens. - Check key imports on launch, provide helpful error message if dependencies aren't available. - Renamed `--models` to `--list-models`. - Numerous bug fixes for corner case crashes. diff --git a/scripts/versionbump.py b/scripts/versionbump.py index 243753100..4d7509e99 100755 --- a/scripts/versionbump.py +++ b/scripts/versionbump.py @@ -157,9 +157,6 @@ def main(): print(f"Removing {version_file}") if not dry_run: os.remove(version_file) - subprocess.run(["git", "add", version_file], check=True) - subprocess.run(["git", "commit", "-m", f"Remove {version_file}"], check=True) - subprocess.run(["git", "push", "origin", "--no-verify"], check=True) if __name__ == "__main__": From d99191e07b2f9f748a27e129eb0ecf15f1a557f5 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 15:01:53 -0700 Subject: [PATCH 049/135] copy --- aider/website/HISTORY.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 0df516832..1adfedb4f 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -18,10 +18,11 @@ cog.out(text) ### Aider v0.56.0 +- Enables prompt caching for Sonnet via OpenRouter. +- Enables 8k output tokens for Sonnet via VertexAI and DeepSeek V2.5. - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. - Now `--[no-]suggest-shell-commands` controls both prompting for and offering to execute shell commands. -- DeepSeek models use 8192 output tokens. - Check key imports on launch, provide helpful error message if dependencies aren't available. - Renamed `--models` to `--list-models`. - Numerous bug fixes for corner case crashes. From 6a0ad9629bc1a5328fd79105785ab2352981fbe2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 15:04:37 -0700 Subject: [PATCH 050/135] copy --- HISTORY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 8d8362348..b79fddc52 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,13 +3,13 @@ ### Aider v0.56.0 -- Enables prompt caching for Sonnet via OpenRouter. +- Enables prompt caching for Sonnet via OpenRouter by @fry69 - Enables 8k output tokens for Sonnet via VertexAI and DeepSeek V2.5. - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. - Now `--[no-]suggest-shell-commands` controls both prompting for and offering to execute shell commands. - Check key imports on launch, provide helpful error message if dependencies aren't available. -- Renamed `--models` to `--list-models`. +- Renamed `--models` to `--list-models` by @fry69. - Numerous bug fixes for corner case crashes. - Aider wrote 56% of the code in this release. From b8ce472cb6181ebe52892823a5b25ba6ad3a18e9 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 9 Sep 2024 15:20:36 -0700 Subject: [PATCH 051/135] copy --- aider/website/HISTORY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 1adfedb4f..1555635e3 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -18,13 +18,13 @@ cog.out(text) ### Aider v0.56.0 -- Enables prompt caching for Sonnet via OpenRouter. +- Enables prompt caching for Sonnet via OpenRouter by @fry69 - Enables 8k output tokens for Sonnet via VertexAI and DeepSeek V2.5. - New `/report` command to open your browser with a pre-populated GitHub Issue. - New `--chat-language` switch to set the spoken language. - Now `--[no-]suggest-shell-commands` controls both prompting for and offering to execute shell commands. - Check key imports on launch, provide helpful error message if dependencies aren't available. -- Renamed `--models` to `--list-models`. +- Renamed `--models` to `--list-models` by @fry69. - Numerous bug fixes for corner case crashes. - Aider wrote 56% of the code in this release. From e3b7b802800c56703a621f7846f917bd66a35750 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 06:40:07 -0700 Subject: [PATCH 052/135] feat: respect user's shell environment in subprocess execution --- aider/run_cmd.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 2fd70a94c..b5edc477e 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -26,12 +26,27 @@ def run_cmd_subprocess(command, verbose=False): if verbose: print("Using run_cmd_subprocess:", command) try: + # Determine the appropriate shell + if platform.system() == "Windows": + # Use PowerShell if it's the parent process + if "powershell" in os.environ.get("PSModulePath", "").lower(): + shell = "powershell" + command = f"powershell -Command {command}" + else: + shell = "cmd" + else: + shell = os.environ.get("SHELL", "/bin/sh") + + if verbose: + print(f"Using shell: {shell}") + process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, shell=True, + executable=shell, encoding=sys.stdout.encoding, errors="replace", bufsize=1, From 4605969921437c89bdf65a07ea851483f049d372 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 06:51:38 -0700 Subject: [PATCH 053/135] fix: improve PowerShell command execution and output capture on Windows --- aider/run_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index b5edc477e..10aa572cb 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -31,7 +31,7 @@ def run_cmd_subprocess(command, verbose=False): # Use PowerShell if it's the parent process if "powershell" in os.environ.get("PSModulePath", "").lower(): shell = "powershell" - command = f"powershell -Command {command}" + command = f'powershell -ExecutionPolicy Bypass -Command "& {{({command}) | Out-String}}"' else: shell = "cmd" else: From 1327c1e893a1436a665397a5ac433970ad0e2f17 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 06:51:43 -0700 Subject: [PATCH 054/135] style: format command string for PowerShell execution --- aider/run_cmd.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 10aa572cb..5434b4a7a 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -31,7 +31,9 @@ def run_cmd_subprocess(command, verbose=False): # Use PowerShell if it's the parent process if "powershell" in os.environ.get("PSModulePath", "").lower(): shell = "powershell" - command = f'powershell -ExecutionPolicy Bypass -Command "& {{({command}) | Out-String}}"' + command = ( + f'powershell -ExecutionPolicy Bypass -Command "& {{({command}) | Out-String}}"' + ) else: shell = "cmd" else: From 765ea801b105826719a223fbfe5a5219e15c94b0 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 09:25:50 -0700 Subject: [PATCH 055/135] refactor: simplify shell command execution logic --- aider/run_cmd.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 5434b4a7a..eca5155f3 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -25,22 +25,18 @@ def run_cmd(command, verbose=False, error_print=None): def run_cmd_subprocess(command, verbose=False): if verbose: print("Using run_cmd_subprocess:", command) + try: + shell = os.environ.get("SHELL", "/bin/sh") + PSModulePath = os.environ.get("PSModulePath", "") # Determine the appropriate shell - if platform.system() == "Windows": - # Use PowerShell if it's the parent process - if "powershell" in os.environ.get("PSModulePath", "").lower(): - shell = "powershell" - command = ( - f'powershell -ExecutionPolicy Bypass -Command "& {{({command}) | Out-String}}"' - ) - else: - shell = "cmd" - else: - shell = os.environ.get("SHELL", "/bin/sh") + if platform.system() == "Windows" and "powershell" in PSModulePath.lower(): + command = f"powershell -Command {command}" if verbose: - print(f"Using shell: {shell}") + print("Running command:", command) + print("SHELL:", shell) + print("PSModulePath:", PSModulePath) process = subprocess.Popen( command, @@ -48,7 +44,6 @@ def run_cmd_subprocess(command, verbose=False): stderr=subprocess.STDOUT, text=True, shell=True, - executable=shell, encoding=sys.stdout.encoding, errors="replace", bufsize=1, From 5de0a0f7a94e32c0ae17482076e214c19f743098 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:28:39 -0700 Subject: [PATCH 056/135] feat: improve shell detection for Windows environments --- aider/run_cmd.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index eca5155f3..b39bb64c6 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -3,6 +3,8 @@ import platform import subprocess import sys from io import BytesIO +import psutil +import ctypes import pexpect @@ -22,21 +24,40 @@ def run_cmd(command, verbose=False, error_print=None): return 1, error_message +def get_parent_process_name(): + try: + if platform.system() == "Windows": + kernel32 = ctypes.windll.kernel32 + h_process = kernel32.OpenProcess(0x0400, False, os.getppid()) + exe_path = ctypes.create_unicode_buffer(260) + kernel32.QueryFullProcessImageNameW(h_process, 0, exe_path, ctypes.byref(ctypes.c_ulong(260))) + kernel32.CloseHandle(h_process) + return os.path.basename(exe_path.value).lower() + else: + return psutil.Process(os.getppid()).name().lower() + except: + return None + def run_cmd_subprocess(command, verbose=False): if verbose: print("Using run_cmd_subprocess:", command) try: shell = os.environ.get("SHELL", "/bin/sh") - PSModulePath = os.environ.get("PSModulePath", "") + parent_process = get_parent_process_name() + # Determine the appropriate shell - if platform.system() == "Windows" and "powershell" in PSModulePath.lower(): - command = f"powershell -Command {command}" + if platform.system() == "Windows": + if parent_process == "powershell.exe": + command = f"powershell -Command {command}" + else: + # Assume cmd.exe or other Windows shell + pass # Use the command as-is if verbose: print("Running command:", command) print("SHELL:", shell) - print("PSModulePath:", PSModulePath) + print("Parent process:", parent_process) process = subprocess.Popen( command, From cb424646761034785c93594dcd99c207daf1f2f9 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:28:42 -0700 Subject: [PATCH 057/135] style: Reorder imports and format code --- aider/run_cmd.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index b39bb64c6..ce904e25e 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -1,12 +1,12 @@ +import ctypes import os import platform import subprocess import sys from io import BytesIO -import psutil -import ctypes import pexpect +import psutil def run_cmd(command, verbose=False, error_print=None): @@ -30,7 +30,9 @@ def get_parent_process_name(): kernel32 = ctypes.windll.kernel32 h_process = kernel32.OpenProcess(0x0400, False, os.getppid()) exe_path = ctypes.create_unicode_buffer(260) - kernel32.QueryFullProcessImageNameW(h_process, 0, exe_path, ctypes.byref(ctypes.c_ulong(260))) + kernel32.QueryFullProcessImageNameW( + h_process, 0, exe_path, ctypes.byref(ctypes.c_ulong(260)) + ) kernel32.CloseHandle(h_process) return os.path.basename(exe_path.value).lower() else: @@ -38,6 +40,7 @@ def get_parent_process_name(): except: return None + def run_cmd_subprocess(command, verbose=False): if verbose: print("Using run_cmd_subprocess:", command) From e5ff5eff756d810a7a8c01c4de77d0401b5ec888 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 09:30:35 -0700 Subject: [PATCH 058/135] refactor: rename and simplify parent process name retrieval function --- aider/run_cmd.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index ce904e25e..6b2e9ba4e 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -6,7 +6,6 @@ import sys from io import BytesIO import pexpect -import psutil def run_cmd(command, verbose=False, error_print=None): @@ -24,7 +23,7 @@ def run_cmd(command, verbose=False, error_print=None): return 1, error_message -def get_parent_process_name(): +def get_windows_parent_process_name(): try: if platform.system() == "Windows": kernel32 = ctypes.windll.kernel32 @@ -37,7 +36,7 @@ def get_parent_process_name(): return os.path.basename(exe_path.value).lower() else: return psutil.Process(os.getppid()).name().lower() - except: + except Exception: return None From 625a49752bdf4489edbe622c48e9846e38c59224 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:30:36 -0700 Subject: [PATCH 059/135] refactor: remove psutil dependency and check parent process only on Windows --- aider/run_cmd.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 6b2e9ba4e..316d19ae7 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -25,17 +25,14 @@ def run_cmd(command, verbose=False, error_print=None): def get_windows_parent_process_name(): try: - if platform.system() == "Windows": - kernel32 = ctypes.windll.kernel32 - h_process = kernel32.OpenProcess(0x0400, False, os.getppid()) - exe_path = ctypes.create_unicode_buffer(260) - kernel32.QueryFullProcessImageNameW( - h_process, 0, exe_path, ctypes.byref(ctypes.c_ulong(260)) - ) - kernel32.CloseHandle(h_process) - return os.path.basename(exe_path.value).lower() - else: - return psutil.Process(os.getppid()).name().lower() + kernel32 = ctypes.windll.kernel32 + h_process = kernel32.OpenProcess(0x0400, False, os.getppid()) + exe_path = ctypes.create_unicode_buffer(260) + kernel32.QueryFullProcessImageNameW( + h_process, 0, exe_path, ctypes.byref(ctypes.c_ulong(260)) + ) + kernel32.CloseHandle(h_process) + return os.path.basename(exe_path.value).lower() except Exception: return None @@ -46,20 +43,20 @@ def run_cmd_subprocess(command, verbose=False): try: shell = os.environ.get("SHELL", "/bin/sh") - parent_process = get_parent_process_name() + parent_process = None # Determine the appropriate shell if platform.system() == "Windows": + parent_process = get_windows_parent_process_name() if parent_process == "powershell.exe": command = f"powershell -Command {command}" - else: - # Assume cmd.exe or other Windows shell - pass # Use the command as-is + # else: Assume cmd.exe or other Windows shell, use the command as-is if verbose: print("Running command:", command) print("SHELL:", shell) - print("Parent process:", parent_process) + if platform.system() == "Windows": + print("Parent process:", parent_process) process = subprocess.Popen( command, From ab9d9c8429487f9a924ecc9bf1ff5bcfa78c2117 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:34:58 -0700 Subject: [PATCH 060/135] refactor: improve subprocess output handling for real-time display --- aider/run_cmd.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 316d19ae7..e72dbe9c3 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -50,7 +50,6 @@ def run_cmd_subprocess(command, verbose=False): parent_process = get_windows_parent_process_name() if parent_process == "powershell.exe": command = f"powershell -Command {command}" - # else: Assume cmd.exe or other Windows shell, use the command as-is if verbose: print("Running command:", command) @@ -66,14 +65,17 @@ def run_cmd_subprocess(command, verbose=False): shell=True, encoding=sys.stdout.encoding, errors="replace", - bufsize=1, + bufsize=0, # Set bufsize to 0 for unbuffered output universal_newlines=True, ) output = [] - for line in process.stdout: - print(line, end="") # Print the line in real-time - output.append(line) # Store the line for later use + while True: + chunk = process.stdout.read(1024) # Read in 1KB chunks + if not chunk: + break + print(chunk, end="", flush=True) # Print the chunk in real-time + output.append(chunk) # Store the chunk for later use process.wait() return process.returncode, "".join(output) From e84caa48a0aa9f2413ebad684862cabb33282a09 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 09:44:52 -0700 Subject: [PATCH 061/135] refactor: modify stdout reading chunk size in run_cmd_subprocess --- aider/run_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index e72dbe9c3..ce0c6ac34 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -71,7 +71,7 @@ def run_cmd_subprocess(command, verbose=False): output = [] while True: - chunk = process.stdout.read(1024) # Read in 1KB chunks + chunk = process.stdout.read(1) if not chunk: break print(chunk, end="", flush=True) # Print the chunk in real-time From f1d1d1b37ad21bfd26a948d42c9334e7ac0003ad Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:44:54 -0700 Subject: [PATCH 062/135] feat: improve Windows parent process detection using psutil --- aider/run_cmd.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index ce0c6ac34..6de2402d6 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -6,6 +6,7 @@ import sys from io import BytesIO import pexpect +import psutil def run_cmd(command, verbose=False, error_print=None): @@ -25,14 +26,16 @@ def run_cmd(command, verbose=False, error_print=None): def get_windows_parent_process_name(): try: - kernel32 = ctypes.windll.kernel32 - h_process = kernel32.OpenProcess(0x0400, False, os.getppid()) - exe_path = ctypes.create_unicode_buffer(260) - kernel32.QueryFullProcessImageNameW( - h_process, 0, exe_path, ctypes.byref(ctypes.c_ulong(260)) - ) - kernel32.CloseHandle(h_process) - return os.path.basename(exe_path.value).lower() + current_process = psutil.Process() + while True: + parent = current_process.parent() + if parent is None: + break + parent_name = parent.name().lower() + if parent_name in ['powershell.exe', 'cmd.exe']: + return parent_name + current_process = parent + return None except Exception: return None From cc94b51a0b7dce7dd027fee52b42338fdea45756 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:44:57 -0700 Subject: [PATCH 063/135] style: use double quotes for string literals in run_cmd.py --- aider/run_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 6de2402d6..f7389ad55 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -32,7 +32,7 @@ def get_windows_parent_process_name(): if parent is None: break parent_name = parent.name().lower() - if parent_name in ['powershell.exe', 'cmd.exe']: + if parent_name in ["powershell.exe", "cmd.exe"]: return parent_name current_process = parent return None From 766569a278150bcec075e19fa5a66d296fd1c4c4 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:45:05 -0700 Subject: [PATCH 064/135] refactor: Remove unused ctypes import --- aider/run_cmd.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index f7389ad55..103f4042b 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -1,4 +1,3 @@ -import ctypes import os import platform import subprocess From 33b69d2ee8a34f15ed1a5010879ce2ea5f147df2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 09:48:23 -0700 Subject: [PATCH 065/135] pip-compiled --- requirements.txt | 8 ++------ requirements/requirements.in | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 24b95b748..a502ad72b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -120,7 +120,6 @@ packaging==24.1 # via # -r requirements/requirements.in # huggingface-hub - # setuptools-scm pathspec==0.12.1 # via # -r requirements/requirements.in @@ -131,6 +130,8 @@ pillow==10.4.0 # via -r requirements/requirements.in prompt-toolkit==3.0.47 # via -r requirements/requirements.in +psutil==6.0.0 + # via -r requirements/requirements.in ptyprocess==0.7.0 # via pexpect pycodestyle==2.12.1 @@ -176,8 +177,6 @@ rpds-py==0.20.0 # referencing scipy==1.13.1 # via -r requirements/requirements.in -setuptools-scm==8.1.0 - # via -r requirements/requirements.in smmap==5.0.1 # via gitdb sniffio==1.3.1 @@ -221,6 +220,3 @@ yarl==1.9.4 # via aiohttp zipp==3.20.1 # via importlib-metadata - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/requirements/requirements.in b/requirements/requirements.in index 74c89d6be..b17a88589 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -25,6 +25,7 @@ importlib_resources pyperclip pexpect json5 +psutil # The proper depdendency is networkx[default], but this brings # in matplotlib and a bunch of other deps From bf3a165961b0c8dbe0661b0f92beac800dbaa877 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 09:57:09 -0700 Subject: [PATCH 066/135] refactor: initialize and reuse PromptSession in InputOutput class --- aider/io.py | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/aider/io.py b/aider/io.py index 03eec020a..ec461eb17 100644 --- a/aider/io.py +++ b/aider/io.py @@ -219,6 +219,17 @@ class InputOutput: current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.append_chat_history(f"\n# aider chat started at {current_time}\n\n") + # Initialize PromptSession + session_kwargs = { + "input": self.input, + "output": self.output, + "lexer": PygmentsLexer(MarkdownLexer), + "editing_mode": self.editingmode, + } + if self.input_history_file is not None: + session_kwargs["history"] = FileHistory(self.input_history_file) + self.prompt_session = PromptSession(**session_kwargs) + def read_image(self, filename): try: with open(str(filename), "rb") as image_file: @@ -317,38 +328,27 @@ class InputOutput: ) ) + kb = KeyBindings() + + @kb.add("escape", "c-m", eager=True) + def _(event): + event.current_buffer.insert_text("\n") + while True: if multiline_input: show = ". " - session_kwargs = { - "message": show, - "completer": completer_instance, - "reserve_space_for_menu": 4, - "complete_style": CompleteStyle.MULTI_COLUMN, - "input": self.input, - "output": self.output, - "lexer": PygmentsLexer(MarkdownLexer), - } - if style: - session_kwargs["style"] = style - - if self.input_history_file is not None: - session_kwargs["history"] = FileHistory(self.input_history_file) - - kb = KeyBindings() - - @kb.add("escape", "c-m", eager=True) - def _(event): - event.current_buffer.insert_text("\n") - - session = PromptSession( - key_bindings=kb, editing_mode=self.editingmode, **session_kwargs - ) try: - line = session.prompt() + line = self.prompt_session.prompt( + show, + completer=completer_instance, + reserve_space_for_menu=4, + complete_style=CompleteStyle.MULTI_COLUMN, + style=style, + key_bindings=kb, + ) except UnicodeEncodeError as err: - self.io.tool_error(str(err)) + self.tool_error(str(err)) return "" if line and line[0] == "{" and not multiline_input: From 43eaf91e8dcc3a60e3259eac4f7a211144696c71 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 10:00:00 -0700 Subject: [PATCH 067/135] refactor: use pre-initialized PromptSession in prompt_ask function --- aider/io.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aider/io.py b/aider/io.py index ec461eb17..976f6a574 100644 --- a/aider/io.py +++ b/aider/io.py @@ -519,7 +519,11 @@ class InputOutput: elif self.yes is False: res = "no" else: - res = prompt(question + " ", default=default, style=style) + res = self.prompt_session.prompt( + question + " ", + default=default, + style=style + ) hist = f"{question.strip()} {res.strip()}" self.append_chat_history(hist, linebreak=True, blockquote=True) From 89891efbb8d45a18d511e907a64152c9eae8834c Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 10:00:05 -0700 Subject: [PATCH 068/135] style: format prompt_session.prompt call to fit on one line --- aider/io.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/aider/io.py b/aider/io.py index 976f6a574..84e4f144b 100644 --- a/aider/io.py +++ b/aider/io.py @@ -519,11 +519,7 @@ class InputOutput: elif self.yes is False: res = "no" else: - res = self.prompt_session.prompt( - question + " ", - default=default, - style=style - ) + res = self.prompt_session.prompt(question + " ", default=default, style=style) hist = f"{question.strip()} {res.strip()}" self.append_chat_history(hist, linebreak=True, blockquote=True) From c152c96fccfbfedb1123e140c4b01d6c26506707 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 10:05:01 -0700 Subject: [PATCH 069/135] copy --- aider/website/docs/usage/tutorials.md | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/website/docs/usage/tutorials.md b/aider/website/docs/usage/tutorials.md index fd910e31a..bf5e03d30 100644 --- a/aider/website/docs/usage/tutorials.md +++ b/aider/website/docs/usage/tutorials.md @@ -8,6 +8,7 @@ description: Intro and tutorial videos made by aider users. Here are some tutorial videos made by aider users: +- [Using aider to incrementally build a non-trivial app](https://youtu.be/QlUt06XLbJE) -- IndyDevDan - [Aider and Replit on mobile with your voice](https://x.com/itsPaulAi/status/1830987090617831810) -- Paul Couvert - [Aider is the OG AI Coding King (Mermaid Diagram AI Agent)](https://www.youtube.com/watch?v=ag-KxYS8Vuw) -- IndyDevDan - [Installing aider in replit and making a Trello clone](https://x.com/itspaulai/status/1828834199597633724) -- Paul Couvert From 484fdd7aa3015832a7d2e56d4f3a971bf1f6c668 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 12:06:45 -0700 Subject: [PATCH 070/135] fix: handle ValueError exception in run_cmd_pexpect function --- aider/run_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/run_cmd.py b/aider/run_cmd.py index 103f4042b..974af9c37 100644 --- a/aider/run_cmd.py +++ b/aider/run_cmd.py @@ -126,6 +126,6 @@ def run_cmd_pexpect(command, verbose=False): child.close() return child.exitstatus, output.getvalue().decode("utf-8", errors="replace") - except (pexpect.ExceptionPexpect, TypeError) as e: + except (pexpect.ExceptionPexpect, TypeError, ValueError) as e: error_msg = f"Error running command {command}: {e}" return 1, error_msg From 00f03d89b914ad5c56255982598b01471e51deb1 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 13:03:31 -0700 Subject: [PATCH 071/135] feat: expand read-only command to handle directories --- aider/commands.py | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index 6f6fb6acd..9cb7b4eb2 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -1088,7 +1088,7 @@ class Commands: def cmd_read_only(self, args): "Add files to the chat that are for reference, not to be edited" if not args.strip(): - self.io.tool_error("Please provide filenames to read.") + self.io.tool_error("Please provide filenames or directories to read.") return filenames = parse_quoted_filenames(args) @@ -1098,23 +1098,38 @@ class Commands: abs_path = self.coder.abs_root_path(expanded_path) if not os.path.exists(abs_path): - self.io.tool_error(f"File not found: {abs_path}") + self.io.tool_error(f"Path not found: {abs_path}") continue - if not os.path.isfile(abs_path): - self.io.tool_error(f"Not a file: {abs_path}") - continue - - if abs_path in self.coder.abs_fnames: - self.io.tool_error(f"{word} is already in the chat as an editable file") - continue - - if abs_path in self.coder.abs_read_only_fnames: - self.io.tool_error(f"{word} is already in the chat as a read-only file") - continue + if os.path.isfile(abs_path): + self._add_read_only_file(abs_path, word) + elif os.path.isdir(abs_path): + self._add_read_only_directory(abs_path, word) + else: + self.io.tool_error(f"Not a file or directory: {abs_path}") + def _add_read_only_file(self, abs_path, original_name): + if abs_path in self.coder.abs_fnames: + self.io.tool_error(f"{original_name} is already in the chat as an editable file") + elif abs_path in self.coder.abs_read_only_fnames: + self.io.tool_error(f"{original_name} is already in the chat as a read-only file") + else: self.coder.abs_read_only_fnames.add(abs_path) - self.io.tool_output(f"Added {word} to read-only files.") + self.io.tool_output(f"Added {original_name} to read-only files.") + + def _add_read_only_directory(self, abs_path, original_name): + added_files = 0 + for root, _, files in os.walk(abs_path): + for file in files: + file_path = os.path.join(root, file) + if file_path not in self.coder.abs_fnames and file_path not in self.coder.abs_read_only_fnames: + self.coder.abs_read_only_fnames.add(file_path) + added_files += 1 + + if added_files > 0: + self.io.tool_output(f"Added {added_files} files from directory {original_name} to read-only files.") + else: + self.io.tool_output(f"No new files added from directory {original_name}.") def cmd_map(self, args): "Print out the current repository map" From 13f9685f13195ec6891f66de535252fc5ed77c3b Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 13:03:36 -0700 Subject: [PATCH 072/135] style: Format code to comply with linter rules --- aider/commands.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index 9cb7b4eb2..cad898462 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -1122,12 +1122,17 @@ class Commands: for root, _, files in os.walk(abs_path): for file in files: file_path = os.path.join(root, file) - if file_path not in self.coder.abs_fnames and file_path not in self.coder.abs_read_only_fnames: + if ( + file_path not in self.coder.abs_fnames + and file_path not in self.coder.abs_read_only_fnames + ): self.coder.abs_read_only_fnames.add(file_path) added_files += 1 - + if added_files > 0: - self.io.tool_output(f"Added {added_files} files from directory {original_name} to read-only files.") + self.io.tool_output( + f"Added {added_files} files from directory {original_name} to read-only files." + ) else: self.io.tool_output(f"No new files added from directory {original_name}.") From c575bae710bd12dce37a09f42467e72276a5ef00 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 13:33:27 -0700 Subject: [PATCH 073/135] feat: add codespell as pre-commit hook --- .pre-commit-config.yaml | 5 +++++ requirements/requirements-dev.in | 1 + 2 files changed, 6 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index daec59aae..cc1b4fd1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,3 +14,8 @@ repos: hooks: - id: flake8 args: ["--show-source"] + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + args: ["--write-changes"] diff --git a/requirements/requirements-dev.in b/requirements/requirements-dev.in index 2ceb41fc5..ccd86fcce 100644 --- a/requirements/requirements-dev.in +++ b/requirements/requirements-dev.in @@ -12,3 +12,4 @@ imgcat pre-commit cogapp semver +codespell From e3e6437dcae4f6a6cfaa4d51c146784d8fdeefda Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 13:37:18 -0700 Subject: [PATCH 074/135] chore: configure codespell to use pyproject.toml and skip specific files --- .pre-commit-config.yaml | 3 ++- pyproject.toml | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cc1b4fd1c..2a62f51e1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,4 +18,5 @@ repos: rev: v2.2.6 hooks: - id: codespell - args: ["--write-changes"] + additional_dependencies: + - tomli diff --git a/pyproject.toml b/pyproject.toml index 7e78a16dc..074f3b054 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,3 +67,6 @@ build-backend = "setuptools.build_meta" [tool.setuptools_scm] write_to = "aider/__version__.py" + +[tool.codespell] +skip = "*.svg,Gemfile.lock" From 971fe5017adae24c50b539140be78dcebced46a7 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 13:38:14 -0700 Subject: [PATCH 075/135] feat: enable automatic writing of codespell changes in pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 074f3b054..7b0a6ccad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,3 +70,4 @@ write_to = "aider/__version__.py" [tool.codespell] skip = "*.svg,Gemfile.lock" +write-changes = true From 2c08cc47e6bbad657dfecf27afcae1cebc4494e5 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 13:38:25 -0700 Subject: [PATCH 076/135] copy --- aider/website/docs/ctags.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aider/website/docs/ctags.md b/aider/website/docs/ctags.md index b57f8de33..11bb4f05f 100644 --- a/aider/website/docs/ctags.md +++ b/aider/website/docs/ctags.md @@ -12,6 +12,7 @@ nav_exclude: true ![robot flowchat](/assets/robot-flowchart.png) + ## Updated Aider no longer uses ctags to build a repo map. @@ -228,7 +229,7 @@ Some possible approaches to reducing the amount of map data are: - Distill the global map, to prioritize important symbols and discard "internal" or otherwise less globally relevant identifiers. Possibly enlist `gpt-3.5-turbo` to perform this distillation in a flexible and language agnostic way. - Provide a mechanism for GPT to start with a distilled subset of the global map, and let it ask to see more detail about subtrees or keywords that it feels are relevant to the current coding task. - - Attempt to analyize the natural language coding task given by the user and predict which subset of the repo map is relevant. Possibly by analysis of prior coding chats within the specific repo. Work on certain files or types of features may require certain somewhat predictable context from elsewhere in the repo. Vector and keyword search against the chat history, repo map or codebase may help here. + - Attempt to analyze the natural language coding task given by the user and predict which subset of the repo map is relevant. Possibly by analysis of prior coding chats within the specific repo. Work on certain files or types of features may require certain somewhat predictable context from elsewhere in the repo. Vector and keyword search against the chat history, repo map or codebase may help here. One key goal is to prefer solutions which are language agnostic or which can be easily deployed against most popular code languages. From ed866d33e4d59b15e47036edefc0fbba27d0ceb9 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 13:40:19 -0700 Subject: [PATCH 077/135] pip-compiled --- requirements/requirements-dev.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 859644fe0..deb14acb1 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -25,6 +25,8 @@ click==8.1.7 # -c requirements/../requirements.txt # pip-tools # typer +codespell==2.3.0 + # via -r requirements/requirements-dev.in cogapp==3.4.1 # via -r requirements/requirements-dev.in contourpy==1.3.0 From 79a424bc101683f77842e644ee57e7f2a8737a54 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 13:49:22 -0700 Subject: [PATCH 078/135] refactor: conditionally initialize and use PromptSession based on pretty flag --- aider/io.py | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/aider/io.py b/aider/io.py index 84e4f144b..3bdbc3589 100644 --- a/aider/io.py +++ b/aider/io.py @@ -219,16 +219,18 @@ class InputOutput: current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.append_chat_history(f"\n# aider chat started at {current_time}\n\n") - # Initialize PromptSession - session_kwargs = { - "input": self.input, - "output": self.output, - "lexer": PygmentsLexer(MarkdownLexer), - "editing_mode": self.editingmode, - } - if self.input_history_file is not None: - session_kwargs["history"] = FileHistory(self.input_history_file) - self.prompt_session = PromptSession(**session_kwargs) + self.prompt_session = None + if self.pretty: + # Initialize PromptSession + session_kwargs = { + "input": self.input, + "output": self.output, + "lexer": PygmentsLexer(MarkdownLexer), + "editing_mode": self.editingmode, + } + if self.input_history_file is not None: + session_kwargs["history"] = FileHistory(self.input_history_file) + self.prompt_session = PromptSession(**session_kwargs) def read_image(self, filename): try: @@ -339,14 +341,17 @@ class InputOutput: show = ". " try: - line = self.prompt_session.prompt( - show, - completer=completer_instance, - reserve_space_for_menu=4, - complete_style=CompleteStyle.MULTI_COLUMN, - style=style, - key_bindings=kb, - ) + if self.prompt_session: + line = self.prompt_session.prompt( + show, + completer=completer_instance, + reserve_space_for_menu=4, + complete_style=CompleteStyle.MULTI_COLUMN, + style=style, + key_bindings=kb, + ) + else: + line = input(show) except UnicodeEncodeError as err: self.tool_error(str(err)) return "" @@ -519,7 +524,10 @@ class InputOutput: elif self.yes is False: res = "no" else: - res = self.prompt_session.prompt(question + " ", default=default, style=style) + if self.prompt_session: + res = self.prompt_session.prompt(question + " ", default=default, style=style) + else: + res = input(question + " ") hist = f"{question.strip()} {res.strip()}" self.append_chat_history(hist, linebreak=True, blockquote=True) From d4e47bc7e73382e4d7bebbf67c863dd060a4bfb8 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:06:51 -0700 Subject: [PATCH 079/135] refactor: update confirm_ask to use prompt_session or input --- aider/io.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/aider/io.py b/aider/io.py index 3bdbc3589..ba38758be 100644 --- a/aider/io.py +++ b/aider/io.py @@ -471,10 +471,14 @@ class InputOutput: self.user_input(f"{question}{res}", log_only=False) else: while True: - res = prompt( - question, - style=Style.from_dict(style), - ) + if self.prompt_session: + res = self.prompt_session.prompt( + question, + style=Style.from_dict(style), + ) + else: + res = input(question) + if not res: res = "y" # Default to Yes if no input break From 13fe2036dbea65bd74bc802c22b2b121368fb4a3 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:06:55 -0700 Subject: [PATCH 080/135] style: remove trailing whitespace in io.py --- aider/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/io.py b/aider/io.py index ba38758be..eb9c6737f 100644 --- a/aider/io.py +++ b/aider/io.py @@ -478,7 +478,7 @@ class InputOutput: ) else: res = input(question) - + if not res: res = "y" # Default to Yes if no input break From 1d312e372db9c33fdc679a334a87c4fbc40097b4 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:07:32 -0700 Subject: [PATCH 081/135] refactor: Remove unused import of 'prompt' from prompt_toolkit --- aider/io.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/io.py b/aider/io.py index eb9c6737f..9591f6f3a 100644 --- a/aider/io.py +++ b/aider/io.py @@ -5,7 +5,6 @@ from dataclasses import dataclass from datetime import datetime from pathlib import Path -from prompt_toolkit import prompt from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter from prompt_toolkit.enums import EditingMode from prompt_toolkit.history import FileHistory From d5d087123a1736448684887e35098b362b720d5a Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:09:29 -0700 Subject: [PATCH 082/135] test: update input mocking in TestInputOutput --- tests/basic/test_io.py | 78 ++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/tests/basic/test_io.py b/tests/basic/test_io.py index ad9293ba5..a7bdf1ae1 100644 --- a/tests/basic/test_io.py +++ b/tests/basic/test_io.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch from aider.dump import dump # noqa: F401 from aider.io import AutoCompleter, ConfirmGroup, InputOutput +import builtins from aider.utils import ChdirTemporaryDirectory @@ -46,12 +47,8 @@ class TestInputOutput(unittest.TestCase): autocompleter = AutoCompleter(root, rel_fnames, addable_rel_fnames, commands, "utf-8") self.assertEqual(autocompleter.words, set(rel_fnames)) - @patch("aider.io.PromptSession") - def test_get_input_is_a_directory_error(self, MockPromptSession): - # Mock the PromptSession to simulate user input - mock_session = MockPromptSession.return_value - mock_session.prompt.return_value = "test input" - + @patch("builtins.input", return_value="test input") + def test_get_input_is_a_directory_error(self, mock_input): io = InputOutput(pretty=False) # Windows tests throw UnicodeDecodeError root = "/" rel_fnames = ["existing_file.txt"] @@ -62,105 +59,106 @@ class TestInputOutput(unittest.TestCase): with patch("aider.io.open", side_effect=IsADirectoryError): result = io.get_input(root, rel_fnames, addable_rel_fnames, commands) self.assertEqual(result, "test input") + mock_input.assert_called_once() - @patch("aider.io.prompt") - def test_confirm_ask_explicit_yes_required(self, mock_prompt): + @patch("builtins.input") + def test_confirm_ask_explicit_yes_required(self, mock_input): io = InputOutput(pretty=False) # Test case 1: explicit_yes_required=True, self.yes=True io.yes = True result = io.confirm_ask("Are you sure?", explicit_yes_required=True) self.assertFalse(result) - mock_prompt.assert_not_called() + mock_input.assert_not_called() # Test case 2: explicit_yes_required=True, self.yes=False io.yes = False result = io.confirm_ask("Are you sure?", explicit_yes_required=True) self.assertFalse(result) - mock_prompt.assert_not_called() + mock_input.assert_not_called() # Test case 3: explicit_yes_required=True, user input required io.yes = None - mock_prompt.return_value = "y" + mock_input.return_value = "y" result = io.confirm_ask("Are you sure?", explicit_yes_required=True) self.assertTrue(result) - mock_prompt.assert_called_once() + mock_input.assert_called_once() - # Reset mock_prompt - mock_prompt.reset_mock() + # Reset mock_input + mock_input.reset_mock() # Test case 4: explicit_yes_required=False, self.yes=True io.yes = True result = io.confirm_ask("Are you sure?", explicit_yes_required=False) self.assertTrue(result) - mock_prompt.assert_not_called() + mock_input.assert_not_called() - @patch("aider.io.prompt") - def test_confirm_ask_with_group(self, mock_prompt): + @patch("builtins.input") + def test_confirm_ask_with_group(self, mock_input): io = InputOutput(pretty=False) group = ConfirmGroup() # Test case 1: No group preference, user selects 'All' - mock_prompt.return_value = "a" + mock_input.return_value = "a" result = io.confirm_ask("Are you sure?", group=group) self.assertTrue(result) self.assertEqual(group.preference, "all") - mock_prompt.assert_called_once() - mock_prompt.reset_mock() + mock_input.assert_called_once() + mock_input.reset_mock() # Test case 2: Group preference is 'All', should not prompt result = io.confirm_ask("Are you sure?", group=group) self.assertTrue(result) - mock_prompt.assert_not_called() + mock_input.assert_not_called() # Test case 3: No group preference, user selects 'Skip all' group.preference = None - mock_prompt.return_value = "s" + mock_input.return_value = "s" result = io.confirm_ask("Are you sure?", group=group) self.assertFalse(result) self.assertEqual(group.preference, "skip") - mock_prompt.assert_called_once() - mock_prompt.reset_mock() + mock_input.assert_called_once() + mock_input.reset_mock() # Test case 4: Group preference is 'Skip all', should not prompt result = io.confirm_ask("Are you sure?", group=group) self.assertFalse(result) - mock_prompt.assert_not_called() + mock_input.assert_not_called() # Test case 5: explicit_yes_required=True, should not offer 'All' option group.preference = None - mock_prompt.return_value = "y" + mock_input.return_value = "y" result = io.confirm_ask("Are you sure?", group=group, explicit_yes_required=True) self.assertTrue(result) self.assertIsNone(group.preference) - mock_prompt.assert_called_once() - self.assertNotIn("(A)ll", mock_prompt.call_args[0][0]) - mock_prompt.reset_mock() + mock_input.assert_called_once() + self.assertNotIn("(A)ll", mock_input.call_args[0][0]) + mock_input.reset_mock() - @patch("aider.io.prompt") - def test_confirm_ask_yes_no(self, mock_prompt): + @patch("builtins.input") + def test_confirm_ask_yes_no(self, mock_input): io = InputOutput(pretty=False) # Test case 1: User selects 'Yes' - mock_prompt.return_value = "y" + mock_input.return_value = "y" result = io.confirm_ask("Are you sure?") self.assertTrue(result) - mock_prompt.assert_called_once() - mock_prompt.reset_mock() + mock_input.assert_called_once() + mock_input.reset_mock() # Test case 2: User selects 'No' - mock_prompt.return_value = "n" + mock_input.return_value = "n" result = io.confirm_ask("Are you sure?") self.assertFalse(result) - mock_prompt.assert_called_once() - mock_prompt.reset_mock() + mock_input.assert_called_once() + mock_input.reset_mock() # Test case 3: Empty input (default to Yes) - mock_prompt.return_value = "" + mock_input.return_value = "" result = io.confirm_ask("Are you sure?") self.assertTrue(result) - mock_prompt.assert_called_once() - mock_prompt.reset_mock() + mock_input.assert_called_once() + mock_input.reset_mock() def test_get_command_completions(self): root = "" From 3685f307c7a5cd6c1cb280577869a7c2fce89534 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:09:33 -0700 Subject: [PATCH 083/135] style: reorder imports in test_io.py --- tests/basic/test_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic/test_io.py b/tests/basic/test_io.py index a7bdf1ae1..ac4a9ef48 100644 --- a/tests/basic/test_io.py +++ b/tests/basic/test_io.py @@ -1,3 +1,4 @@ +import builtins import os import unittest from pathlib import Path @@ -5,7 +6,6 @@ from unittest.mock import MagicMock, patch from aider.dump import dump # noqa: F401 from aider.io import AutoCompleter, ConfirmGroup, InputOutput -import builtins from aider.utils import ChdirTemporaryDirectory From 8da88eef6482db56a9163997c1ea3897deed8a0a Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:09:40 -0700 Subject: [PATCH 084/135] fix: remove unused import of builtins module --- tests/basic/test_io.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/basic/test_io.py b/tests/basic/test_io.py index ac4a9ef48..05770ef01 100644 --- a/tests/basic/test_io.py +++ b/tests/basic/test_io.py @@ -1,4 +1,3 @@ -import builtins import os import unittest from pathlib import Path From fb87dd883cf487bd0b3a2a5272be03bfd8018b08 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:18:32 -0700 Subject: [PATCH 085/135] test: patch input() to return empty string This commit patches the `input()` builtin to return an empty string in the test setup, preventing tests from hanging while waiting for user input. It also adds cleanup for the patch in the teardown method. --- tests/basic/test_main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index 934ef42c0..be8748191 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -5,7 +5,7 @@ import tempfile from io import StringIO from pathlib import Path from unittest import TestCase -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock, patch, mock_open import git from prompt_toolkit.input import DummyInput @@ -29,6 +29,8 @@ class TestMain(TestCase): # Fake home directory prevents tests from using the real ~/.aider.conf.yml file: self.homedir_obj = IgnorantTemporaryDirectory() os.environ["HOME"] = self.homedir_obj.name + self.input_patcher = patch('builtins.input', return_value='') + self.mock_input = self.input_patcher.start() def tearDown(self): os.chdir(self.original_cwd) @@ -36,6 +38,7 @@ class TestMain(TestCase): self.homedir_obj.cleanup() os.environ.clear() os.environ.update(self.original_env) + self.input_patcher.stop() def test_main_with_empty_dir_no_files_on_command(self): main(["--no-git"], input=DummyInput(), output=DummyOutput()) From 645252168c0365441faeef73e2a97a25394c74a2 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:18:37 -0700 Subject: [PATCH 086/135] style: sort imports and fix quotation marks --- tests/basic/test_main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index be8748191..f888f0559 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -5,7 +5,7 @@ import tempfile from io import StringIO from pathlib import Path from unittest import TestCase -from unittest.mock import MagicMock, patch, mock_open +from unittest.mock import MagicMock, mock_open, patch import git from prompt_toolkit.input import DummyInput @@ -29,7 +29,7 @@ class TestMain(TestCase): # Fake home directory prevents tests from using the real ~/.aider.conf.yml file: self.homedir_obj = IgnorantTemporaryDirectory() os.environ["HOME"] = self.homedir_obj.name - self.input_patcher = patch('builtins.input', return_value='') + self.input_patcher = patch("builtins.input", return_value="") self.mock_input = self.input_patcher.start() def tearDown(self): From 59bdc4572826020bc2f31fb3c591fc5f5159aef6 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 14:18:56 -0700 Subject: [PATCH 087/135] refactor: Remove unused mock_open import --- tests/basic/test_main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index f888f0559..cc6ce1e41 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -5,7 +5,7 @@ import tempfile from io import StringIO from pathlib import Path from unittest import TestCase -from unittest.mock import MagicMock, mock_open, patch +from unittest.mock import MagicMock, patch import git from prompt_toolkit.input import DummyInput From 454c2f4d0ee29e02e1a7515637c0729eb0f129bd Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 14:30:04 -0700 Subject: [PATCH 088/135] feat: add --exit flag to test cases for controlled termination --- tests/basic/test_main.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index cc6ce1e41..1bd2815ed 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -41,22 +41,22 @@ class TestMain(TestCase): self.input_patcher.stop() def test_main_with_empty_dir_no_files_on_command(self): - main(["--no-git"], input=DummyInput(), output=DummyOutput()) + main(["--no-git", "--exit"], input=DummyInput(), output=DummyOutput()) def test_main_with_emptqy_dir_new_file(self): - main(["foo.txt", "--yes", "--no-git"], input=DummyInput(), output=DummyOutput()) + main(["foo.txt", "--yes", "--no-git", "--exit"], input=DummyInput(), output=DummyOutput()) self.assertTrue(os.path.exists("foo.txt")) @patch("aider.repo.GitRepo.get_commit_message", return_value="mock commit message") def test_main_with_empty_git_dir_new_file(self, _): make_repo() - main(["--yes", "foo.txt"], input=DummyInput(), output=DummyOutput()) + main(["--yes", "foo.txt", "--exit"], input=DummyInput(), output=DummyOutput()) self.assertTrue(os.path.exists("foo.txt")) @patch("aider.repo.GitRepo.get_commit_message", return_value="mock commit message") def test_main_with_empty_git_dir_new_files(self, _): make_repo() - main(["--yes", "foo.txt", "bar.txt"], input=DummyInput(), output=DummyOutput()) + main(["--yes", "foo.txt", "bar.txt", "--exit"], input=DummyInput(), output=DummyOutput()) self.assertTrue(os.path.exists("foo.txt")) self.assertTrue(os.path.exists("bar.txt")) @@ -73,7 +73,7 @@ class TestMain(TestCase): subdir.mkdir() make_repo(str(subdir)) main( - ["--yes", str(subdir / "foo.txt"), str(subdir / "bar.txt")], + ["--yes", str(subdir / "foo.txt"), str(subdir / "bar.txt"), "--exit"], input=DummyInput(), output=DummyOutput(), ) @@ -107,7 +107,7 @@ class TestMain(TestCase): # This will throw a git error on windows if get_tracked_files doesn't # properly convert git/posix/paths to git\posix\paths. # Because aider will try and `git add` a file that's already in the repo. - main(["--yes", str(fname)], input=DummyInput(), output=DummyOutput()) + main(["--yes", str(fname), "--exit"], input=DummyInput(), output=DummyOutput()) def test_setup_git(self): io = InputOutput(pretty=False, yes=True) @@ -371,7 +371,7 @@ class TestMain(TestCase): def test_verbose_mode_lists_env_vars(self): self.create_env_file(".env", "AIDER_DARK_MODE=on") with patch("sys.stdout", new_callable=StringIO) as mock_stdout: - main(["--no-git", "--verbose"], input=DummyInput(), output=DummyOutput()) + main(["--no-git", "--verbose", "--exit"], input=DummyInput(), output=DummyOutput()) output = mock_stdout.getvalue() relevant_output = "\n".join( line From fd18adb0720c3a9235a37e439a7be2ad89a224e1 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 14:34:25 -0700 Subject: [PATCH 089/135] refactor: handle prompt toolkit initialization errors gracefully --- aider/io.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/aider/io.py b/aider/io.py index 9591f6f3a..44ddd336d 100644 --- a/aider/io.py +++ b/aider/io.py @@ -210,11 +210,6 @@ class InputOutput: self.encoding = encoding self.dry_run = dry_run - if pretty: - self.console = Console() - else: - self.console = Console(force_terminal=False, no_color=True) - current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.append_chat_history(f"\n# aider chat started at {current_time}\n\n") @@ -229,7 +224,16 @@ class InputOutput: } if self.input_history_file is not None: session_kwargs["history"] = FileHistory(self.input_history_file) - self.prompt_session = PromptSession(**session_kwargs) + try: + self.prompt_session = PromptSession(**session_kwargs) + except Exception as err: + self.tool_error(f"Can't initialize prompt toolkit: {err}") + self.pretty = False + + if self.pretty: + self.console = Console() + else: + self.console = Console(force_terminal=False, no_color=True) def read_image(self, filename): try: From 33b11d0efb95b5471db97f118c6c823fe20e9a7f Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 14:48:54 -0700 Subject: [PATCH 090/135] refactor: simplify console initialization and error handling --- aider/io.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/aider/io.py b/aider/io.py index 44ddd336d..521d548e4 100644 --- a/aider/io.py +++ b/aider/io.py @@ -226,14 +226,12 @@ class InputOutput: session_kwargs["history"] = FileHistory(self.input_history_file) try: self.prompt_session = PromptSession(**session_kwargs) + self.console = Console() # pretty console except Exception as err: - self.tool_error(f"Can't initialize prompt toolkit: {err}") - self.pretty = False - - if self.pretty: - self.console = Console() + self.console = Console(force_terminal=False, no_color=True) + self.tool_error(f"Can't initialize prompt toolkit: {err}") # non-pretty else: - self.console = Console(force_terminal=False, no_color=True) + self.console = Console(force_terminal=False, no_color=True) # non-pretty def read_image(self, filename): try: From fa49ab09c4a29cdcf5335d3ea97786fc7be76aaf Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 10 Sep 2024 15:24:11 -0700 Subject: [PATCH 091/135] test: update code_theme tests to check InputOutput initialization --- tests/basic/test_main.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index 1bd2815ed..d5725f22b 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -272,23 +272,23 @@ class TestMain(TestCase): self.assertEqual(args[1], None) def test_dark_mode_sets_code_theme(self): - # Mock Coder.create to capture the configuration - with patch("aider.coders.Coder.create") as MockCoder: + # Mock InputOutput to capture the configuration + with patch("aider.main.InputOutput") as MockInputOutput: main(["--dark-mode", "--no-git"], input=DummyInput(), output=DummyOutput()) - # Ensure Coder.create was called - MockCoder.assert_called_once() + # Ensure InputOutput was called + MockInputOutput.assert_called_once() # Check if the code_theme setting is for dark mode - _, kwargs = MockCoder.call_args + _, kwargs = MockInputOutput.call_args self.assertEqual(kwargs["code_theme"], "monokai") def test_light_mode_sets_code_theme(self): - # Mock Coder.create to capture the configuration - with patch("aider.coders.Coder.create") as MockCoder: + # Mock InputOutput to capture the configuration + with patch("aider.main.InputOutput") as MockInputOutput: main(["--light-mode", "--no-git"], input=DummyInput(), output=DummyOutput()) - # Ensure Coder.create was called - MockCoder.assert_called_once() + # Ensure InputOutput was called + MockInputOutput.assert_called_once() # Check if the code_theme setting is for light mode - _, kwargs = MockCoder.call_args + _, kwargs = MockInputOutput.call_args self.assertEqual(kwargs["code_theme"], "default") def create_env_file(self, file_name, content): @@ -298,25 +298,25 @@ class TestMain(TestCase): def test_env_file_flag_sets_automatic_variable(self): env_file_path = self.create_env_file(".env.test", "AIDER_DARK_MODE=True") - with patch("aider.coders.Coder.create") as MockCoder: + with patch("aider.main.InputOutput") as MockInputOutput: main( ["--env-file", str(env_file_path), "--no-git"], input=DummyInput(), output=DummyOutput(), ) - MockCoder.assert_called_once() + MockInputOutput.assert_called_once() # Check if the color settings are for dark mode - _, kwargs = MockCoder.call_args + _, kwargs = MockInputOutput.call_args self.assertEqual(kwargs["code_theme"], "monokai") def test_default_env_file_sets_automatic_variable(self): self.create_env_file(".env", "AIDER_DARK_MODE=True") - with patch("aider.coders.Coder.create") as MockCoder: + with patch("aider.main.InputOutput") as MockInputOutput: main(["--no-git"], input=DummyInput(), output=DummyOutput()) - # Ensure Coder.create was called - MockCoder.assert_called_once() + # Ensure InputOutput was called + MockInputOutput.assert_called_once() # Check if the color settings are for dark mode - _, kwargs = MockCoder.call_args + _, kwargs = MockInputOutput.call_args self.assertEqual(kwargs["code_theme"], "monokai") def test_false_vals_in_env_file(self): From 0a3b4147fa5bbeea3176af7350041c3b9df375a0 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 10 Sep 2024 15:32:43 -0700 Subject: [PATCH 092/135] test: update main tests to handle None input and add --exit flag --- tests/basic/test_main.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index d5725f22b..c25bee48f 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -29,7 +29,7 @@ class TestMain(TestCase): # Fake home directory prevents tests from using the real ~/.aider.conf.yml file: self.homedir_obj = IgnorantTemporaryDirectory() os.environ["HOME"] = self.homedir_obj.name - self.input_patcher = patch("builtins.input", return_value="") + self.input_patcher = patch("builtins.input", return_value=None) self.mock_input = self.input_patcher.start() def tearDown(self): @@ -274,7 +274,8 @@ class TestMain(TestCase): def test_dark_mode_sets_code_theme(self): # Mock InputOutput to capture the configuration with patch("aider.main.InputOutput") as MockInputOutput: - main(["--dark-mode", "--no-git"], input=DummyInput(), output=DummyOutput()) + MockInputOutput.return_value.get_input.return_value = None + main(["--dark-mode", "--no-git", "--exit"], input=DummyInput(), output=DummyOutput()) # Ensure InputOutput was called MockInputOutput.assert_called_once() # Check if the code_theme setting is for dark mode @@ -284,7 +285,8 @@ class TestMain(TestCase): def test_light_mode_sets_code_theme(self): # Mock InputOutput to capture the configuration with patch("aider.main.InputOutput") as MockInputOutput: - main(["--light-mode", "--no-git"], input=DummyInput(), output=DummyOutput()) + MockInputOutput.return_value.get_input.return_value = None + main(["--light-mode", "--no-git", "--exit"], input=DummyInput(), output=DummyOutput()) # Ensure InputOutput was called MockInputOutput.assert_called_once() # Check if the code_theme setting is for light mode @@ -299,8 +301,10 @@ class TestMain(TestCase): def test_env_file_flag_sets_automatic_variable(self): env_file_path = self.create_env_file(".env.test", "AIDER_DARK_MODE=True") with patch("aider.main.InputOutput") as MockInputOutput: + MockInputOutput.return_value.get_input.return_value = None + MockInputOutput.return_value.get_input.confirm_ask = True main( - ["--env-file", str(env_file_path), "--no-git"], + ["--env-file", str(env_file_path), "--no-git", "--exit"], input=DummyInput(), output=DummyOutput(), ) @@ -312,7 +316,9 @@ class TestMain(TestCase): def test_default_env_file_sets_automatic_variable(self): self.create_env_file(".env", "AIDER_DARK_MODE=True") with patch("aider.main.InputOutput") as MockInputOutput: - main(["--no-git"], input=DummyInput(), output=DummyOutput()) + MockInputOutput.return_value.get_input.return_value = None + MockInputOutput.return_value.get_input.confirm_ask = True + main(["--no-git", "--exit"], input=DummyInput(), output=DummyOutput()) # Ensure InputOutput was called MockInputOutput.assert_called_once() # Check if the color settings are for dark mode From 7315624b980b7cecc3d99f3dd547489c016f505d Mon Sep 17 00:00:00 2001 From: Jay Alammar Date: Wed, 11 Sep 2024 10:55:45 -0400 Subject: [PATCH 093/135] bugfix --- aider/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index d8cba5d32..d513e9ecf 100644 --- a/aider/models.py +++ b/aider/models.py @@ -90,13 +90,13 @@ MODEL_SETTINGS = [ "whole", weak_model_name="gpt-4o-mini", reminder="sys", + ), ModelSettings( "gpt-3.5-turbo-0125", "whole", weak_model_name="gpt-4o-mini", reminder="sys", ), - ), ModelSettings( "gpt-3.5-turbo-1106", "whole", From 5cdcbb1a262128c4f03101ad5f9b966083347ea5 Mon Sep 17 00:00:00 2001 From: Jay Alammar Date: Wed, 11 Sep 2024 11:04:38 -0400 Subject: [PATCH 094/135] Add to docs --- aider/website/docs/llms/cohere.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/docs/llms/cohere.md b/aider/website/docs/llms/cohere.md index d72297c36..99eea15b9 100644 --- a/aider/website/docs/llms/cohere.md +++ b/aider/website/docs/llms/cohere.md @@ -18,7 +18,7 @@ python -m pip install aider-chat export COHERE_API_KEY= # Mac/Linux setx COHERE_API_KEY # Windows, restart shell after setx -aider --model command-r-plus +aider --model command-r-plus-08-2024 # List models available from Cohere aider --list-models cohere_chat/ From 007f841328fbf577628d8b2eb207374ef6ad1a12 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 08:18:07 -0700 Subject: [PATCH 095/135] copy --- aider/website/docs/troubleshooting/imports.md | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/aider/website/docs/troubleshooting/imports.md b/aider/website/docs/troubleshooting/imports.md index 2eba51b82..088e80916 100644 --- a/aider/website/docs/troubleshooting/imports.md +++ b/aider/website/docs/troubleshooting/imports.md @@ -10,22 +10,39 @@ all of its required dependencies. If aider reports `ImportErrors`, this probably means it has been installed incorrectly. +## Install with pipx -## Dependency versions +If you are having problems with import errors you should consider +[installing aider using pipx](/docs/install/pipx.html). +This will ensure that aider is installed in its own python environment, +with the correct set of dependencies. -Aider pins its dependencies and is tested to work with those specific versions. -You should be careful about upgrading or downgrading other python libraries that -aider uses. +## Package managers like Homebrew, AUR, ports -If you need other versions of packages for your project, -consider +Package managers often install aider with the wrong dependencies, leading +to import errors and other problems. +It is not recommended to install aider with these tools. +Instead, consider [installing aider using pipx](/docs/install/pipx.html). +## Dependency versions matter +Aider pins its dependencies and is tested to work with those specific versions. +If you are installing aider with pip (rather than pipx), +you should be careful about upgrading or downgrading the python packages that +aider uses. + +In particular, be careful with the packages with pinned versions +noted at the end of +[aider's requirements.in file](https://github.com/paul-gauthier/aider/blob/main/requirements/requirements.in). +Also be wary of upgrading `litellm`, as it changes versions frequently +and sometimes introduces bugs or backwards incompatible changes. ## Replit -You can `pip install aider-chat` on replit, or you can install it via -pipx. +You can `pip install aider-chat` on replit. + +Or you can install aider with +pipx as follows: {% include replit-pipx.md %} From ba54e4a6e0058963f97b7a6dde92c05492afed0a Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 08:50:28 -0700 Subject: [PATCH 096/135] feat: Add new leaderboard entries for command-r-plus-08-2024 and command-r-08-2024 models --- aider/website/_data/edit_leaderboard.yml | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 217c82142..5afd4288b 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1039,4 +1039,50 @@ date: 2024-09-06 versions: 0.55.1.dev seconds_per_case: 61.6 + total_cost: 0.0000 + +- dirname: 2024-09-11-15-42-17--command-r-plus-08-2024-whole + test_cases: 133 + model: openrouter/cohere/command-r-plus-08-2024 + edit_format: whole + commit_hash: b43ed20 + pass_rate_1: 27.1 + pass_rate_2: 38.3 + percent_cases_well_formed: 100.0 + error_outputs: 0 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 7 + lazy_comments: 10 + syntax_errors: 0 + indentation_errors: 3 + exhausted_context_windows: 0 + test_timeouts: 4 + command: aider --model openrouter/cohere/command-r-plus-08-2024 + date: 2024-09-11 + versions: 0.56.1.dev + seconds_per_case: 20.3 + total_cost: 0.0000 + +- dirname: 2024-09-11-15-47-02--command-r-08-2024-whole + test_cases: 133 + model: openrouter/cohere/command-r-08-2024 + edit_format: whole + commit_hash: b43ed20-dirty + pass_rate_1: 30.1 + pass_rate_2: 38.3 + percent_cases_well_formed: 100.0 + error_outputs: 0 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 4 + lazy_comments: 0 + syntax_errors: 1 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 2 + command: aider --model openrouter/cohere/command-r-08-2024 + date: 2024-09-11 + versions: 0.56.1.dev + seconds_per_case: 7.6 total_cost: 0.0000 \ No newline at end of file From 408ecc1bd776eb963160f663ae5d9dda486c4924 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 08:50:35 -0700 Subject: [PATCH 097/135] copy --- aider/website/docs/leaderboards/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/docs/leaderboards/index.md b/aider/website/docs/leaderboards/index.md index 2414539b0..77b726560 100644 --- a/aider/website/docs/leaderboards/index.md +++ b/aider/website/docs/leaderboards/index.md @@ -321,6 +321,6 @@ mod_dates = [get_last_modified_date(file) for file in files] latest_mod_date = max(mod_dates) cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}") ]]]--> -September 06, 2024. +September 11, 2024.

From 13ac0f0968c050ca5d4688aa73e9bf5fc6554fdf Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 08:54:16 -0700 Subject: [PATCH 098/135] fix: Update model names and commands in edit_leaderboard.yml --- aider/website/_data/edit_leaderboard.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 5afd4288b..22bdb0043 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1043,7 +1043,7 @@ - dirname: 2024-09-11-15-42-17--command-r-plus-08-2024-whole test_cases: 133 - model: openrouter/cohere/command-r-plus-08-2024 + model: Command R+ (08-24) edit_format: whole commit_hash: b43ed20 pass_rate_1: 27.1 @@ -1058,7 +1058,7 @@ indentation_errors: 3 exhausted_context_windows: 0 test_timeouts: 4 - command: aider --model openrouter/cohere/command-r-plus-08-2024 + command: aider --model cohere_chat/command-r-plus-08-2024 date: 2024-09-11 versions: 0.56.1.dev seconds_per_case: 20.3 @@ -1066,7 +1066,7 @@ - dirname: 2024-09-11-15-47-02--command-r-08-2024-whole test_cases: 133 - model: openrouter/cohere/command-r-08-2024 + model: Command R (08-24) edit_format: whole commit_hash: b43ed20-dirty pass_rate_1: 30.1 @@ -1081,7 +1081,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 2 - command: aider --model openrouter/cohere/command-r-08-2024 + command: aider --model cohere_chat/command-r-08-2024 date: 2024-09-11 versions: 0.56.1.dev seconds_per_case: 7.6 From 94a609d75e58f5d9c76507ebe0c616ddea779aa4 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 08:56:46 -0700 Subject: [PATCH 099/135] fix: Update model names in edit_leaderboard.yml --- aider/website/_data/edit_leaderboard.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 22bdb0043..f1a84375f 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1058,7 +1058,7 @@ indentation_errors: 3 exhausted_context_windows: 0 test_timeouts: 4 - command: aider --model cohere_chat/command-r-plus-08-2024 + command: aider --model command-r-plus-08-2024 date: 2024-09-11 versions: 0.56.1.dev seconds_per_case: 20.3 @@ -1081,7 +1081,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 2 - command: aider --model cohere_chat/command-r-08-2024 + command: aider --model command-r-08-2024 date: 2024-09-11 versions: 0.56.1.dev seconds_per_case: 7.6 From ca43a37567861f5ab312751c156b2a57c5e734f2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 09:53:13 -0700 Subject: [PATCH 100/135] copy --- aider/website/docs/troubleshooting/imports.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aider/website/docs/troubleshooting/imports.md b/aider/website/docs/troubleshooting/imports.md index 088e80916..6773cba76 100644 --- a/aider/website/docs/troubleshooting/imports.md +++ b/aider/website/docs/troubleshooting/imports.md @@ -35,6 +35,9 @@ aider uses. In particular, be careful with the packages with pinned versions noted at the end of [aider's requirements.in file](https://github.com/paul-gauthier/aider/blob/main/requirements/requirements.in). +These versions are pinned because aider is known not to work with the +latest versions of these libraries. + Also be wary of upgrading `litellm`, as it changes versions frequently and sometimes introduces bugs or backwards incompatible changes. From 35588b69849b91f2674915e19b9d1b54ac449604 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 09:54:47 -0700 Subject: [PATCH 101/135] fix: Fix formatting of assistant_output assignment in base_coder.py --- aider/coders/base_coder.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 78737d4f6..1cb6b6395 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -1094,7 +1094,7 @@ class Coder: utils.show_messages(messages, functions=self.functions) self.multi_response_content = "" - self.mdstream=self.io.assistant_output("", self.stream) + self.mdstream = self.io.assistant_output("", self.stream) retry_delay = 0.125 @@ -1867,7 +1867,6 @@ class Coder: message=commit_message, ) - self.io.tool_output("No changes made to git tracked files.") return self.gpt_prompts.files_content_gpt_no_edits except ANY_GIT_ERROR as err: self.io.tool_error(f"Unable to commit: {str(err)}") @@ -1886,6 +1885,8 @@ class Coder: return if self.commit_before_message[-1] != self.repo.get_head_commit_sha(): self.io.tool_output("You can use /undo to undo and discard each aider commit.") + else: + self.io.tool_output("No changes made to git tracked files.") def dirty_commit(self): if not self.need_commit_before_edits: From 385f2693c4e62ba53688e2317be8e47b2ddbd259 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 13:14:40 -0700 Subject: [PATCH 102/135] copy --- aider/website/docs/scripting.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aider/website/docs/scripting.md b/aider/website/docs/scripting.md index c90e92cd0..aab42357d 100644 --- a/aider/website/docs/scripting.md +++ b/aider/website/docs/scripting.md @@ -26,7 +26,9 @@ for FILE in *.py ; do done ``` -User `aider --help` to see all the command line options, but these are useful for scripting: +User `aider --help` to see all the +[command line options](/docs/config/options.html), +but these are useful for scripting: ``` --stream, --no-stream From 615dc5fe4beed6ee7e151b75d4cf624eaf2c12a4 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 13:18:07 -0700 Subject: [PATCH 103/135] copy --- aider/website/docs/scripting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/docs/scripting.md b/aider/website/docs/scripting.md index aab42357d..5bcd1ff00 100644 --- a/aider/website/docs/scripting.md +++ b/aider/website/docs/scripting.md @@ -26,7 +26,7 @@ for FILE in *.py ; do done ``` -User `aider --help` to see all the +Use `aider --help` to see all the [command line options](/docs/config/options.html), but these are useful for scripting: From 1603ffa6c284dce28e56f56b237c73ae225aadce Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 14:01:10 -0700 Subject: [PATCH 104/135] fix: Update sample.aider.conf.yml and args_formatter.py --- aider/args_formatter.py | 6 ++- aider/website/assets/sample.aider.conf.yml | 60 ++++++++++++---------- aider/website/docs/config/aider_conf.md | 60 ++++++++++++---------- 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/aider/args_formatter.py b/aider/args_formatter.py index f97cb433d..df8bfac39 100644 --- a/aider/args_formatter.py +++ b/aider/args_formatter.py @@ -144,8 +144,12 @@ class YamlHelpFormatter(argparse.HelpFormatter): if default: parts.append(f"#{switch}: {default}\n") + elif action.nargs in ("*", "+") or isinstance(action, argparse._AppendAction): + parts.append(f"#{switch}: xxx") + parts.append(f"## Specify multiple values like this:") + parts.append(f"#{switch}: [xxx,yyyy,zzz]\n") else: - parts.append(f"#{switch}:\n") + parts.append(f"#{switch}: xxx\n") ### # parts.append(str(action)) diff --git a/aider/website/assets/sample.aider.conf.yml b/aider/website/assets/sample.aider.conf.yml index c100ed0ed..9b9b46077 100644 --- a/aider/website/assets/sample.aider.conf.yml +++ b/aider/website/assets/sample.aider.conf.yml @@ -12,19 +12,19 @@ # options: ## show this help message and exit -#help: +#help: xxx ####### # Main: ## Specify the OpenAI API key -#openai-api-key: +#openai-api-key: xxx ## Specify the Anthropic API key -#anthropic-api-key: +#anthropic-api-key: xxx ## Specify the model to use for the main chat -#model: +#model: xxx ## Use claude-3-opus-20240229 model for the main chat #opus: false @@ -54,22 +54,22 @@ # Model Settings: ## List known models which match the (partial) MODEL name -#list-models: +#list-models: xxx ## Specify the api base url -#openai-api-base: +#openai-api-base: xxx ## Specify the api_type -#openai-api-type: +#openai-api-type: xxx ## Specify the api_version -#openai-api-version: +#openai-api-version: xxx ## Specify the deployment_id -#openai-api-deployment-id: +#openai-api-deployment-id: xxx ## Specify the OpenAI organization ID -#openai-organization-id: +#openai-organization-id: xxx ## Specify a file with aider model settings for unknown models #model-settings-file: .aider.model.settings.yml @@ -81,16 +81,16 @@ #verify-ssl: true ## Specify what edit format the LLM should use (default depends on model) -#edit-format: +#edit-format: xxx ## Specify the model to use for commit messages and chat history summarization (default depends on --model) -#weak-model: +#weak-model: xxx ## Only work with models that have meta-data available (default: True) #show-model-warnings: true ## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024) -#map-tokens: +#map-tokens: xxx ## Control how often the repo map is refreshed (default: auto) #map-refresh: auto @@ -105,7 +105,7 @@ #map-multiplier-no-files: true ## Maximum number of tokens to use for chat history. If not specified, uses the model's max_chat_history_tokens. -#max-chat-history-tokens: +#max-chat-history-tokens: xxx ## Specify the .env file to load (default: .env in git root) #env-file: .env @@ -123,7 +123,7 @@ #restore-chat-history: false ## Log the conversation with the LLM to this file (for example, .aider.llm.history) -#llm-history-file: +#llm-history-file: xxx ################## # Output Settings: @@ -144,7 +144,7 @@ #user-input-color: #00cc00 ## Set the color for tool output (default: None) -#tool-output-color: +#tool-output-color: xxx ## Set the color for tool error messages (default: #FF2222) #tool-error-color: #FF2222 @@ -198,7 +198,7 @@ #commit: false ## Specify a custom prompt for generating commit messages -#commit-prompt: +#commit-prompt: xxx ## Perform a dry run without modifying files (default: False) #dry-run: false @@ -210,13 +210,15 @@ #lint: false ## Specify lint commands to run for different languages, eg: "python: flake8 --select=..." (can be used multiple times) -#lint-cmd: +#lint-cmd: xxx +## Specify multiple values like this: +#lint-cmd: [xxx,yyyy,zzz] ## Enable/disable automatic linting after changes (default: True) #auto-lint: true ## Specify command to run tests -#test-cmd: +#test-cmd: xxx ## Enable/disable automatic testing after changes (default: False) #auto-test: false @@ -228,10 +230,14 @@ # Other Settings: ## specify a file to edit (can be used multiple times) -#file: +#file: xxx +## Specify multiple values like this: +#file: [xxx,yyyy,zzz] ## specify a read-only file (can be used multiple times) -#read: +#read: xxx +## Specify multiple values like this: +#read: [xxx,yyyy,zzz] ## Use VI editing mode in the terminal (default: False) #vim: false @@ -240,10 +246,10 @@ #voice-language: en ## Specify the language to use in the chat (default: None, uses system settings) -#chat-language: +#chat-language: xxx ## Show the version number and exit -#version: +#version: xxx ## Check for updates and return status in the exit code #just-check-update: false @@ -258,7 +264,7 @@ #upgrade: false ## Apply the changes from the given file instead of running the chat (debug) -#apply: +#apply: xxx ## Always say yes to every confirmation #yes: false @@ -276,16 +282,16 @@ #exit: false ## Specify a single message to send the LLM, process reply then exit (disables chat mode) -#message: +#message: xxx ## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode) -#message-file: +#message-file: xxx ## Specify the encoding for input and output (default: utf-8) #encoding: utf-8 ## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory) -#config: +#config: xxx ## Run aider in your browser #gui: false diff --git a/aider/website/docs/config/aider_conf.md b/aider/website/docs/config/aider_conf.md index 6a2112d59..d906e11bd 100644 --- a/aider/website/docs/config/aider_conf.md +++ b/aider/website/docs/config/aider_conf.md @@ -60,19 +60,19 @@ cog.outl("```") # options: ## show this help message and exit -#help: +#help: xxx ####### # Main: ## Specify the OpenAI API key -#openai-api-key: +#openai-api-key: xxx ## Specify the Anthropic API key -#anthropic-api-key: +#anthropic-api-key: xxx ## Specify the model to use for the main chat -#model: +#model: xxx ## Use claude-3-opus-20240229 model for the main chat #opus: false @@ -102,22 +102,22 @@ cog.outl("```") # Model Settings: ## List known models which match the (partial) MODEL name -#list-models: +#list-models: xxx ## Specify the api base url -#openai-api-base: +#openai-api-base: xxx ## Specify the api_type -#openai-api-type: +#openai-api-type: xxx ## Specify the api_version -#openai-api-version: +#openai-api-version: xxx ## Specify the deployment_id -#openai-api-deployment-id: +#openai-api-deployment-id: xxx ## Specify the OpenAI organization ID -#openai-organization-id: +#openai-organization-id: xxx ## Specify a file with aider model settings for unknown models #model-settings-file: .aider.model.settings.yml @@ -129,16 +129,16 @@ cog.outl("```") #verify-ssl: true ## Specify what edit format the LLM should use (default depends on model) -#edit-format: +#edit-format: xxx ## Specify the model to use for commit messages and chat history summarization (default depends on --model) -#weak-model: +#weak-model: xxx ## Only work with models that have meta-data available (default: True) #show-model-warnings: true ## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024) -#map-tokens: +#map-tokens: xxx ## Control how often the repo map is refreshed (default: auto) #map-refresh: auto @@ -153,7 +153,7 @@ cog.outl("```") #map-multiplier-no-files: true ## Maximum number of tokens to use for chat history. If not specified, uses the model's max_chat_history_tokens. -#max-chat-history-tokens: +#max-chat-history-tokens: xxx ## Specify the .env file to load (default: .env in git root) #env-file: .env @@ -171,7 +171,7 @@ cog.outl("```") #restore-chat-history: false ## Log the conversation with the LLM to this file (for example, .aider.llm.history) -#llm-history-file: +#llm-history-file: xxx ################## # Output Settings: @@ -192,7 +192,7 @@ cog.outl("```") #user-input-color: #00cc00 ## Set the color for tool output (default: None) -#tool-output-color: +#tool-output-color: xxx ## Set the color for tool error messages (default: #FF2222) #tool-error-color: #FF2222 @@ -246,7 +246,7 @@ cog.outl("```") #commit: false ## Specify a custom prompt for generating commit messages -#commit-prompt: +#commit-prompt: xxx ## Perform a dry run without modifying files (default: False) #dry-run: false @@ -258,13 +258,15 @@ cog.outl("```") #lint: false ## Specify lint commands to run for different languages, eg: "python: flake8 --select=..." (can be used multiple times) -#lint-cmd: +#lint-cmd: xxx +## Specify multiple values like this: +#lint-cmd: [xxx,yyyy,zzz] ## Enable/disable automatic linting after changes (default: True) #auto-lint: true ## Specify command to run tests -#test-cmd: +#test-cmd: xxx ## Enable/disable automatic testing after changes (default: False) #auto-test: false @@ -276,10 +278,14 @@ cog.outl("```") # Other Settings: ## specify a file to edit (can be used multiple times) -#file: +#file: xxx +## Specify multiple values like this: +#file: [xxx,yyyy,zzz] ## specify a read-only file (can be used multiple times) -#read: +#read: xxx +## Specify multiple values like this: +#read: [xxx,yyyy,zzz] ## Use VI editing mode in the terminal (default: False) #vim: false @@ -288,10 +294,10 @@ cog.outl("```") #voice-language: en ## Specify the language to use in the chat (default: None, uses system settings) -#chat-language: +#chat-language: xxx ## Show the version number and exit -#version: +#version: xxx ## Check for updates and return status in the exit code #just-check-update: false @@ -306,7 +312,7 @@ cog.outl("```") #upgrade: false ## Apply the changes from the given file instead of running the chat (debug) -#apply: +#apply: xxx ## Always say yes to every confirmation #yes: false @@ -324,16 +330,16 @@ cog.outl("```") #exit: false ## Specify a single message to send the LLM, process reply then exit (disables chat mode) -#message: +#message: xxx ## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode) -#message-file: +#message-file: xxx ## Specify the encoding for input and output (default: utf-8) #encoding: utf-8 ## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory) -#config: +#config: xxx ## Run aider in your browser #gui: false From 05b3b3df885b184107c5472124f39b014673bbaa Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Wed, 11 Sep 2024 14:01:15 -0700 Subject: [PATCH 105/135] fix: Remove f-string prefix from line without placeholders --- aider/args_formatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/args_formatter.py b/aider/args_formatter.py index df8bfac39..1412ea53e 100644 --- a/aider/args_formatter.py +++ b/aider/args_formatter.py @@ -146,7 +146,7 @@ class YamlHelpFormatter(argparse.HelpFormatter): parts.append(f"#{switch}: {default}\n") elif action.nargs in ("*", "+") or isinstance(action, argparse._AppendAction): parts.append(f"#{switch}: xxx") - parts.append(f"## Specify multiple values like this:") + parts.append("## Specify multiple values like this:") parts.append(f"#{switch}: [xxx,yyyy,zzz]\n") else: parts.append(f"#{switch}: xxx\n") From 36fa7733768bf66be3cdcc4fb2f8916c0660a5bc Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 11 Sep 2024 14:38:23 -0700 Subject: [PATCH 106/135] fix: Simplify get_help_md function in commands.py --- aider/commands.py | 6 +----- aider/main.py | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index e819bacc0..e6035ad10 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -1187,11 +1187,7 @@ def parse_quoted_filenames(args): def get_help_md(): - from aider.coders import Coder - from aider.models import Model - - coder = Coder(Model("gpt-3.5-turbo"), None) - md = coder.commands.get_help_md() + md = Commands(None, None).get_help_md() return md diff --git a/aider/main.py b/aider/main.py index b2d0e9d97..293b6cbff 100644 --- a/aider/main.py +++ b/aider/main.py @@ -300,6 +300,10 @@ def sanity_check_repo(repo, io): if not repo: return True + if not repo.repo.working_tree_dir: + io.tool_error("The git repo does not seem to have a working tree?") + return False + try: repo.get_tracked_files() if not repo.git_repo_error: From 94af92c784319e951af189d3efe36b55206e8a28 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 13:01:54 -0700 Subject: [PATCH 107/135] feat: Add leaderboard graph component --- aider/website/_includes/leaderboard_graph.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 aider/website/_includes/leaderboard_graph.html diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html new file mode 100644 index 000000000..e69de29bb From 13d3b7c9b35d946d9515259f7d8b5f199e979326 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 13:01:55 -0700 Subject: [PATCH 108/135] refactor: Refactor the edit leaderboard graph into a reusable component --- .../website/_includes/leaderboard_graph.html | 76 ++++++++ aider/website/docs/leaderboards/index.md | 164 ++---------------- 2 files changed, 88 insertions(+), 152 deletions(-) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index e69de29bb..07729a104 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -0,0 +1,76 @@ + + diff --git a/aider/website/docs/leaderboards/index.md b/aider/website/docs/leaderboards/index.md index 77b726560..8b5f7d2ed 100644 --- a/aider/website/docs/leaderboards/index.md +++ b/aider/website/docs/leaderboards/index.md @@ -55,83 +55,14 @@ The model also has to successfully apply all its changes to the source file with - - +{% include leaderboard_graph.html + chart_id="editChart" + data=edit_sorted + row_prefix="edit-row" + pass_rate_key="pass_rate_2" +%} From 6eb993999aee3dbdc968913bf8d692957fade742 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:07:41 -0700 Subject: [PATCH 112/135] copy --- aider/website/docs/leaderboards/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/docs/leaderboards/index.md b/aider/website/docs/leaderboards/index.md index 8b5f7d2ed..42178bb03 100644 --- a/aider/website/docs/leaderboards/index.md +++ b/aider/website/docs/leaderboards/index.md @@ -181,6 +181,6 @@ mod_dates = [get_last_modified_date(file) for file in files] latest_mod_date = max(mod_dates) cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}") ]]]--> -September 11, 2024. +September 12, 2024.

From 297b51b997f18ca25184b2bb65ea91147c168613 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:11:26 -0700 Subject: [PATCH 113/135] pct --- aider/website/_data/o1_results.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/_data/o1_results.yml b/aider/website/_data/o1_results.yml index 90eff18f2..852a7c863 100644 --- a/aider/website/_data/o1_results.yml +++ b/aider/website/_data/o1_results.yml @@ -77,7 +77,7 @@ commit_hash: 36fa773-dirty, 291b456 pass_rate_1: 49.6 pass_rate_2: 70.7 - percent_cases_well_formed: 100.0 + percent_cases_well_formed: 90.0 error_outputs: 0 num_malformed_responses: 0 num_with_malformed_responses: 0 From 71f3f3a22bc34fdd8c0eef5ef77c7bb5560ab124 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:12:48 -0700 Subject: [PATCH 114/135] copy --- aider/website/_data/edit_leaderboard.yml | 25 +++++++++++++++++++++++- aider/website/_data/o1_results.yml | 2 +- aider/website/_posts/2024-09-12-o1.md | 3 +++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index f1a84375f..d7eecdeaa 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1085,4 +1085,27 @@ date: 2024-09-11 versions: 0.56.1.dev seconds_per_case: 7.6 - total_cost: 0.0000 \ No newline at end of file + total_cost: 0.0000 + +- dirname: 2024-09-12-19-57-35--o1-mini-whole + test_cases: 133 + model: o1-mini + edit_format: whole + commit_hash: 36fa773-dirty, 291b456 + pass_rate_1: 49.6 + pass_rate_2: 70.7 + percent_cases_well_formed: 90.0 + error_outputs: 0 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 17 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 1 + command: (not currently supported) + date: 2024-09-12 + versions: 0.56.1.dev + seconds_per_case: 103.0 + total_cost: 5.3725 \ No newline at end of file diff --git a/aider/website/_data/o1_results.yml b/aider/website/_data/o1_results.yml index 852a7c863..cb3adce2a 100644 --- a/aider/website/_data/o1_results.yml +++ b/aider/website/_data/o1_results.yml @@ -87,7 +87,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 1 - command: aider --model openai/o1-mini + command: (not currently supported) date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 diff --git a/aider/website/_posts/2024-09-12-o1.md b/aider/website/_posts/2024-09-12-o1.md index 89e8d1f90..214f7137b 100644 --- a/aider/website/_posts/2024-09-12-o1.md +++ b/aider/website/_posts/2024-09-12-o1.md @@ -27,6 +27,9 @@ efficiently edit the source code. The whole format requires the o1-mini to return a fresh copy of the entire file, increasing costs and latency. +OpenAI o1-mini does not support system prompts or temperature settings, +so aider was modified to complete this benchmark. +The released aider will not yet work with o1-mini. {: .note } > These are *preliminiary* benchmark results, which will be updated as From 8aee4d25ed6de2fb6c624edaf8f5c9674e511532 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:19:53 -0700 Subject: [PATCH 115/135] add ModelSettings.use_system_prompt --- aider/coders/base_coder.py | 14 ++++++++++---- aider/models.py | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 823b418a0..b380f08c4 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -966,10 +966,16 @@ class Coder: chunks = ChatChunks() - chunks.system = [ - dict(role="user", content=main_sys), - dict(role="assistant", content="Ok."), - ] + if self.main_model.use_system_prompt: + chunks.system = [ + dict(role="system", content=main_sys), + ] + else: + chunks.system = [ + dict(role="user", content=main_sys), + dict(role="assistant", content="Ok."), + ] + chunks.examples = example_messages self.summarize_end() diff --git a/aider/models.py b/aider/models.py index d513e9ecf..08faf966b 100644 --- a/aider/models.py +++ b/aider/models.py @@ -77,6 +77,7 @@ class ModelSettings: max_tokens: Optional[int] = None cache_control: bool = False caches_by_default: bool = False + use_system_prompt: bool = True # https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo @@ -425,6 +426,22 @@ MODEL_SETTINGS = [ lazy=True, reminder="sys", ), + ModelSettings( + "openai/o1-mini", + "whole", + weak_model_name="openai/gpt-4o-mini", + use_repo_map=True, + reminder="user", + use_system_prompt=False, + ), + ModelSettings( + "o1-mini", + "whole", + weak_model_name="gpt-4o-mini", + use_repo_map=True, + reminder="user", + use_system_prompt=False, + ), ] From 1755d2e0f45067e9df7f3e9a10b1920184c61c88 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:24:21 -0700 Subject: [PATCH 116/135] fix: Use temperature setting from model configuration --- aider/coders/base_coder.py | 7 ++++++- aider/models.py | 3 +++ aider/sendchat.py | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index b380f08c4..18eec044d 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -1381,6 +1381,11 @@ class Coder: self.io.log_llm_history("TO LLM", format_messages(messages)) + if self.main_model.use_temperature: + temp = self.temperature + else: + temp = None + completion = None try: hash_object, completion = send_completion( @@ -1388,7 +1393,7 @@ class Coder: messages, functions, self.stream, - self.temperature, + temp, extra_headers=model.extra_headers, max_tokens=model.max_tokens, ) diff --git a/aider/models.py b/aider/models.py index 08faf966b..6a23dac59 100644 --- a/aider/models.py +++ b/aider/models.py @@ -78,6 +78,7 @@ class ModelSettings: cache_control: bool = False caches_by_default: bool = False use_system_prompt: bool = True + use_temperature: bool = True # https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo @@ -433,6 +434,7 @@ MODEL_SETTINGS = [ use_repo_map=True, reminder="user", use_system_prompt=False, + use_temperature=False, ), ModelSettings( "o1-mini", @@ -441,6 +443,7 @@ MODEL_SETTINGS = [ use_repo_map=True, reminder="user", use_system_prompt=False, + use_temperature=False, ), ] diff --git a/aider/sendchat.py b/aider/sendchat.py index af3d126e0..55c64b2fe 100644 --- a/aider/sendchat.py +++ b/aider/sendchat.py @@ -60,9 +60,10 @@ def send_completion( kwargs = dict( model=model_name, messages=messages, - # temperature=temperature, stream=stream, ) + if temperature is not None: + kwargs["temperature"] = temperature if functions is not None: function = functions[0] From 09cb4c4b09efc2f2c2c3f8d4ffe6dc592ce1c95b Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:27:35 -0700 Subject: [PATCH 117/135] copy --- aider/website/_data/edit_leaderboard.yml | 2 +- aider/website/_data/o1_results.yml | 2 +- aider/website/_posts/2024-09-12-o1.md | 14 +++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index d7eecdeaa..99de22395 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1104,7 +1104,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 1 - command: (not currently supported) + command: aider --model openai/o1-mini --no-stream date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 diff --git a/aider/website/_data/o1_results.yml b/aider/website/_data/o1_results.yml index cb3adce2a..86b7c0818 100644 --- a/aider/website/_data/o1_results.yml +++ b/aider/website/_data/o1_results.yml @@ -87,7 +87,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 1 - command: (not currently supported) + command: aider --model openai/o1-mini --no-stream date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 diff --git a/aider/website/_posts/2024-09-12-o1.md b/aider/website/_posts/2024-09-12-o1.md index 214f7137b..45a9f037c 100644 --- a/aider/website/_posts/2024-09-12-o1.md +++ b/aider/website/_posts/2024-09-12-o1.md @@ -27,9 +27,17 @@ efficiently edit the source code. The whole format requires the o1-mini to return a fresh copy of the entire file, increasing costs and latency. -OpenAI o1-mini does not support system prompts or temperature settings, -so aider was modified to complete this benchmark. -The released aider will not yet work with o1-mini. +OpenAI o1-mini does not support system prompts, temperature settings or streaming. +Aider has been updated to work within these constraints. +To use o1-mini with aider you need to run the latest version from the main branch: + +``` +aider --install-main-branch +# or... +python -m pip install --upgrade git+https://github.com/paul-gauthier/aider.git + +aider --model openai/o1-mini --no-stream +``` {: .note } > These are *preliminiary* benchmark results, which will be updated as From fb420de09e0f53f203f7d0b2c683fa440d2dcac3 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:42:52 -0700 Subject: [PATCH 118/135] feat: Add new model settings for openai/o1-preview and o1-preview --- aider/models.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/aider/models.py b/aider/models.py index 6a23dac59..c893a0c02 100644 --- a/aider/models.py +++ b/aider/models.py @@ -445,6 +445,24 @@ MODEL_SETTINGS = [ use_system_prompt=False, use_temperature=False, ), + ModelSettings( + "openai/o1-preview", + "whole", + weak_model_name="openai/gpt-4o-mini", + use_repo_map=True, + reminder="user", + use_system_prompt=False, + use_temperature=False, + ), + ModelSettings( + "o1-preview", + "whole", + weak_model_name="gpt-4o-mini", + use_repo_map=True, + reminder="user", + use_system_prompt=False, + use_temperature=False, + ), ] From efa0c0e2921dbd21a118146e821a5a66003a9397 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 14:46:32 -0700 Subject: [PATCH 119/135] fix: Disable streaming if main model does not support it --- aider/main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/aider/main.py b/aider/main.py index 293b6cbff..d8a90dfe8 100644 --- a/aider/main.py +++ b/aider/main.py @@ -577,6 +577,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F args.map_refresh = "files" try: + if not main_model.streaming: + if args.stream: + io.tool_warning("Warning: Streaming is not supported by the selected model. Disabling streaming.") + args.stream = False + coder = Coder.create( main_model=main_model, edit_format=args.edit_format, From 94a2bc5ef52097d3b96922d6566d09240117d8a4 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 14:46:36 -0700 Subject: [PATCH 120/135] style: Improve formatting of warning message --- aider/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aider/main.py b/aider/main.py index d8a90dfe8..86ad15fed 100644 --- a/aider/main.py +++ b/aider/main.py @@ -579,7 +579,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F try: if not main_model.streaming: if args.stream: - io.tool_warning("Warning: Streaming is not supported by the selected model. Disabling streaming.") + io.tool_warning( + "Warning: Streaming is not supported by the selected model. Disabling" + " streaming." + ) args.stream = False coder = Coder.create( From 99a75ac21383732f241fc12068c2a197ecce6a11 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:47:18 -0700 Subject: [PATCH 121/135] feat: Add streaming option to ModelSettings --- aider/models.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/aider/models.py b/aider/models.py index c893a0c02..31dffcc7a 100644 --- a/aider/models.py +++ b/aider/models.py @@ -79,6 +79,7 @@ class ModelSettings: caches_by_default: bool = False use_system_prompt: bool = True use_temperature: bool = True + streaming: bool = True # https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo @@ -435,6 +436,7 @@ MODEL_SETTINGS = [ reminder="user", use_system_prompt=False, use_temperature=False, + streaming=False, ), ModelSettings( "o1-mini", @@ -444,6 +446,7 @@ MODEL_SETTINGS = [ reminder="user", use_system_prompt=False, use_temperature=False, + streaming=False, ), ModelSettings( "openai/o1-preview", @@ -453,6 +456,7 @@ MODEL_SETTINGS = [ reminder="user", use_system_prompt=False, use_temperature=False, + streaming=False, ), ModelSettings( "o1-preview", @@ -462,6 +466,7 @@ MODEL_SETTINGS = [ reminder="user", use_system_prompt=False, use_temperature=False, + streaming=False, ), ] From 859fc1f18454d37f7cf1227f584719dbb47e93b0 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 14:49:21 -0700 Subject: [PATCH 122/135] fix: Adjust streaming settings before creating Coder object --- aider/main.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/aider/main.py b/aider/main.py index 86ad15fed..1ef078eb0 100644 --- a/aider/main.py +++ b/aider/main.py @@ -576,15 +576,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.cache_prompts and args.map_refresh == "auto": args.map_refresh = "files" - try: - if not main_model.streaming: - if args.stream: - io.tool_warning( - "Warning: Streaming is not supported by the selected model. Disabling" - " streaming." - ) - args.stream = False + if not main_model.streaming: + if args.stream: + io.tool_warning( + "Warning: Streaming is not supported by the selected model. Disabling streaming." + ) + args.stream = False + try: coder = Coder.create( main_model=main_model, edit_format=args.edit_format, From 9f4d9d801e143bb99e1d769c5297d6f356e94feb Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 14:52:27 -0700 Subject: [PATCH 123/135] copy --- aider/website/_data/edit_leaderboard.yml | 2 +- aider/website/_data/o1_results.yml | 2 +- aider/website/_posts/2024-09-12-o1.md | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 99de22395..8ed43927d 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1104,7 +1104,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 1 - command: aider --model openai/o1-mini --no-stream + command: aider --model o1-mini date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 diff --git a/aider/website/_data/o1_results.yml b/aider/website/_data/o1_results.yml index 86b7c0818..728d6965e 100644 --- a/aider/website/_data/o1_results.yml +++ b/aider/website/_data/o1_results.yml @@ -87,7 +87,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 1 - command: aider --model openai/o1-mini --no-stream + command: aider --model o1-mini date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 diff --git a/aider/website/_posts/2024-09-12-o1.md b/aider/website/_posts/2024-09-12-o1.md index 45a9f037c..4e0780184 100644 --- a/aider/website/_posts/2024-09-12-o1.md +++ b/aider/website/_posts/2024-09-12-o1.md @@ -27,16 +27,19 @@ efficiently edit the source code. The whole format requires the o1-mini to return a fresh copy of the entire file, increasing costs and latency. -OpenAI o1-mini does not support system prompts, temperature settings or streaming. -Aider has been updated to work within these constraints. -To use o1-mini with aider you need to run the latest version from the main branch: + +## Using aider with o1-mini and o1-preview + +OpenAI's new o1 models are supported in the development version of aider: ``` aider --install-main-branch # or... python -m pip install --upgrade git+https://github.com/paul-gauthier/aider.git -aider --model openai/o1-mini --no-stream +aider --model o1-mini + +aider --model o1-preview ``` {: .note } From 4598a376fdc866d8f98f20fa5711d8718a8b1c0b Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 15:01:27 -0700 Subject: [PATCH 124/135] copy --- HISTORY.md | 13 +++++++++++++ aider/website/HISTORY.md | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 385813cfb..1d15781d3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,19 @@ # Release history +### main branch + +- Support for OpenAI o1 models: + - `aider --model o1-mini` + - `aider --model o1-preview` +- On Windows, `/run` correctly uses PowerShell or cmd.exe. +- Support for new 08-2024 Cohere models. +- Can now recursively add directories with `/read-only`. +- User input prompts now fall back to simple `input()` if `--no-pretty` or a Windows console is not available. +- Improved sanity check of git repo on startup. +- Improvements to prompt cache chunking strategy. +- Bugfix to remove spurious "No changes made to git tracked files." + ### Aider v0.56.0 - Enables prompt caching for Sonnet via OpenRouter by @fry69 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 149a9b86c..b60e044e2 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -16,6 +16,19 @@ cog.out(text) # Release history +### main branch + +- Support for OpenAI o1 models: + - `aider --model o1-mini` + - `aider --model o1-preview` +- On Windows, `/run` correctly uses PowerShell or cmd.exe. +- Support for new 08-2024 Cohere models. +- Can now recursively add directories with `/read-only`. +- User input prompts now fall back to simple `input()` if `--no-pretty` or a Windows console is not available. +- Improved sanity check of git repo on startup. +- Improvements to prompt cache chunking strategy. +- Bugfix to remove spurious "No changes made to git tracked files." + ### Aider v0.56.0 - Enables prompt caching for Sonnet via OpenRouter by @fry69 From 2605d44db63c5b7bc3ba9e0a39676103ca02db3a Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 15:10:32 -0700 Subject: [PATCH 125/135] feat: Add different colors for 'whole' and 'diff' edit formats in leaderboard graph --- aider/website/_includes/leaderboard_graph.html | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index a6137b5ef..9e202a093 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -7,8 +7,8 @@ datasets: [{ label: 'Percent completed correctly', data: [], - backgroundColor: 'rgba(54, 162, 235, 0.2)', - borderColor: 'rgba(54, 162, 235, 1)', + backgroundColor: [], + borderColor: [], borderWidth: 1 }] }; @@ -18,7 +18,8 @@ allData.push({ model: '{{ row.model }}', pass_rate: {{ row[include.pass_rate_key] }}, - percent_cases_well_formed: {{ row.percent_cases_well_formed }} + percent_cases_well_formed: {{ row.percent_cases_well_formed }}, + edit_format: '{{ row.edit_format }}' }); {% endfor %} @@ -28,6 +29,8 @@ leaderboardData.labels = []; leaderboardData.datasets[0].data = []; + leaderboardData.datasets[0].backgroundColor = []; + leaderboardData.datasets[0].borderColor = []; allData.forEach(function(row, index) { var rowElement = document.getElementById('{{ include.row_prefix }}-' + index); @@ -37,6 +40,14 @@ if (showAll || rowElement.classList.contains('selected')) { leaderboardData.labels.push(row.model); leaderboardData.datasets[0].data.push(row.pass_rate); + + if (row.edit_format === 'whole') { + leaderboardData.datasets[0].backgroundColor.push('rgba(255, 99, 132, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(255, 99, 132, 1)'); + } else { + leaderboardData.datasets[0].backgroundColor.push('rgba(54, 162, 235, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(54, 162, 235, 1)'); + } } }); From 71c5fd13727ab8ccc5a4f46c75fee9aee8deb58b Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 15:12:10 -0700 Subject: [PATCH 126/135] feat: Add legend to leaderboard chart --- .../website/_includes/leaderboard_graph.html | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index 9e202a093..94af31fdc 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -51,6 +51,17 @@ } }); + // Apply legend filtering + var meta = leaderboardChart.getDatasetMeta(0); + meta.data.forEach(function(bar, index) { + if (leaderboardData.labels.includes(allData[index].model)) { + bar.hidden = (allData[index].edit_format === 'whole' && meta.data[0].hidden) || + (allData[index].edit_format !== 'whole' && meta.data[1].hidden); + } else { + bar.hidden = true; + } + }); + leaderboardChart.update(); } @@ -73,6 +84,46 @@ y: { beginAtZero: true } + }, + plugins: { + legend: { + display: true, + position: 'top', + labels: { + generateLabels: function(chart) { + return [ + { + text: 'whole', + fillStyle: 'rgba(255, 99, 132, 0.2)', + strokeStyle: 'rgba(255, 99, 132, 1)', + lineWidth: 1, + hidden: false + }, + { + text: 'diff/udiff/diff-fenced', + fillStyle: 'rgba(54, 162, 235, 0.2)', + strokeStyle: 'rgba(54, 162, 235, 1)', + lineWidth: 1, + hidden: false + } + ]; + } + }, + onClick: function(e, legendItem, legend) { + var index = legendItem.index; + var ci = legend.chart; + var alreadyHidden = (ci.getDatasetMeta(0).data[0].hidden === true); + + ci.data.datasets[0].data.forEach(function(dataPoint, i) { + var meta = ci.getDatasetMeta(0); + var shouldBeHidden = (index === 0 && allData[i].edit_format !== 'whole') || + (index === 1 && allData[i].edit_format === 'whole'); + meta.data[i].hidden = shouldBeHidden; + }); + + ci.update(); + } + } } } }); From 84b1c1031ad7bcb7908b5566bcbafa334dc31ed5 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 15:13:22 -0700 Subject: [PATCH 127/135] feat: add label to y-axis of leaderboard graph --- aider/website/_includes/leaderboard_graph.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index 94af31fdc..a7b0640cd 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -82,7 +82,11 @@ options: { scales: { y: { - beginAtZero: true + beginAtZero: true, + title: { + display: true, + text: 'Correct Exercises (%)' + } } }, plugins: { From 291d3509ebadfe03928b3671daba38e33a211735 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 15:17:32 -0700 Subject: [PATCH 128/135] copy --- aider/website/_data/o1_results.yml | 8 ++++---- aider/website/_posts/2024-09-12-o1.md | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/aider/website/_data/o1_results.yml b/aider/website/_data/o1_results.yml index 728d6965e..96d2ac1d6 100644 --- a/aider/website/_data/o1_results.yml +++ b/aider/website/_data/o1_results.yml @@ -1,6 +1,6 @@ - dirname: 2024-07-18-18-57-46--gpt-4o-mini-whole test_cases: 133 - model: gpt-4o-mini + model: gpt-4o-mini (whole) edit_format: whole commit_hash: d31eef3-dirty pass_rate_1: 40.6 @@ -24,7 +24,7 @@ - dirname: 2024-07-04-14-32-08--claude-3.5-sonnet-diff-continue test_cases: 133 - model: claude-3.5-sonnet + model: claude-3.5-sonnet (diff) edit_format: diff commit_hash: 35f21b5 pass_rate_1: 57.1 @@ -48,7 +48,7 @@ - dirname: 2024-08-06-18-28-39--gpt-4o-2024-08-06-diff-again test_cases: 133 - model: gpt-4o-2024-08-06 + model: gpt-4o-2024-08-06 (diff) edit_format: diff commit_hash: ed9ed89 pass_rate_1: 57.1 @@ -72,7 +72,7 @@ - dirname: 2024-09-12-19-57-35--o1-mini-whole test_cases: 133 - model: o1-mini + model: o1-mini (whole) edit_format: whole commit_hash: 36fa773-dirty, 291b456 pass_rate_1: 49.6 diff --git a/aider/website/_posts/2024-09-12-o1.md b/aider/website/_posts/2024-09-12-o1.md index 4e0780184..e9d087a91 100644 --- a/aider/website/_posts/2024-09-12-o1.md +++ b/aider/website/_posts/2024-09-12-o1.md @@ -9,9 +9,9 @@ nav_exclude: true # Benchmark results for OpenAI o1-mini -OpenAI o1-mini is priced similarly to GPT-4o and Claude 3.5 Sonnet. -o1-mini scored below those models -when using the simple "whole" editing format. +OpenAI o1-mini is priced similarly to GPT-4o and Claude 3.5 Sonnet, +but scored below those models +when using the "whole" editing format. It was close enough to GPT-4o to be within the margin of error. The o1-mini model had trouble following the very simple whole editing format. @@ -21,8 +21,8 @@ the response format. Note that o1-mini's "whole" score is compared against GPT-4o and Sonnet "diff" results. -Using diff is more challenging for GPT-4o and Sonnet, -but it allows them to return search/replace blocks to +Using diff is more challenging, +but allows the model to return search/replace blocks to efficiently edit the source code. The whole format requires the o1-mini to return a fresh copy of the entire file, increasing costs and latency. From b4dad65e9f94b4795a3d39ffbd095e465270ee31 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 15:18:57 -0700 Subject: [PATCH 129/135] feat: Add configuration to display all x-axis labels --- aider/website/_includes/leaderboard_graph.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index a7b0640cd..4596dc1df 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -87,6 +87,13 @@ display: true, text: 'Correct Exercises (%)' } + }, + x: { + ticks: { + autoSkip: false, + maxRotation: 90, + minRotation: 90 + } } }, plugins: { From af407c4c8fb0290ca80e4e1ccdcf7c30fde90446 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 15:20:23 -0700 Subject: [PATCH 130/135] copy --- aider/website/_includes/leaderboard_graph.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index 4596dc1df..d38527d42 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -92,7 +92,7 @@ ticks: { autoSkip: false, maxRotation: 90, - minRotation: 90 + minRotation: 0 } } }, From 45474a230e998958613f13e4ada3826ebad3c890 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 15:22:28 -0700 Subject: [PATCH 131/135] feat: Add distinct colors for edit formats in leaderboard chart --- .../website/_includes/leaderboard_graph.html | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index d38527d42..9b5796085 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -41,12 +41,26 @@ leaderboardData.labels.push(row.model); leaderboardData.datasets[0].data.push(row.pass_rate); - if (row.edit_format === 'whole') { - leaderboardData.datasets[0].backgroundColor.push('rgba(255, 99, 132, 0.2)'); - leaderboardData.datasets[0].borderColor.push('rgba(255, 99, 132, 1)'); - } else { - leaderboardData.datasets[0].backgroundColor.push('rgba(54, 162, 235, 0.2)'); - leaderboardData.datasets[0].borderColor.push('rgba(54, 162, 235, 1)'); + switch (row.edit_format) { + case 'whole': + leaderboardData.datasets[0].backgroundColor.push('rgba(255, 99, 132, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(255, 99, 132, 1)'); + break; + case 'diff': + leaderboardData.datasets[0].backgroundColor.push('rgba(54, 162, 235, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(54, 162, 235, 1)'); + break; + case 'udiff': + leaderboardData.datasets[0].backgroundColor.push('rgba(75, 192, 192, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(75, 192, 192, 1)'); + break; + case 'diff-fenced': + leaderboardData.datasets[0].backgroundColor.push('rgba(153, 102, 255, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(153, 102, 255, 1)'); + break; + default: + leaderboardData.datasets[0].backgroundColor.push('rgba(201, 203, 207, 0.2)'); + leaderboardData.datasets[0].borderColor.push('rgba(201, 203, 207, 1)'); } } }); @@ -111,11 +125,25 @@ hidden: false }, { - text: 'diff/udiff/diff-fenced', + text: 'diff', fillStyle: 'rgba(54, 162, 235, 0.2)', strokeStyle: 'rgba(54, 162, 235, 1)', lineWidth: 1, hidden: false + }, + { + text: 'udiff', + fillStyle: 'rgba(75, 192, 192, 0.2)', + strokeStyle: 'rgba(75, 192, 192, 1)', + lineWidth: 1, + hidden: false + }, + { + text: 'diff-fenced', + fillStyle: 'rgba(153, 102, 255, 0.2)', + strokeStyle: 'rgba(153, 102, 255, 1)', + lineWidth: 1, + hidden: false } ]; } @@ -123,13 +151,11 @@ onClick: function(e, legendItem, legend) { var index = legendItem.index; var ci = legend.chart; - var alreadyHidden = (ci.getDatasetMeta(0).data[0].hidden === true); + var clickedFormat = legendItem.text; ci.data.datasets[0].data.forEach(function(dataPoint, i) { var meta = ci.getDatasetMeta(0); - var shouldBeHidden = (index === 0 && allData[i].edit_format !== 'whole') || - (index === 1 && allData[i].edit_format === 'whole'); - meta.data[i].hidden = shouldBeHidden; + meta.data[i].hidden = allData[i].edit_format !== clickedFormat; }); ci.update(); From 752e823da806d22cbb054ad0ca5097d2bf70996d Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 12 Sep 2024 15:23:33 -0700 Subject: [PATCH 132/135] feat: Dynamically generate legend labels based on unique edit formats --- .../website/_includes/leaderboard_graph.html | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/aider/website/_includes/leaderboard_graph.html b/aider/website/_includes/leaderboard_graph.html index 9b5796085..a862103c7 100644 --- a/aider/website/_includes/leaderboard_graph.html +++ b/aider/website/_includes/leaderboard_graph.html @@ -116,46 +116,46 @@ position: 'top', labels: { generateLabels: function(chart) { - return [ - { - text: 'whole', - fillStyle: 'rgba(255, 99, 132, 0.2)', - strokeStyle: 'rgba(255, 99, 132, 1)', - lineWidth: 1, - hidden: false - }, - { - text: 'diff', - fillStyle: 'rgba(54, 162, 235, 0.2)', - strokeStyle: 'rgba(54, 162, 235, 1)', - lineWidth: 1, - hidden: false - }, - { - text: 'udiff', - fillStyle: 'rgba(75, 192, 192, 0.2)', - strokeStyle: 'rgba(75, 192, 192, 1)', - lineWidth: 1, - hidden: false - }, - { - text: 'diff-fenced', - fillStyle: 'rgba(153, 102, 255, 0.2)', - strokeStyle: 'rgba(153, 102, 255, 1)', - lineWidth: 1, - hidden: false + var uniqueFormats = [...new Set(allData.map(item => item.edit_format))]; + return uniqueFormats.map(format => { + var color; + switch (format) { + case 'whole': + color = { fill: 'rgba(255, 99, 132, 0.2)', stroke: 'rgba(255, 99, 132, 1)' }; + break; + case 'diff': + color = { fill: 'rgba(54, 162, 235, 0.2)', stroke: 'rgba(54, 162, 235, 1)' }; + break; + case 'udiff': + color = { fill: 'rgba(75, 192, 192, 0.2)', stroke: 'rgba(75, 192, 192, 1)' }; + break; + case 'diff-fenced': + color = { fill: 'rgba(153, 102, 255, 0.2)', stroke: 'rgba(153, 102, 255, 1)' }; + break; + default: + color = { fill: 'rgba(201, 203, 207, 0.2)', stroke: 'rgba(201, 203, 207, 1)' }; } - ]; + return { + text: format, + fillStyle: color.fill, + strokeStyle: color.stroke, + lineWidth: 1, + hidden: false + }; + }); } }, onClick: function(e, legendItem, legend) { - var index = legendItem.index; var ci = legend.chart; var clickedFormat = legendItem.text; + legendItem.hidden = !legendItem.hidden; + ci.data.datasets[0].data.forEach(function(dataPoint, i) { var meta = ci.getDatasetMeta(0); - meta.data[i].hidden = allData[i].edit_format !== clickedFormat; + if (allData[i].edit_format === clickedFormat) { + meta.data[i].hidden = legendItem.hidden; + } }); ci.update(); From 1fbb5079d54adcf0a919a58d2d6a5a5eab950ce5 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 15:38:28 -0700 Subject: [PATCH 133/135] unhack o1 mini --- benchmark/benchmark.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/benchmark/benchmark.py b/benchmark/benchmark.py index 2b459a1f7..3d559b9be 100755 --- a/benchmark/benchmark.py +++ b/benchmark/benchmark.py @@ -549,8 +549,7 @@ def run_test_real( chat_history_file=history_fname, ) - weak_model = "gpt-4o-mini" - main_model = models.Model(model_name, weak_model) + main_model = models.Model(model_name) edit_format = edit_format or main_model.edit_format dump(main_model) From c00ac809099424b3cf10bef89b70aaa44fad736e Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 15:38:40 -0700 Subject: [PATCH 134/135] o1-mini diff results --- aider/website/_data/edit_leaderboard.yml | 28 +++++++++++++++++++-- aider/website/_data/o1_results.yml | 26 +++++++++++++++++++- aider/website/_posts/2024-09-12-o1.md | 31 +++++++++++++----------- 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 8ed43927d..95d07f2b0 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1089,7 +1089,7 @@ - dirname: 2024-09-12-19-57-35--o1-mini-whole test_cases: 133 - model: o1-mini + model: o1-mini (whole) edit_format: whole commit_hash: 36fa773-dirty, 291b456 pass_rate_1: 49.6 @@ -1108,4 +1108,28 @@ date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 - total_cost: 5.3725 \ No newline at end of file + total_cost: 5.3725 + +- dirname: 2024-09-12-20-56-22--o1-mini-diff + test_cases: 133 + model: o1-mini (diff) + edit_format: diff + commit_hash: 4598a37-dirty, 291b456, 752e823-dirty + pass_rate_1: 45.1 + pass_rate_2: 62.4 + percent_cases_well_formed: 85.7 + error_outputs: 26 + num_malformed_responses: 26 + num_with_malformed_responses: 19 + user_asks: 2 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 1 + command: aider --model o1-mini --edit-format diff + date: 2024-09-12 + versions: 0.56.1.dev + seconds_per_case: 177.7 + total_cost: 11.1071 + \ No newline at end of file diff --git a/aider/website/_data/o1_results.yml b/aider/website/_data/o1_results.yml index 96d2ac1d6..292e258a2 100644 --- a/aider/website/_data/o1_results.yml +++ b/aider/website/_data/o1_results.yml @@ -91,4 +91,28 @@ date: 2024-09-12 versions: 0.56.1.dev seconds_per_case: 103.0 - total_cost: 5.3725 \ No newline at end of file + total_cost: 5.3725 + +- dirname: 2024-09-12-20-56-22--o1-mini-diff + test_cases: 133 + model: o1-mini (diff) + edit_format: diff + commit_hash: 4598a37-dirty, 291b456, 752e823-dirty + pass_rate_1: 45.1 + pass_rate_2: 62.4 + percent_cases_well_formed: 85.7 + error_outputs: 26 + num_malformed_responses: 26 + num_with_malformed_responses: 19 + user_asks: 2 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 1 + command: aider --model o1-mini --edit-format diff + date: 2024-09-12 + versions: 0.56.1.dev + seconds_per_case: 177.7 + total_cost: 11.1071 + \ No newline at end of file diff --git a/aider/website/_posts/2024-09-12-o1.md b/aider/website/_posts/2024-09-12-o1.md index e9d087a91..96b58c097 100644 --- a/aider/website/_posts/2024-09-12-o1.md +++ b/aider/website/_posts/2024-09-12-o1.md @@ -10,23 +10,26 @@ nav_exclude: true # Benchmark results for OpenAI o1-mini OpenAI o1-mini is priced similarly to GPT-4o and Claude 3.5 Sonnet, -but scored below those models -when using the "whole" editing format. -It was close enough to GPT-4o to be within the margin of error. +but scored below those models. -The o1-mini model had trouble following the very simple whole editing format. -It's possible that it would get a better score if aider prompted with -more examples or was adapted to parse o1-mini's favorite way to mangle -the response format. +It works best with the +["whole" edit format](/docs/leaderboards/#notes-on-the-edit-format), +where it returns a full copy of the source code file with changes. +Other frontier models like GPT-4o and Sonnet are able to achieve +high benchmark scores using the +["diff" edit format](/docs/leaderboards/#notes-on-the-edit-format), +This allows them to return search/replace blocks to +efficiently edit the source code, saving time and token costs. -Note that o1-mini's "whole" score is compared against GPT-4o and Sonnet -"diff" results. -Using diff is more challenging, -but allows the model to return search/replace blocks to -efficiently edit the source code. -The whole format requires the o1-mini to return a fresh copy of the entire file, -increasing costs and latency. +The o1-mini model had trouble conforming to both the whole and diff edit formats. +Aider is extremely permissive and tries hard to accept anything close +to the correct formats. +It's possible that o1-mini would get better scores if aider prompted with +more examples or was adapted to parse o1-mini's favorite ways to mangle +the response formats. +Over time it may be possible to better harness o1-mini's capabilities through +different prompting and editing formats. ## Using aider with o1-mini and o1-preview From 72f52bdef0c4b1f50e52bbae80d3913d36af31c0 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 12 Sep 2024 15:41:02 -0700 Subject: [PATCH 135/135] copy --- aider/website/_posts/2024-09-12-o1.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/aider/website/_posts/2024-09-12-o1.md b/aider/website/_posts/2024-09-12-o1.md index 96b58c097..0b06fdee3 100644 --- a/aider/website/_posts/2024-09-12-o1.md +++ b/aider/website/_posts/2024-09-12-o1.md @@ -9,6 +9,17 @@ nav_exclude: true # Benchmark results for OpenAI o1-mini + + +{% assign edit_sorted = site.data.o1_results | sort: 'pass_rate_2' | reverse %} +{% include leaderboard_graph.html + chart_id="editChart" + data=edit_sorted + row_prefix="edit-row" + pass_rate_key="pass_rate_2" +%} + + OpenAI o1-mini is priced similarly to GPT-4o and Claude 3.5 Sonnet, but scored below those models. @@ -24,10 +35,10 @@ efficiently edit the source code, saving time and token costs. The o1-mini model had trouble conforming to both the whole and diff edit formats. Aider is extremely permissive and tries hard to accept anything close to the correct formats. + It's possible that o1-mini would get better scores if aider prompted with more examples or was adapted to parse o1-mini's favorite ways to mangle the response formats. - Over time it may be possible to better harness o1-mini's capabilities through different prompting and editing formats. @@ -49,6 +60,7 @@ aider --model o1-preview > These are *preliminiary* benchmark results, which will be updated as > additional benchmark runs complete and rate limits open up. + @@ -60,7 +72,6 @@ aider --model o1-preview - {% assign edit_sorted = site.data.o1_results | sort: 'pass_rate_2' | reverse %} {% for row in edit_sorted %} @@ -73,14 +84,6 @@ aider --model o1-preview
{{ row.model }}
- - -{% include leaderboard_graph.html - chart_id="editChart" - data=edit_sorted - row_prefix="edit-row" - pass_rate_key="pass_rate_2" -%}