mirror of
https://github.com/Aider-AI/aider
synced 2026-04-26 01:25:17 +02:00
Compare commits
183 Commits
v0.64.1.de
...
v0.65.1.de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a73e77a819 | ||
|
|
b5f1659382 | ||
|
|
beb6722f57 | ||
|
|
a052b89152 | ||
|
|
95b391350f | ||
|
|
5773eac03f | ||
|
|
da4ace2875 | ||
|
|
e507c5b502 | ||
|
|
722c2c2668 | ||
|
|
8e7bfef9f1 | ||
|
|
1811f0d0d5 | ||
|
|
6b9d534fe2 | ||
|
|
dc4562a845 | ||
|
|
c15af63bc9 | ||
|
|
5b68c2c7d9 | ||
|
|
b70e0bd1f6 | ||
|
|
743f0f5540 | ||
|
|
e647a5b733 | ||
|
|
df1d259e42 | ||
|
|
e3efab7fbf | ||
|
|
cd79f7f4b0 | ||
|
|
5d175745bf | ||
|
|
e648bac74b | ||
|
|
e5c0ebd0a0 | ||
|
|
608a43402c | ||
|
|
75bc2dd564 | ||
|
|
bbd81c3cf7 | ||
|
|
301eb7c74d | ||
|
|
a756039f27 | ||
|
|
b4d1b71ee7 | ||
|
|
8d85a4754d | ||
|
|
a1b48049a9 | ||
|
|
6789844c1f | ||
|
|
c602a839ca | ||
|
|
01c7793e90 | ||
|
|
47b013b034 | ||
|
|
dc2047804a | ||
|
|
885e5cbd7c | ||
|
|
635a5196e8 | ||
|
|
cbd339190b | ||
|
|
266093189d | ||
|
|
62b02d4370 | ||
|
|
8546a1dc86 | ||
|
|
ae98bf237f | ||
|
|
0398deb005 | ||
|
|
3a1492977b | ||
|
|
ef40a456e8 | ||
|
|
583b78c0c1 | ||
|
|
c0988de581 | ||
|
|
34a190e29b | ||
|
|
0940598708 | ||
|
|
7e6cbb3efa | ||
|
|
7dc4e00c75 | ||
|
|
8a598eacaf | ||
|
|
8592fad9cd | ||
|
|
fa72a89d35 | ||
|
|
5e99c51d93 | ||
|
|
905976e765 | ||
|
|
3ebd47d3db | ||
|
|
bf4c7c475a | ||
|
|
bf38371971 | ||
|
|
18460f4f91 | ||
|
|
f94e3e6aba | ||
|
|
1647da2942 | ||
|
|
86e2cdb1fb | ||
|
|
764702a377 | ||
|
|
837a97ffdf | ||
|
|
217e9b96d8 | ||
|
|
524274fcf4 | ||
|
|
6d5f576b92 | ||
|
|
445f9fa7df | ||
|
|
2ff3a23606 | ||
|
|
c5ce57ea7f | ||
|
|
351b8e50f0 | ||
|
|
68be6c5742 | ||
|
|
7a34a2dfa9 | ||
|
|
49ce9e1209 | ||
|
|
c84e192324 | ||
|
|
d696673f07 | ||
|
|
2957d463c9 | ||
|
|
af48e50898 | ||
|
|
f4b964a4b8 | ||
|
|
a79ce7a151 | ||
|
|
21bb83c55a | ||
|
|
7122ceb16c | ||
|
|
f9bcfe341c | ||
|
|
13c5bfdd88 | ||
|
|
bf79c2cb99 | ||
|
|
325cdfcf57 | ||
|
|
7d14d4ade9 | ||
|
|
1b7d12194e | ||
|
|
91f238aded | ||
|
|
78ff489995 | ||
|
|
ff791439e2 | ||
|
|
3f8b2d6b99 | ||
|
|
4dcbce58ed | ||
|
|
0427deb897 | ||
|
|
f3eb3409e3 | ||
|
|
86619052ca | ||
|
|
0c59d3234e | ||
|
|
939d7ea3fb | ||
|
|
dc8761763d | ||
|
|
4894914db1 | ||
|
|
aee94a0584 | ||
|
|
c550422168 | ||
|
|
cebd9cabb3 | ||
|
|
3f16652d56 | ||
|
|
2ebf48ca71 | ||
|
|
c2f184f5bb | ||
|
|
e56651e5c0 | ||
|
|
1d09e96127 | ||
|
|
73de0ea8be | ||
|
|
757eac0579 | ||
|
|
bb78e2f57f | ||
|
|
92579243c5 | ||
|
|
8d0ba40d67 | ||
|
|
ff8c1aace9 | ||
|
|
cf74dc9b48 | ||
|
|
e63df83091 | ||
|
|
14522dbbcd | ||
|
|
91daea9e01 | ||
|
|
12b789fc4e | ||
|
|
baa13351a6 | ||
|
|
8f83204f0f | ||
|
|
80f5b60e1d | ||
|
|
54525f6696 | ||
|
|
3dc50216b5 | ||
|
|
324430a696 | ||
|
|
65d7957610 | ||
|
|
6ac4993cf2 | ||
|
|
100744a952 | ||
|
|
3a331e55dc | ||
|
|
a57f81ba5f | ||
|
|
ca0b55fbbf | ||
|
|
38a3cf98dd | ||
|
|
1234ad92e5 | ||
|
|
488edc24ce | ||
|
|
307c23631a | ||
|
|
83d2241883 | ||
|
|
f9126416e8 | ||
|
|
4e9ae16cb3 | ||
|
|
ef8bfdffa7 | ||
|
|
bfb090331f | ||
|
|
5506d0f25b | ||
|
|
6ebd2d0883 | ||
|
|
a16dcaba4e | ||
|
|
f06452c6c5 | ||
|
|
6a0a97cb41 | ||
|
|
711102b438 | ||
|
|
6d53eb0aaa | ||
|
|
0ccf04a2c5 | ||
|
|
070ce35b44 | ||
|
|
a8296e5de5 | ||
|
|
d17f25e975 | ||
|
|
23095ada85 | ||
|
|
f9ef161991 | ||
|
|
28004bae2f | ||
|
|
17aef7be7d | ||
|
|
ebba8f5110 | ||
|
|
dbd7f51f5c | ||
|
|
fbadfcfa7c | ||
|
|
2c12234604 | ||
|
|
13cb6a315c | ||
|
|
48e7376002 | ||
|
|
60d82eddee | ||
|
|
30ee89c7e9 | ||
|
|
25bcea6aec | ||
|
|
488c88da91 | ||
|
|
8fdcd92260 | ||
|
|
781a40df52 | ||
|
|
2412c81d92 | ||
|
|
a7fc0f9d2e | ||
|
|
9eab021a50 | ||
|
|
c189a52e5e | ||
|
|
6d6d763dd3 | ||
|
|
3cfbaa0ed6 | ||
|
|
e1b4571fdf | ||
|
|
08027ea9c4 | ||
|
|
d0528a00c1 | ||
|
|
7ae6a2ba9a | ||
|
|
ad0e5c4770 | ||
|
|
a8a3e2401b | ||
|
|
a7f59a2e2b |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,4 +11,5 @@ _site
|
||||
.jekyll-cache/
|
||||
.jekyll-metadata
|
||||
aider/__version__.py
|
||||
.venv/
|
||||
.venv/
|
||||
.gitattributes
|
||||
|
||||
19
HISTORY.md
19
HISTORY.md
@@ -1,8 +1,25 @@
|
||||
|
||||
# Release history
|
||||
|
||||
### main branch
|
||||
|
||||
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
||||
- Added `--[no-]detect-urls` flag to disable detecting and offering to scrape URLs found in the chat.
|
||||
- Ollama models now default to an 8k context window.
|
||||
- Added [RepoMap support for Dart language](https://aider.chat/docs/languages.html) by @malkoG.
|
||||
- Ask 2.5% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
|
||||
- Skip suggesting files that share names with files already in chat.
|
||||
- `/editor` returns and prefill the file content into the prompt, so you can use `/editor` to compose messages that start with `/commands`, etc.
|
||||
- Enhanced error handling for analytics.
|
||||
- Improved handling of UnknownEditFormat exceptions with helpful documentation links.
|
||||
- Bumped dependencies to pick up grep-ast 0.4.0 for Dart language support.
|
||||
- Aider wrote 81% of the code in this release.
|
||||
|
||||
### Aider v0.64.1
|
||||
|
||||
- Disable streaming for o1 on OpenRouter.
|
||||
|
||||
### Aider v0.64.0
|
||||
|
||||
- Added [`/editor` command](https://aider.chat/docs/usage/commands.html) to open system editor for writing prompts, by @thehunmonkgroup.
|
||||
- Full support for `gpt-4o-2024-11-20`.
|
||||
- Stream o1 models by default.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
try:
|
||||
from aider.__version__ import __version__
|
||||
except Exception:
|
||||
__version__ = "0.64.1.dev"
|
||||
__version__ = "0.65.1.dev"
|
||||
|
||||
__all__ = [__version__]
|
||||
|
||||
@@ -5,7 +5,7 @@ import time
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
from mixpanel import Mixpanel
|
||||
from mixpanel import Mixpanel, MixpanelException
|
||||
from posthog import Posthog
|
||||
|
||||
from aider import __version__
|
||||
@@ -78,7 +78,7 @@ class Analytics:
|
||||
if not self.user_id:
|
||||
return False
|
||||
|
||||
PERCENT = 1
|
||||
PERCENT = 2.5
|
||||
return self.is_uuid_in_percentage(self.user_id, PERCENT)
|
||||
|
||||
def is_uuid_in_percentage(self, uuid_str, percent):
|
||||
@@ -159,7 +159,7 @@ class Analytics:
|
||||
return None
|
||||
|
||||
def event(self, event_name, main_model=None, **kwargs):
|
||||
if not (self.mp or self.ph) and not self.logfile:
|
||||
if not self.mp and not self.ph and not self.logfile:
|
||||
return
|
||||
|
||||
properties = {}
|
||||
@@ -182,7 +182,10 @@ class Analytics:
|
||||
properties["aider_version"] = __version__
|
||||
|
||||
if self.mp:
|
||||
self.mp.track(self.user_id, event_name, dict(properties))
|
||||
try:
|
||||
self.mp.track(self.user_id, event_name, dict(properties))
|
||||
except MixpanelException:
|
||||
self.mp = None # Disable mixpanel on connection errors
|
||||
|
||||
if self.ph:
|
||||
self.ph.capture(self.user_id, event_name, dict(properties))
|
||||
|
||||
@@ -193,6 +193,12 @@ def get_parser(default_config_files, git_root):
|
||||
default=".aider.model.metadata.json",
|
||||
help="Specify a file with context window and costs for unknown models",
|
||||
)
|
||||
group.add_argument(
|
||||
"--alias",
|
||||
action="append",
|
||||
metavar="ALIAS:MODEL",
|
||||
help="Add a model alias (can be used multiple times)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--verify-ssl",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
@@ -738,6 +744,12 @@ def get_parser(default_config_files, git_root):
|
||||
default=True,
|
||||
help="Enable/disable fancy input with history and completion (default: True)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--detect-urls",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=True,
|
||||
help="Enable/disable detection and offering to add URLs to chat (default: True)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--editor",
|
||||
help="Specify which editor to use for the /editor command",
|
||||
|
||||
@@ -37,6 +37,15 @@ from ..dump import dump # noqa: F401
|
||||
from .chat_chunks import ChatChunks
|
||||
|
||||
|
||||
class UnknownEditFormat(ValueError):
|
||||
def __init__(self, edit_format, valid_formats):
|
||||
self.edit_format = edit_format
|
||||
self.valid_formats = valid_formats
|
||||
super().__init__(
|
||||
f"Unknown edit format {edit_format}. Valid formats are: {', '.join(valid_formats)}"
|
||||
)
|
||||
|
||||
|
||||
class MissingAPIKeyError(ValueError):
|
||||
pass
|
||||
|
||||
@@ -91,6 +100,7 @@ class Coder:
|
||||
cache_warming_thread = None
|
||||
num_cache_warming_pings = 0
|
||||
suggest_shell_commands = True
|
||||
detect_urls = True
|
||||
ignore_mentions = None
|
||||
chat_language = None
|
||||
|
||||
@@ -156,7 +166,12 @@ class Coder:
|
||||
res.original_kwargs = dict(kwargs)
|
||||
return res
|
||||
|
||||
raise ValueError(f"Unknown edit format {edit_format}")
|
||||
valid_formats = [
|
||||
str(c.edit_format)
|
||||
for c in coders.__all__
|
||||
if hasattr(c, "edit_format") and c.edit_format is not None
|
||||
]
|
||||
raise UnknownEditFormat(edit_format, valid_formats)
|
||||
|
||||
def clone(self, **kwargs):
|
||||
new_coder = Coder.create(from_coder=self, **kwargs)
|
||||
@@ -267,6 +282,7 @@ class Coder:
|
||||
num_cache_warming_pings=0,
|
||||
suggest_shell_commands=True,
|
||||
chat_language=None,
|
||||
detect_urls=True,
|
||||
):
|
||||
# Fill in a dummy Analytics if needed, but it is never .enable()'d
|
||||
self.analytics = analytics if analytics is not None else Analytics()
|
||||
@@ -280,6 +296,7 @@ class Coder:
|
||||
self.ignore_mentions = set()
|
||||
|
||||
self.suggest_shell_commands = suggest_shell_commands
|
||||
self.detect_urls = detect_urls
|
||||
|
||||
self.num_cache_warming_pings = num_cache_warming_pings
|
||||
|
||||
@@ -812,6 +829,9 @@ class Coder:
|
||||
|
||||
def check_for_urls(self, inp: str) -> List[str]:
|
||||
"""Check input for URLs and offer to add them to the chat."""
|
||||
if not self.detect_urls:
|
||||
return []
|
||||
|
||||
url_pattern = re.compile(r"(https?://[^\s/$.?#].[^\s]*[^\s,.])")
|
||||
urls = list(set(url_pattern.findall(inp))) # Use set to remove duplicates
|
||||
added_urls = []
|
||||
@@ -1059,7 +1079,7 @@ class Coder:
|
||||
max_input_tokens = self.main_model.info.get("max_input_tokens") or 0
|
||||
# Add the reminder prompt if we still have room to include it.
|
||||
if (
|
||||
max_input_tokens is None
|
||||
not max_input_tokens
|
||||
or total_tokens < max_input_tokens
|
||||
and self.gpt_prompts.system_reminder
|
||||
):
|
||||
@@ -1405,9 +1425,18 @@ class Coder:
|
||||
|
||||
addable_rel_fnames = self.get_addable_relative_files()
|
||||
|
||||
# Get basenames of files already in chat or read-only
|
||||
existing_basenames = {os.path.basename(f) for f in self.get_inchat_relative_files()} | {
|
||||
os.path.basename(self.get_rel_fname(f)) for f in self.abs_read_only_fnames
|
||||
}
|
||||
|
||||
mentioned_rel_fnames = set()
|
||||
fname_to_rel_fnames = {}
|
||||
for rel_fname in addable_rel_fnames:
|
||||
# Skip files that share a basename with files already in chat
|
||||
if os.path.basename(rel_fname) in existing_basenames:
|
||||
continue
|
||||
|
||||
normalized_rel_fname = rel_fname.replace("\\", "/")
|
||||
normalized_words = set(word.replace("\\", "/") for word in words)
|
||||
if normalized_rel_fname in normalized_words:
|
||||
|
||||
@@ -1365,9 +1365,8 @@ class Commands:
|
||||
"Open an editor to write a prompt"
|
||||
|
||||
user_input = pipe_editor(initial_content, suffix="md", editor=self.editor)
|
||||
self.io.user_input(user_input, log_only=False)
|
||||
self.io.add_to_input_history(user_input)
|
||||
return user_input
|
||||
if user_input.strip():
|
||||
self.io.set_placeholder(user_input.rstrip())
|
||||
|
||||
|
||||
def expand_subdir(file_path):
|
||||
|
||||
14
aider/io.py
14
aider/io.py
@@ -198,6 +198,7 @@ class InputOutput:
|
||||
editingmode=EditingMode.EMACS,
|
||||
fancy_input=True,
|
||||
):
|
||||
self.placeholder = None
|
||||
self.never_prompts = set()
|
||||
self.editingmode = editingmode
|
||||
no_color = os.environ.get("NO_COLOR")
|
||||
@@ -427,8 +428,13 @@ class InputOutput:
|
||||
|
||||
try:
|
||||
if self.prompt_session:
|
||||
# Use placeholder if set, then clear it
|
||||
default = self.placeholder or ""
|
||||
self.placeholder = None
|
||||
|
||||
line = self.prompt_session.prompt(
|
||||
show,
|
||||
default=default,
|
||||
completer=completer_instance,
|
||||
reserve_space_for_menu=4,
|
||||
complete_style=CompleteStyle.MULTI_COLUMN,
|
||||
@@ -536,11 +542,11 @@ class InputOutput:
|
||||
hist = "\n" + content.strip() + "\n\n"
|
||||
self.append_chat_history(hist)
|
||||
|
||||
def offer_url(self, url, prompt="Open URL for more info?"):
|
||||
def offer_url(self, url, prompt="Open URL for more info?", allow_never=True):
|
||||
"""Offer to open a URL in the browser, returns True if opened."""
|
||||
if url in self.never_prompts:
|
||||
return False
|
||||
if self.confirm_ask(prompt, subject=url, allow_never=True):
|
||||
if self.confirm_ask(prompt, subject=url, allow_never=allow_never):
|
||||
webbrowser.open(url)
|
||||
return True
|
||||
return False
|
||||
@@ -739,6 +745,10 @@ class InputOutput:
|
||||
|
||||
self.console.print(show_resp)
|
||||
|
||||
def set_placeholder(self, placeholder):
|
||||
"""Set a one-time placeholder text for the next input prompt."""
|
||||
self.placeholder = placeholder
|
||||
|
||||
def print(self, message=""):
|
||||
print(message)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import sys
|
||||
import threading
|
||||
import traceback
|
||||
import webbrowser
|
||||
from dataclasses import fields
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
@@ -17,11 +18,13 @@ from aider import __version__, models, urls, utils
|
||||
from aider.analytics import Analytics
|
||||
from aider.args import get_parser
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import UnknownEditFormat
|
||||
from aider.commands import Commands, SwitchCoder
|
||||
from aider.format_settings import format_settings, scrub_sensitive_info
|
||||
from aider.history import ChatSummary
|
||||
from aider.io import InputOutput
|
||||
from aider.llm import litellm # noqa: F401; properly init litellm on launch
|
||||
from aider.models import ModelSettings
|
||||
from aider.repo import ANY_GIT_ERROR, GitRepo
|
||||
from aider.report import report_uncaught_exceptions
|
||||
from aider.versioncheck import check_version, install_from_main_branch, install_upgrade
|
||||
@@ -633,6 +636,18 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
register_models(git_root, args.model_settings_file, io, verbose=args.verbose)
|
||||
register_litellm_models(git_root, args.model_metadata_file, io, verbose=args.verbose)
|
||||
|
||||
# Process any command line aliases
|
||||
if args.alias:
|
||||
for alias_def in args.alias:
|
||||
# Split on first colon only
|
||||
parts = alias_def.split(":", 1)
|
||||
if len(parts) != 2:
|
||||
io.tool_error(f"Invalid alias format: {alias_def}")
|
||||
io.tool_output("Format should be: alias:model-name")
|
||||
return 1
|
||||
alias, model = parts
|
||||
models.MODEL_ALIASES[alias.strip()] = model.strip()
|
||||
|
||||
if not args.model:
|
||||
args.model = "gpt-4o-2024-08-06"
|
||||
if os.environ.get("ANTHROPIC_API_KEY"):
|
||||
@@ -646,9 +661,15 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
)
|
||||
|
||||
if args.verbose:
|
||||
io.tool_output("Model info:")
|
||||
io.tool_output("Model metadata:")
|
||||
io.tool_output(json.dumps(main_model.info, indent=4))
|
||||
|
||||
io.tool_output("Model settings:")
|
||||
for attr in sorted(fields(ModelSettings), key=lambda x: x.name):
|
||||
val = getattr(main_model, attr.name)
|
||||
val = json.dumps(val, indent=4)
|
||||
io.tool_output(f"{attr.name}: {val}")
|
||||
|
||||
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
|
||||
if lint_cmds is None:
|
||||
return 1
|
||||
@@ -743,7 +764,12 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
num_cache_warming_pings=args.cache_keepalive_pings,
|
||||
suggest_shell_commands=args.suggest_shell_commands,
|
||||
chat_language=args.chat_language,
|
||||
detect_urls=args.detect_urls,
|
||||
)
|
||||
except UnknownEditFormat as err:
|
||||
io.tool_error(str(err))
|
||||
io.offer_url(urls.edit_formats, "Open documentation about edit formats?")
|
||||
return 1
|
||||
except ValueError as err:
|
||||
io.tool_error(str(err))
|
||||
return 1
|
||||
@@ -805,17 +831,17 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
|
||||
io.tool_output('Use /help <question> for help, run "aider --help" to see cmd line args')
|
||||
|
||||
show = False
|
||||
if args.show_release_notes is True:
|
||||
show = True
|
||||
elif args.show_release_notes is None and is_first_run:
|
||||
io.tool_output()
|
||||
show = io.confirm_ask("Would you like to see what's new in this version?")
|
||||
|
||||
if show:
|
||||
io.tool_output(f"Opening release notes: {urls.release_notes}")
|
||||
io.tool_output()
|
||||
webbrowser.open(urls.release_notes)
|
||||
elif args.show_release_notes is None and is_first_run:
|
||||
io.tool_output()
|
||||
io.offer_url(
|
||||
urls.release_notes,
|
||||
"Would you like to see what's new in this version?",
|
||||
allow_never=False,
|
||||
)
|
||||
|
||||
if git_root and Path.cwd().resolve() != Path(git_root).resolve():
|
||||
io.tool_warning(
|
||||
|
||||
@@ -61,6 +61,23 @@ claude-3-5-sonnet-20241022
|
||||
|
||||
ANTHROPIC_MODELS = [ln.strip() for ln in ANTHROPIC_MODELS.splitlines() if ln.strip()]
|
||||
|
||||
# Mapping of model aliases to their canonical names
|
||||
MODEL_ALIASES = {
|
||||
# Claude models
|
||||
"sonnet": "claude-3-sonnet-20241022",
|
||||
"haiku": "claude-3-haiku-20241022",
|
||||
"opus": "claude-3-opus-20240229",
|
||||
# GPT models
|
||||
"4": "gpt-4-0613",
|
||||
"4o": "gpt-4o-2024-08-06",
|
||||
"4-turbo": "gpt-4-1106-preview",
|
||||
"35turbo": "gpt-3.5-turbo",
|
||||
"35-turbo": "gpt-3.5-turbo",
|
||||
"3": "gpt-3.5-turbo",
|
||||
# Other models
|
||||
"deepseek": "deepseek/deepseek-coder",
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class ModelSettings:
|
||||
@@ -711,6 +728,7 @@ MODEL_SETTINGS = [
|
||||
reminder="user",
|
||||
use_system_prompt=False,
|
||||
use_temperature=False,
|
||||
streaming=False,
|
||||
),
|
||||
ModelSettings(
|
||||
"openrouter/openai/o1-preview",
|
||||
@@ -722,6 +740,7 @@ MODEL_SETTINGS = [
|
||||
reminder="user",
|
||||
use_system_prompt=False,
|
||||
use_temperature=False,
|
||||
streaming=False,
|
||||
),
|
||||
ModelSettings(
|
||||
"openrouter/qwen/qwen-2.5-coder-32b-instruct",
|
||||
@@ -817,7 +836,8 @@ model_info_manager = ModelInfoManager()
|
||||
|
||||
class Model(ModelSettings):
|
||||
def __init__(self, model, weak_model=None, editor_model=None, editor_edit_format=None):
|
||||
self.name = model
|
||||
# Map any alias to its canonical name
|
||||
self.name = MODEL_ALIASES.get(model, model)
|
||||
self.max_chat_history_tokens = 1024
|
||||
self.weak_model = None
|
||||
self.editor_model = None
|
||||
@@ -933,10 +953,11 @@ class Model(ModelSettings):
|
||||
and ("2.5" in model or "2-5" in model)
|
||||
and "32b" in model
|
||||
):
|
||||
"openrouter/qwen/qwen-2.5-coder-32b-instruct",
|
||||
self.edit_format = "diff"
|
||||
self.editor_edit_format = "editor-diff"
|
||||
self.use_repo_map = True
|
||||
if model.startswith("ollama/") or model.startswith("ollama_chat/"):
|
||||
self.extra_params = dict(num_ctx=8 * 1024)
|
||||
return # <--
|
||||
|
||||
# use the defaults
|
||||
@@ -1099,6 +1120,9 @@ def register_models(model_settings_fnames):
|
||||
if not os.path.exists(model_settings_fname):
|
||||
continue
|
||||
|
||||
if not Path(model_settings_fname).read_text().strip():
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(model_settings_fname, "r") as model_settings_file:
|
||||
model_settings_list = yaml.safe_load(model_settings_file)
|
||||
|
||||
91
aider/queries/tree-sitter-dart-tags.scm
Normal file
91
aider/queries/tree-sitter-dart-tags.scm
Normal file
@@ -0,0 +1,91 @@
|
||||
(class_definition
|
||||
name: (identifier) @name.definition.class) @definition.class
|
||||
|
||||
(method_signature
|
||||
(function_signature)) @definition.method
|
||||
|
||||
(type_alias
|
||||
(type_identifier) @name.definition.type) @definition.type
|
||||
|
||||
(method_signature
|
||||
(getter_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(setter_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(function_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(factory_constructor_signature
|
||||
(identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(constructor_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(operator_signature)) @definition.method
|
||||
|
||||
(method_signature) @definition.method
|
||||
|
||||
(mixin_declaration
|
||||
(mixin)
|
||||
(identifier) @name.definition.mixin) @definition.mixin
|
||||
|
||||
(extension_declaration
|
||||
name: (identifier) @name.definition.extension) @definition.extension
|
||||
|
||||
(enum_declaration
|
||||
name: (identifier) @name.definition.enum) @definition.enum
|
||||
|
||||
(function_signature
|
||||
name: (identifier) @name.definition.function) @definition.function
|
||||
|
||||
(new_expression
|
||||
(type_identifier) @name.reference.class) @reference.class
|
||||
|
||||
(initialized_variable_definition
|
||||
name: (identifier)
|
||||
value: (identifier) @name.reference.class
|
||||
value: (selector
|
||||
"!"?
|
||||
(argument_part
|
||||
(arguments
|
||||
(argument)*))?)?) @reference.class
|
||||
|
||||
(assignment_expression
|
||||
left: (assignable_expression
|
||||
(identifier)
|
||||
(unconditional_assignable_selector
|
||||
"."
|
||||
(identifier) @name.reference.call))) @reference.call
|
||||
|
||||
(assignment_expression
|
||||
left: (assignable_expression
|
||||
(identifier)
|
||||
(conditional_assignable_selector
|
||||
"?."
|
||||
(identifier) @name.reference.call))) @reference.call
|
||||
|
||||
((identifier) @name
|
||||
(selector
|
||||
"!"?
|
||||
(conditional_assignable_selector
|
||||
"?." (identifier) @name.reference.call)?
|
||||
(unconditional_assignable_selector
|
||||
"."? (identifier) @name.reference.call)?
|
||||
(argument_part
|
||||
(arguments
|
||||
(argument)*))?)*
|
||||
(cascade_section
|
||||
(cascade_selector
|
||||
(identifier)) @name.reference.call
|
||||
(argument_part
|
||||
(arguments
|
||||
(argument)*))?)?) @reference.call
|
||||
|
||||
|
||||
@@ -13,3 +13,4 @@ git_index_version = "https://github.com/Aider-AI/aider/issues/211"
|
||||
install_properly = "https://aider.chat/docs/troubleshooting/imports.html"
|
||||
analytics = "https://aider.chat/docs/more/analytics.html"
|
||||
release_notes = "https://aider.chat/HISTORY.html#release-notes"
|
||||
edit_formats = "https://aider.chat/docs/more/edit-formats.html"
|
||||
|
||||
@@ -24,9 +24,26 @@ cog.out(text)
|
||||
]]]-->
|
||||
|
||||
|
||||
|
||||
### main branch
|
||||
|
||||
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
||||
- Added `--[no-]detect-urls` flag to disable detecting and offering to scrape URLs found in the chat.
|
||||
- Ollama models now default to an 8k context window.
|
||||
- Added [RepoMap support for Dart language](https://aider.chat/docs/languages.html) by @malkoG.
|
||||
- Ask 2.5% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
|
||||
- Skip suggesting files that share names with files already in chat.
|
||||
- `/editor` returns and prefill the file content into the prompt, so you can use `/editor` to compose messages that start with `/commands`, etc.
|
||||
- Enhanced error handling for analytics.
|
||||
- Improved handling of UnknownEditFormat exceptions with helpful documentation links.
|
||||
- Bumped dependencies to pick up grep-ast 0.4.0 for Dart language support.
|
||||
- Aider wrote 81% of the code in this release.
|
||||
|
||||
### Aider v0.64.1
|
||||
|
||||
- Disable streaming for o1 on OpenRouter.
|
||||
|
||||
### Aider v0.64.0
|
||||
|
||||
- Added [`/editor` command](https://aider.chat/docs/usage/commands.html) to open system editor for writing prompts, by @thehunmonkgroup.
|
||||
- Full support for `gpt-4o-2024-11-20`.
|
||||
- Stream o1 models by default.
|
||||
|
||||
@@ -2143,8 +2143,8 @@
|
||||
Paul Gauthier (aider): 201
|
||||
start_tag: v0.49.0
|
||||
total_lines: 324
|
||||
- aider_percentage: 56.18
|
||||
aider_total: 450
|
||||
- aider_percentage: 52.49
|
||||
aider_total: 580
|
||||
end_date: '2024-08-20'
|
||||
end_tag: v0.51.0
|
||||
file_counts:
|
||||
@@ -2178,6 +2178,12 @@
|
||||
Paul Gauthier: 3
|
||||
aider/utils.py:
|
||||
Paul Gauthier (aider): 6
|
||||
aider/website/_includes/code-in-json-benchmark.js:
|
||||
Paul Gauthier: 101
|
||||
Paul Gauthier (aider): 64
|
||||
aider/website/_includes/code-in-json-syntax.js:
|
||||
Paul Gauthier: 73
|
||||
Paul Gauthier (aider): 66
|
||||
aider/website/docs/leaderboards/index.md:
|
||||
Paul Gauthier: 1
|
||||
benchmark/benchmark.py:
|
||||
@@ -2198,10 +2204,10 @@
|
||||
Paul Gauthier: 15
|
||||
Paul Gauthier (aider): 104
|
||||
grand_total:
|
||||
Paul Gauthier: 351
|
||||
Paul Gauthier (aider): 450
|
||||
Paul Gauthier: 525
|
||||
Paul Gauthier (aider): 580
|
||||
start_tag: v0.50.0
|
||||
total_lines: 801
|
||||
total_lines: 1105
|
||||
- aider_percentage: 68.1
|
||||
aider_total: 521
|
||||
end_date: '2024-08-23'
|
||||
@@ -2267,8 +2273,8 @@
|
||||
pcamp: 1
|
||||
start_tag: v0.51.0
|
||||
total_lines: 765
|
||||
- aider_percentage: 58.61
|
||||
aider_total: 405
|
||||
- aider_percentage: 61.4
|
||||
aider_total: 455
|
||||
end_date: '2024-08-27'
|
||||
end_tag: v0.53.0
|
||||
file_counts:
|
||||
@@ -2333,13 +2339,15 @@
|
||||
tests/basic/test_repomap.py:
|
||||
Paul Gauthier: 4
|
||||
Paul Gauthier (aider): 63
|
||||
tests/fixtures/sample-code-base/sample.js:
|
||||
Paul Gauthier (aider): 50
|
||||
tests/fixtures/sample-code-base/sample.py:
|
||||
Paul Gauthier (aider): 68
|
||||
grand_total:
|
||||
Paul Gauthier: 286
|
||||
Paul Gauthier (aider): 405
|
||||
Paul Gauthier (aider): 455
|
||||
start_tag: v0.52.0
|
||||
total_lines: 691
|
||||
total_lines: 741
|
||||
- aider_percentage: 63.75
|
||||
aider_total: 204
|
||||
end_date: '2024-08-28'
|
||||
@@ -3013,3 +3021,88 @@
|
||||
Paul Gauthier (aider): 385
|
||||
start_tag: v0.62.0
|
||||
total_lines: 699
|
||||
- aider_percentage: 73.15
|
||||
aider_total: 880
|
||||
end_date: '2024-11-21'
|
||||
end_tag: v0.64.0
|
||||
file_counts:
|
||||
aider/__init__.py:
|
||||
Paul Gauthier: 1
|
||||
aider/analytics.py:
|
||||
Paul Gauthier: 20
|
||||
Paul Gauthier (aider): 21
|
||||
aider/args.py:
|
||||
Paul Gauthier: 2
|
||||
Paul Gauthier (aider): 10
|
||||
aider/coders/base_coder.py:
|
||||
Paul Gauthier: 15
|
||||
Paul Gauthier (aider): 3
|
||||
caetanominuzzo: 1
|
||||
aider/commands.py:
|
||||
Chad Phillips: 4
|
||||
Paul Gauthier: 5
|
||||
Paul Gauthier (aider): 19
|
||||
aider/editor.py:
|
||||
Chad Phillips: 133
|
||||
Paul Gauthier (aider): 13
|
||||
aider/exceptions.py:
|
||||
Paul Gauthier: 5
|
||||
aider/help_pats.py:
|
||||
Paul Gauthier: 1
|
||||
aider/io.py:
|
||||
Chad Phillips: 9
|
||||
Paul Gauthier (aider): 41
|
||||
mw: 21
|
||||
aider/main.py:
|
||||
Paul Gauthier: 21
|
||||
Paul Gauthier (aider): 41
|
||||
aider/models.py:
|
||||
Paul Gauthier: 41
|
||||
Paul Gauthier (aider): 33
|
||||
aider/repo.py:
|
||||
Paul Gauthier (aider): 5
|
||||
aider/urls.py:
|
||||
Paul Gauthier: 1
|
||||
aider/website/_includes/edit-leaderboard.js:
|
||||
Paul Gauthier (aider): 97
|
||||
aider/website/_includes/quant-chart.js:
|
||||
Paul Gauthier: 3
|
||||
Paul Gauthier (aider): 66
|
||||
aider/website/_includes/refactor-leaderboard.js:
|
||||
Paul Gauthier (aider): 90
|
||||
aider/website/docs/leaderboards/index.md:
|
||||
Paul Gauthier: 1
|
||||
Paul Gauthier (aider): 10
|
||||
aider/website/share/index.md:
|
||||
Paul Gauthier (aider): 29
|
||||
benchmark/over_time.py:
|
||||
Paul Gauthier: 11
|
||||
Paul Gauthier (aider): 162
|
||||
scripts/blame.py:
|
||||
Paul Gauthier: 1
|
||||
Paul Gauthier (aider): 2
|
||||
scripts/issues.py:
|
||||
Paul Gauthier: 5
|
||||
Paul Gauthier (aider): 12
|
||||
scripts/versionbump.py:
|
||||
Paul Gauthier: 7
|
||||
tests/basic/test_analytics.py:
|
||||
Paul Gauthier: 12
|
||||
Paul Gauthier (aider): 30
|
||||
tests/basic/test_commands.py:
|
||||
Paul Gauthier (aider): 4
|
||||
tests/basic/test_editor.py:
|
||||
Paul Gauthier (aider): 129
|
||||
tests/basic/test_main.py:
|
||||
Paul Gauthier (aider): 8
|
||||
tests/basic/test_models.py:
|
||||
Paul Gauthier: 3
|
||||
Paul Gauthier (aider): 55
|
||||
grand_total:
|
||||
Chad Phillips: 146
|
||||
Paul Gauthier: 155
|
||||
Paul Gauthier (aider): 880
|
||||
caetanominuzzo: 1
|
||||
mw: 21
|
||||
start_tag: v0.63.0
|
||||
total_lines: 1203
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
|
||||
- dirname: 2024-05-03-20-47-24--gemini-1.5-pro-diff-fenced
|
||||
test_cases: 133
|
||||
model: gemini-1.5-pro-latest
|
||||
released: 2024-05-03
|
||||
model: gemini-1.5-pro-001
|
||||
edit_format: diff-fenced
|
||||
commit_hash: 3a48dfb, 5d32dd7
|
||||
pass_rate_1: 45.9
|
||||
@@ -410,6 +411,7 @@
|
||||
- dirname: 2024-06-08-22-37-55--qwen2-72b-instruct-whole
|
||||
test_cases: 133
|
||||
model: Qwen2 72B Instruct
|
||||
released: 2024-06-08
|
||||
edit_format: whole
|
||||
commit_hash: 02c7335-dirty, 1a97498-dirty
|
||||
pass_rate_1: 44.4
|
||||
@@ -835,6 +837,7 @@
|
||||
- dirname: 2024-08-28-07-10-50--gemini-1.5-pro-exp-0827-diff-fenced
|
||||
test_cases: 133
|
||||
model: gemini-1.5-pro-exp-0827
|
||||
released: 2024-08-27
|
||||
edit_format: diff-fenced
|
||||
commit_hash: d8adc75
|
||||
pass_rate_1: 54.9
|
||||
@@ -1206,6 +1209,7 @@
|
||||
- dirname: 2024-09-24-16-26-45--gemini-1.5-pro-002-diff-fenced
|
||||
test_cases: 133
|
||||
model: gemini-1.5-pro-002
|
||||
released: 2024-09-24
|
||||
edit_format: diff-fenced
|
||||
commit_hash: 6b5fe9b, 3edcd71
|
||||
pass_rate_1: 49.6
|
||||
@@ -1796,7 +1800,7 @@
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
|
||||
command: aider --model openai/hf:Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://glhf.chat/api/openai/v1
|
||||
date: 2024-11-09
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 22.5
|
||||
@@ -1894,4 +1898,51 @@
|
||||
date: 2024-11-20
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 40.7
|
||||
total_cost: 0.1497
|
||||
total_cost: 0.1497
|
||||
|
||||
- dirname: 2024-11-21-17-46-36--gemini-exp-1121-diff
|
||||
test_cases: 133
|
||||
model: gemini-exp-1121
|
||||
released: 2024-11-21
|
||||
edit_format: diff
|
||||
commit_hash: e94961a
|
||||
pass_rate_1: 46.6
|
||||
pass_rate_2: 57.9
|
||||
percent_cases_well_formed: 83.5
|
||||
error_outputs: 101
|
||||
num_malformed_responses: 101
|
||||
num_with_malformed_responses: 22
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 2
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model gemini/gemini-exp-1121
|
||||
date: 2024-11-21
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 60.3
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-15-20-33-31--gemini-exp-1114-diff
|
||||
test_cases: 133
|
||||
model: gemini-exp-1114
|
||||
released: 2024-11-14
|
||||
edit_format: diff
|
||||
commit_hash: 0bf17a4
|
||||
pass_rate_1: 50.4
|
||||
pass_rate_2: 60.9
|
||||
percent_cases_well_formed: 85.7
|
||||
error_outputs: 70
|
||||
num_malformed_responses: 70
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 2
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 4
|
||||
command: aider --model gemini/gemini-exp-1114
|
||||
date: 2024-11-15
|
||||
versions: 0.63.2.dev
|
||||
seconds_per_case: 38.6
|
||||
@@ -1,6 +1,6 @@
|
||||
- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct
|
||||
test_cases: 133
|
||||
model: HuggingFace weights via glhf.chat
|
||||
model: "HuggingFace via GLHF: BF16"
|
||||
released: 2024-11-12
|
||||
edit_format: diff
|
||||
commit_hash: ec9982a
|
||||
@@ -16,78 +16,284 @@
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
|
||||
command: aider --model openai/hf:Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://glhf.chat/api/openai/v1
|
||||
date: 2024-11-09
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 22.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-20-15-17-37--qwen25-32b-or-diff
|
||||
test_cases: 133
|
||||
model: openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
- dirname: 2024-11-22-18-56-13--ollama-qwen2.5-coder:32b-instruct-fp16
|
||||
test_cases: 132
|
||||
model: "Ollama: fp16"
|
||||
edit_format: diff
|
||||
commit_hash: e917424
|
||||
pass_rate_1: 49.6
|
||||
pass_rate_2: 65.4
|
||||
percent_cases_well_formed: 84.2
|
||||
error_outputs: 43
|
||||
num_malformed_responses: 31
|
||||
num_with_malformed_responses: 21
|
||||
user_asks: 43
|
||||
lazy_comments: 0
|
||||
syntax_errors: 2
|
||||
indentation_errors: 2
|
||||
exhausted_context_windows: 12
|
||||
test_timeouts: 2
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-20
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 40.7
|
||||
total_cost: 0.1497
|
||||
|
||||
- dirname: 2024-09-20-21-47-17--qwen2.5-32b-instruct-q8_0-whole
|
||||
test_cases: 133
|
||||
model: ollama/qwen2.5:32b-instruct-q8_0
|
||||
edit_format: whole
|
||||
commit_hash: 2753ac6
|
||||
pass_rate_1: 46.6
|
||||
pass_rate_2: 58.6
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 1
|
||||
commit_hash: f06452c-dirty, 6a0a97c-dirty, 4e9ae16-dirty, 5506d0f-dirty
|
||||
pass_rate_1: 58.3
|
||||
pass_rate_2: 71.4
|
||||
percent_cases_well_formed: 90.2
|
||||
error_outputs: 27
|
||||
num_malformed_responses: 26
|
||||
num_with_malformed_responses: 13
|
||||
user_asks: 2
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 0
|
||||
command: aider --model ollama/qwen2.5-coder:32b-instruct-fp16
|
||||
date: 2024-11-22
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 119.6
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-22-14-53-26--hyperbolic-qwen25coder32binstruct
|
||||
test_cases: 133
|
||||
model: "Hyperbolic: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: f9ef161, 17aef7b-dirty
|
||||
pass_rate_1: 57.9
|
||||
pass_rate_2: 69.2
|
||||
percent_cases_well_formed: 91.7
|
||||
error_outputs: 30
|
||||
num_malformed_responses: 29
|
||||
num_with_malformed_responses: 11
|
||||
user_asks: 9
|
||||
lazy_comments: 0
|
||||
syntax_errors: 4
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
command: aider --model ollama/qwen2.5:32b-instruct-q8_0
|
||||
date: 2024-09-20
|
||||
versions: 0.56.1.dev
|
||||
seconds_per_case: 1763.7
|
||||
command: aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://api.hyperbolic.xyz/v1/
|
||||
date: 2024-11-22
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 33.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-22-17-53-35--qwen25-coder-32b-Instruct-4bit
|
||||
test_cases: 133
|
||||
model: "mlx-community: 4bit"
|
||||
edit_format: diff
|
||||
commit_hash: a16dcab-dirty
|
||||
pass_rate_1: 60.2
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 88.7
|
||||
error_outputs: 31
|
||||
num_malformed_responses: 30
|
||||
num_with_malformed_responses: 15
|
||||
user_asks: 6
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 0
|
||||
command: aider --model openai/mlx-community/Qwen2.5-Coder-32B-Instruct-4bit
|
||||
date: 2024-11-23
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 53.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-09-30-14-09-43--qwen2.5-32b-whole-2
|
||||
- dirname: 2024-11-23-15-07-20--qwen25-coder-32b-Instruct-8bit
|
||||
test_cases: 133
|
||||
model: ollama/qwen2.5:32b
|
||||
edit_format: whole
|
||||
commit_hash: 765c4cb
|
||||
pass_rate_1: 44.4
|
||||
pass_rate_2: 54.1
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 9
|
||||
model: "mlx-community: 8bit"
|
||||
edit_format: diff
|
||||
commit_hash: a16dcab-dirty
|
||||
pass_rate_1: 59.4
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 92.5
|
||||
error_outputs: 20
|
||||
num_malformed_responses: 15
|
||||
num_with_malformed_responses: 10
|
||||
user_asks: 7
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 2
|
||||
command: aider --model openai/mlx-community/Qwen2.5-Coder-32B-Instruct-8bit
|
||||
date: 2024-11-23
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 98.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-22-18-18--or-all-or-fixed-blank-messages2
|
||||
test_cases: 133
|
||||
model: "OpenRouter: multiple"
|
||||
edit_format: diff
|
||||
commit_hash: 0c59d32
|
||||
pass_rate_1: 57.1
|
||||
pass_rate_2: 67.7
|
||||
percent_cases_well_formed: 95.5
|
||||
error_outputs: 56
|
||||
num_malformed_responses: 10
|
||||
num_with_malformed_responses: 6
|
||||
user_asks: 14
|
||||
lazy_comments: 0
|
||||
syntax_errors: 6
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 3
|
||||
test_timeouts: 1
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 21.2
|
||||
total_cost: 0.1420
|
||||
|
||||
- dirname: 2024-11-23-21-08-53--ollama-qwen2.5-coder:32b-instruct-q4_K_M-8kctx
|
||||
test_cases: 133
|
||||
model: "Ollama: q4_K_M"
|
||||
edit_format: diff
|
||||
commit_hash: baa1335-dirty, e63df83-dirty, ff8c1aa-dirty
|
||||
pass_rate_1: 54.9
|
||||
pass_rate_2: 66.9
|
||||
percent_cases_well_formed: 94.0
|
||||
error_outputs: 21
|
||||
num_malformed_responses: 21
|
||||
num_with_malformed_responses: 8
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model ollama/qwen2.5:32b
|
||||
date: 2024-09-30
|
||||
versions: 0.58.1.dev
|
||||
seconds_per_case: 134.9
|
||||
command: aider --model ollama/qwen2.5-coder:32b-instruct-q4_K_M
|
||||
date: 2024-11-23
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 35.7
|
||||
total_cost: 0.0000
|
||||
|
||||
|
||||
- dirname: 2024-11-24-02-23-32--deepinfra-qwen-diff
|
||||
test_cases: 133
|
||||
model: "Deepinfra: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: bb78e2f
|
||||
pass_rate_1: 58.6
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 94.7
|
||||
error_outputs: 15
|
||||
num_malformed_responses: 13
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 3
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 2
|
||||
test_timeouts: 3
|
||||
command: aider --model deepinfra/Qwen/Qwen2.5-Coder-32B-Instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 17.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-04-12-58--fireworks-qwen-diff
|
||||
test_cases: 133
|
||||
model: "Fireworks: unknown"
|
||||
edit_format: diff
|
||||
commit_hash: 757eac0
|
||||
pass_rate_1: 57.9
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 94.0
|
||||
error_outputs: 23
|
||||
num_malformed_responses: 19
|
||||
num_with_malformed_responses: 8
|
||||
user_asks: 8
|
||||
lazy_comments: 0
|
||||
syntax_errors: 6
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 1
|
||||
command: aider --model fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 10.4
|
||||
total_cost: 0.5759
|
||||
|
||||
- dirname: 2024-11-24-02-04-59--ollama-qwen2.5-coder:32b-instruct-q2_K-8kctx
|
||||
test_cases: 133
|
||||
model: "Ollama: q2_K"
|
||||
edit_format: diff
|
||||
commit_hash: 757eac0, bb78e2f, 8d0ba40-dirty, 1d09e96
|
||||
pass_rate_1: 48.9
|
||||
pass_rate_2: 61.7
|
||||
percent_cases_well_formed: 91.7
|
||||
error_outputs: 32
|
||||
num_malformed_responses: 32
|
||||
num_with_malformed_responses: 11
|
||||
user_asks: 8
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 1
|
||||
command: aider --model ollama/qwen2.5-coder:32b-instruct-q2_K
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 97.8
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-14-56-49--qwen25-32b-or-fireworks
|
||||
test_cases: 133
|
||||
model: "Fireworks via OpenRouter: unknown"
|
||||
edit_format: diff
|
||||
commit_hash: c2f184f
|
||||
pass_rate_1: 55.6
|
||||
pass_rate_2: 67.7
|
||||
percent_cases_well_formed: 94.0
|
||||
error_outputs: 39
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 8
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 1
|
||||
indentation_errors: 1
|
||||
exhausted_context_windows: 7
|
||||
test_timeouts: 4
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 16.1
|
||||
total_cost: 0.1391
|
||||
|
||||
- dirname: 2024-11-24-22-03-19--or-hyperbolic-or-fixed-blank-messages2
|
||||
test_cases: 133
|
||||
model: "Hyperbolic via OpenRouter: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: 0c59d32
|
||||
pass_rate_1: 55.6
|
||||
pass_rate_2: 68.4
|
||||
percent_cases_well_formed: 89.5
|
||||
error_outputs: 28
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 14
|
||||
user_asks: 29
|
||||
lazy_comments: 0
|
||||
syntax_errors: 1
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 1
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 41.5
|
||||
total_cost: 0.1402
|
||||
|
||||
- dirname: 2024-11-24-15-00-50--qwen25-32b-or-deepinfra
|
||||
test_cases: 133
|
||||
model: "Deepinfra via OpenRouter: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: c2f184f
|
||||
pass_rate_1: 57.1
|
||||
pass_rate_2: 69.9
|
||||
percent_cases_well_formed: 89.5
|
||||
error_outputs: 35
|
||||
num_malformed_responses: 31
|
||||
num_with_malformed_responses: 14
|
||||
user_asks: 11
|
||||
lazy_comments: 0
|
||||
syntax_errors: 1
|
||||
indentation_errors: 1
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 1
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 28.5
|
||||
total_cost: 0.1390
|
||||
@@ -1,16 +1,5 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var ctx = document.getElementById('quantChart').getContext('2d');
|
||||
var chartData = {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: [],
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
|
||||
var allData = [];
|
||||
{% for row in site.data.quant %}
|
||||
allData.push({
|
||||
@@ -19,51 +8,88 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
{% endfor %}
|
||||
|
||||
allData.forEach(function(row) {
|
||||
chartData.labels.push(row.model);
|
||||
chartData.datasets[0].data.push(row.pass_rate_2);
|
||||
});
|
||||
// Sort data by pass_rate_2 in descending order
|
||||
allData.sort((a, b) => b.pass_rate_2 - a.pass_rate_2);
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: chartData,
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Aider coder editing benchmark',
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Percent completed correctly',
|
||||
font: {
|
||||
size: 14
|
||||
var chart;
|
||||
|
||||
function updateChart(filterText) {
|
||||
var filteredData = allData.filter(row =>
|
||||
row.model.toLowerCase().includes(filterText.toLowerCase())
|
||||
);
|
||||
|
||||
var chartData = {
|
||||
labels: filteredData.map(row => row.model),
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: filteredData.map(row => row.pass_rate_2),
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
|
||||
if (chart) {
|
||||
chart.data = chartData;
|
||||
chart.update();
|
||||
} else {
|
||||
chart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: chartData,
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Aider code editing benchmark',
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
ticks: {
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 16
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Percent completed correctly',
|
||||
font: {
|
||||
size: 14
|
||||
}
|
||||
},
|
||||
ticks: {
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Provider: quantization',
|
||||
font: {
|
||||
size: 14
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initial chart render
|
||||
updateChart('');
|
||||
|
||||
// Connect search input to chart filtering
|
||||
document.getElementById('quantSearchInput').addEventListener('keyup', function() {
|
||||
updateChart(this.value);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Quantization matters
|
||||
excerpt: Open source LLMs are becoming very powerful, but pay attention to how you (or your provider) is quantizing the model. It can strongly affect code editing skill.
|
||||
title: Details matter with open source models
|
||||
excerpt: Open source LLMs are becoming very powerful, but pay attention to how you (or your provider) are serving the model. It can affect code editing skill.
|
||||
highlight_image: /assets/quantization.jpg
|
||||
draft: false
|
||||
nav_exclude: true
|
||||
@@ -9,35 +9,161 @@ nav_exclude: true
|
||||
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
|
||||
{% endif %}
|
||||
|
||||
# Quantization matters
|
||||
# Details matter with open source models
|
||||
{: .no_toc }
|
||||
|
||||
Open source models like Qwen 2.5 32B are performing very well on
|
||||
Open source models like Qwen 2.5 32B Instruct are performing very well on
|
||||
aider's code editing benchmark, rivaling closed source frontier models.
|
||||
But pay attention to how your model is being quantized, as it
|
||||
can strongly impact code editing skill.
|
||||
Heavily quantized models are often used by cloud API providers
|
||||
and local model servers like Ollama.
|
||||
|
||||
<canvas id="quantChart" width="800" height="450" style="margin: 20px 0"></canvas>
|
||||
But pay attention to how your model is being served and quantized,
|
||||
as it can impact code editing skill.
|
||||
Open source models are often available at a variety of quantizations,
|
||||
and can be served with different token limits.
|
||||
These details matter when working with code.
|
||||
|
||||
The graph and table below compares different versions of the Qwen 2.5 Coder 32B Instruct model,
|
||||
served both locally and from a variety of cloud providers.
|
||||
|
||||
- The [HuggingFace BF16 weights](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct) served via [glhf.chat](https://glhf.chat).
|
||||
- [4bit and 8bit quants for mlx](https://t.co/cwX3DYX35D).
|
||||
- The results from [OpenRouter's mix of providers](https://openrouter.ai/qwen/qwen-2.5-coder-32b-instruct/providers) which serve the model with different levels of quantization.
|
||||
- Results from individual providers served via OpenRouter and directly to their own APIs.
|
||||
- Ollama locally serving different quantizations from the [Ollama model library](https://ollama.com/library/qwen2.5-coder:32b-instruct-q4_K_M).
|
||||
|
||||
The best versions of the model rival GPT-4o, while the worst performer
|
||||
is more like the older GPT-4 Turbo.
|
||||
Suboptimal choices in quantization and token limits can
|
||||
easily produce far worse results.
|
||||
|
||||
This benchmarking effort highlighted a number of pitfalls and details which
|
||||
can have a significant impact on the model's ability to correctly edit code:
|
||||
|
||||
- Quantization -- Open source models are often available at dozens of different quantizations.
|
||||
- Context window -- Cloud providers can decide how large a context window to accept,
|
||||
and they often choose differently. Ollama defaults to a tiny 2k context window,
|
||||
and silently discards data that exceeds it.
|
||||
- Output token limits -- Open source models are often served with wildly
|
||||
differing output token limits. This has a direct impact on how much code the
|
||||
model can write or edit in a response.
|
||||
- Buggy cloud providers -- Between Qwen and DeepSeep, there were
|
||||
multiple cloud providers with broken or buggy API endpoints that seemed
|
||||
to be returning result different from expected based on the advertised
|
||||
quantization and context sizes.
|
||||
|
||||
|
||||
### Sections
|
||||
{: .no_toc }
|
||||
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
## Benchmark results
|
||||
|
||||
<canvas id="quantChart" width="800" height="600" style="margin: 20px 0"></canvas>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
{% include quant-chart.js %}
|
||||
</script>
|
||||
|
||||
The graph above compares 4 different versions of the Qwen 2.5 32B model,
|
||||
served both locally and from cloud providers.
|
||||
<input type="text" id="quantSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
|
||||
|
||||
- The [HuggingFace weights](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct) served via [glhf.chat](https://glhf.chat).
|
||||
- The results from [OpenRouter's mix of providers](https://openrouter.ai/qwen/qwen-2.5-coder-32b-instruct/providers).
|
||||
- Two Ollama models run locally.
|
||||
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
|
||||
<thead style="background-color: #f2f2f2;">
|
||||
<tr>
|
||||
<th style="padding: 8px; text-align: left;">Model</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
|
||||
<th style="padding: 8px; text-align: left;">Command</th>
|
||||
<th style="padding: 8px; text-align: center;">Edit format</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% assign quant_sorted = site.data.quant | sort: 'pass_rate_2' | reverse %}
|
||||
{% for row in quant_sorted %}
|
||||
<tr style="border-bottom: 1px solid #ddd;">
|
||||
<td style="padding: 8px;">{{ row.model }}</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_2 }}%</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
|
||||
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
The best version of the model rivals GPT-4o, while the worst performer
|
||||
is more like GPT-3.5 Turbo.
|
||||
<style>
|
||||
tr.selected {
|
||||
color: #0056b3;
|
||||
}
|
||||
table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
td, th {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
td:nth-child(3), td:nth-child(4) {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
document.getElementById('quantSearchInput').addEventListener('keyup', function() {
|
||||
var input = this.value.toLowerCase();
|
||||
var rows = document.querySelectorAll('tbody tr');
|
||||
|
||||
rows.forEach(function(row) {
|
||||
var text = row.textContent.toLowerCase();
|
||||
if(text.includes(input)) {
|
||||
row.style.display = '';
|
||||
row.classList.add('selected');
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
row.classList.remove('selected');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
## Setting Ollama's context window size
|
||||
|
||||
[Ollama uses a 2k context window by default](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-specify-the-context-window-size),
|
||||
which is very small for working with aider.
|
||||
Unlike most other LLM servers, Ollama does not throw an error if you submit
|
||||
a request that exceeds the context window.
|
||||
Instead, it just silently truncates the request by discarding the "oldest" messages
|
||||
in the chat to make it fit within the context window.
|
||||
|
||||
All of the Ollama results above were collected with at least an 8k context window, which
|
||||
is large enough to attempt all the coding problems in the benchmark.
|
||||
Aider sets Ollama's context window to 8k by default.
|
||||
|
||||
You can change the Ollama server's context window with a
|
||||
[`.aider.model.settings.yml` file](https://aider.chat/docs/config/adv-model-settings.html#model-settings)
|
||||
like this:
|
||||
|
||||
```
|
||||
- name: ollama/qwen2.5-coder:32b-instruct-fp16
|
||||
extra_params:
|
||||
num_ctx: 8192
|
||||
```
|
||||
|
||||
## Choosing providers with OpenRouter
|
||||
|
||||
OpenRouter allows you to ignore specific providers in your
|
||||
[preferences](https://openrouter.ai/settings/preferences).
|
||||
This can be effective to exclude highly quantized or otherwise
|
||||
undesirable providers.
|
||||
This can be used to limit your OpenRouter requests to be
|
||||
served by only your preferred providers.
|
||||
|
||||
## Notes
|
||||
|
||||
This article went through many revisions as I received feedback from
|
||||
numerous members of the community.
|
||||
Here are some of the noteworthy learnings and changes:
|
||||
|
||||
- The first version of this article included incorrect Ollama models.
|
||||
- Earlier Ollama results used the too small default 2k context window,
|
||||
artificially harming the benchmark results.
|
||||
- The benchmark results appear to have uncovered a problem in the way
|
||||
OpenRouter was communicating with Hyperbolic.
|
||||
They fixed the issue 11/24/24, shortly after it was pointed out.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 103 KiB |
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 59 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 148 KiB |
File diff suppressed because it is too large
Load Diff
@@ -86,6 +86,14 @@
|
||||
## Specify a file with context window and costs for unknown models
|
||||
#model-metadata-file: .aider.model.metadata.json
|
||||
|
||||
## Add a model alias (can be used multiple times)
|
||||
#alias: xxx
|
||||
## Specify multiple values like this:
|
||||
#alias:
|
||||
# - xxx
|
||||
# - yyy
|
||||
# - zzz
|
||||
|
||||
## Verify the SSL cert when connecting to models (default: True)
|
||||
#verify-ssl: true
|
||||
|
||||
@@ -368,6 +376,9 @@
|
||||
## Enable/disable fancy input with history and completion (default: True)
|
||||
#fancy-input: true
|
||||
|
||||
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
#detect-urls: true
|
||||
|
||||
## Specify which editor to use for the /editor command
|
||||
#editor: xxx
|
||||
|
||||
|
||||
@@ -90,6 +90,9 @@
|
||||
## Specify a file with context window and costs for unknown models
|
||||
#AIDER_MODEL_METADATA_FILE=.aider.model.metadata.json
|
||||
|
||||
## Add a model alias (can be used multiple times)
|
||||
#AIDER_ALIAS=
|
||||
|
||||
## Verify the SSL cert when connecting to models (default: True)
|
||||
#AIDER_VERIFY_SSL=true
|
||||
|
||||
@@ -351,6 +354,9 @@
|
||||
## Enable/disable fancy input with history and completion (default: True)
|
||||
#AIDER_FANCY_INPUT=true
|
||||
|
||||
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
#AIDER_DETECT_URLS=true
|
||||
|
||||
## Specify which editor to use for the /editor command
|
||||
#AIDER_EDITOR=
|
||||
|
||||
|
||||
@@ -11,6 +11,13 @@ description: Configuring advanced settings for LLMs.
|
||||
In most cases, you can safely ignore aider's warning about unknown context
|
||||
window size and model costs.
|
||||
|
||||
{: .note }
|
||||
Aider never *enforces* token limits, it only *reports* token limit errors
|
||||
from the API provider.
|
||||
You probably don't need to
|
||||
configure aider with the proper token limits
|
||||
for unusual models.
|
||||
|
||||
But, you can register context window limits and costs for models that aren't known
|
||||
to aider. Create a `.aider.model.metadata.json` file in one of these locations:
|
||||
|
||||
@@ -1209,7 +1216,7 @@ cog.out("```\n")
|
||||
name: openrouter/openai/o1-mini
|
||||
reminder: user
|
||||
send_undo_reply: false
|
||||
streaming: true
|
||||
streaming: false
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
@@ -1225,7 +1232,7 @@ cog.out("```\n")
|
||||
name: openrouter/openai/o1-preview
|
||||
reminder: user
|
||||
send_undo_reply: false
|
||||
streaming: true
|
||||
streaming: false
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
|
||||
@@ -142,6 +142,14 @@ cog.outl("```")
|
||||
## Specify a file with context window and costs for unknown models
|
||||
#model-metadata-file: .aider.model.metadata.json
|
||||
|
||||
## Add a model alias (can be used multiple times)
|
||||
#alias: xxx
|
||||
## Specify multiple values like this:
|
||||
#alias:
|
||||
# - xxx
|
||||
# - yyy
|
||||
# - zzz
|
||||
|
||||
## Verify the SSL cert when connecting to models (default: True)
|
||||
#verify-ssl: true
|
||||
|
||||
@@ -424,6 +432,9 @@ cog.outl("```")
|
||||
## Enable/disable fancy input with history and completion (default: True)
|
||||
#fancy-input: true
|
||||
|
||||
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
#detect-urls: true
|
||||
|
||||
## Specify which editor to use for the /editor command
|
||||
#editor: xxx
|
||||
|
||||
|
||||
@@ -132,6 +132,9 @@ cog.outl("```")
|
||||
## Specify a file with context window and costs for unknown models
|
||||
#AIDER_MODEL_METADATA_FILE=.aider.model.metadata.json
|
||||
|
||||
## Add a model alias (can be used multiple times)
|
||||
#AIDER_ALIAS=
|
||||
|
||||
## Verify the SSL cert when connecting to models (default: True)
|
||||
#AIDER_VERIFY_SSL=true
|
||||
|
||||
@@ -393,6 +396,9 @@ cog.outl("```")
|
||||
## Enable/disable fancy input with history and completion (default: True)
|
||||
#AIDER_FANCY_INPUT=true
|
||||
|
||||
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
#AIDER_DETECT_URLS=true
|
||||
|
||||
## Specify which editor to use for the /editor command
|
||||
#AIDER_EDITOR=
|
||||
|
||||
|
||||
72
aider/website/docs/config/model-aliases.md
Normal file
72
aider/website/docs/config/model-aliases.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
parent: Configuration
|
||||
nav_order: 1000
|
||||
description: Assign convenient short names to models.
|
||||
---
|
||||
|
||||
# Model Aliases
|
||||
|
||||
Model aliases allow you to create shorthand names for models you frequently use. This is particularly useful for models with long names or when you want to standardize model usage across your team.
|
||||
|
||||
## Command Line Usage
|
||||
|
||||
You can define aliases when launching aider using the `--alias` option:
|
||||
|
||||
```bash
|
||||
aider --alias "fast:gpt-3.5-turbo" --alias "smart:gpt-4"
|
||||
```
|
||||
|
||||
Multiple aliases can be defined by using the `--alias` option multiple times. Each alias definition should be in the format `alias:model-name`.
|
||||
|
||||
## Configuration File
|
||||
|
||||
You can also define aliases in your [`.aider.conf.yml` file](https://aider.chat/docs/config/aider_conf.html):
|
||||
|
||||
```yaml
|
||||
alias:
|
||||
- "fast:gpt-3.5-turbo"
|
||||
- "smart:gpt-4"
|
||||
- "hacker:claude-3-sonnet-20240229"
|
||||
```
|
||||
|
||||
## Using Aliases
|
||||
|
||||
Once defined, you can use the alias instead of the full model name:
|
||||
|
||||
```bash
|
||||
aider --model fast # Uses gpt-3.5-turbo
|
||||
aider --model smart # Uses gpt-4
|
||||
```
|
||||
|
||||
## Built-in Aliases
|
||||
|
||||
Aider includes some built-in aliases for convenience:
|
||||
|
||||
<!--[[[cog
|
||||
import cog
|
||||
from aider.models import MODEL_ALIASES
|
||||
|
||||
for alias, model in sorted(MODEL_ALIASES.items()):
|
||||
cog.outl(f"- `{alias}`: {model}")
|
||||
]]]-->
|
||||
- `3`: gpt-3.5-turbo
|
||||
- `35-turbo`: gpt-3.5-turbo
|
||||
- `35turbo`: gpt-3.5-turbo
|
||||
- `4`: gpt-4-0613
|
||||
- `4-turbo`: gpt-4-1106-preview
|
||||
- `4o`: gpt-4o-2024-08-06
|
||||
- `deepseek`: deepseek/deepseek-coder
|
||||
- `haiku`: claude-3-haiku-20241022
|
||||
- `opus`: claude-3-opus-20240229
|
||||
- `sonnet`: claude-3-sonnet-20241022
|
||||
<!--[[[end]]]-->
|
||||
|
||||
## Priority
|
||||
|
||||
If the same alias is defined in multiple places, the priority is:
|
||||
|
||||
1. Command line aliases (highest priority)
|
||||
2. Configuration file aliases
|
||||
3. Built-in aliases (lowest priority)
|
||||
|
||||
This allows you to override built-in aliases with your own preferences.
|
||||
@@ -32,9 +32,9 @@ usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
|
||||
[--openai-api-type] [--openai-api-version]
|
||||
[--openai-api-deployment-id] [--openai-organization-id]
|
||||
[--model-settings-file] [--model-metadata-file]
|
||||
[--verify-ssl | --no-verify-ssl] [--edit-format]
|
||||
[--architect] [--weak-model] [--editor-model]
|
||||
[--editor-edit-format]
|
||||
[--alias] [--verify-ssl | --no-verify-ssl]
|
||||
[--edit-format] [--architect] [--weak-model]
|
||||
[--editor-model] [--editor-edit-format]
|
||||
[--show-model-warnings | --no-show-model-warnings]
|
||||
[--max-chat-history-tokens] [--env-file]
|
||||
[--cache-prompts | --no-cache-prompts]
|
||||
@@ -73,7 +73,8 @@ usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
|
||||
[--message-file] [--load] [--encoding] [-c]
|
||||
[--gui | --no-gui | --browser | --no-browser]
|
||||
[--suggest-shell-commands | --no-suggest-shell-commands]
|
||||
[--fancy-input | --no-fancy-input] [--editor]
|
||||
[--fancy-input | --no-fancy-input]
|
||||
[--detect-urls | --no-detect-urls] [--editor]
|
||||
[--voice-format] [--voice-language]
|
||||
|
||||
```
|
||||
@@ -191,6 +192,10 @@ Specify a file with context window and costs for unknown models
|
||||
Default: .aider.model.metadata.json
|
||||
Environment variable: `AIDER_MODEL_METADATA_FILE`
|
||||
|
||||
### `--alias ALIAS:MODEL`
|
||||
Add a model alias (can be used multiple times)
|
||||
Environment variable: `AIDER_ALIAS`
|
||||
|
||||
### `--verify-ssl`
|
||||
Verify the SSL cert when connecting to models (default: True)
|
||||
Default: True
|
||||
@@ -673,6 +678,14 @@ Aliases:
|
||||
- `--fancy-input`
|
||||
- `--no-fancy-input`
|
||||
|
||||
### `--detect-urls`
|
||||
Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
Default: True
|
||||
Environment variable: `AIDER_DETECT_URLS`
|
||||
Aliases:
|
||||
- `--detect-urls`
|
||||
- `--no-detect-urls`
|
||||
|
||||
### `--editor VALUE`
|
||||
Specify which editor to use for the /editor command
|
||||
Environment variable: `AIDER_EDITOR`
|
||||
|
||||
@@ -210,7 +210,7 @@ You can also refer to the
|
||||
## How are the "aider wrote xx% of code" stats computed?
|
||||
|
||||
[Aider is tightly integrated with git](/docs/git.html) so all
|
||||
one of aider's code changes are committed to the repo with proper attribution.
|
||||
of aider's code changes are committed to the repo with proper attribution.
|
||||
The
|
||||
[stats are computed](https://github.com/Aider-AI/aider/blob/main/scripts/blame.py)
|
||||
by doing something like `git blame` on the repo,
|
||||
|
||||
@@ -62,6 +62,7 @@ cog.out(get_supported_languages_md())
|
||||
| cpp | .cc | ✓ | ✓ |
|
||||
| cpp | .cpp | ✓ | ✓ |
|
||||
| css | .css | | ✓ |
|
||||
| dart | .dart | ✓ | ✓ |
|
||||
| dockerfile | .dockerfile | | ✓ |
|
||||
| dot | .dot | | ✓ |
|
||||
| elisp | .el | ✓ | ✓ |
|
||||
|
||||
@@ -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.')}")
|
||||
]]]-->
|
||||
November 21, 2024.
|
||||
November 24, 2024.
|
||||
<!--[[[end]]]-->
|
||||
</p>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
parent: Connecting to LLMs
|
||||
nav_order: 850
|
||||
---
|
||||
|
||||
# Editing format
|
||||
|
||||
Aider uses different "edit formats" to collect code edits from different LLMs.
|
||||
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
|
||||
and may limit how large a file can be edited.
|
||||
Models which can use one of the diff formats are much more efficient,
|
||||
using far fewer tokens.
|
||||
Models that use a diff-like format are able to
|
||||
edit larger files with less cost and without hitting token limits.
|
||||
|
||||
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
|
||||
and the [other models recommended on the LLM page](https://aider.chat/docs/llms.html).
|
||||
For lesser known models aider will default to using the "whole" editing format
|
||||
since it is the easiest format for an LLM to use.
|
||||
|
||||
If you would like to experiment with the more advanced formats, you can
|
||||
use these switches: `--edit-format diff` or `--edit-format udiff`.
|
||||
26
aider/website/docs/llms/lm-studio.md
Normal file
26
aider/website/docs/llms/lm-studio.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
parent: Connecting to LLMs
|
||||
nav_order: 400
|
||||
---
|
||||
|
||||
# LM Studio
|
||||
|
||||
To use LM Studio:
|
||||
|
||||
```
|
||||
python -m pip install -U aider-chat
|
||||
|
||||
export LM_STUDIO_API_KEY=<key> # Mac/Linux
|
||||
setx LM_STUDIO_API_KEY <key> # Windows, restart shell after setx
|
||||
|
||||
export LM_STUDIO_API_BASE=<url> # Mac/Linux
|
||||
setx LM_STUDIO_API_BASE <url> # Windows, restart shell after setx
|
||||
|
||||
aider --model lm_studio/<your-model-name>
|
||||
```
|
||||
|
||||
|
||||
|
||||
See the [model warnings](warnings.html)
|
||||
section for information on warnings which will occur
|
||||
when working with models that aider is not familiar with.
|
||||
@@ -20,24 +20,49 @@ python -m pip install -U aider-chat
|
||||
export OLLAMA_API_BASE=http://127.0.0.1:11434 # Mac/Linux
|
||||
setx OLLAMA_API_BASE http://127.0.0.1:11434 # Windows, restart shell after setx
|
||||
|
||||
aider --model ollama/<model>
|
||||
aider --model ollama_chat/<model>
|
||||
```
|
||||
|
||||
In particular, `llama3:70b` works well with aider:
|
||||
{: .note }
|
||||
Using `ollama_chat/` is recommended over `ollama/`.
|
||||
|
||||
|
||||
```
|
||||
ollama pull llama3:70b
|
||||
ollama serve
|
||||
|
||||
# In another terminal window...
|
||||
export OLLAMA_API_BASE=http://127.0.0.1:11434 # Mac/Linux
|
||||
setx OLLAMA_API_BASE http://127.0.0.1:11434 # Windows, restart shell after setx
|
||||
|
||||
aider --model ollama/llama3:70b
|
||||
```
|
||||
|
||||
See the [model warnings](warnings.html)
|
||||
section for information on warnings which will occur
|
||||
when working with models that aider is not familiar with.
|
||||
|
||||
## API Key
|
||||
|
||||
If you are using an ollama that requires an API key you can set `OLLAMA_API_KEY`:
|
||||
|
||||
```
|
||||
export OLLAMA_API_KEY=<api-key> # Mac/Linux
|
||||
setx OLLAMA_API_KEY <api-key> # Windows, restart shell after setx
|
||||
```
|
||||
|
||||
## Setting the context window size
|
||||
|
||||
[Ollama uses a 2k context window by default](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-specify-the-context-window-size),
|
||||
which is very small for working with aider.
|
||||
|
||||
Aider sets Ollama's context window to 8k by default.
|
||||
If you would like
|
||||
a larger context window
|
||||
you can use a
|
||||
[`.aider.model.settings.yml` file](https://aider.chat/docs/config/adv-model-settings.html#model-settings)
|
||||
like this:
|
||||
|
||||
```
|
||||
- name: ollama/qwen2.5-coder:32b-instruct-fp16
|
||||
extra_params:
|
||||
num_ctx: 8192
|
||||
```
|
||||
|
||||
Unlike most other LLM servers, Ollama does not throw an error if you submit
|
||||
a request that exceeds the context window.
|
||||
Instead, it just silently truncates the request by discarding the "oldest" messages
|
||||
in the chat to make it fit within the context window.
|
||||
So if your context window is too small, you won't get an error.
|
||||
Aider will probably just fail to work well and experience
|
||||
a lot of
|
||||
[file editing problems](https://aider.chat/docs/troubleshooting/edit-errors.html).
|
||||
|
||||
@@ -15,10 +15,10 @@ python -m pip install -U aider-chat
|
||||
export XAI_API_KEY=<key> # Mac/Linux
|
||||
setx XAI_API_KEY <key> # Windows, restart shell after setx
|
||||
|
||||
aider --model xai/groq-beta
|
||||
aider --model xai/grok-beta
|
||||
|
||||
# List models available from xAI
|
||||
aider --list-models groq/
|
||||
aider --list-models xai/
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,14 @@ disobeying the system prompt instructions.
|
||||
Most local models are just barely capable of working with aider,
|
||||
so editing errors are probably unavoidable.
|
||||
|
||||
Local models which have been quantized are even more likely to have problems
|
||||
## Local models: context window and quantization
|
||||
|
||||
Be especially careful about the
|
||||
[Ollama context window](https://aider.chat/docs/llms/ollama.html#setting-the-context-window-size)
|
||||
when working with local models.
|
||||
It defaults to be very small and silently discards data if you exceed it.
|
||||
|
||||
Local models which have been quantized are more likely to have editing problems
|
||||
because they are not capable enough to follow aider's system prompts.
|
||||
|
||||
## Try the whole edit format
|
||||
|
||||
@@ -33,6 +33,13 @@ To reduce output tokens:
|
||||
For more info: https://aider.chat/docs/token-limits.html
|
||||
```
|
||||
|
||||
{: .note }
|
||||
Aider never *enforces* token limits, it only *reports* token limit errors
|
||||
from the API provider.
|
||||
You probably don't need to
|
||||
[configure aider with the proper token limits](http://0.0.0.0:4000/docs/config/adv-model-settings.html#context-window-size-and-token-costs)
|
||||
for unusual models.
|
||||
|
||||
## Input tokens & context window size
|
||||
|
||||
The most common problem is trying to send too much data to a
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
parent: Usage
|
||||
nav_order: 60
|
||||
description: Using the chat, ask and help chat modes.
|
||||
description: Using the code, architect, ask and help chat modes.
|
||||
---
|
||||
|
||||
# Chat modes
|
||||
|
||||
@@ -155,6 +155,9 @@ def main(
|
||||
tries: int = typer.Option(2, "--tries", "-r", help="Number of tries for running tests"),
|
||||
threads: int = typer.Option(1, "--threads", "-t", help="Number of threads to run in parallel"),
|
||||
num_tests: int = typer.Option(-1, "--num-tests", "-n", help="Number of tests to run"),
|
||||
num_ctx: Optional[int] = typer.Option(
|
||||
None, "--num-ctx", help="Override model context window size"
|
||||
),
|
||||
exercises_dir: str = typer.Option(
|
||||
EXERCISES_DIR_DEFAULT, "--exercises-dir", help="Directory with exercise files"
|
||||
),
|
||||
@@ -247,6 +250,7 @@ def main(
|
||||
max_apply_update_errors,
|
||||
editor_model,
|
||||
editor_edit_format,
|
||||
num_ctx,
|
||||
)
|
||||
|
||||
all_results.append(results)
|
||||
@@ -526,6 +530,7 @@ def run_test_real(
|
||||
max_apply_update_errors,
|
||||
editor_model,
|
||||
editor_edit_format,
|
||||
num_ctx=None,
|
||||
):
|
||||
if not os.path.isdir(testdir):
|
||||
print("Not a dir:", testdir)
|
||||
@@ -588,6 +593,11 @@ def run_test_real(
|
||||
editor_model=editor_model,
|
||||
editor_edit_format=editor_edit_format,
|
||||
)
|
||||
|
||||
if num_ctx:
|
||||
if not main_model.extra_params:
|
||||
main_model.extra_params = {}
|
||||
main_model.extra_params["num_ctx"] = num_ctx
|
||||
edit_format = edit_format or main_model.edit_format
|
||||
|
||||
dump(main_model)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
docker run \
|
||||
-it --rm \
|
||||
--add-host=host.docker.internal:host-gateway \
|
||||
-v `pwd`:/aider \
|
||||
-v `pwd`/tmp.benchmarks/.:/benchmarks \
|
||||
-e OPENAI_API_KEY=$OPENAI_API_KEY \
|
||||
|
||||
@@ -1,278 +1,168 @@
|
||||
from dataclasses import dataclass
|
||||
from datetime import date
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import yaml
|
||||
from imgcat import imgcat
|
||||
from matplotlib import rc
|
||||
|
||||
from aider.dump import dump # noqa: 401
|
||||
|
||||
LABEL_FONT_SIZE = 16 # Font size for scatter plot dot labels
|
||||
@dataclass
|
||||
class ModelData:
|
||||
name: str
|
||||
release_date: date
|
||||
pass_rate: float
|
||||
|
||||
@property
|
||||
def color(self) -> str:
|
||||
model = self.name.lower()
|
||||
if "gemini" in model and "pro" in model:
|
||||
return "magenta"
|
||||
if "qwen" in model:
|
||||
return "darkblue"
|
||||
if "mistral" in model:
|
||||
return "cyan"
|
||||
if "haiku" in model:
|
||||
return "pink"
|
||||
if "deepseek" in model:
|
||||
return "brown"
|
||||
if "sonnet" in model:
|
||||
return "orange"
|
||||
if "-4o" in model:
|
||||
return "purple"
|
||||
if "gpt-4" in model:
|
||||
return "red"
|
||||
if "gpt-3.5" in model:
|
||||
return "green"
|
||||
return "lightblue"
|
||||
|
||||
@property
|
||||
def legend_label(self) -> str:
|
||||
model = self.name.lower()
|
||||
if "gemini" in model and "pro" in model:
|
||||
return "Gemini 1.5 Pro"
|
||||
if "claude-3-sonnet" in model:
|
||||
return "Sonnet"
|
||||
if "o1-preview" in model:
|
||||
return "O1 Preview"
|
||||
if "gpt-3.5" in model:
|
||||
return "GPT-3.5 Turbo"
|
||||
if "gpt-4-" in model and "-4o" not in model:
|
||||
return "GPT-4"
|
||||
if "qwen" in model:
|
||||
return "Qwen"
|
||||
if "-4o" in model:
|
||||
return "GPT-4o"
|
||||
if "haiku" in model:
|
||||
return "Haiku"
|
||||
if "deepseek" in model:
|
||||
return "DeepSeek"
|
||||
if "mistral" in model:
|
||||
return "Mistral"
|
||||
return model
|
||||
|
||||
|
||||
def get_legend_label(model):
|
||||
model = model.lower()
|
||||
if "claude-3-sonnet" in model:
|
||||
return "Sonnet"
|
||||
if "o1-preview" in model:
|
||||
return "O1 Preview"
|
||||
if "gpt-3.5" in model:
|
||||
return "GPT-3.5 Turbo"
|
||||
if "gpt-4-" in model and "-4o" not in model:
|
||||
return "GPT-4"
|
||||
if "qwen" in model:
|
||||
return "Qwen"
|
||||
if "-4o" in model:
|
||||
return "GPT-4o"
|
||||
if "haiku" in model:
|
||||
return "Haiku"
|
||||
if "deepseek" in model:
|
||||
return "DeepSeek"
|
||||
if "mistral" in model:
|
||||
return "Mistral"
|
||||
if "o1-preview" in model:
|
||||
return "o1-preview"
|
||||
return model
|
||||
class BenchmarkPlotter:
|
||||
LABEL_FONT_SIZE = 16
|
||||
|
||||
def __init__(self):
|
||||
self.setup_plot_style()
|
||||
|
||||
def get_model_color(model):
|
||||
default = "lightblue"
|
||||
def setup_plot_style(self):
|
||||
plt.rcParams["hatch.linewidth"] = 0.5
|
||||
plt.rcParams["hatch.color"] = "#444444"
|
||||
rc("font", **{"family": "sans-serif", "sans-serif": ["Helvetica"], "size": 10})
|
||||
plt.rcParams["text.color"] = "#444444"
|
||||
|
||||
if model == "gpt-4o-mini":
|
||||
return default
|
||||
def load_data(self, yaml_file: str) -> List[ModelData]:
|
||||
with open(yaml_file, "r") as file:
|
||||
data = yaml.safe_load(file)
|
||||
|
||||
if "qwen" in model.lower():
|
||||
return "darkblue"
|
||||
models = []
|
||||
for entry in data:
|
||||
if "released" in entry and "pass_rate_2" in entry:
|
||||
model = ModelData(
|
||||
name=entry["model"].split("(")[0].strip(),
|
||||
release_date=entry["released"],
|
||||
pass_rate=entry["pass_rate_2"],
|
||||
)
|
||||
models.append(model)
|
||||
return models
|
||||
|
||||
if "mistral" in model.lower():
|
||||
return "cyan"
|
||||
def create_figure(self) -> Tuple[plt.Figure, plt.Axes]:
|
||||
fig, ax = plt.subplots(figsize=(12, 8))
|
||||
ax.grid(axis="y", zorder=0, lw=0.2)
|
||||
for spine in ax.spines.values():
|
||||
spine.set_edgecolor("#DDDDDD")
|
||||
spine.set_linewidth(0.5)
|
||||
return fig, ax
|
||||
|
||||
if "haiku" in model.lower():
|
||||
return "pink"
|
||||
def plot_model_series(self, ax: plt.Axes, models: List[ModelData]):
|
||||
# Group models by color
|
||||
color_groups: Dict[str, List[ModelData]] = {}
|
||||
for model in models:
|
||||
if model.color not in color_groups:
|
||||
color_groups[model.color] = []
|
||||
color_groups[model.color].append(model)
|
||||
|
||||
if "deepseek" in model.lower():
|
||||
return "brown"
|
||||
# Plot each color group
|
||||
for color, group in color_groups.items():
|
||||
sorted_group = sorted(group, key=lambda x: x.release_date)
|
||||
dates = [m.release_date for m in sorted_group]
|
||||
rates = [m.pass_rate for m in sorted_group]
|
||||
|
||||
if "sonnet" in model.lower():
|
||||
return "orange"
|
||||
# Plot line
|
||||
ax.plot(dates, rates, c=color, alpha=0.5, linewidth=1)
|
||||
|
||||
if "-4o" in model:
|
||||
return "purple"
|
||||
# Plot points
|
||||
ax.scatter(dates, rates, c=color, alpha=0.5, s=120)
|
||||
|
||||
if "gpt-4" in model:
|
||||
return "red"
|
||||
# Add label for first point
|
||||
first_model = sorted_group[0]
|
||||
ax.annotate(
|
||||
first_model.legend_label,
|
||||
(first_model.release_date, first_model.pass_rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color=color,
|
||||
alpha=0.8,
|
||||
fontsize=self.LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if "gpt-3.5" in model:
|
||||
return "green"
|
||||
|
||||
return default
|
||||
|
||||
|
||||
def plot_over_time(yaml_file):
|
||||
with open(yaml_file, "r") as file:
|
||||
data = yaml.safe_load(file)
|
||||
|
||||
dates = []
|
||||
pass_rates = []
|
||||
models = []
|
||||
|
||||
print("Debug: Raw data from YAML file:")
|
||||
print(data)
|
||||
|
||||
for entry in data:
|
||||
if "released" in entry and "pass_rate_2" in entry:
|
||||
dates.append(entry["released"])
|
||||
pass_rates.append(entry["pass_rate_2"])
|
||||
models.append(entry["model"].split("(")[0].strip())
|
||||
|
||||
print("Debug: Processed data:")
|
||||
print("Dates:", dates)
|
||||
print("Pass rates:", pass_rates)
|
||||
print("Models:", models)
|
||||
|
||||
if not dates or not pass_rates:
|
||||
print(
|
||||
"Error: No data to plot. Check if the YAML file is empty or if the data is in the"
|
||||
" expected format."
|
||||
def set_labels_and_style(self, ax: plt.Axes):
|
||||
ax.set_xlabel("Model release date", fontsize=18, color="#555")
|
||||
ax.set_ylabel(
|
||||
"Aider code editing benchmark,\npercent completed correctly", fontsize=18, color="#555"
|
||||
)
|
||||
return
|
||||
ax.set_title("LLM code editing skill by model release date", fontsize=20)
|
||||
ax.set_ylim(30, 90)
|
||||
plt.xticks(fontsize=14, rotation=45, ha="right")
|
||||
plt.tight_layout(pad=1.0)
|
||||
|
||||
plt.rcParams["hatch.linewidth"] = 0.5
|
||||
plt.rcParams["hatch.color"] = "#444444"
|
||||
def save_and_display(self, fig: plt.Figure):
|
||||
plt.savefig("aider/website/assets/models-over-time.png")
|
||||
plt.savefig("aider/website/assets/models-over-time.svg")
|
||||
imgcat(fig)
|
||||
|
||||
rc("font", **{"family": "sans-serif", "sans-serif": ["Helvetica"], "size": 10})
|
||||
plt.rcParams["text.color"] = "#444444"
|
||||
|
||||
fig, ax = plt.subplots(figsize=(12, 8)) # Make figure square
|
||||
|
||||
print("Debug: Figure created. Plotting data...")
|
||||
ax.grid(axis="y", zorder=0, lw=0.2)
|
||||
for spine in ax.spines.values():
|
||||
spine.set_edgecolor("#DDDDDD")
|
||||
spine.set_linewidth(0.5)
|
||||
|
||||
colors = [get_model_color(model) for model in models]
|
||||
|
||||
# Separate data points by color
|
||||
purple_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "purple"]
|
||||
red_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "red"]
|
||||
green_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "green"]
|
||||
orange_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "orange"]
|
||||
brown_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "brown"]
|
||||
pink_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "pink"]
|
||||
qwen_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "darkblue"]
|
||||
mistral_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "cyan"]
|
||||
|
||||
# Create a mapping of colors to first points and labels
|
||||
color_to_first_point = {}
|
||||
color_to_label = {}
|
||||
|
||||
for date, rate, color, model in sorted(zip(dates, pass_rates, colors, models)):
|
||||
if color not in color_to_first_point:
|
||||
color_to_first_point[color] = (date, rate)
|
||||
color_to_label[color] = get_legend_label(model)
|
||||
|
||||
# Plot lines and add labels at first points
|
||||
if purple_points:
|
||||
purple_dates, purple_rates = zip(*sorted(purple_points))
|
||||
ax.plot(purple_dates, purple_rates, c="purple", alpha=0.5, linewidth=1)
|
||||
if "purple" in color_to_first_point:
|
||||
date, rate = color_to_first_point["purple"]
|
||||
ax.annotate(
|
||||
color_to_label["purple"],
|
||||
(date, rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color="purple",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if red_points:
|
||||
red_dates, red_rates = zip(*sorted(red_points))
|
||||
ax.plot(red_dates, red_rates, c="red", alpha=0.5, linewidth=1)
|
||||
if "red" in color_to_first_point:
|
||||
date, rate = color_to_first_point["red"]
|
||||
ax.annotate(
|
||||
color_to_label["red"],
|
||||
(date, rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color="red",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if green_points:
|
||||
green_dates, green_rates = zip(*sorted(green_points))
|
||||
ax.plot(green_dates, green_rates, c="green", alpha=0.5, linewidth=1)
|
||||
if "green" in color_to_first_point:
|
||||
date, rate = color_to_first_point["green"]
|
||||
ax.annotate(
|
||||
color_to_label["green"],
|
||||
(date, rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color="green",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if orange_points:
|
||||
orange_dates, orange_rates = zip(*sorted(orange_points))
|
||||
ax.plot(orange_dates, orange_rates, c="orange", alpha=0.5, linewidth=1)
|
||||
if "orange" in color_to_first_point:
|
||||
date, rate = color_to_first_point["orange"]
|
||||
ax.annotate(
|
||||
color_to_label["orange"],
|
||||
(date, rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color="orange",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if brown_points:
|
||||
brown_dates, brown_rates = zip(*sorted(brown_points))
|
||||
ax.plot(brown_dates, brown_rates, c="brown", alpha=0.5, linewidth=1)
|
||||
if "brown" in color_to_first_point:
|
||||
date, rate = color_to_first_point["brown"]
|
||||
ax.annotate(
|
||||
color_to_label["brown"],
|
||||
(date, rate),
|
||||
xytext=(10, -10),
|
||||
textcoords="offset points",
|
||||
color="brown",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if pink_points:
|
||||
pink_dates, pink_rates = zip(*sorted(pink_points))
|
||||
ax.plot(pink_dates, pink_rates, c="pink", alpha=0.5, linewidth=1)
|
||||
if "pink" in color_to_first_point:
|
||||
date, rate = color_to_first_point["pink"]
|
||||
ax.annotate(
|
||||
color_to_label["pink"],
|
||||
(date, rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color="pink",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if qwen_points:
|
||||
qwen_dates, qwen_rates = zip(*sorted(qwen_points))
|
||||
ax.plot(qwen_dates, qwen_rates, c="darkblue", alpha=0.5, linewidth=1)
|
||||
if "darkblue" in color_to_first_point:
|
||||
date, rate = color_to_first_point["darkblue"]
|
||||
ax.annotate(
|
||||
color_to_label["darkblue"],
|
||||
(date, rate),
|
||||
xytext=(10, 5),
|
||||
textcoords="offset points",
|
||||
color="darkblue",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
if mistral_points:
|
||||
mistral_dates, mistral_rates = zip(*sorted(mistral_points))
|
||||
ax.plot(mistral_dates, mistral_rates, c="cyan", alpha=0.5, linewidth=1)
|
||||
if "cyan" in color_to_first_point:
|
||||
date, rate = color_to_first_point["cyan"]
|
||||
ax.annotate(
|
||||
color_to_label["cyan"],
|
||||
(date, rate),
|
||||
xytext=(10, -10),
|
||||
textcoords="offset points",
|
||||
color="cyan",
|
||||
alpha=0.8,
|
||||
fontsize=LABEL_FONT_SIZE,
|
||||
)
|
||||
|
||||
# Plot points without legend
|
||||
for date, rate, color in zip(dates, pass_rates, colors):
|
||||
ax.scatter([date], [rate], c=[color], alpha=0.5, s=120)
|
||||
|
||||
ax.set_xlabel("Model release date", fontsize=18, color="#555")
|
||||
ax.set_ylabel(
|
||||
"Aider code editing benchmark,\npercent completed correctly", fontsize=18, color="#555"
|
||||
)
|
||||
ax.set_title("LLM code editing skill by model release date", fontsize=20)
|
||||
ax.set_ylim(30, 90) # Adjust y-axis limit to accommodate higher values
|
||||
plt.xticks(fontsize=14, rotation=45, ha="right") # Rotate x-axis labels for better readability
|
||||
plt.tight_layout(pad=1.0) # Adjust layout since we don't need room for legend anymore
|
||||
|
||||
print("Debug: Saving figures...")
|
||||
plt.savefig("tmp_over_time.png")
|
||||
plt.savefig("tmp_over_time.svg")
|
||||
|
||||
print("Debug: Displaying figure with imgcat...")
|
||||
imgcat(fig)
|
||||
|
||||
print("Debug: Figure generation complete.")
|
||||
def plot(self, yaml_file: str):
|
||||
models = self.load_data(yaml_file)
|
||||
fig, ax = self.create_figure()
|
||||
self.plot_model_series(ax, models)
|
||||
self.set_labels_and_style(ax)
|
||||
self.save_and_display(fig)
|
||||
|
||||
|
||||
# Example usage
|
||||
plot_over_time("aider/website/_data/edit_leaderboard.yml")
|
||||
def main():
|
||||
plotter = BenchmarkPlotter()
|
||||
models = plotter.load_data("aider/website/_data/edit_leaderboard.yml")
|
||||
|
||||
# Print release dates and model names
|
||||
for model in sorted(models, key=lambda x: x.release_date):
|
||||
print(f"{model.release_date}: {model.name}")
|
||||
|
||||
plotter.plot("aider/website/_data/edit_leaderboard.yml")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
aiohappyeyeballs==2.4.3
|
||||
# via aiohttp
|
||||
aiohttp==3.11.2
|
||||
aiohttp==3.11.7
|
||||
# via litellm
|
||||
aiosignal==1.3.1
|
||||
# via aiohttp
|
||||
@@ -62,11 +62,11 @@ gitdb==4.0.11
|
||||
# via gitpython
|
||||
gitpython==3.1.43
|
||||
# via -r requirements/requirements.in
|
||||
grep-ast==0.3.3
|
||||
grep-ast==0.4.0
|
||||
# via -r requirements/requirements.in
|
||||
h11==0.14.0
|
||||
# via httpcore
|
||||
httpcore==1.0.6
|
||||
httpcore==1.0.7
|
||||
# via httpx
|
||||
httpx==0.27.2
|
||||
# via openai
|
||||
@@ -96,7 +96,7 @@ jsonschema==4.23.0
|
||||
# litellm
|
||||
jsonschema-specifications==2024.10.1
|
||||
# via jsonschema
|
||||
litellm==1.52.8
|
||||
litellm==1.52.16
|
||||
# via -r requirements/requirements.in
|
||||
markdown-it-py==3.0.0
|
||||
# via rich
|
||||
@@ -120,7 +120,7 @@ numpy==1.26.4
|
||||
# via
|
||||
# -r requirements/requirements.in
|
||||
# scipy
|
||||
openai==1.54.4
|
||||
openai==1.55.1
|
||||
# via litellm
|
||||
packaging==24.2
|
||||
# via
|
||||
@@ -134,7 +134,7 @@ pexpect==4.9.0
|
||||
# via -r requirements/requirements.in
|
||||
pillow==10.4.0
|
||||
# via -r requirements/requirements.in
|
||||
posthog==3.7.0
|
||||
posthog==3.7.3
|
||||
# via -r requirements/requirements.in
|
||||
prompt-toolkit==3.0.48
|
||||
# via -r requirements/requirements.in
|
||||
@@ -150,11 +150,11 @@ pycodestyle==2.12.1
|
||||
# via flake8
|
||||
pycparser==2.22
|
||||
# via cffi
|
||||
pydantic==2.9.2
|
||||
pydantic==2.10.2
|
||||
# via
|
||||
# litellm
|
||||
# openai
|
||||
pydantic-core==2.23.4
|
||||
pydantic-core==2.27.1
|
||||
# via pydantic
|
||||
pydub==0.25.1
|
||||
# via -r requirements/requirements.in
|
||||
@@ -219,7 +219,7 @@ tokenizers==0.19.1
|
||||
# via
|
||||
# -r requirements/requirements.in
|
||||
# litellm
|
||||
tqdm==4.67.0
|
||||
tqdm==4.67.1
|
||||
# via
|
||||
# huggingface-hub
|
||||
# openai
|
||||
@@ -241,7 +241,7 @@ urllib3==2.2.3
|
||||
# requests
|
||||
wcwidth==0.2.13
|
||||
# via prompt-toolkit
|
||||
yarl==1.17.1
|
||||
yarl==1.18.0
|
||||
# via aiohttp
|
||||
zipp==3.21.0
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#
|
||||
# pip-compile --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --constraint=requirements/requirements-help.txt --output-file=requirements/requirements-browser.txt requirements/requirements-browser.in
|
||||
#
|
||||
altair==5.4.1
|
||||
altair==5.5.0
|
||||
# via streamlit
|
||||
attrs==24.2.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# jsonschema
|
||||
# referencing
|
||||
@@ -19,85 +19,85 @@ cachetools==5.5.0
|
||||
# via streamlit
|
||||
certifi==2024.8.30
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# requests
|
||||
charset-normalizer==3.4.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# requests
|
||||
click==8.1.7
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# streamlit
|
||||
gitdb==4.0.11
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# gitpython
|
||||
gitpython==3.1.43
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# streamlit
|
||||
idna==3.10
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# requests
|
||||
jinja2==3.1.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# altair
|
||||
# pydeck
|
||||
jsonschema==4.23.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# altair
|
||||
jsonschema-specifications==2024.10.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# jsonschema
|
||||
markdown-it-py==3.0.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# rich
|
||||
markupsafe==3.0.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# jinja2
|
||||
mdurl==0.1.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# markdown-it-py
|
||||
narwhals==1.13.5
|
||||
narwhals==1.14.2
|
||||
# via altair
|
||||
numpy==1.26.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# pandas
|
||||
@@ -105,8 +105,8 @@ numpy==1.26.4
|
||||
# streamlit
|
||||
packaging==24.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# altair
|
||||
@@ -117,27 +117,27 @@ pandas==2.2.3
|
||||
# streamlit
|
||||
pillow==10.4.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# streamlit
|
||||
protobuf==5.28.3
|
||||
# via streamlit
|
||||
pyarrow==18.0.0
|
||||
pyarrow==18.1.0
|
||||
# via streamlit
|
||||
pydeck==0.9.1
|
||||
# via streamlit
|
||||
pygments==2.18.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# rich
|
||||
python-dateutil==2.9.0.post0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# pandas
|
||||
pytz==2024.2
|
||||
@@ -146,41 +146,41 @@ pytz==2024.2
|
||||
# pandas
|
||||
referencing==0.35.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# jsonschema
|
||||
# jsonschema-specifications
|
||||
requests==2.32.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# streamlit
|
||||
rich==13.9.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# streamlit
|
||||
rpds-py==0.21.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# jsonschema
|
||||
# referencing
|
||||
six==1.16.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# python-dateutil
|
||||
smmap==5.0.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# gitdb
|
||||
streamlit==1.40.1
|
||||
streamlit==1.40.2
|
||||
# via -r requirements/requirements-browser.in
|
||||
tenacity==8.5.0
|
||||
# via
|
||||
@@ -188,12 +188,12 @@ tenacity==8.5.0
|
||||
# streamlit
|
||||
toml==0.10.2
|
||||
# via streamlit
|
||||
tornado==6.4.1
|
||||
tornado==6.4.2
|
||||
# via streamlit
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# altair
|
||||
@@ -204,8 +204,8 @@ tzdata==2024.2
|
||||
# pandas
|
||||
urllib3==2.2.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
# requests
|
||||
|
||||
@@ -12,20 +12,20 @@ build==1.2.2.post1
|
||||
# via pip-tools
|
||||
certifi==2024.8.30
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# requests
|
||||
cfgv==3.4.0
|
||||
# via pre-commit
|
||||
charset-normalizer==3.4.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# requests
|
||||
click==8.1.7
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# pip-tools
|
||||
# typer
|
||||
codespell==2.3.0
|
||||
@@ -48,28 +48,28 @@ docutils==0.21.2
|
||||
# sphinx-rtd-theme
|
||||
filelock==3.16.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# virtualenv
|
||||
fonttools==4.55.0
|
||||
# via matplotlib
|
||||
identify==2.6.2
|
||||
identify==2.6.3
|
||||
# via pre-commit
|
||||
idna==3.10
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# requests
|
||||
imagesize==1.4.1
|
||||
# via sphinx
|
||||
imgcat==0.5.0
|
||||
imgcat==0.6.0
|
||||
# via -r requirements/requirements-dev.in
|
||||
iniconfig==2.0.0
|
||||
# via pytest
|
||||
jinja2==3.1.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# sphinx
|
||||
kiwisolver==1.4.7
|
||||
# via matplotlib
|
||||
@@ -77,20 +77,20 @@ lox==0.12.0
|
||||
# via -r requirements/requirements-dev.in
|
||||
markdown-it-py==3.0.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# rich
|
||||
markupsafe==3.0.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# jinja2
|
||||
matplotlib==3.9.2
|
||||
# via -r requirements/requirements-dev.in
|
||||
mdurl==0.1.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# markdown-it-py
|
||||
multiprocess==0.70.17
|
||||
# via pathos
|
||||
@@ -98,15 +98,15 @@ nodeenv==1.9.1
|
||||
# via pre-commit
|
||||
numpy==1.26.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# contourpy
|
||||
# matplotlib
|
||||
# pandas
|
||||
packaging==24.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# build
|
||||
# matplotlib
|
||||
# pytest
|
||||
@@ -117,8 +117,8 @@ pathos==0.3.3
|
||||
# via lox
|
||||
pillow==10.4.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# matplotlib
|
||||
pip-tools==7.4.1
|
||||
# via -r requirements/requirements-dev.in
|
||||
@@ -134,8 +134,8 @@ pre-commit==4.0.1
|
||||
# via -r requirements/requirements-dev.in
|
||||
pygments==2.18.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# rich
|
||||
# sphinx
|
||||
pyparsing==3.2.0
|
||||
@@ -148,26 +148,26 @@ pytest==8.3.3
|
||||
# via -r requirements/requirements-dev.in
|
||||
python-dateutil==2.9.0.post0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# matplotlib
|
||||
# pandas
|
||||
pytz==2024.2
|
||||
# via pandas
|
||||
pyyaml==6.0.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# pre-commit
|
||||
requests==2.32.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# sphinx
|
||||
rich==13.9.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# typer
|
||||
semver==3.0.2
|
||||
# via -r requirements/requirements-dev.in
|
||||
@@ -175,8 +175,8 @@ shellingham==1.5.4
|
||||
# via typer
|
||||
six==1.16.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# python-dateutil
|
||||
snowballstemmer==2.2.0
|
||||
# via sphinx
|
||||
@@ -200,23 +200,23 @@ sphinxcontrib-qthelp==2.0.0
|
||||
# via sphinx
|
||||
sphinxcontrib-serializinghtml==2.0.0
|
||||
# via sphinx
|
||||
typer==0.13.0
|
||||
typer==0.13.1
|
||||
# via -r requirements/requirements-dev.in
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# typer
|
||||
tzdata==2024.2
|
||||
# via pandas
|
||||
urllib3==2.2.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# requests
|
||||
virtualenv==20.27.1
|
||||
virtualenv==20.28.0
|
||||
# via pre-commit
|
||||
wheel==0.45.0
|
||||
wheel==0.45.1
|
||||
# via pip-tools
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
|
||||
@@ -6,65 +6,65 @@
|
||||
#
|
||||
aiohappyeyeballs==2.4.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
aiohttp==3.11.2
|
||||
aiohttp==3.11.7
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# huggingface-hub
|
||||
# llama-index-core
|
||||
aiosignal==1.3.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
annotated-types==0.7.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# pydantic
|
||||
anyio==4.6.2.post1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# httpx
|
||||
attrs==24.2.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
certifi==2024.8.30
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# httpcore
|
||||
# httpx
|
||||
# requests
|
||||
charset-normalizer==3.4.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# requests
|
||||
click==8.1.7
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# nltk
|
||||
dataclasses-json==0.6.7
|
||||
# via llama-index-core
|
||||
deprecated==1.2.14
|
||||
deprecated==1.2.15
|
||||
# via llama-index-core
|
||||
dirtyjson==1.0.8
|
||||
# via llama-index-core
|
||||
filelock==3.16.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# huggingface-hub
|
||||
# torch
|
||||
@@ -73,14 +73,14 @@ filetype==1.2.0
|
||||
# via llama-index-core
|
||||
frozenlist==1.5.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
# aiosignal
|
||||
fsspec==2024.10.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# huggingface-hub
|
||||
# llama-index-core
|
||||
# torch
|
||||
@@ -90,31 +90,31 @@ greenlet==3.0.3
|
||||
# sqlalchemy
|
||||
h11==0.14.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# httpcore
|
||||
httpcore==1.0.6
|
||||
httpcore==1.0.7
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# httpx
|
||||
httpx==0.27.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# llama-index-core
|
||||
huggingface-hub[inference]==0.26.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# llama-index-embeddings-huggingface
|
||||
# sentence-transformers
|
||||
# tokenizers
|
||||
# transformers
|
||||
idna==3.10
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# anyio
|
||||
# httpx
|
||||
@@ -122,24 +122,24 @@ idna==3.10
|
||||
# yarl
|
||||
jinja2==3.1.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# torch
|
||||
joblib==1.4.2
|
||||
# via
|
||||
# nltk
|
||||
# scikit-learn
|
||||
llama-index-core==0.11.23
|
||||
llama-index-core==0.12.0
|
||||
# via
|
||||
# -r requirements/requirements-help.in
|
||||
# llama-index-embeddings-huggingface
|
||||
llama-index-embeddings-huggingface==0.3.1
|
||||
llama-index-embeddings-huggingface==0.4.0
|
||||
# via -r requirements/requirements-help.in
|
||||
markupsafe==3.0.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# jinja2
|
||||
marshmallow==3.23.1
|
||||
@@ -148,8 +148,8 @@ mpmath==1.3.0
|
||||
# via sympy
|
||||
multidict==6.1.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
# yarl
|
||||
mypy-extensions==1.0.0
|
||||
@@ -158,16 +158,16 @@ nest-asyncio==1.6.0
|
||||
# via llama-index-core
|
||||
networkx==3.2.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# llama-index-core
|
||||
# torch
|
||||
nltk==3.9.1
|
||||
# via llama-index-core
|
||||
numpy==1.26.4
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# llama-index-core
|
||||
# scikit-learn
|
||||
@@ -175,54 +175,54 @@ numpy==1.26.4
|
||||
# transformers
|
||||
packaging==24.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# huggingface-hub
|
||||
# marshmallow
|
||||
# transformers
|
||||
pillow==10.4.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# llama-index-core
|
||||
# sentence-transformers
|
||||
propcache==0.2.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
# yarl
|
||||
pydantic==2.9.2
|
||||
pydantic==2.10.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# llama-index-core
|
||||
pydantic-core==2.23.4
|
||||
pydantic-core==2.27.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# pydantic
|
||||
pyyaml==6.0.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# huggingface-hub
|
||||
# llama-index-core
|
||||
# transformers
|
||||
regex==2024.11.6
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# nltk
|
||||
# tiktoken
|
||||
# transformers
|
||||
requests==2.32.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# huggingface-hub
|
||||
# llama-index-core
|
||||
@@ -234,16 +234,16 @@ scikit-learn==1.5.2
|
||||
# via sentence-transformers
|
||||
scipy==1.13.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# scikit-learn
|
||||
# sentence-transformers
|
||||
sentence-transformers==3.3.0
|
||||
sentence-transformers==3.3.1
|
||||
# via llama-index-embeddings-huggingface
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# anyio
|
||||
# httpx
|
||||
sqlalchemy[asyncio]==2.0.36
|
||||
@@ -258,20 +258,20 @@ threadpoolctl==3.5.0
|
||||
# via scikit-learn
|
||||
tiktoken==0.8.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# llama-index-core
|
||||
tokenizers==0.19.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# transformers
|
||||
torch==2.2.2
|
||||
# via sentence-transformers
|
||||
tqdm==4.67.0
|
||||
tqdm==4.67.1
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# huggingface-hub
|
||||
# llama-index-core
|
||||
# nltk
|
||||
@@ -281,8 +281,8 @@ transformers==4.44.2
|
||||
# via sentence-transformers
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# huggingface-hub
|
||||
# llama-index-core
|
||||
@@ -297,16 +297,16 @@ typing-inspect==0.9.0
|
||||
# llama-index-core
|
||||
urllib3==2.2.3
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# requests
|
||||
wrapt==1.16.0
|
||||
wrapt==1.17.0
|
||||
# via
|
||||
# deprecated
|
||||
# llama-index-core
|
||||
yarl==1.17.1
|
||||
yarl==1.18.0
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# aiohttp
|
||||
|
||||
@@ -15,8 +15,8 @@ pyee==12.0.0
|
||||
# via playwright
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||
# -c requirements.txt
|
||||
# -c requirements/../requirements.txt
|
||||
# -c requirements/requirements-browser.txt
|
||||
# -c requirements/requirements-dev.txt
|
||||
# -c requirements/requirements-help.txt
|
||||
|
||||
@@ -15,6 +15,6 @@ RUN bundle install --retry 5 --jobs 20
|
||||
ENTRYPOINT [ "docker-entrypoint.sh" ]
|
||||
|
||||
# bundle exec jekyll serve --force_polling -H 0.0.0.0 -P 4000
|
||||
CMD [ "bundle", "exec", "jekyll", "serve", "--force_polling", "-H", "0.0.0.0", "-P", "4000" ]
|
||||
CMD [ "bundle", "exec", "jekyll", "serve", "--verbose", "--trace", "--force_polling", "-H", "0.0.0.0", "-P", "4000" ]
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ cog $ARG \
|
||||
aider/website/docs/config/options.md \
|
||||
aider/website/docs/config/aider_conf.md \
|
||||
aider/website/docs/config/adv-model-settings.md \
|
||||
aider/website/docs/config/model-aliases.md \
|
||||
aider/website/docs/leaderboards/index.md \
|
||||
aider/website/docs/llms/other.md \
|
||||
aider/website/docs/more/infinite-output.md \
|
||||
|
||||
72
scripts/update-history.py
Executable file
72
scripts/update-history.py
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
from aider import __version__
|
||||
|
||||
|
||||
def get_base_version():
|
||||
# Parse current version like "0.64.2.dev" to get major.minor
|
||||
match = re.match(r"(\d+\.\d+)", __version__)
|
||||
if not match:
|
||||
raise ValueError(f"Could not parse version: {__version__}")
|
||||
return match.group(1) + ".0"
|
||||
|
||||
|
||||
def run_git_log():
|
||||
base_ver = get_base_version()
|
||||
cmd = [
|
||||
"git",
|
||||
"log",
|
||||
"-p",
|
||||
f"v{base_ver}..HEAD",
|
||||
"--",
|
||||
"aider/",
|
||||
":!aider/website/",
|
||||
":!scripts/",
|
||||
":!HISTORY.md",
|
||||
]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
return result.stdout
|
||||
|
||||
|
||||
def main():
|
||||
# Get the git log output
|
||||
diff_content = run_git_log()
|
||||
|
||||
# Save to temporary file
|
||||
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".diff") as tmp:
|
||||
tmp.write(diff_content)
|
||||
tmp_path = tmp.name
|
||||
|
||||
# Run blame to get aider percentage
|
||||
blame_result = subprocess.run(["python3", "scripts/blame.py"], capture_output=True, text=True)
|
||||
aider_line = blame_result.stdout.strip().split("\n")[-1] # Get last line with percentage
|
||||
|
||||
# Construct and run the aider command
|
||||
message = f"""
|
||||
Update the history with changes shown in the diffs.
|
||||
Describe actual user-facing changes, not every single commit that was made implementing them.
|
||||
Don't edit or duplicate changes that have existing history entries, just add any new items not already listed.
|
||||
Be sure to attribute changes to the proper .x version.
|
||||
Changes in the .x-dev version should be listed under a "### main branch" heading
|
||||
|
||||
Also, add this as the last bullet under the "### main branch" section:
|
||||
{aider_line}
|
||||
""" # noqa
|
||||
|
||||
cmd = ["aider", "HISTORY.md", "--read", tmp_path, "--msg", message, "--no-auto-commit"]
|
||||
subprocess.run(cmd)
|
||||
|
||||
# Run update-docs.sh after aider
|
||||
subprocess.run(["scripts/update-docs.sh"])
|
||||
|
||||
# Cleanup
|
||||
os.unlink(tmp_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch
|
||||
import git
|
||||
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import UnknownEditFormat
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.io import InputOutput
|
||||
from aider.models import Model
|
||||
@@ -168,6 +169,37 @@ class TestCoder(unittest.TestCase):
|
||||
|
||||
self.assertEqual(coder.abs_fnames, set([str(fname.resolve())]))
|
||||
|
||||
def test_skip_duplicate_basename_mentions(self):
|
||||
with GitTemporaryDirectory():
|
||||
io = InputOutput(pretty=False, yes=True)
|
||||
coder = Coder.create(self.GPT35, None, io)
|
||||
|
||||
# Create files with same basename in different directories
|
||||
fname1 = Path("dir1") / "file.txt"
|
||||
fname2 = Path("dir2") / "file.txt"
|
||||
fname3 = Path("dir3") / "unique.txt"
|
||||
|
||||
for fname in [fname1, fname2, fname3]:
|
||||
fname.parent.mkdir(parents=True, exist_ok=True)
|
||||
fname.touch()
|
||||
|
||||
# Add one file to chat
|
||||
coder.add_rel_fname(str(fname1))
|
||||
|
||||
# Mock get_tracked_files to return all files
|
||||
mock = MagicMock()
|
||||
mock.return_value = set([str(fname1), str(fname2), str(fname3)])
|
||||
coder.repo.get_tracked_files = mock
|
||||
|
||||
# Check that file mentions skip files with duplicate basenames
|
||||
mentioned = coder.get_file_mentions(f"Check {fname2} and {fname3}")
|
||||
self.assertEqual(mentioned, {str(fname3)})
|
||||
|
||||
# Add a read-only file with same basename
|
||||
coder.abs_read_only_fnames.add(str(fname2.resolve()))
|
||||
mentioned = coder.get_file_mentions(f"Check {fname1} and {fname3}")
|
||||
self.assertEqual(mentioned, {str(fname3)})
|
||||
|
||||
def test_check_for_file_mentions_read_only(self):
|
||||
with GitTemporaryDirectory():
|
||||
io = InputOutput(
|
||||
@@ -821,32 +853,55 @@ This command will print 'Hello, World!' to the console."""
|
||||
with GitTemporaryDirectory():
|
||||
io = InputOutput(yes=True)
|
||||
coder = Coder.create(self.GPT35, "diff", io=io, suggest_shell_commands=False)
|
||||
self.assertFalse(coder.suggest_shell_commands)
|
||||
|
||||
def mock_send(*args, **kwargs):
|
||||
coder.partial_response_content = """Here's a shell command to run:
|
||||
def test_detect_urls_enabled(self):
|
||||
with GitTemporaryDirectory():
|
||||
io = InputOutput(yes=True)
|
||||
coder = Coder.create(self.GPT35, "diff", io=io, detect_urls=True)
|
||||
coder.commands.scraper = MagicMock()
|
||||
coder.commands.scraper.scrape = MagicMock(return_value="some content")
|
||||
|
||||
```bash
|
||||
echo "Hello, World!"
|
||||
```
|
||||
# Test with a message containing a URL
|
||||
message = "Check out https://example.com"
|
||||
coder.check_for_urls(message)
|
||||
coder.commands.scraper.scrape.assert_called_once_with("https://example.com")
|
||||
|
||||
This command will print 'Hello, World!' to the console."""
|
||||
coder.partial_response_function_call = dict()
|
||||
return []
|
||||
def test_detect_urls_disabled(self):
|
||||
with GitTemporaryDirectory():
|
||||
io = InputOutput(yes=True)
|
||||
coder = Coder.create(self.GPT35, "diff", io=io, detect_urls=False)
|
||||
coder.commands.scraper = MagicMock()
|
||||
coder.commands.scraper.scrape = MagicMock(return_value="some content")
|
||||
|
||||
coder.send = mock_send
|
||||
# Test with a message containing a URL
|
||||
message = "Check out https://example.com"
|
||||
result = coder.check_for_urls(message)
|
||||
self.assertEqual(result, [])
|
||||
coder.commands.scraper.scrape.assert_not_called()
|
||||
|
||||
# Mock the handle_shell_commands method to check if it's called
|
||||
coder.handle_shell_commands = MagicMock()
|
||||
def test_unknown_edit_format_exception(self):
|
||||
# Test the exception message format
|
||||
invalid_format = "invalid_format"
|
||||
valid_formats = ["diff", "whole", "map"]
|
||||
exc = UnknownEditFormat(invalid_format, valid_formats)
|
||||
expected_msg = (
|
||||
f"Unknown edit format {invalid_format}. Valid formats are: {', '.join(valid_formats)}"
|
||||
)
|
||||
self.assertEqual(str(exc), expected_msg)
|
||||
|
||||
# Run the coder with a message
|
||||
coder.run(with_message="Suggest a shell command")
|
||||
def test_unknown_edit_format_creation(self):
|
||||
# Test that creating a Coder with invalid edit format raises the exception
|
||||
io = InputOutput(yes=True)
|
||||
invalid_format = "invalid_format"
|
||||
|
||||
# Check if the shell command was added to the list
|
||||
self.assertEqual(len(coder.shell_commands), 1)
|
||||
self.assertEqual(coder.shell_commands[0].strip(), 'echo "Hello, World!"')
|
||||
with self.assertRaises(UnknownEditFormat) as cm:
|
||||
Coder.create(self.GPT35, invalid_format, io=io)
|
||||
|
||||
# Check if handle_shell_commands was called with the correct argument
|
||||
coder.handle_shell_commands.assert_not_called()
|
||||
exc = cm.exception
|
||||
self.assertEqual(exc.edit_format, invalid_format)
|
||||
self.assertIsInstance(exc.valid_formats, list)
|
||||
self.assertTrue(len(exc.valid_formats) > 0)
|
||||
|
||||
def test_coder_create_with_new_file_oserror(self):
|
||||
with GitTemporaryDirectory():
|
||||
|
||||
@@ -99,6 +99,7 @@ def test_pipe_editor():
|
||||
patch("aider.editor.write_temp_file") as mock_write,
|
||||
patch("builtins.open") as mock_open,
|
||||
patch("os.remove") as mock_remove,
|
||||
patch("subprocess.call") as mock_subprocess,
|
||||
):
|
||||
# Setup mocks
|
||||
mock_write.return_value = "temp.txt"
|
||||
@@ -106,22 +107,21 @@ def test_pipe_editor():
|
||||
mock_file.__enter__.return_value.read.return_value = modified_content
|
||||
mock_open.return_value = mock_file
|
||||
|
||||
with patch("subprocess.call") as mock_subprocess:
|
||||
# Test with default editor
|
||||
result = pipe_editor(test_content)
|
||||
assert result == modified_content
|
||||
mock_write.assert_called_with(test_content, None)
|
||||
mock_subprocess.assert_called()
|
||||
# Test with default editor
|
||||
result = pipe_editor(test_content)
|
||||
assert result == modified_content
|
||||
mock_write.assert_called_with(test_content, None)
|
||||
mock_subprocess.assert_called()
|
||||
|
||||
# Test with custom editor
|
||||
result = pipe_editor(test_content, editor="code")
|
||||
assert result == modified_content
|
||||
mock_subprocess.assert_called()
|
||||
# Test with custom editor
|
||||
result = pipe_editor(test_content, editor="code")
|
||||
assert result == modified_content
|
||||
mock_subprocess.assert_called()
|
||||
|
||||
# Test with suffix
|
||||
result = pipe_editor(test_content, suffix="md")
|
||||
assert result == modified_content
|
||||
mock_write.assert_called_with(test_content, "md")
|
||||
# Test with suffix
|
||||
result = pipe_editor(test_content, suffix="md")
|
||||
assert result == modified_content
|
||||
mock_write.assert_called_with(test_content, "md")
|
||||
|
||||
# Test cleanup on permission error
|
||||
mock_remove.side_effect = PermissionError
|
||||
|
||||
@@ -637,6 +637,49 @@ class TestMain(TestCase):
|
||||
)
|
||||
self.assertTrue(coder.suggest_shell_commands)
|
||||
|
||||
def test_detect_urls_default(self):
|
||||
with GitTemporaryDirectory():
|
||||
coder = main(
|
||||
["--exit", "--yes"],
|
||||
input=DummyInput(),
|
||||
output=DummyOutput(),
|
||||
return_coder=True,
|
||||
)
|
||||
self.assertTrue(coder.detect_urls)
|
||||
|
||||
def test_detect_urls_disabled(self):
|
||||
with GitTemporaryDirectory():
|
||||
coder = main(
|
||||
["--no-detect-urls", "--exit", "--yes"],
|
||||
input=DummyInput(),
|
||||
output=DummyOutput(),
|
||||
return_coder=True,
|
||||
)
|
||||
self.assertFalse(coder.detect_urls)
|
||||
|
||||
def test_detect_urls_enabled(self):
|
||||
with GitTemporaryDirectory():
|
||||
coder = main(
|
||||
["--detect-urls", "--exit", "--yes"],
|
||||
input=DummyInput(),
|
||||
output=DummyOutput(),
|
||||
return_coder=True,
|
||||
)
|
||||
self.assertTrue(coder.detect_urls)
|
||||
|
||||
def test_invalid_edit_format(self):
|
||||
with GitTemporaryDirectory():
|
||||
with patch("aider.io.InputOutput.offer_url") as mock_offer_url:
|
||||
result = main(
|
||||
["--edit-format", "not-a-real-format", "--exit", "--yes"],
|
||||
input=DummyInput(),
|
||||
output=DummyOutput(),
|
||||
)
|
||||
self.assertEqual(result, 1) # main() should return 1 on error
|
||||
mock_offer_url.assert_called_once()
|
||||
args, _ = mock_offer_url.call_args
|
||||
self.assertEqual(args[0], "https://aider.chat/docs/more/edit-formats.html")
|
||||
|
||||
def test_chat_language_spanish(self):
|
||||
with GitTemporaryDirectory():
|
||||
coder = main(
|
||||
|
||||
@@ -92,6 +92,36 @@ class TestModels(unittest.TestCase):
|
||||
any("bogus-model" in msg for msg in warning_messages)
|
||||
) # Check that one of the warnings mentions the bogus model
|
||||
|
||||
def test_model_aliases(self):
|
||||
# Test common aliases
|
||||
model = Model("4")
|
||||
self.assertEqual(model.name, "gpt-4-0613")
|
||||
|
||||
model = Model("4o")
|
||||
self.assertEqual(model.name, "gpt-4o-2024-08-06")
|
||||
|
||||
model = Model("35turbo")
|
||||
self.assertEqual(model.name, "gpt-3.5-turbo")
|
||||
|
||||
model = Model("35-turbo")
|
||||
self.assertEqual(model.name, "gpt-3.5-turbo")
|
||||
|
||||
model = Model("3")
|
||||
self.assertEqual(model.name, "gpt-3.5-turbo")
|
||||
|
||||
model = Model("sonnet")
|
||||
self.assertEqual(model.name, "claude-3-sonnet-20241022")
|
||||
|
||||
model = Model("haiku")
|
||||
self.assertEqual(model.name, "claude-3-haiku-20241022")
|
||||
|
||||
model = Model("opus")
|
||||
self.assertEqual(model.name, "claude-3-opus-20240229")
|
||||
|
||||
# Test non-alias passes through unchanged
|
||||
model = Model("gpt-4")
|
||||
self.assertEqual(model.name, "gpt-4")
|
||||
|
||||
def test_aider_extra_model_settings(self):
|
||||
import tempfile
|
||||
|
||||
|
||||
@@ -373,6 +373,19 @@ class TestRepoMapAllLanguages(unittest.TestCase):
|
||||
|
||||
def test_get_repo_map_all_languages(self):
|
||||
language_files = {
|
||||
"dart": (
|
||||
"test.dart",
|
||||
"""void main() {
|
||||
print('Hello, World!');
|
||||
}
|
||||
|
||||
class Greeter {
|
||||
String sayHello(String name) {
|
||||
return 'Hello, $name!';
|
||||
}
|
||||
}
|
||||
""",
|
||||
),
|
||||
"c": (
|
||||
"test.c",
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user