mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-27 15:55:00 +00:00
Merge branch 'main' into polyglot-qwen2.5-coder-32b-instruct-whole-results
This commit is contained in:
commit
42f6c20ada
33 changed files with 1349 additions and 1103 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -15,3 +15,4 @@ aider/_version.py
|
||||||
.venv/
|
.venv/
|
||||||
.#*
|
.#*
|
||||||
.gitattributes
|
.gitattributes
|
||||||
|
tmp.benchmarks/
|
12
HISTORY.md
12
HISTORY.md
|
@ -1,10 +1,18 @@
|
||||||
# Release history
|
# Release history
|
||||||
|
|
||||||
### main branch
|
### Aider v0.70.0
|
||||||
|
|
||||||
- Full support for o1 models.
|
- Full support for o1 models.
|
||||||
|
- Watch files now honors `--subtree-only`, and only watches that subtree.
|
||||||
|
- Improved prompting for watch files, to work more reliably with more models.
|
||||||
|
- New install methods via uv, including one-liners.
|
||||||
|
- Support for openrouter/deepseek/deepseek-chat model.
|
||||||
|
- Better error handling when interactive commands are attempted via `/load` or `--load`.
|
||||||
|
- Display read-only files with abs path if its shorter than rel path.
|
||||||
- Ask 10% of users to opt-in to analytics.
|
- Ask 10% of users to opt-in to analytics.
|
||||||
- Aider wrote 75% of the code in this release.
|
- Bugfix for auto-suggest.
|
||||||
|
- Gracefully handle unicode errors in git path names.
|
||||||
|
- Aider wrote 74% of the code in this release.
|
||||||
|
|
||||||
### Aider v0.69.1
|
### Aider v0.69.1
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
|
|
||||||
Aider lets you pair program with LLMs,
|
Aider lets you pair program with LLMs,
|
||||||
to edit code in your local git repository.
|
to edit code in your local git repository.
|
||||||
Start a new project or work with an existing git repo.
|
Start a new project or work with an existing code base.
|
||||||
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
|
||||||
[connect to almost any LLM](https://aider.chat/docs/llms.html).
|
|
||||||
|
|
||||||
<!-- SCREENCAST START -->
|
<!-- SCREENCAST START -->
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -78,7 +77,6 @@ for more details.
|
||||||
- Aider will edit your files to complete your request.
|
- Aider will edit your files to complete your request.
|
||||||
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
|
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
|
||||||
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
|
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
|
||||||
- Aider works best with GPT-4o & Claude 3.5 Sonnet and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
|
||||||
- Aider can edit multiple files at once for complex requests.
|
- Aider can edit multiple files at once for complex requests.
|
||||||
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
|
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
|
||||||
- Edit files in your editor while chatting with aider,
|
- Edit files in your editor while chatting with aider,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
__version__ = "0.69.2.dev"
|
__version__ = "0.70.1.dev"
|
||||||
safe_version = __version__
|
safe_version = __version__
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -106,7 +106,7 @@ def get_parser(default_config_files, git_root):
|
||||||
const=gpt_3_model_name,
|
const=gpt_3_model_name,
|
||||||
help=f"Use {gpt_3_model_name} model for the main chat",
|
help=f"Use {gpt_3_model_name} model for the main chat",
|
||||||
)
|
)
|
||||||
deepseek_model = "deepseek/deepseek-coder"
|
deepseek_model = "deepseek/deepseek-chat"
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--deepseek",
|
"--deepseek",
|
||||||
action="store_const",
|
action="store_const",
|
||||||
|
|
|
@ -52,6 +52,8 @@ class Commands:
|
||||||
io,
|
io,
|
||||||
coder,
|
coder,
|
||||||
voice_language=None,
|
voice_language=None,
|
||||||
|
voice_input_device=None,
|
||||||
|
voice_format=None,
|
||||||
verify_ssl=True,
|
verify_ssl=True,
|
||||||
args=None,
|
args=None,
|
||||||
parser=None,
|
parser=None,
|
||||||
|
@ -1009,7 +1011,7 @@ class Commands:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.coder.event("interactive help")
|
self.coder.event("interactive help")
|
||||||
from aider.coders import Coder
|
from aider.coders.base_coder import Coder
|
||||||
|
|
||||||
if not self.help:
|
if not self.help:
|
||||||
res = install_help_extra(self.io)
|
res = install_help_extra(self.io)
|
||||||
|
@ -1069,7 +1071,7 @@ class Commands:
|
||||||
self.io.tool_error(f"Please provide a question or topic for the {edit_format} chat.")
|
self.io.tool_error(f"Please provide a question or topic for the {edit_format} chat.")
|
||||||
return
|
return
|
||||||
|
|
||||||
from aider.coders import Coder
|
from aider.coders.base_coder import Coder
|
||||||
|
|
||||||
coder = Coder.create(
|
coder = Coder.create(
|
||||||
io=self.io,
|
io=self.io,
|
||||||
|
@ -1117,7 +1119,7 @@ class Commands:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.voice = voice.Voice(
|
self.voice = voice.Voice(
|
||||||
audio_format=self.args.voice_format, device_name=self.args.voice_input_device
|
audio_format=self.voice_format or "wav", device_name=self.voice_input_device
|
||||||
)
|
)
|
||||||
except voice.SoundDeviceError:
|
except voice.SoundDeviceError:
|
||||||
self.io.tool_error(
|
self.io.tool_error(
|
||||||
|
@ -1309,7 +1311,12 @@ class Commands:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.io.tool_output(f"\nExecuting: {cmd}")
|
self.io.tool_output(f"\nExecuting: {cmd}")
|
||||||
self.run(cmd)
|
try:
|
||||||
|
self.run(cmd)
|
||||||
|
except SwitchCoder:
|
||||||
|
self.io.tool_error(
|
||||||
|
f"Command '{cmd}' is only supported in interactive mode, skipping."
|
||||||
|
)
|
||||||
|
|
||||||
def completions_raw_save(self, document, complete_event):
|
def completions_raw_save(self, document, complete_event):
|
||||||
return self.completions_raw_read_only(document, complete_event)
|
return self.completions_raw_read_only(document, complete_event)
|
||||||
|
|
10
aider/io.py
10
aider/io.py
|
@ -203,6 +203,7 @@ class InputOutput:
|
||||||
fancy_input=True,
|
fancy_input=True,
|
||||||
file_watcher=None,
|
file_watcher=None,
|
||||||
multiline_mode=False,
|
multiline_mode=False,
|
||||||
|
root=".",
|
||||||
):
|
):
|
||||||
self.placeholder = None
|
self.placeholder = None
|
||||||
self.interrupted = False
|
self.interrupted = False
|
||||||
|
@ -270,6 +271,7 @@ class InputOutput:
|
||||||
self.console = Console(force_terminal=False, no_color=True) # non-pretty
|
self.console = Console(force_terminal=False, no_color=True) # non-pretty
|
||||||
|
|
||||||
self.file_watcher = file_watcher
|
self.file_watcher = file_watcher
|
||||||
|
self.root = root
|
||||||
|
|
||||||
def _get_style(self):
|
def _get_style(self):
|
||||||
style_dict = {}
|
style_dict = {}
|
||||||
|
@ -913,7 +915,13 @@ class InputOutput:
|
||||||
editable_files = [f for f in sorted(rel_fnames) if f not in rel_read_only_fnames]
|
editable_files = [f for f in sorted(rel_fnames) if f not in rel_read_only_fnames]
|
||||||
|
|
||||||
if read_only_files:
|
if read_only_files:
|
||||||
files_with_label = ["Readonly:"] + read_only_files
|
# Use shorter of abs/rel paths for readonly files
|
||||||
|
ro_paths = []
|
||||||
|
for rel_path in read_only_files:
|
||||||
|
abs_path = os.path.abspath(os.path.join(self.root, rel_path))
|
||||||
|
ro_paths.append(abs_path if len(abs_path) < len(rel_path) else rel_path)
|
||||||
|
|
||||||
|
files_with_label = ["Readonly:"] + ro_paths
|
||||||
read_only_output = StringIO()
|
read_only_output = StringIO()
|
||||||
Console(file=read_only_output, force_terminal=False).print(Columns(files_with_label))
|
Console(file=read_only_output, force_terminal=False).print(Columns(files_with_label))
|
||||||
read_only_lines = read_only_output.getvalue().splitlines()
|
read_only_lines = read_only_output.getvalue().splitlines()
|
||||||
|
|
|
@ -113,7 +113,9 @@ def setup_git(git_root, io):
|
||||||
except ANY_GIT_ERROR:
|
except ANY_GIT_ERROR:
|
||||||
pass
|
pass
|
||||||
elif cwd == Path.home():
|
elif cwd == Path.home():
|
||||||
io.tool_warning("You should probably run aider in your project's directory, not your home dir.")
|
io.tool_warning(
|
||||||
|
"You should probably run aider in your project's directory, not your home dir."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
elif cwd and io.confirm_ask(
|
elif cwd and io.confirm_ask(
|
||||||
"No git repo found, create one to track aider's changes (recommended)?"
|
"No git repo found, create one to track aider's changes (recommended)?"
|
||||||
|
@ -173,7 +175,7 @@ def check_gitignore(git_root, io, ask=True):
|
||||||
existing_lines = content.splitlines()
|
existing_lines = content.splitlines()
|
||||||
for pat in patterns:
|
for pat in patterns:
|
||||||
if pat not in existing_lines:
|
if pat not in existing_lines:
|
||||||
if '*' in pat or (Path(git_root) / pat).exists():
|
if "*" in pat or (Path(git_root) / pat).exists():
|
||||||
patterns_to_add.append(pat)
|
patterns_to_add.append(pat)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
|
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
|
||||||
|
@ -393,6 +395,12 @@ def sanity_check_repo(repo, io):
|
||||||
if not repo.git_repo_error:
|
if not repo.git_repo_error:
|
||||||
return True
|
return True
|
||||||
error_msg = str(repo.git_repo_error)
|
error_msg = str(repo.git_repo_error)
|
||||||
|
except UnicodeDecodeError as exc:
|
||||||
|
error_msg = (
|
||||||
|
"Failed to read the Git repository. This issue is likely caused by a path encoded "
|
||||||
|
f'in a format different from the expected encoding "{sys.getfilesystemencoding()}".\n'
|
||||||
|
f"Internal error: {str(exc)}"
|
||||||
|
)
|
||||||
except ANY_GIT_ERROR as exc:
|
except ANY_GIT_ERROR as exc:
|
||||||
error_msg = str(exc)
|
error_msg = str(exc)
|
||||||
bad_ver = "version in (1, 2)" in error_msg
|
bad_ver = "version in (1, 2)" in error_msg
|
||||||
|
@ -796,6 +804,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||||
commands = Commands(
|
commands = Commands(
|
||||||
io,
|
io,
|
||||||
None,
|
None,
|
||||||
|
voice_language=args.voice_language,
|
||||||
|
voice_input_device=args.voice_input_device,
|
||||||
|
voice_format=args.voice_format,
|
||||||
verify_ssl=args.verify_ssl,
|
verify_ssl=args.verify_ssl,
|
||||||
args=args,
|
args=args,
|
||||||
parser=parser,
|
parser=parser,
|
||||||
|
|
|
@ -75,7 +75,7 @@ MODEL_ALIASES = {
|
||||||
"35-turbo": "gpt-3.5-turbo",
|
"35-turbo": "gpt-3.5-turbo",
|
||||||
"3": "gpt-3.5-turbo",
|
"3": "gpt-3.5-turbo",
|
||||||
# Other models
|
# Other models
|
||||||
"deepseek": "deepseek/deepseek-coder",
|
"deepseek": "deepseek/deepseek-chat",
|
||||||
"flash": "gemini/gemini-2.0-flash-exp",
|
"flash": "gemini/gemini-2.0-flash-exp",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,27 @@
|
||||||
{
|
{
|
||||||
"vertex_ai-language-models/gemini-2.0-flash-exp": {
|
"openrouter/openai/o1": {
|
||||||
"max_tokens": 8192,
|
"max_tokens": 100000,
|
||||||
"max_input_tokens": 1048576,
|
"max_input_tokens": 200000,
|
||||||
"max_output_tokens": 8192,
|
"max_output_tokens": 100000,
|
||||||
"max_images_per_prompt": 3000,
|
"input_cost_per_token": 0.000015,
|
||||||
"max_videos_per_prompt": 10,
|
"output_cost_per_token": 0.00006,
|
||||||
"max_video_length": 1,
|
"cache_read_input_token_cost": 0.0000075,
|
||||||
"max_audio_length_hours": 8.4,
|
"litellm_provider": "openrouter",
|
||||||
"max_audio_per_prompt": 1,
|
|
||||||
"max_pdf_size_mb": 30,
|
|
||||||
"litellm_provider": "vertex_ai-language-models",
|
|
||||||
"mode": "chat",
|
"mode": "chat",
|
||||||
"supports_system_messages": true,
|
|
||||||
"supports_function_calling": true,
|
"supports_function_calling": true,
|
||||||
|
"supports_parallel_function_calling": true,
|
||||||
"supports_vision": true,
|
"supports_vision": true,
|
||||||
"supports_response_schema": true,
|
"supports_prompt_caching": true,
|
||||||
"source": "https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2"
|
"supports_system_messages": true,
|
||||||
|
"supports_response_schema": true
|
||||||
},
|
},
|
||||||
"gemini/gemini-2.0-flash-exp": {
|
"openrouter/deepseek/deepseek-chat": {
|
||||||
"max_tokens": 8192,
|
"max_tokens": 8192,
|
||||||
"max_input_tokens": 1048576,
|
"max_input_tokens": 66000,
|
||||||
"max_output_tokens": 8192,
|
"max_output_tokens": 4096,
|
||||||
"max_images_per_prompt": 3000,
|
"input_cost_per_token": 0.00000014,
|
||||||
"max_videos_per_prompt": 10,
|
"output_cost_per_token": 0.00000028,
|
||||||
"max_video_length": 1,
|
"litellm_provider": "openrouter",
|
||||||
"max_audio_length_hours": 8.4,
|
"mode": "chat"
|
||||||
"max_audio_per_prompt": 1,
|
|
||||||
"max_pdf_size_mb": 30,
|
|
||||||
"litellm_provider": "gemini",
|
|
||||||
"mode": "chat",
|
|
||||||
"supports_system_messages": true,
|
|
||||||
"supports_function_calling": true,
|
|
||||||
"supports_vision": true,
|
|
||||||
"supports_response_schema": true,
|
|
||||||
"source": "https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2"
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
watch_code_prompt = """
|
watch_code_prompt = """
|
||||||
Find the "AI" comments below (marked with █) in the code files I've shared with you.
|
I've written your instructions in comments in the code and marked them with "ai"
|
||||||
I've written your instructions there.
|
You can see the "AI" comments shown below (marked with █).
|
||||||
Follow my instructions as given in the AI comments and make the requested changes.
|
Find them in the code files I've shared with you, and follow their instructions.
|
||||||
Also, be sure to remove all the "AI" comments from the code too.
|
|
||||||
|
After completing those instructions, also be sure to remove all the "AI" comments from the code too.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
watch_ask_prompt = """/ask
|
watch_ask_prompt = """/ask
|
||||||
|
|
|
@ -23,11 +23,19 @@ cog.out(text)
|
||||||
]]]-->
|
]]]-->
|
||||||
|
|
||||||
|
|
||||||
### main branch
|
### Aider v0.70.0
|
||||||
|
|
||||||
- Full support for o1 models.
|
- Full support for o1 models.
|
||||||
|
- Watch files now honors `--subtree-only`, and only watches that subtree.
|
||||||
|
- Improved prompting for watch files, to work more reliably with more models.
|
||||||
|
- New install methods via uv, including one-liners.
|
||||||
|
- Support for openrouter/deepseek/deepseek-chat model.
|
||||||
|
- Better error handling when interactive commands are attempted via `/load` or `--load`.
|
||||||
|
- Display read-only files with abs path if its shorter than rel path.
|
||||||
- Ask 10% of users to opt-in to analytics.
|
- Ask 10% of users to opt-in to analytics.
|
||||||
- Aider wrote 75% of the code in this release.
|
- Bugfix for auto-suggest.
|
||||||
|
- Gracefully handle unicode errors in git path names.
|
||||||
|
- Aider wrote 74% of the code in this release.
|
||||||
|
|
||||||
### Aider v0.69.1
|
### Aider v0.69.1
|
||||||
|
|
||||||
|
|
|
@ -3457,3 +3457,91 @@
|
||||||
Paul Gauthier (aider): 207
|
Paul Gauthier (aider): 207
|
||||||
start_tag: v0.68.0
|
start_tag: v0.68.0
|
||||||
total_lines: 305
|
total_lines: 305
|
||||||
|
- aider_percentage: 74.22
|
||||||
|
aider_total: 875
|
||||||
|
end_date: '2024-12-26'
|
||||||
|
end_tag: v0.70.0
|
||||||
|
file_counts:
|
||||||
|
aider/__init__.py:
|
||||||
|
Paul Gauthier: 1
|
||||||
|
aider/analytics.py:
|
||||||
|
Paul Gauthier: 6
|
||||||
|
Paul Gauthier (aider): 41
|
||||||
|
aider/args.py:
|
||||||
|
Evan Johnson: 2
|
||||||
|
aider/coders/search_replace.py:
|
||||||
|
Paul Gauthier: 5
|
||||||
|
aider/commands.py:
|
||||||
|
Paul Gauthier (aider): 41
|
||||||
|
aider/help_pats.py:
|
||||||
|
Paul Gauthier: 3
|
||||||
|
aider/io.py:
|
||||||
|
Paul Gauthier: 7
|
||||||
|
Paul Gauthier (aider): 9
|
||||||
|
aider/main.py:
|
||||||
|
Paul Gauthier: 15
|
||||||
|
Paul Gauthier (aider): 5
|
||||||
|
apaz-cli: 3
|
||||||
|
mdk: 6
|
||||||
|
aider/models.py:
|
||||||
|
Paul Gauthier: 29
|
||||||
|
aider/repo.py:
|
||||||
|
Paul Gauthier: 14
|
||||||
|
aider/utils.py:
|
||||||
|
Paul Gauthier: 2
|
||||||
|
aider/watch.py:
|
||||||
|
Paul Gauthier: 13
|
||||||
|
aider/website/_includes/head_custom.html:
|
||||||
|
Paul Gauthier (aider): 4
|
||||||
|
aider/website/_includes/leaderboard.js:
|
||||||
|
Paul Gauthier (aider): 14
|
||||||
|
aider/website/docs/leaderboards/index.md:
|
||||||
|
Paul Gauthier: 28
|
||||||
|
Paul Gauthier (aider): 2
|
||||||
|
benchmark/Dockerfile:
|
||||||
|
Paul Gauthier: 8
|
||||||
|
Paul Gauthier (aider): 43
|
||||||
|
benchmark/benchmark.py:
|
||||||
|
Paul Gauthier: 69
|
||||||
|
Paul Gauthier (aider): 153
|
||||||
|
benchmark/clone-exercism.sh:
|
||||||
|
Paul Gauthier: 2
|
||||||
|
Paul Gauthier (aider): 18
|
||||||
|
benchmark/cpp-test.sh:
|
||||||
|
Paul Gauthier: 10
|
||||||
|
Paul Gauthier (aider): 1
|
||||||
|
benchmark/docker.sh:
|
||||||
|
Paul Gauthier (aider): 4
|
||||||
|
benchmark/install-docker-ubuntu.sh:
|
||||||
|
Paul Gauthier (aider): 63
|
||||||
|
benchmark/npm-test.sh:
|
||||||
|
Paul Gauthier: 10
|
||||||
|
Paul Gauthier (aider): 3
|
||||||
|
benchmark/problem_stats.py:
|
||||||
|
Paul Gauthier: 35
|
||||||
|
Paul Gauthier (aider): 318
|
||||||
|
benchmark/rsync.sh:
|
||||||
|
Paul Gauthier: 7
|
||||||
|
Paul Gauthier (aider): 26
|
||||||
|
scripts/blame.py:
|
||||||
|
Paul Gauthier (aider): 6
|
||||||
|
scripts/my_models.py:
|
||||||
|
Paul Gauthier (aider): 95
|
||||||
|
scripts/update-blame.sh:
|
||||||
|
Paul Gauthier (aider): 3
|
||||||
|
scripts/update-docs.sh:
|
||||||
|
Paul Gauthier: 1
|
||||||
|
tests/basic/test_analytics.py:
|
||||||
|
Paul Gauthier (aider): 19
|
||||||
|
tests/basic/test_main.py:
|
||||||
|
Paul Gauthier (aider): 7
|
||||||
|
tests/basic/test_sanity_check_repo.py:
|
||||||
|
mdk: 28
|
||||||
|
grand_total:
|
||||||
|
Evan Johnson: 2
|
||||||
|
Paul Gauthier: 265
|
||||||
|
Paul Gauthier (aider): 875
|
||||||
|
apaz-cli: 3
|
||||||
|
mdk: 34
|
||||||
|
start_tag: v0.69.0
|
||||||
|
total_lines: 1179
|
||||||
|
|
|
@ -257,10 +257,36 @@
|
||||||
versions: 0.69.2.dev
|
versions: 0.69.2.dev
|
||||||
seconds_per_case: 12.2
|
seconds_per_case: 12.2
|
||||||
total_cost: 0.0000
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-23-01-11-56--yi-test
|
||||||
|
test_cases: 225
|
||||||
|
model: yi-lightning
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: 2b1625e
|
||||||
|
pass_rate_1: 5.8
|
||||||
|
pass_rate_2: 12.9
|
||||||
|
pass_num_1: 13
|
||||||
|
pass_num_2: 29
|
||||||
|
percent_cases_well_formed: 92.9
|
||||||
|
error_outputs: 87
|
||||||
|
num_malformed_responses: 72
|
||||||
|
num_with_malformed_responses: 16
|
||||||
|
user_asks: 107
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 1
|
||||||
|
test_timeouts: 6
|
||||||
|
total_tests: 225
|
||||||
|
command: aider --model openai/yi-lightning
|
||||||
|
date: 2024-12-23
|
||||||
|
versions: 0.69.2.dev
|
||||||
|
seconds_per_case: 146.7
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
|
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
|
||||||
test_cases: 225
|
test_cases: 225
|
||||||
model: DeepSeek Chat V3 Preview
|
model: DeepSeek Chat V3
|
||||||
edit_format: diff
|
edit_format: diff
|
||||||
commit_hash: 0a23c4a-dirty
|
commit_hash: 0a23c4a-dirty
|
||||||
pass_rate_1: 22.7
|
pass_rate_1: 22.7
|
||||||
|
@ -308,4 +334,5 @@
|
||||||
date: 2024-12-26
|
date: 2024-12-26
|
||||||
versions: 0.69.2.dev
|
versions: 0.69.2.dev
|
||||||
seconds_per_case: 42.0
|
seconds_per_case: 42.0
|
||||||
total_cost: 0.0000
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
<canvas id="blameChart" width="800" height="360" style="margin-top: 20px"></canvas>
|
<div class="chart-container">
|
||||||
<canvas id="linesChart" width="800" height="360" style="margin-top: 20px"></canvas>
|
<canvas id="blameChart" style="margin-top: 20px"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="linesChart" style="margin-top: 20px"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.chart-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
|
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
|
||||||
|
@ -24,10 +37,17 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
var linesData = {
|
var linesData = {
|
||||||
labels: labels,
|
labels: labels,
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Aider\'s lines of new code',
|
label: 'Aider',
|
||||||
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.aider_total }} },{% endfor %}],
|
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.aider_total }} },{% endfor %}],
|
||||||
backgroundColor: 'rgba(255, 99, 132, 0.8)',
|
backgroundColor: 'rgba(54, 162, 235, 0.8)',
|
||||||
borderColor: 'rgba(255, 99, 132, 1)',
|
borderColor: 'rgba(54, 162, 235, 1)',
|
||||||
|
borderWidth: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Human',
|
||||||
|
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.total_lines | minus: row.aider_total }} },{% endfor %}],
|
||||||
|
backgroundColor: 'rgba(200, 200, 200, 0.8)',
|
||||||
|
borderColor: 'rgba(200, 200, 200, 1)',
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
@ -36,6 +56,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: blameData,
|
data: blameData,
|
||||||
options: {
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
@ -85,9 +106,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: linesData,
|
data: linesData,
|
||||||
options: {
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
stacked: true,
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Version'
|
text: 'Version'
|
||||||
|
@ -98,6 +121,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
y: {
|
y: {
|
||||||
|
stacked: true,
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Lines of new code'
|
text: 'Lines of new code'
|
||||||
|
@ -107,12 +131,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
legend: {
|
legend: {
|
||||||
display: false
|
display: true,
|
||||||
|
position: 'chartArea',
|
||||||
|
reverse: true
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: function(context) {
|
label: function(context) {
|
||||||
var label = 'New lines of code by aider';
|
var label = context.dataset.label;
|
||||||
var value = context.parsed.y || 0;
|
var value = context.parsed.y || 0;
|
||||||
return `${label}: ${value}`;
|
return `${label}: ${value}`;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +146,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Lines of new code written by aider, by release',
|
text: 'Lines of new code, by release',
|
||||||
font: {
|
font: {
|
||||||
size: 16
|
size: 16
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||||
[connect to almost any LLM](https://aider.chat/docs/llms.html).
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,7 +44,7 @@
|
||||||
## Use gpt-3.5-turbo model for the main chat
|
## Use gpt-3.5-turbo model for the main chat
|
||||||
#35turbo: false
|
#35turbo: false
|
||||||
|
|
||||||
## Use deepseek/deepseek-coder model for the main chat
|
## Use deepseek/deepseek-chat model for the main chat
|
||||||
#deepseek: false
|
#deepseek: false
|
||||||
|
|
||||||
## Use o1-mini model for the main chat
|
## Use o1-mini model for the main chat
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
## Use gpt-3.5-turbo model for the main chat
|
## Use gpt-3.5-turbo model for the main chat
|
||||||
#AIDER_35TURBO=
|
#AIDER_35TURBO=
|
||||||
|
|
||||||
## Use deepseek/deepseek-coder model for the main chat
|
## Use deepseek/deepseek-chat model for the main chat
|
||||||
#AIDER_DEEPSEEK=
|
#AIDER_DEEPSEEK=
|
||||||
|
|
||||||
## Use o1-mini model for the main chat
|
## Use o1-mini model for the main chat
|
||||||
|
|
|
@ -96,7 +96,7 @@ cog.outl("```")
|
||||||
## Use gpt-3.5-turbo model for the main chat
|
## Use gpt-3.5-turbo model for the main chat
|
||||||
#35turbo: false
|
#35turbo: false
|
||||||
|
|
||||||
## Use deepseek/deepseek-coder model for the main chat
|
## Use deepseek/deepseek-chat model for the main chat
|
||||||
#deepseek: false
|
#deepseek: false
|
||||||
|
|
||||||
## Use o1-mini model for the main chat
|
## Use o1-mini model for the main chat
|
||||||
|
|
|
@ -88,7 +88,7 @@ cog.outl("```")
|
||||||
## Use gpt-3.5-turbo model for the main chat
|
## Use gpt-3.5-turbo model for the main chat
|
||||||
#AIDER_35TURBO=
|
#AIDER_35TURBO=
|
||||||
|
|
||||||
## Use deepseek/deepseek-coder model for the main chat
|
## Use deepseek/deepseek-chat model for the main chat
|
||||||
#AIDER_DEEPSEEK=
|
#AIDER_DEEPSEEK=
|
||||||
|
|
||||||
## Use o1-mini model for the main chat
|
## Use o1-mini model for the main chat
|
||||||
|
|
|
@ -55,7 +55,7 @@ for alias, model in sorted(MODEL_ALIASES.items()):
|
||||||
- `4`: gpt-4-0613
|
- `4`: gpt-4-0613
|
||||||
- `4-turbo`: gpt-4-1106-preview
|
- `4-turbo`: gpt-4-1106-preview
|
||||||
- `4o`: gpt-4o
|
- `4o`: gpt-4o
|
||||||
- `deepseek`: deepseek/deepseek-coder
|
- `deepseek`: deepseek/deepseek-chat
|
||||||
- `flash`: gemini/gemini-2.0-flash-exp
|
- `flash`: gemini/gemini-2.0-flash-exp
|
||||||
- `haiku`: claude-3-5-haiku-20241022
|
- `haiku`: claude-3-5-haiku-20241022
|
||||||
- `opus`: claude-3-opus-20240229
|
- `opus`: claude-3-opus-20240229
|
||||||
|
|
|
@ -136,7 +136,7 @@ Aliases:
|
||||||
- `-3`
|
- `-3`
|
||||||
|
|
||||||
### `--deepseek`
|
### `--deepseek`
|
||||||
Use deepseek/deepseek-coder model for the main chat
|
Use deepseek/deepseek-chat model for the main chat
|
||||||
Environment variable: `AIDER_DEEPSEEK`
|
Environment variable: `AIDER_DEEPSEEK`
|
||||||
|
|
||||||
### `--o1-mini`
|
### `--o1-mini`
|
||||||
|
|
|
@ -237,16 +237,12 @@ tr:hover { background-color: #f5f5f5; }
|
||||||
</style>
|
</style>
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Model Name</th><th class='right'>Total Tokens</th><th class='right'>Percent</th></tr>
|
<tr><th>Model Name</th><th class='right'>Total Tokens</th><th class='right'>Percent</th></tr>
|
||||||
<tr><td>claude-3-5-sonnet-20241022</td><td class='right'>1,918,086</td><td class='right'>98.0%</td></tr>
|
<tr><td>deepseek/deepseek-chat</td><td class='right'>1,422,360</td><td class='right'>62.0%</td></tr>
|
||||||
<tr><td>o1-preview</td><td class='right'>33,530</td><td class='right'>1.7%</td></tr>
|
<tr><td>claude-3-5-sonnet-20241022</td><td class='right'>823,708</td><td class='right'>35.9%</td></tr>
|
||||||
<tr><td>gpt-4o</td><td class='right'>4,273</td><td class='right'>0.2%</td></tr>
|
<tr><td>o1</td><td class='right'>37,290</td><td class='right'>1.6%</td></tr>
|
||||||
<tr><td>openrouter/REDACTED</td><td class='right'>1,234</td><td class='right'>0.1%</td></tr>
|
<tr><td>gemini/gemini-2.0-flash-exp</td><td class='right'>4,827</td><td class='right'>0.2%</td></tr>
|
||||||
<tr><td>openai/gpt-4o-mini</td><td class='right'>141</td><td class='right'>0.0%</td></tr>
|
<tr><td>gpt-4o</td><td class='right'>4,473</td><td class='right'>0.2%</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{: .note :}
|
|
||||||
Some models show as REDACTED, because they are new or unpopular models.
|
|
||||||
Aider's analytics only records the names of "well known" LLMs.
|
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
## How are the "aider wrote xx% of code" stats computed?
|
## How are the "aider wrote xx% of code" stats computed?
|
||||||
|
|
|
@ -20,8 +20,8 @@ it works best with models that score well on the benchmarks.
|
||||||
|
|
||||||
|
|
||||||
{: .note :}
|
{: .note :}
|
||||||
The old
|
The
|
||||||
[aider code editing leaderboard](edit.html)
|
[original aider code editing leaderboard](edit.html)
|
||||||
has been replaced by this
|
has been replaced by this
|
||||||
new, much more challenging
|
new, much more challenging
|
||||||
[polyglot leaderboard](https://aider.chat/2024/12/21/polyglot.html).
|
[polyglot leaderboard](https://aider.chat/2024/12/21/polyglot.html).
|
||||||
|
@ -122,6 +122,6 @@ mod_dates = [get_last_modified_date(file) for file in files]
|
||||||
latest_mod_date = max(mod_dates)
|
latest_mod_date = max(mod_dates)
|
||||||
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
|
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
|
||||||
]]]-->
|
]]]-->
|
||||||
December 22, 2024.
|
December 26, 2024.
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -53,6 +53,12 @@ To use aider installed via `pipx` with AWS Bedrock, you must add the `boto3` dep
|
||||||
pipx inject aider-chat boto3
|
pipx inject aider-chat boto3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You must install `boto3` dependency to aider's virtual environment installed via one-liner or uv by running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv tool run --from aider-chat pip install boto3
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Running Aider with Bedrock
|
## Running Aider with Bedrock
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,8 @@ cog.out(''.join(lines))
|
||||||
- TOGETHERAI_API_KEY
|
- TOGETHERAI_API_KEY
|
||||||
- VOLCENGINE_API_KEY
|
- VOLCENGINE_API_KEY
|
||||||
- VOYAGE_API_KEY
|
- VOYAGE_API_KEY
|
||||||
|
- WATSONX_API_KEY
|
||||||
|
- WX_API_KEY
|
||||||
- XAI_API_KEY
|
- XAI_API_KEY
|
||||||
- XINFERENCE_API_KEY
|
- XINFERENCE_API_KEY
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|
|
@ -32,9 +32,8 @@ cog.out(text)
|
||||||
|
|
||||||
Aider lets you pair program with LLMs,
|
Aider lets you pair program with LLMs,
|
||||||
to edit code in your local git repository.
|
to edit code in your local git repository.
|
||||||
Start a new project or work with an existing git repo.
|
Start a new project or work with an existing code base.
|
||||||
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
{% include works-best.md %}
|
||||||
[connect to almost any LLM](https://aider.chat/docs/llms.html).
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -105,7 +104,7 @@ for more details.
|
||||||
- Aider will edit your files to complete your request.
|
- Aider will edit your files to complete your request.
|
||||||
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
|
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
|
||||||
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
|
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
|
||||||
- Aider works best with GPT-4o & Claude 3.5 Sonnet and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
- {% capture included_content %}{% include works-best.md %}{% endcapture %}{{ included_content | strip_newlines | strip }}
|
||||||
- Aider can edit multiple files at once for complex requests.
|
- Aider can edit multiple files at once for complex requests.
|
||||||
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
|
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
|
||||||
- Edit files in your editor while chatting with aider,
|
- Edit files in your editor while chatting with aider,
|
||||||
|
|
|
@ -11,6 +11,7 @@ RUN apt-get update && apt-get install -y \
|
||||||
python3.11-venv \
|
python3.11-venv \
|
||||||
python3.11-dev \
|
python3.11-dev \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
|
ca-certificates-java \
|
||||||
openjdk-21-jdk \
|
openjdk-21-jdk \
|
||||||
libtbb-dev \
|
libtbb-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
@ -18,10 +19,18 @@ RUN apt-get update && apt-get install -y \
|
||||||
# Make python3.11 the default python3
|
# Make python3.11 the default python3
|
||||||
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
|
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
|
||||||
|
|
||||||
# Install Go
|
# Install Go with architecture detection
|
||||||
RUN curl -OL https://golang.org/dl/go1.21.5.linux-amd64.tar.gz && \
|
RUN ARCH=$(uname -m) && \
|
||||||
tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz && \
|
if [ "$ARCH" = "x86_64" ]; then \
|
||||||
rm go1.21.5.linux-amd64.tar.gz
|
GOARCH="amd64"; \
|
||||||
|
elif [ "$ARCH" = "aarch64" ]; then \
|
||||||
|
GOARCH="arm64"; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi && \
|
||||||
|
curl -L "https://golang.org/dl/go1.21.5.linux-$GOARCH.tar.gz" -o go.tar.gz && \
|
||||||
|
tar -C /usr/local -xzf go.tar.gz && \
|
||||||
|
rm go.tar.gz
|
||||||
ENV PATH="/usr/local/go/bin:${PATH}"
|
ENV PATH="/usr/local/go/bin:${PATH}"
|
||||||
|
|
||||||
# Install Rust
|
# Install Rust
|
||||||
|
|
|
@ -31,7 +31,7 @@ from aider.io import InputOutput
|
||||||
|
|
||||||
BENCHMARK_DNAME = Path(os.environ.get("AIDER_BENCHMARK_DIR", "tmp.benchmarks"))
|
BENCHMARK_DNAME = Path(os.environ.get("AIDER_BENCHMARK_DIR", "tmp.benchmarks"))
|
||||||
|
|
||||||
EXERCISES_DIR_DEFAULT = "exercism-python"
|
EXERCISES_DIR_DEFAULT = "polyglot-benchmark"
|
||||||
|
|
||||||
app = typer.Typer(add_completion=False, pretty_exceptions_enable=False)
|
app = typer.Typer(add_completion=False, pretty_exceptions_enable=False)
|
||||||
|
|
||||||
|
@ -176,11 +176,6 @@ def main(
|
||||||
"--replay",
|
"--replay",
|
||||||
help="Replay previous .aider.chat.history.md responses from previous benchmark run",
|
help="Replay previous .aider.chat.history.md responses from previous benchmark run",
|
||||||
),
|
),
|
||||||
max_apply_update_errors: int = typer.Option(
|
|
||||||
3,
|
|
||||||
"--max-apply-update-errors",
|
|
||||||
help="Maximum number of apply update errors before stopping the test",
|
|
||||||
),
|
|
||||||
keywords: str = typer.Option(
|
keywords: str = typer.Option(
|
||||||
None, "--keywords", "-k", help="Only run tests that contain keywords (comma sep)"
|
None, "--keywords", "-k", help="Only run tests that contain keywords (comma sep)"
|
||||||
),
|
),
|
||||||
|
@ -342,7 +337,6 @@ def main(
|
||||||
verbose,
|
verbose,
|
||||||
commit_hash,
|
commit_hash,
|
||||||
replay,
|
replay,
|
||||||
max_apply_update_errors,
|
|
||||||
editor_model,
|
editor_model,
|
||||||
editor_edit_format,
|
editor_edit_format,
|
||||||
num_ctx,
|
num_ctx,
|
||||||
|
@ -367,7 +361,6 @@ def main(
|
||||||
verbose,
|
verbose,
|
||||||
commit_hash,
|
commit_hash,
|
||||||
replay,
|
replay,
|
||||||
max_apply_update_errors,
|
|
||||||
editor_model,
|
editor_model,
|
||||||
editor_edit_format,
|
editor_edit_format,
|
||||||
)
|
)
|
||||||
|
@ -645,7 +638,6 @@ def run_test_real(
|
||||||
verbose,
|
verbose,
|
||||||
commit_hash,
|
commit_hash,
|
||||||
replay,
|
replay,
|
||||||
max_apply_update_errors,
|
|
||||||
editor_model,
|
editor_model,
|
||||||
editor_edit_format,
|
editor_edit_format,
|
||||||
num_ctx=None,
|
num_ctx=None,
|
||||||
|
@ -792,7 +784,6 @@ def run_test_real(
|
||||||
)
|
)
|
||||||
dump(coder.ignore_mentions)
|
dump(coder.ignore_mentions)
|
||||||
|
|
||||||
coder.max_apply_update_errors = max_apply_update_errors
|
|
||||||
coder.show_announcements()
|
coder.show_announcements()
|
||||||
|
|
||||||
timeouts = 0
|
timeouts = 0
|
||||||
|
|
|
@ -205,16 +205,18 @@ def analyze_exercise_solutions(dirs=None, topn=None, copy_hard_set=False):
|
||||||
|
|
||||||
# Distribution table of how many models solved each exercise
|
# Distribution table of how many models solved each exercise
|
||||||
print("\nDistribution of solutions:")
|
print("\nDistribution of solutions:")
|
||||||
print("Models Exercises Cumulative")
|
print("Models Exercises Cumulative RevCumulative")
|
||||||
print("-" * 35)
|
print("-" * 50)
|
||||||
counts = [0] * (total_models + 1)
|
counts = [0] * (total_models + 1)
|
||||||
for ex, models in exercise_solutions.items():
|
for ex, models in exercise_solutions.items():
|
||||||
counts[len(models)] += 1
|
counts[len(models)] += 1
|
||||||
|
|
||||||
cumsum = 0
|
cumsum = 0
|
||||||
|
revcumsum = sum(counts) # Start with total number of exercises
|
||||||
for i, count in enumerate(counts):
|
for i, count in enumerate(counts):
|
||||||
cumsum += count
|
cumsum += count
|
||||||
print(f"{i:>6d} {count:>9d} {cumsum:>10d}")
|
print(f"{i:>6d} {count:>9d} {cumsum:>10d} {revcumsum:>12d}")
|
||||||
|
revcumsum -= count # Decrement the reverse cumulative sum
|
||||||
|
|
||||||
# Count parse errors per exercise
|
# Count parse errors per exercise
|
||||||
parse_error_counts = defaultdict(int)
|
parse_error_counts = defaultdict(int)
|
||||||
|
|
|
@ -1721,3 +1721,33 @@ class TestCommands(TestCase):
|
||||||
|
|
||||||
del coder
|
del coder
|
||||||
del commands
|
del commands
|
||||||
|
|
||||||
|
def test_cmd_load_with_switch_coder(self):
|
||||||
|
with GitTemporaryDirectory() as repo_dir:
|
||||||
|
io = InputOutput(pretty=False, fancy_input=False, yes=True)
|
||||||
|
coder = Coder.create(self.GPT35, None, io)
|
||||||
|
commands = Commands(io, coder)
|
||||||
|
|
||||||
|
# Create a temporary file with commands
|
||||||
|
commands_file = Path(repo_dir) / "test_commands.txt"
|
||||||
|
commands_file.write_text("/ask Tell me about the code\n/model gpt-4\n")
|
||||||
|
|
||||||
|
# Mock run to raise SwitchCoder for /ask and /model
|
||||||
|
def mock_run(cmd):
|
||||||
|
if cmd.startswith(("/ask", "/model")):
|
||||||
|
raise SwitchCoder()
|
||||||
|
return None
|
||||||
|
|
||||||
|
with mock.patch.object(commands, "run", side_effect=mock_run):
|
||||||
|
# Capture tool_error output
|
||||||
|
with mock.patch.object(io, "tool_error") as mock_tool_error:
|
||||||
|
commands.cmd_load(str(commands_file))
|
||||||
|
|
||||||
|
# Check that appropriate error messages were shown
|
||||||
|
mock_tool_error.assert_any_call(
|
||||||
|
"Command '/ask Tell me about the code' is only supported in interactive"
|
||||||
|
" mode, skipping."
|
||||||
|
)
|
||||||
|
mock_tool_error.assert_any_call(
|
||||||
|
"Command '/model gpt-4' is only supported in interactive mode, skipping."
|
||||||
|
)
|
||||||
|
|
|
@ -8,6 +8,8 @@ from git import GitError, Repo
|
||||||
|
|
||||||
from aider import urls
|
from aider import urls
|
||||||
from aider.main import sanity_check_repo
|
from aider.main import sanity_check_repo
|
||||||
|
from aider.repo import GitRepo
|
||||||
|
from aider.io import InputOutput
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -182,3 +184,41 @@ def test_sanity_check_repo_with_no_repo(mock_io):
|
||||||
# Assert that no errors or outputs were logged
|
# Assert that no errors or outputs were logged
|
||||||
mock_io.tool_error.assert_not_called()
|
mock_io.tool_error.assert_not_called()
|
||||||
mock_io.tool_output.assert_not_called()
|
mock_io.tool_output.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def corrupt_git_index(repo_path):
|
||||||
|
index_path = os.path.join(repo_path, ".git", "index")
|
||||||
|
with open(index_path, "r+b") as f:
|
||||||
|
# Verify the file has the correct signature
|
||||||
|
signature = f.read(4)
|
||||||
|
if signature != b"DIRC":
|
||||||
|
raise ValueError("Invalid git index file signature.")
|
||||||
|
|
||||||
|
# Seek to the data section and inject invalid bytes to simulate encoding error
|
||||||
|
f.seek(77)
|
||||||
|
f.write(b"\xF5" * 5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanity_check_repo_with_corrupt_index(create_repo, mock_io):
|
||||||
|
repo_path, repo = create_repo
|
||||||
|
# Corrupt the Git index file
|
||||||
|
corrupt_git_index(repo_path)
|
||||||
|
|
||||||
|
# Create GitRepo instance
|
||||||
|
git_repo = GitRepo(InputOutput(), None, repo_path)
|
||||||
|
|
||||||
|
# Call the function
|
||||||
|
result = sanity_check_repo(git_repo, mock_io)
|
||||||
|
|
||||||
|
# Assert that the function returns False
|
||||||
|
assert result is False
|
||||||
|
|
||||||
|
# Assert that the appropriate error messages were logged
|
||||||
|
mock_io.tool_error.assert_called_with("Unable to read git repository, it may be corrupt?")
|
||||||
|
mock_io.tool_output.assert_called_with(
|
||||||
|
(
|
||||||
|
"Failed to read the Git repository. This issue is likely caused by a path encoded "
|
||||||
|
"in a format different from the expected encoding \"utf-8\".\n"
|
||||||
|
"Internal error: 'utf-8' codec can't decode byte 0xf5 in position 3: invalid start byte"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue