From 486c5ce65ca5e48958c148ad302820f2ab02079b Mon Sep 17 00:00:00 2001 From: Krazer Date: Tue, 11 Jun 2024 17:15:48 -0500 Subject: [PATCH 01/45] add support to load/override model settings --- aider/args.py | 8 ++++- aider/main.py | 64 ++++++++++++++++++++++++----------- aider/models.py | 51 +++++++++++++++++++++------- website/docs/llms/warnings.md | 37 +++++++++++++++++++- website/docs/options.md | 7 +++- 5 files changed, 131 insertions(+), 36 deletions(-) diff --git a/aider/args.py b/aider/args.py index 4fc956062..b67756db2 100644 --- a/aider/args.py +++ b/aider/args.py @@ -141,9 +141,15 @@ def get_parser(default_config_files, git_root): env_var="OPENAI_ORGANIZATION_ID", help="Specify the OpenAI organization ID", ) + group.add_argument( + "--model-settings-file", + metavar="MODEL_SETTINGS_FILE", + default=None, + help="Specify a file with aider model settings for unknown models", + ) group.add_argument( "--model-metadata-file", - metavar="MODEL_FILE", + metavar="MODEL_METADATA_FILE", default=None, help="Specify a file with context window and costs for unknown models", ) diff --git a/aider/main.py b/aider/main.py index 79c1511d8..4fe21aba1 100644 --- a/aider/main.py +++ b/aider/main.py @@ -205,7 +205,48 @@ def parse_lint_cmds(lint_cmds, io): return return res +def generate_search_path_list(default_fname, git_root, command_line_file): + files = [] + default_file = Path(default_fname) + files.append(Path.home() / default_file) # homedir + if git_root: + files.append(Path(git_root) / default_file) # git root + if command_line_file: + files.append(command_line_file) + files.append(default_file.resolve()) + files = list(map(str, files)) + files = list(dict.fromkeys(files)) + + return files + +def register_models(git_root, model_settings_fname, io): + model_settings_files = generate_search_path_list(".aider.models.yml", git_root, model_settings_fname) + + try: + files_loaded = models.register_models(model_settings_files) + if len(files_loaded) > 0: + io.tool_output(f"Loaded {len(files_loaded)} model settings file(s)") + for file_loaded in files_loaded: + io.tool_output(f" - {file_loaded}") + except Exception as e: + io.tool_error(f"Error loading aider model settings: {e}") + return 1 + + return None +def register_litellm_models(git_root, model_metadata_fname, io): + model_metatdata_files = generate_search_path_list(".aider.litellm.models.json", git_root, model_metadata_fname) + + try: + model_metadata_files_loaded = models.register_litellm_models(model_metatdata_files) + if len(model_metadata_files_loaded) > 0: + io.tool_output(f"Loaded {len(model_metadata_files_loaded)} litellm model file(s)") + for model_metadata_file in model_metadata_files_loaded: + io.tool_output(f" - {model_metadata_file}") + except Exception as e: + io.tool_error(f"Error loading litellm models: {e}") + return 1 + def main(argv=None, input=None, output=None, force_git_root=None, return_coder=False): if argv is None: argv = sys.argv[1:] @@ -336,26 +377,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.openai_organization_id: os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id - model_def_files = [] - model_def_fname = Path(".aider.models.json") - model_def_files.append(Path.home() / model_def_fname) # homedir - if git_root: - model_def_files.append(Path(git_root) / model_def_fname) # git root - if args.model_metadata_file: - model_def_files.append(args.model_metadata_file) - model_def_files.append(model_def_fname.resolve()) - model_def_files = list(map(str, model_def_files)) - model_def_files = list(dict.fromkeys(model_def_files)) - try: - model_metadata_files_loaded = models.register_models(model_def_files) - if len(model_metadata_files_loaded) > 0: - io.tool_output(f"Loaded {len(model_metadata_files_loaded)} model file(s)") - for model_metadata_file in model_metadata_files_loaded: - io.tool_output(f" - {model_metadata_file}") - except Exception as e: - io.tool_error(f"Error loading model info/cost: {e}") - return 1 - + register_models(git_root, args.model_settings_file, io) + register_litellm_models(git_root, args.model_metadata_file, io) + main_model = models.Model(args.model, weak_model=args.weak_model) lint_cmds = parse_lint_cmds(args.lint_cmd, io) diff --git a/aider/models.py b/aider/models.py index f51b38bc4..19e04167a 100644 --- a/aider/models.py +++ b/aider/models.py @@ -1,5 +1,6 @@ import difflib import json +import yaml import math import os import sys @@ -425,23 +426,47 @@ class Model: return validate_variables(["GROQ_API_KEY"]) return res - - -def register_models(model_def_fnames): - model_metadata_files_loaded = [] - for model_def_fname in model_def_fnames: - if not os.path.exists(model_def_fname): + +def register_models(model_settings_fnames): + files_loaded = [] + for model_settings_fname in model_settings_fnames: + if not os.path.exists(model_settings_fname): continue - model_metadata_files_loaded.append(model_def_fname) + try: - with open(model_def_fname, "r") as model_def_file: + with open(model_settings_fname, "r") as model_settings_file: + model_settings_list = yaml.safe_load(model_settings_file) + + for model_settings_dict in model_settings_list: + model_settings = ModelSettings(**model_settings_dict) + existing_model_settings = next((ms for ms in MODEL_SETTINGS if ms.name == model_settings.name), None) + + if existing_model_settings: + MODEL_SETTINGS.remove(existing_model_settings) + MODEL_SETTINGS.append(model_settings) + except Exception as e: + raise Exception(f"Error loading model settings from {model_settings_fname}: {e}") + files_loaded.append(model_settings_fname) + + return files_loaded + + +def register_litellm_models(model_fnames): + files_loaded = [] + for model_fname in model_fnames: + if not os.path.exists(model_fname): + continue + + try: + with open(model_fname, "r") as model_def_file: model_def = json.load(model_def_file) - except json.JSONDecodeError as e: - raise Exception(f"Error loading model definition from {model_def_fname}: {e}") + litellm.register_model(model_def) + except Exception as e: + raise Exception(f"Error loading model definition from {model_fname}: {e}") + + files_loaded.append(model_fname) - litellm.register_model(model_def) - - return model_metadata_files_loaded + return files_loaded def validate_variables(vars): diff --git a/website/docs/llms/warnings.md b/website/docs/llms/warnings.md index 213f7cb8d..c33acffd2 100644 --- a/website/docs/llms/warnings.md +++ b/website/docs/llms/warnings.md @@ -8,10 +8,45 @@ nav_order: 900 {% include model-warnings.md %} +## Adding settings for missing models +You can register model settings used by aider for unknown models. +Create a `.aider.models.yml` file in one of these locations: + +- Your home directory. +- The root if your git repo. +- The current directory where you launch aider. +- Or specify a specific file with the `--model-settings-file ` switch. + +If the files above exist, they will be loaded in that order. +Files loaded last will take priority. + +The yaml file should be a a list of dictionary objects for each model, as follows: + +``` +- name: "gpt-3.5-turbo" + edit_format: "whole" + weak_model_name: "gpt-3.5-turbo" + use_repo_map: false + send_undo_reply: false + accepts_images: false + lazy: false + reminder_as_sys_msg: true + examples_as_sys_msg: false +- name: "gpt-4-turbo-2024-04-09" + edit_format: "udiff" + weak_model_name: "gpt-3.5-turbo" + use_repo_map: true + send_undo_reply: true + accepts_images: true + lazy: true + reminder_as_sys_msg: true + examples_as_sys_msg: false +``` + ## Specifying context window size and token costs You can register context window limits and costs for models that aren't known -to aider. Create a `.aider.models.json` file in one of these locations: +to aider. Create a `.aider.litellm.models.json` file in one of these locations: - Your home directory. - The root if your git repo. diff --git a/website/docs/options.md b/website/docs/options.md index 2183782d5..9fe24efe3 100644 --- a/website/docs/options.md +++ b/website/docs/options.md @@ -19,7 +19,8 @@ usage: aider [-h] [--vim] [--openai-api-key] [--anthropic-api-key] [--35turbo] [--models] [--openai-api-base] [--openai-api-type] [--openai-api-version] [--openai-api-deployment-id] [--openai-organization-id] - [--model-metadata-file] [--edit-format] [--weak-model] + [--model-settings-file] [--model-metadata-file] + [--edit-format] [--weak-model] [--show-model-warnings | --no-show-model-warnings] [--map-tokens] [--max-chat-history-tokens] [--env-file] [--input-history-file] [--chat-history-file] @@ -128,6 +129,10 @@ Environment variable: `OPENAI_API_DEPLOYMENT_ID` Specify the OpenAI organization ID Environment variable: `OPENAI_ORGANIZATION_ID` +### `--model-settings-file MODEL_FILE` +Specify a file with aider model settings for unknown models +Environment variable: `AIDER_MODEL_SETTINGS_FILE` + ### `--model-metadata-file MODEL_FILE` Specify a file with context window and costs for unknown models Environment variable: `AIDER_MODEL_METADATA_FILE` From c76957973d59dba67f2a0ee9ea59f2755c0874da Mon Sep 17 00:00:00 2001 From: Krazer Date: Tue, 11 Jun 2024 17:28:21 -0500 Subject: [PATCH 02/45] fix space --- website/docs/options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/options.md b/website/docs/options.md index 9fe24efe3..69f4d7e7d 100644 --- a/website/docs/options.md +++ b/website/docs/options.md @@ -20,7 +20,7 @@ usage: aider [-h] [--vim] [--openai-api-key] [--anthropic-api-key] [--openai-api-type] [--openai-api-version] [--openai-api-deployment-id] [--openai-organization-id] [--model-settings-file] [--model-metadata-file] - [--edit-format] [--weak-model] + [--edit-format] [--weak-model] [--show-model-warnings | --no-show-model-warnings] [--map-tokens] [--max-chat-history-tokens] [--env-file] [--input-history-file] [--chat-history-file] From 249109ba9a14aef66887267191092d3e8e58d8a4 Mon Sep 17 00:00:00 2001 From: "John-Mason P. Shackelford" Date: Fri, 31 May 2024 16:16:35 -0400 Subject: [PATCH 03/45] All AIDER_* environment vars may now be placed within .env --- .pre-commit-config.yaml | 2 +- aider/args.py | 20 +++++++++- aider/main.py | 13 ++++--- aider/tests/test_main.py | 80 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 95b449726..9222c3e25 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ repos: - - repo: https://github.com/pycqa/isort + - repo: https://github.com/PyCQA/isort rev: 5.12.0 hooks: - id: isort diff --git a/aider/args.py b/aider/args.py index 070905bb4..4b0b1bccb 100644 --- a/aider/args.py +++ b/aider/args.py @@ -12,6 +12,21 @@ from aider.args_formatter import MarkdownHelpFormatter, YamlHelpFormatter from .dump import dump # noqa: F401 +def default_env_file(git_root): + return os.path.join(git_root, ".env") if git_root else ".env" + + +def get_preparser(git_root): + parser = configargparse.ArgumentParser(add_help=False) + parser.add_argument( + "--env-file", + metavar="ENV_FILE", + default=default_env_file(git_root), + help="Specify the .env file to load (default: .env in git root)", + ) + return parser + + def get_parser(default_config_files, git_root): parser = configargparse.ArgumentParser( description="aider is GPT powered coding in your terminal", @@ -184,11 +199,12 @@ def get_parser(default_config_files, git_root): " max_chat_history_tokens." ), ) - default_env_file = os.path.join(git_root, ".env") if git_root else ".env" + # This is a duplicate of the argument in the preparser and is a no-op by this time of + # argument parsing, but it's here so that the help is displayed as expected. group.add_argument( "--env-file", metavar="ENV_FILE", - default=default_env_file, + default=default_env_file(git_root), help="Specify the .env file to load (default: .env in git root)", ) diff --git a/aider/main.py b/aider/main.py index c4d211fc7..f1da79066 100644 --- a/aider/main.py +++ b/aider/main.py @@ -10,7 +10,7 @@ from prompt_toolkit.enums import EditingMode from streamlit.web import cli from aider import __version__, models, utils -from aider.args import get_parser +from aider.args import get_parser, get_preparser from aider.coders import Coder from aider.commands import SwitchModel from aider.io import InputOutput @@ -129,7 +129,7 @@ def format_settings(parser, args): for arg, val in sorted(vars(args).items()): if val: val = scrub_sensitive_info(args, str(val)) - show += f" - {arg}: {val}\n" + show += f" - {arg}: {val}\n" # noqa: E221 return show @@ -225,6 +225,12 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F default_config_files.append(Path.home() / conf_fname) # homedir default_config_files = list(map(str, default_config_files)) + preparser = get_preparser(git_root) + pre_args, _ = preparser.parse_known_args() + + # Load the .env file specified in the arguments + load_dotenv(pre_args.env_file) + parser = get_parser(default_config_files, git_root) args = parser.parse_args(argv) @@ -320,9 +326,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F cmd_line = scrub_sensitive_info(args, cmd_line) io.tool_output(cmd_line, log_only=True) - if args.env_file: - load_dotenv(args.env_file) - if args.anthropic_api_key: os.environ["ANTHROPIC_API_KEY"] = args.anthropic_api_key diff --git a/aider/tests/test_main.py b/aider/tests/test_main.py index d319a78dd..001551a28 100644 --- a/aider/tests/test_main.py +++ b/aider/tests/test_main.py @@ -237,3 +237,83 @@ class TestMain(TestCase): main(["--message", test_message]) args, kwargs = MockInputOutput.call_args self.assertEqual(args[1], None) + + def test_dark_mode_sets_code_theme(self): + # Mock Coder.create to capture the configuration + with patch("aider.coders.Coder.create") as MockCoder: + main(["--dark-mode", "--no-git"], input=DummyInput(), output=DummyOutput()) + # Ensure Coder.create was called + MockCoder.assert_called_once() + # Check if the code_theme setting is for dark mode + _, kwargs = MockCoder.call_args + self.assertEqual(kwargs["code_theme"], "monokai") + + def test_light_mode_sets_code_theme(self): + # Mock Coder.create to capture the configuration + with patch("aider.coders.Coder.create") as MockCoder: + main(["--light-mode", "--no-git"], input=DummyInput(), output=DummyOutput()) + # Ensure Coder.create was called + MockCoder.assert_called_once() + # Check if the code_theme setting is for light mode + _, kwargs = MockCoder.call_args + self.assertEqual(kwargs["code_theme"], "default") + + def test_env_file_flag_read(self): + # Create a temporary .env file + env_file_path = Path(self.tempdir) / ".env.test" + env_content = "TEST_ENV_VAR=12345" + env_file_path.write_text(env_content) + + # Run the main function with the --env-file flag + main( + ["--env-file", str(env_file_path), "--no-git"], input=DummyInput(), output=DummyOutput() + ) + + # Check if the environment variable is loaded + self.assertEqual(os.getenv("TEST_ENV_VAR"), "12345") + + def test_default_env_file_read(self): + # Create a temporary .env file + env_file_path = Path(self.tempdir) / ".env" + env_content = "TEST_ENV_VAR=12345" + env_file_path.write_text(env_content) + + # Run the main function with the --env-file flag + main(["--no-git"], input=DummyInput(), output=DummyOutput()) + + # Check if the environment variable is loaded + self.assertEqual(os.getenv("TEST_ENV_VAR"), "12345") + + def test_env_file_flag_sets_automatic_variable(self): + # Create a temporary .env file with custom settings + env_file_path = Path(self.tempdir) / ".env.test" + env_content = "AIDER_DARK_MODE=True" + env_file_path.write_text(env_content) + + # Mock the InputOutput to capture the configuration + with patch("aider.coders.Coder.create") as MockCoder: + main( + ["--env-file", str(env_file_path), "--no-git"], + input=DummyInput(), + output=DummyOutput(), + ) + # Ensure Coder.create was called + MockCoder.assert_called_once() + # Check if the color settings are for dark mode + _, kwargs = MockCoder.call_args + self.assertEqual(kwargs["code_theme"], "monokai") + + def test_default_env_file_sets_automatic_variable(self): + # Create a default .env file in the temporary directory + env_file_path = Path(self.tempdir) / ".env" + env_content = "AIDER_DARK_MODE=True" + env_file_path.write_text(env_content) + + # Mock the InputOutput to capture the configuration + with patch("aider.coders.Coder.create") as MockCoder: + main(["--no-git"], input=DummyInput(), output=DummyOutput()) + # Ensure Coder.create was called + MockCoder.assert_called_once() + # Check if the color settings are for dark mode + _, kwargs = MockCoder.call_args + self.assertEqual(kwargs["code_theme"], "monokai") From 75ec0f626600690675a2275700c9458a49a05265 Mon Sep 17 00:00:00 2001 From: "John-Mason P. Shackelford" Date: Sat, 1 Jun 2024 10:51:38 -0400 Subject: [PATCH 04/45] Added tests to ensure boolean values in .env file are properly handled. --- aider/main.py | 2 +- aider/tests/test_main.py | 69 ++++++++++++++++------------------------ 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/aider/main.py b/aider/main.py index f1da79066..8799acd6c 100644 --- a/aider/main.py +++ b/aider/main.py @@ -226,7 +226,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F default_config_files = list(map(str, default_config_files)) preparser = get_preparser(git_root) - pre_args, _ = preparser.parse_known_args() + pre_args, _ = preparser.parse_known_args(argv) # Load the .env file specified in the arguments load_dotenv(pre_args.env_file) diff --git a/aider/tests/test_main.py b/aider/tests/test_main.py index 001551a28..7eebe1351 100644 --- a/aider/tests/test_main.py +++ b/aider/tests/test_main.py @@ -1,5 +1,4 @@ import os -import shutil import subprocess import tempfile from pathlib import Path @@ -18,14 +17,18 @@ from aider.utils import GitTemporaryDirectory, make_repo class TestMain(TestCase): def setUp(self): + self.original_env = os.environ.copy() os.environ["OPENAI_API_KEY"] = "deadbeef" self.original_cwd = os.getcwd() - self.tempdir = tempfile.mkdtemp() + self.tempdir_obj = tempfile.TemporaryDirectory() + self.tempdir = self.tempdir_obj.name os.chdir(self.tempdir) def tearDown(self): os.chdir(self.original_cwd) - shutil.rmtree(self.tempdir, ignore_errors=True) + self.tempdir_obj.cleanup() + os.environ.clear() + os.environ.update(self.original_env) def test_main_with_empty_dir_no_files_on_command(self): main(["--no-git"], input=DummyInput(), output=DummyOutput()) @@ -258,58 +261,26 @@ class TestMain(TestCase): _, kwargs = MockCoder.call_args self.assertEqual(kwargs["code_theme"], "default") - def test_env_file_flag_read(self): - # Create a temporary .env file - env_file_path = Path(self.tempdir) / ".env.test" - env_content = "TEST_ENV_VAR=12345" - env_file_path.write_text(env_content) - - # Run the main function with the --env-file flag - main( - ["--env-file", str(env_file_path), "--no-git"], input=DummyInput(), output=DummyOutput() - ) - - # Check if the environment variable is loaded - self.assertEqual(os.getenv("TEST_ENV_VAR"), "12345") - - def test_default_env_file_read(self): - # Create a temporary .env file - env_file_path = Path(self.tempdir) / ".env" - env_content = "TEST_ENV_VAR=12345" - env_file_path.write_text(env_content) - - # Run the main function with the --env-file flag - main(["--no-git"], input=DummyInput(), output=DummyOutput()) - - # Check if the environment variable is loaded - self.assertEqual(os.getenv("TEST_ENV_VAR"), "12345") + def create_env_file(self, file_name, content): + env_file_path = Path(self.tempdir) / file_name + env_file_path.write_text(content) + return env_file_path def test_env_file_flag_sets_automatic_variable(self): - # Create a temporary .env file with custom settings - env_file_path = Path(self.tempdir) / ".env.test" - env_content = "AIDER_DARK_MODE=True" - env_file_path.write_text(env_content) - - # Mock the InputOutput to capture the configuration + env_file_path = self.create_env_file(".env.test", "AIDER_DARK_MODE=True") with patch("aider.coders.Coder.create") as MockCoder: main( ["--env-file", str(env_file_path), "--no-git"], input=DummyInput(), output=DummyOutput(), ) - # Ensure Coder.create was called MockCoder.assert_called_once() # Check if the color settings are for dark mode _, kwargs = MockCoder.call_args self.assertEqual(kwargs["code_theme"], "monokai") def test_default_env_file_sets_automatic_variable(self): - # Create a default .env file in the temporary directory - env_file_path = Path(self.tempdir) / ".env" - env_content = "AIDER_DARK_MODE=True" - env_file_path.write_text(env_content) - - # Mock the InputOutput to capture the configuration + self.create_env_file(".env", "AIDER_DARK_MODE=True") with patch("aider.coders.Coder.create") as MockCoder: main(["--no-git"], input=DummyInput(), output=DummyOutput()) # Ensure Coder.create was called @@ -317,3 +288,19 @@ class TestMain(TestCase): # Check if the color settings are for dark mode _, kwargs = MockCoder.call_args self.assertEqual(kwargs["code_theme"], "monokai") + + def test_false_vals_in_env_file(self): + self.create_env_file(".env", "AIDER_SHOW_DIFFS=off") + with patch("aider.coders.Coder.create") as MockCoder: + main(["--no-git"], input=DummyInput(), output=DummyOutput()) + MockCoder.assert_called_once() + _, kwargs = MockCoder.call_args + self.assertEqual(kwargs["show_diffs"], False) + + def test_true_vals_in_env_file(self): + self.create_env_file(".env", "AIDER_SHOW_DIFFS=on") + with patch("aider.coders.Coder.create") as MockCoder: + main(["--no-git"], input=DummyInput(), output=DummyOutput()) + MockCoder.assert_called_once() + _, kwargs = MockCoder.call_args + self.assertEqual(kwargs["show_diffs"], True) From f4e4e3af877fcc781c21a05abdf485211683aac6 Mon Sep 17 00:00:00 2001 From: "John-Mason P. Shackelford" Date: Sat, 1 Jun 2024 11:50:43 -0400 Subject: [PATCH 05/45] Added check to ensure verbose output contains environment variables set with .env --- aider/main.py | 6 ++++++ aider/tests/test_main.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/aider/main.py b/aider/main.py index 8799acd6c..ac8281d4d 100644 --- a/aider/main.py +++ b/aider/main.py @@ -124,6 +124,12 @@ def check_gitignore(git_root, io, ask=True): def format_settings(parser, args): show = scrub_sensitive_info(args, parser.format_values()) + # clean up the headings for consistency w/ new lines + heading_env = "Environment Variables:" + heading_defaults = "Defaults:" + if heading_env in show: + show = show.replace(heading_env, "\n" + heading_env) + show = show.replace(heading_defaults, "\n" + heading_defaults) show += "\n" show += "Option settings:\n" for arg, val in sorted(vars(args).items()): diff --git a/aider/tests/test_main.py b/aider/tests/test_main.py index 7eebe1351..83e0d1234 100644 --- a/aider/tests/test_main.py +++ b/aider/tests/test_main.py @@ -1,6 +1,7 @@ import os import subprocess import tempfile +from io import StringIO from pathlib import Path from unittest import TestCase from unittest.mock import MagicMock, patch @@ -304,3 +305,18 @@ class TestMain(TestCase): MockCoder.assert_called_once() _, kwargs = MockCoder.call_args self.assertEqual(kwargs["show_diffs"], True) + + def test_verbose_mode_lists_env_vars(self): + self.create_env_file(".env", "AIDER_DARK_MODE=on") + with patch("sys.stdout", new_callable=StringIO) as mock_stdout: + main(["--no-git", "--verbose"], input=DummyInput(), output=DummyOutput()) + output = mock_stdout.getvalue() + relevant_output = "\n".join( + line + for line in output.splitlines() + if "AIDER_DARK_MODE" in line or "dark_mode" in line + ) # this bit just helps failing assertions to be easier to read + self.assertIn("AIDER_DARK_MODE", relevant_output) + self.assertIn("dark_mode", relevant_output) + self.assertRegex(relevant_output, r"AIDER_DARK_MODE:\s+on") + self.assertRegex(relevant_output, r"dark_mode:\s+True") From dd6a7964b6f34e4bfa63d172b48c38fce0270b36 Mon Sep 17 00:00:00 2001 From: "John-Mason P. Shackelford" Date: Tue, 18 Jun 2024 11:39:26 -0400 Subject: [PATCH 06/45] tempdirs in test_main now cleanup without windows errors --- aider/tests/test_main.py | 6 +++--- aider/utils.py | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/aider/tests/test_main.py b/aider/tests/test_main.py index 83e0d1234..b576d3754 100644 --- a/aider/tests/test_main.py +++ b/aider/tests/test_main.py @@ -13,7 +13,7 @@ from prompt_toolkit.output import DummyOutput from aider.dump import dump # noqa: F401 from aider.io import InputOutput from aider.main import check_gitignore, main, setup_git -from aider.utils import GitTemporaryDirectory, make_repo +from aider.utils import GitTemporaryDirectory, IgnorantTemporaryDirectory, make_repo class TestMain(TestCase): @@ -21,7 +21,7 @@ class TestMain(TestCase): self.original_env = os.environ.copy() os.environ["OPENAI_API_KEY"] = "deadbeef" self.original_cwd = os.getcwd() - self.tempdir_obj = tempfile.TemporaryDirectory() + self.tempdir_obj = IgnorantTemporaryDirectory() self.tempdir = self.tempdir_obj.name os.chdir(self.tempdir) @@ -34,7 +34,7 @@ class TestMain(TestCase): def test_main_with_empty_dir_no_files_on_command(self): main(["--no-git"], input=DummyInput(), output=DummyOutput()) - def test_main_with_empty_dir_new_file(self): + def test_main_with_emptqy_dir_new_file(self): main(["foo.txt", "--yes", "--no-git"], input=DummyInput(), output=DummyOutput()) self.assertTrue(os.path.exists("foo.txt")) diff --git a/aider/utils.py b/aider/utils.py index 7636eb119..6d097fbe7 100644 --- a/aider/utils.py +++ b/aider/utils.py @@ -17,11 +17,17 @@ class IgnorantTemporaryDirectory: return self.temp_dir.__enter__() def __exit__(self, exc_type, exc_val, exc_tb): + self.cleanup() + + def cleanup(self): try: - self.temp_dir.__exit__(exc_type, exc_val, exc_tb) + self.temp_dir.cleanup() except (OSError, PermissionError): pass # Ignore errors (Windows) + def __getattr__(self, item): + return getattr(self.temp_dir, item) + class ChdirTemporaryDirectory(IgnorantTemporaryDirectory): def __init__(self): From 705bb64580885c8d91b69dd9f12bd3c0fd58c9fa Mon Sep 17 00:00:00 2001 From: John-Mason Shackelford <160164118+jpshack-at-palomar@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:10:57 -0400 Subject: [PATCH 07/45] Update windows-tests.yml --- .github/workflows/windows-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index de4520aa6..c5b2696a6 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -13,6 +13,7 @@ on: - README.md branches: - main + - issue-630 jobs: build: From b4291aef377d5e596e3cb1f830914d5fa98368b2 Mon Sep 17 00:00:00 2001 From: John-Mason Shackelford <160164118+jpshack-at-palomar@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:13:36 -0400 Subject: [PATCH 08/45] Update windows-tests.yml --- .github/workflows/windows-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index c5b2696a6..de4520aa6 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -13,7 +13,6 @@ on: - README.md branches: - main - - issue-630 jobs: build: From 39f10aefe0079a9e5e7ad7a33f40c5f8a680628e Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 10:05:10 -0700 Subject: [PATCH 09/45] Finished removing reliance on aider: --- aider/commands.py | 2 +- aider/tests/test_commands.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index f6b0c3cba..58fa7d6c6 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -332,7 +332,7 @@ class Commands: last_commit = self.coder.repo.repo.head.commit if ( - not last_commit.message.startswith("aider:") + "(aider)" not in last_commit.committer.name or last_commit.hexsha[:7] != self.coder.last_aider_commit_hash ): self.io.tool_error("The last commit was not made by aider in this chat session.") diff --git a/aider/tests/test_commands.py b/aider/tests/test_commands.py index 8cc67b6d8..2fa84817b 100644 --- a/aider/tests/test_commands.py +++ b/aider/tests/test_commands.py @@ -523,16 +523,20 @@ class TestCommands(TestCase): other_path.write_text("other content") repo.git.add(str(other_path)) + os.environ["GIT_COMMITTER_NAME"] = "Foo (aider)" + # Create and commit a file filename = "test_file.txt" file_path = Path(repo_dir) / filename file_path.write_text("first content") repo.git.add(filename) - repo.git.commit("-m", "aider: first commit") + repo.git.commit("-m", "first commit") file_path.write_text("second content") repo.git.add(filename) - repo.git.commit("-m", "aider: second commit") + repo.git.commit("-m", "second commit") + + del os.environ["GIT_COMMITTER_NAME"] # Store the commit hash last_commit_hash = repo.head.commit.hexsha[:7] From 9e228670a23ba5c338f7553a349bc2b75dac30f7 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 11:18:52 -0700 Subject: [PATCH 10/45] append (aider) to author if aider wrote the code --- aider/commands.py | 2 +- aider/repo.py | 23 ++++++++++++++++------- aider/tests/test_commands.py | 4 ++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index 58fa7d6c6..00189fecd 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -332,7 +332,7 @@ class Commands: last_commit = self.coder.repo.repo.head.commit if ( - "(aider)" not in last_commit.committer.name + not last_commit.author.name.endswith(" (aider)") or last_commit.hexsha[:7] != self.coder.last_aider_commit_hash ): self.io.tool_error("The last commit was not made by aider in this chat session.") diff --git a/aider/repo.py b/aider/repo.py index 214d2c6d9..38f5ef8f5 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -88,11 +88,15 @@ class GitRepo: else: cmd += ["-a"] + original_user_name = self.repo.config_reader().get_value("user", "name") + original_committer_name_env = os.environ.get("GIT_COMMITTER_NAME") + + committer_name = f"{original_user_name} (aider)" + os.environ["GIT_COMMITTER_NAME"] = committer_name + if aider_edits: - user_name = self.repo.config_reader().get_value("user", "name") - committer_name = f"{user_name} (aider)" - original_committer_name = os.environ.get("GIT_COMMITTER_NAME") - os.environ["GIT_COMMITTER_NAME"] = committer_name + original_auther_name_env = os.environ.get("GIT_AUTHOR_NAME") + os.environ["GIT_AUTHOR_NAME"] = committer_name self.repo.git.commit(cmd) commit_hash = self.repo.head.commit.hexsha[:7] @@ -100,10 +104,15 @@ class GitRepo: # Restore the original GIT_COMMITTER_NAME if aider_edits: - if original_committer_name is not None: - os.environ["GIT_COMMITTER_NAME"] = original_committer_name + if original_auther_name_env is not None: + os.environ["GIT_AUTHOR_NAME"] = original_auther_name_env else: - del os.environ["GIT_COMMITTER_NAME"] + del os.environ["GIT_AUTHOR_NAME"] + + if original_committer_name_env is not None: + os.environ["GIT_COMMITTER_NAME"] = original_committer_name_env + else: + del os.environ["GIT_COMMITTER_NAME"] return commit_hash, commit_message diff --git a/aider/tests/test_commands.py b/aider/tests/test_commands.py index 2fa84817b..f6629f481 100644 --- a/aider/tests/test_commands.py +++ b/aider/tests/test_commands.py @@ -523,7 +523,7 @@ class TestCommands(TestCase): other_path.write_text("other content") repo.git.add(str(other_path)) - os.environ["GIT_COMMITTER_NAME"] = "Foo (aider)" + os.environ["GIT_AUTHOR_NAME"] = "Foo (aider)" # Create and commit a file filename = "test_file.txt" @@ -536,7 +536,7 @@ class TestCommands(TestCase): repo.git.add(filename) repo.git.commit("-m", "second commit") - del os.environ["GIT_COMMITTER_NAME"] + del os.environ["GIT_AUTHOR_NAME"] # Store the commit hash last_commit_hash = repo.head.commit.hexsha[:7] From aa3dbac94c67a98371715093b2945f783d642975 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 11:23:34 -0700 Subject: [PATCH 11/45] updated git docs --- website/docs/git.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/website/docs/git.md b/website/docs/git.md index b25418b93..f9c8bb5ad 100644 --- a/website/docs/git.md +++ b/website/docs/git.md @@ -14,14 +14,21 @@ Aider is tightly integrated with git, which makes it easy to: Aider specifically uses git in these ways: - - It asks to create a git repo if you launch it in a directory without one. - - Whenever aider edits a file, it commits those changes with a descriptive commit message. This makes it easy to undo or review aider's changes. - - Aider takes special care before editing files that already have uncommitted changes (dirty files). Aider will first commit any preexisting changes with a descriptive commit message. This keeps your edits separate from aider's edits, and makes sure you never lose your work if aider makes an inappropriate change. +- It asks to create a git repo if you launch it in a directory without one. +- Whenever aider edits a file, it commits those changes with a descriptive commit message. This makes it easy to undo or review aider's changes. +These commits will have "(aider)" appended to their git author and git committer metadata. +- Aider takes special care before editing files that already have uncommitted changes (dirty files). Aider will first commit any preexisting changes with a descriptive commit message. +This keeps your edits separate from aider's edits, and makes sure you never lose your work if aider makes an inappropriate change. +These commits will have "(aider)" appended to their git committer metadata. + +## In-chat commands Aider also allows you to use in-chat commands to `/diff` or `/undo` the last change. To do more complex management of your git history, you cat use raw `git` commands, either by using `/git` within the chat, or with standard git tools outside of aider. +## Disabling git integration + While it is not recommended, you can disable aider's use of git in a few ways: - `--no-auto-commits` will stop aider from git committing each of its changes. From fed0bf55c2e4c19e4b855a14d74cb88be7435b9d Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 11:34:45 -0700 Subject: [PATCH 12/45] Add support for generating dotenv help text. --- aider/args.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/aider/args.py b/aider/args.py index 4b0b1bccb..c6b44acc6 100644 --- a/aider/args.py +++ b/aider/args.py @@ -7,7 +7,7 @@ import sys import configargparse from aider import __version__, models -from aider.args_formatter import MarkdownHelpFormatter, YamlHelpFormatter +from aider.args_formatter import MarkdownHelpFormatter, YamlHelpFormatter#, DotEnvFormatter from .dump import dump # noqa: F401 @@ -516,16 +516,31 @@ def get_sample_yaml(): return argparse.ArgumentParser.format_help(parser) return parser.format_help() +def get_sample_dotenv(): + os.environ["COLUMNS"] = "120" + sys.argv = ["aider"] + parser = get_parser([], None) + + # This instantiates all the action.env_var values + parser.parse_known_args() + + parser.formatter_class = DotEnvFormatter + + return argparse.ArgumentParser.format_help(parser) + return parser.format_help() def main(): arg = sys.argv[1] if len(sys.argv[1:]) else None if arg == "md": print(get_md_help()) + elif arg == "dotenv": + print(get_sample_dotenv()) else: print(get_sample_yaml()) + if __name__ == "__main__": status = main() sys.exit(status) From 289ab516e912ca9862067877c58b53a67ac70c5d Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 18 Jun 2024 11:34:46 -0700 Subject: [PATCH 13/45] Added DotEnvFormatter class for formatting .env help text in argparse. --- aider/args.py | 2 +- aider/args_formatter.py | 74 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/aider/args.py b/aider/args.py index c6b44acc6..98b612905 100644 --- a/aider/args.py +++ b/aider/args.py @@ -7,7 +7,7 @@ import sys import configargparse from aider import __version__, models -from aider.args_formatter import MarkdownHelpFormatter, YamlHelpFormatter#, DotEnvFormatter +from aider.args_formatter import MarkdownHelpFormatter, YamlHelpFormatter, DotEnvFormatter from .dump import dump # noqa: F401 diff --git a/aider/args_formatter.py b/aider/args_formatter.py index 2503cd007..1c898cd90 100644 --- a/aider/args_formatter.py +++ b/aider/args_formatter.py @@ -3,6 +3,80 @@ import argparse from .dump import dump # noqa: F401 +class DotEnvFormatter(argparse.HelpFormatter): + def start_section(self, heading): + res = "\n\n" + res += "#" * (len(heading) + 3) + res += f"\n# {heading}" + super().start_section(res) + + def _format_usage(self, usage, actions, groups, prefix): + return "" + + def _format_text(self, text): + return """ +########################################################## +# Sample .env +# This file lists *all* the valid configuration entries. +# Place in your home dir, or at the root of your git repo. +########################################################## + +""" + + def _format_action(self, action): + if not action.option_strings: + return "" + + parts = [""] + + metavar = action.metavar + if not metavar and isinstance(action, argparse._StoreAction): + metavar = "VALUE" + + default = action.default + if default == argparse.SUPPRESS: + default = "" + elif isinstance(default, str): + pass + elif isinstance(default, list) and not default: + default = "" + elif action.default is not None: + default = "true" if default else "false" + else: + default = "" + + if action.help: + parts.append(f"## {action.help}") + + for switch in action.option_strings: + if switch.startswith("--"): + break + switch = switch.lstrip("-") + + if isinstance(action, argparse._StoreTrueAction): + default = False + elif isinstance(action, argparse._StoreConstAction): + default = False + + if default is False: + default = "false" + if default is True: + default = "true" + + if default: + parts.append(f"{switch}={default}\n") + else: + parts.append(f"{switch}=\n") + + return "\n".join(parts) + "\n" + + def _format_action_invocation(self, action): + return "" + + def _format_args(self, action, default_metavar): + return "" + + class YamlHelpFormatter(argparse.HelpFormatter): def start_section(self, heading): res = "\n\n" From 3c210286ba2bda0fd89371cdd94b3aa83cd5f742 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 18 Jun 2024 11:35:54 -0700 Subject: [PATCH 14/45] Add environment variable information to argparse help text. --- aider/args_formatter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aider/args_formatter.py b/aider/args_formatter.py index 1c898cd90..4a8aa4d0b 100644 --- a/aider/args_formatter.py +++ b/aider/args_formatter.py @@ -48,6 +48,13 @@ class DotEnvFormatter(argparse.HelpFormatter): if action.help: parts.append(f"## {action.help}") + if action.env_var: + env_var = action.env_var + if default: + parts.append(f"{env_var}={default}\n") + else: + parts.append(f"{env_var}=\n") + for switch in action.option_strings: if switch.startswith("--"): break From a2cd025476aa2c1c9cf80491a90729c09e3d799b Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Tue, 18 Jun 2024 12:43:42 -0700 Subject: [PATCH 15/45] Updated dotenv.md with sample dotenv content generation cog script. --- website/docs/dotenv.md | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/website/docs/dotenv.md b/website/docs/dotenv.md index e45fc5783..f68fc0fb4 100644 --- a/website/docs/dotenv.md +++ b/website/docs/dotenv.md @@ -19,15 +19,9 @@ You can give it an explicit file to load with the `--env-file ` parame Here is an example `.env` file: -``` -OPENAI_API_KEY= -ANTHROPIC_API_KEY= -GROQ_API_KEY= -OPENROUTER_API_KEY= - -AZURE_API_KEY= -AZURE_API_VERSION=2023-05-15 -AZURE_API_BASE=https://example-endpoint.openai.azure.com - -OLLAMA_API_BASE=http://127.0.0.1:11434 +```dotenv +[[[cog +from aider.args import get_sample_dotenv +print(get_sample_dotenv()) +]]] ``` From 2cb4c0d5abc866bcdbdc8ef6045065fad6ab7226 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 12:57:19 -0700 Subject: [PATCH 16/45] Updated .env docs --- aider/args_formatter.py | 50 ++++---- aider/urls.py | 1 + scripts/update-docs.sh | 1 + website/assets/sample.env | 226 +++++++++++++++++++++++++++++++++ website/docs/dotenv.md | 254 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 495 insertions(+), 37 deletions(-) create mode 100644 website/assets/sample.env diff --git a/aider/args_formatter.py b/aider/args_formatter.py index 4a8aa4d0b..b7dfbc540 100644 --- a/aider/args_formatter.py +++ b/aider/args_formatter.py @@ -1,5 +1,7 @@ import argparse +from aider import urls + from .dump import dump # noqa: F401 @@ -14,24 +16,36 @@ class DotEnvFormatter(argparse.HelpFormatter): return "" def _format_text(self, text): - return """ + return f""" ########################################################## -# Sample .env +# Sample aider .env file # This file lists *all* the valid configuration entries. # Place in your home dir, or at the root of your git repo. ########################################################## +################# +# LLM parameters: +# +# Include xxx_API_KEY parameters and other params needed for your LLMs. +# See {urls.llms} for details. + +## OpenAI +#OPENAI_API_KEY= + +## Anthropic +#ANTHROPIC_API_KEY= + +##... """ def _format_action(self, action): if not action.option_strings: return "" - parts = [""] + if not action.env_var: + return - metavar = action.metavar - if not metavar and isinstance(action, argparse._StoreAction): - metavar = "VALUE" + parts = [""] default = action.default if default == argparse.SUPPRESS: @@ -51,29 +65,9 @@ class DotEnvFormatter(argparse.HelpFormatter): if action.env_var: env_var = action.env_var if default: - parts.append(f"{env_var}={default}\n") + parts.append(f"#{env_var}={default}\n") else: - parts.append(f"{env_var}=\n") - - for switch in action.option_strings: - if switch.startswith("--"): - break - switch = switch.lstrip("-") - - if isinstance(action, argparse._StoreTrueAction): - default = False - elif isinstance(action, argparse._StoreConstAction): - default = False - - if default is False: - default = "false" - if default is True: - default = "true" - - if default: - parts.append(f"{switch}={default}\n") - else: - parts.append(f"{switch}=\n") + parts.append(f"#{env_var}=\n") return "\n".join(parts) + "\n" diff --git a/aider/urls.py b/aider/urls.py index d2863e705..8e21742d3 100644 --- a/aider/urls.py +++ b/aider/urls.py @@ -6,3 +6,4 @@ enable_playwright = "https://aider.chat/docs/install/optional.html#enable-playwr favicon = "https://aider.chat/assets/icons/favicon-32x32.png" model_warnings = "https://aider.chat/docs/llms/warnings.html" token_limits = "https://aider.chat/docs/troubleshooting/token-limits.html" +llms = "https://aider.chat/docs/llms.html" diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh index 4fe32efba..fc16c4c66 100755 --- a/scripts/update-docs.sh +++ b/scripts/update-docs.sh @@ -14,6 +14,7 @@ cog $ARG \ README.md \ website/index.md \ website/HISTORY.md \ + website/docs/dotenv.md \ website/docs/commands.md \ website/docs/languages.md \ website/docs/options.md \ diff --git a/website/assets/sample.env b/website/assets/sample.env new file mode 100644 index 000000000..ac7c100ee --- /dev/null +++ b/website/assets/sample.env @@ -0,0 +1,226 @@ +########################################################## +# Sample aider .env file +# This file lists *all* the valid configuration entries. +# Place in your home dir, or at the root of your git repo. +########################################################## + +################# +# LLM parameters: +# +# Include xxx_API_KEY parameters and other params needed for your LLMs. +# See https://aider.chat/docs/llms.html for details. + +## OpenAI +#OPENAI_API_KEY= + +## Anthropic +#ANTHROPIC_API_KEY= + +##... + +####### +# Main: + +## Log the conversation with the LLM to this file (for example, .aider.llm.history) +#AIDER_LLM_HISTORY_FILE= + +## Specify the OpenAI API key +#OPENAI_API_KEY= + +## Specify the Anthropic API key +#ANTHROPIC_API_KEY= + +## Specify the model to use for the main chat (default: gpt-4o) +#AIDER_MODEL=gpt-4o + +## Use claude-3-opus-20240229 model for the main chat +#AIDER_OPUS= + +## Use claude-3-sonnet-20240229 model for the main chat +#AIDER_SONNET= + +## Use gpt-4-0613 model for the main chat +#AIDER_4= + +## Use gpt-4o model for the main chat +#AIDER_4O= + +## Use gpt-4-1106-preview model for the main chat +#AIDER_4_TURBO= + +## Use gpt-3.5-turbo model for the main chat +#AIDER_35TURBO= + +################# +# Model Settings: + +## List known models which match the (partial) MODEL name +#AIDER_MODELS= + +## Specify the api base url +#OPENAI_API_BASE= + +## Specify the api_type +#OPENAI_API_TYPE= + +## Specify the api_version +#OPENAI_API_VERSION= + +## Specify the deployment_id +#OPENAI_API_DEPLOYMENT_ID= + +## Specify the OpenAI organization ID +#OPENAI_ORGANIZATION_ID= + +## Specify a file with context window and costs for unknown models +#AIDER_MODEL_METADATA_FILE= + +## Specify what edit format the LLM should use (default depends on model) +#AIDER_EDIT_FORMAT= + +## Specify the model to use for commit messages and chat history summarization (default depends on --model) +#AIDER_WEAK_MODEL= + +## Only work with models that have meta-data available (default: True) +#AIDER_SHOW_MODEL_WARNINGS=true + +## Max number of tokens to use for repo map, use 0 to disable (default: 1024) +#AIDER_MAP_TOKENS=true + +## Maximum number of tokens to use for chat history. If not specified, uses the model's max_chat_history_tokens. +#AIDER_MAX_CHAT_HISTORY_TOKENS= + +## Specify the .env file to load (default: .env in git root) +#AIDER_ENV_FILE=.env + +################ +# History Files: + +## Specify the chat input history file (default: .aider.input.history) +#AIDER_INPUT_HISTORY_FILE=.aider.input.history + +## Specify the chat history file (default: .aider.chat.history.md) +#AIDER_CHAT_HISTORY_FILE=.aider.chat.history.md + +## Restore the previous chat history messages (default: False) +#AIDER_RESTORE_CHAT_HISTORY=false + +################## +# Output Settings: + +## Use colors suitable for a dark terminal background (default: False) +#AIDER_DARK_MODE=false + +## Use colors suitable for a light terminal background (default: False) +#AIDER_LIGHT_MODE=false + +## Enable/disable pretty, colorized output (default: True) +#AIDER_PRETTY=true + +## Enable/disable streaming responses (default: True) +#AIDER_STREAM=true + +## Set the color for user input (default: #00cc00) +#AIDER_USER_INPUT_COLOR=#00cc00 + +## Set the color for tool output (default: None) +#AIDER_TOOL_OUTPUT_COLOR= + +## Set the color for tool error messages (default: red) +#AIDER_TOOL_ERROR_COLOR=#FF2222 + +## Set the color for assistant output (default: #0088ff) +#AIDER_ASSISTANT_OUTPUT_COLOR=#0088ff + +## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light) +#AIDER_CODE_THEME=default + +## Show diffs when committing changes (default: False) +#AIDER_SHOW_DIFFS=false + +############### +# Git Settings: + +## Enable/disable looking for a git repo (default: True) +#AIDER_GIT=true + +## Enable/disable adding .aider* to .gitignore (default: True) +#AIDER_GITIGNORE=true + +## Specify the aider ignore file (default: .aiderignore in git root) +#AIDER_AIDERIGNORE=.aiderignore + +## Enable/disable auto commit of LLM changes (default: True) +#AIDER_AUTO_COMMITS=true + +## Enable/disable commits when repo is found dirty (default: True) +#AIDER_DIRTY_COMMITS=true + +## Perform a dry run without modifying files (default: False) +#AIDER_DRY_RUN=false + +######################## +# Fixing and committing: + +## Commit all pending changes with a suitable commit message, then exit +#AIDER_COMMIT=false + +## Lint and fix provided files, or dirty files if none provided +#AIDER_LINT=false + +## Specify lint commands to run for different languages, eg: "python: flake8 --select=..." (can be used multiple times) +#AIDER_LINT_CMD= + +## Enable/disable automatic linting after changes (default: True) +#AIDER_AUTO_LINT=true + +## Specify command to run tests +#AIDER_TEST_CMD= + +## Enable/disable automatic testing after changes (default: False) +#AIDER_AUTO_TEST=false + +## Run tests and fix problems found +#AIDER_TEST=false + +################# +# Other Settings: + +## Use VI editing mode in the terminal (default: False) +#AIDER_VIM=false + +## Specify the language for voice using ISO 639-1 code (default: auto) +#AIDER_VOICE_LANGUAGE=en + +## Check for updates and return status in the exit code +#AIDER_CHECK_UPDATE=false + +## Skips checking for the update when the program runs +#AIDER_SKIP_CHECK_UPDATE=false + +## Apply the changes from the given file instead of running the chat (debug) +#AIDER_APPLY= + +## Always say yes to every confirmation +#AIDER_YES= + +## Enable verbose output +#AIDER_VERBOSE=false + +## Print the repo map and exit (debug) +#AIDER_SHOW_REPO_MAP=false + +## Print the system prompts and exit (debug) +#AIDER_SHOW_PROMPTS=false + +## Specify a single message to send the LLM, process reply then exit (disables chat mode) +#AIDER_MESSAGE= + +## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode) +#AIDER_MESSAGE_FILE= + +## Specify the encoding for input and output (default: utf-8) +#AIDER_ENCODING=utf-8 + +## Run aider in your browser +#AIDER_GUI=false diff --git a/website/docs/dotenv.md b/website/docs/dotenv.md index f68fc0fb4..71d2f1e50 100644 --- a/website/docs/dotenv.md +++ b/website/docs/dotenv.md @@ -4,12 +4,12 @@ nav_order: 900 description: Using a .env file to store LLM API keys for aider. --- -# Storing LLM params in .env +# Config with .env You can use a `.env` file to store API keys and other settings for the -models you use with aider. -You currently can not set general aider options -in the `.env` file, only LLM environment variables. +models you use with aider +You can also set many general aider options +in the `.env` file. {% include special-keys.md %} @@ -17,11 +17,247 @@ Aider will look for a `.env` file in the root of your git repo or in the current directory. You can give it an explicit file to load with the `--env-file ` parameter. -Here is an example `.env` file: +Below is a sample `.env` file, which you +can also +[download from GitHub](https://github.com/paul-gauthier/aider/blob/main/website/assets/sample.env). -```dotenv -[[[cog + ``` +########################################################## +# Sample aider .env file +# This file lists *all* the valid configuration entries. +# Place in your home dir, or at the root of your git repo. +########################################################## + +################# +# LLM parameters: +# +# Include xxx_API_KEY parameters and other params needed for your LLMs. +# See https://aider.chat/docs/llms.html for details. + +## OpenAI +#OPENAI_API_KEY= + +## Anthropic +#ANTHROPIC_API_KEY= + +##... + +####### +# Main: + +## Log the conversation with the LLM to this file (for example, .aider.llm.history) +#AIDER_LLM_HISTORY_FILE= + +## Specify the OpenAI API key +#OPENAI_API_KEY= + +## Specify the Anthropic API key +#ANTHROPIC_API_KEY= + +## Specify the model to use for the main chat (default: gpt-4o) +#AIDER_MODEL=gpt-4o + +## Use claude-3-opus-20240229 model for the main chat +#AIDER_OPUS= + +## Use claude-3-sonnet-20240229 model for the main chat +#AIDER_SONNET= + +## Use gpt-4-0613 model for the main chat +#AIDER_4= + +## Use gpt-4o model for the main chat +#AIDER_4O= + +## Use gpt-4-1106-preview model for the main chat +#AIDER_4_TURBO= + +## Use gpt-3.5-turbo model for the main chat +#AIDER_35TURBO= + +################# +# Model Settings: + +## List known models which match the (partial) MODEL name +#AIDER_MODELS= + +## Specify the api base url +#OPENAI_API_BASE= + +## Specify the api_type +#OPENAI_API_TYPE= + +## Specify the api_version +#OPENAI_API_VERSION= + +## Specify the deployment_id +#OPENAI_API_DEPLOYMENT_ID= + +## Specify the OpenAI organization ID +#OPENAI_ORGANIZATION_ID= + +## Specify a file with context window and costs for unknown models +#AIDER_MODEL_METADATA_FILE= + +## Specify what edit format the LLM should use (default depends on model) +#AIDER_EDIT_FORMAT= + +## Specify the model to use for commit messages and chat history summarization (default depends on --model) +#AIDER_WEAK_MODEL= + +## Only work with models that have meta-data available (default: True) +#AIDER_SHOW_MODEL_WARNINGS=true + +## Max number of tokens to use for repo map, use 0 to disable (default: 1024) +#AIDER_MAP_TOKENS=true + +## Maximum number of tokens to use for chat history. If not specified, uses the model's max_chat_history_tokens. +#AIDER_MAX_CHAT_HISTORY_TOKENS= + +## Specify the .env file to load (default: .env in git root) +#AIDER_ENV_FILE=.env + +################ +# History Files: + +## Specify the chat input history file (default: .aider.input.history) +#AIDER_INPUT_HISTORY_FILE=.aider.input.history + +## Specify the chat history file (default: .aider.chat.history.md) +#AIDER_CHAT_HISTORY_FILE=.aider.chat.history.md + +## Restore the previous chat history messages (default: False) +#AIDER_RESTORE_CHAT_HISTORY=false + +################## +# Output Settings: + +## Use colors suitable for a dark terminal background (default: False) +#AIDER_DARK_MODE=false + +## Use colors suitable for a light terminal background (default: False) +#AIDER_LIGHT_MODE=false + +## Enable/disable pretty, colorized output (default: True) +#AIDER_PRETTY=true + +## Enable/disable streaming responses (default: True) +#AIDER_STREAM=true + +## Set the color for user input (default: #00cc00) +#AIDER_USER_INPUT_COLOR=#00cc00 + +## Set the color for tool output (default: None) +#AIDER_TOOL_OUTPUT_COLOR= + +## Set the color for tool error messages (default: red) +#AIDER_TOOL_ERROR_COLOR=#FF2222 + +## Set the color for assistant output (default: #0088ff) +#AIDER_ASSISTANT_OUTPUT_COLOR=#0088ff + +## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light) +#AIDER_CODE_THEME=default + +## Show diffs when committing changes (default: False) +#AIDER_SHOW_DIFFS=false + +############### +# Git Settings: + +## Enable/disable looking for a git repo (default: True) +#AIDER_GIT=true + +## Enable/disable adding .aider* to .gitignore (default: True) +#AIDER_GITIGNORE=true + +## Specify the aider ignore file (default: .aiderignore in git root) +#AIDER_AIDERIGNORE=.aiderignore + +## Enable/disable auto commit of LLM changes (default: True) +#AIDER_AUTO_COMMITS=true + +## Enable/disable commits when repo is found dirty (default: True) +#AIDER_DIRTY_COMMITS=true + +## Perform a dry run without modifying files (default: False) +#AIDER_DRY_RUN=false + +######################## +# Fixing and committing: + +## Commit all pending changes with a suitable commit message, then exit +#AIDER_COMMIT=false + +## Lint and fix provided files, or dirty files if none provided +#AIDER_LINT=false + +## Specify lint commands to run for different languages, eg: "python: flake8 --select=..." (can be used multiple times) +#AIDER_LINT_CMD= + +## Enable/disable automatic linting after changes (default: True) +#AIDER_AUTO_LINT=true + +## Specify command to run tests +#AIDER_TEST_CMD= + +## Enable/disable automatic testing after changes (default: False) +#AIDER_AUTO_TEST=false + +## Run tests and fix problems found +#AIDER_TEST=false + +################# +# Other Settings: + +## Use VI editing mode in the terminal (default: False) +#AIDER_VIM=false + +## Specify the language for voice using ISO 639-1 code (default: auto) +#AIDER_VOICE_LANGUAGE=en + +## Check for updates and return status in the exit code +#AIDER_CHECK_UPDATE=false + +## Skips checking for the update when the program runs +#AIDER_SKIP_CHECK_UPDATE=false + +## Apply the changes from the given file instead of running the chat (debug) +#AIDER_APPLY= + +## Always say yes to every confirmation +#AIDER_YES= + +## Enable verbose output +#AIDER_VERBOSE=false + +## Print the repo map and exit (debug) +#AIDER_SHOW_REPO_MAP=false + +## Print the system prompts and exit (debug) +#AIDER_SHOW_PROMPTS=false + +## Specify a single message to send the LLM, process reply then exit (disables chat mode) +#AIDER_MESSAGE= + +## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode) +#AIDER_MESSAGE_FILE= + +## Specify the encoding for input and output (default: utf-8) +#AIDER_ENCODING=utf-8 + +## Run aider in your browser +#AIDER_GUI=false +``` + + + From 1a8f3ff43153ed2cb6d07515c4bd6dac6657662f Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 12:58:41 -0700 Subject: [PATCH 17/45] copy --- aider/args_formatter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aider/args_formatter.py b/aider/args_formatter.py index b7dfbc540..cc7e3e73d 100644 --- a/aider/args_formatter.py +++ b/aider/args_formatter.py @@ -18,9 +18,9 @@ class DotEnvFormatter(argparse.HelpFormatter): def _format_text(self, text): return f""" ########################################################## -# Sample aider .env file -# This file lists *all* the valid configuration entries. -# Place in your home dir, or at the root of your git repo. +# Sample aider .env file. +# Place at the root of your git repo. +# Or use `aider --env ` to specify. ########################################################## ################# From 5fd567362de9e339a52c7068f3351300938aee4b Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 13:06:09 -0700 Subject: [PATCH 18/45] improved author/committer name tests --- aider/tests/test_repo.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/aider/tests/test_repo.py b/aider/tests/test_repo.py index 961fe8ee9..e4497d72a 100644 --- a/aider/tests/test_repo.py +++ b/aider/tests/test_repo.py @@ -160,11 +160,23 @@ class TestRepo(unittest.TestCase): # check the committer name commit = raw_repo.head.commit + self.assertEqual(commit.author.name, "Test User (aider)") + self.assertEqual(commit.committer.name, "Test User (aider)") + + # commit a change without aider_edits + fname.write_text("new content again!") + git_repo.commit(fnames=[str(fname)], aider_edits=False) + + # check the committer name + commit = raw_repo.head.commit + self.assertEqual(commit.author.name, "Test User") self.assertEqual(commit.committer.name, "Test User (aider)") # check that the original committer name is restored original_committer_name = os.environ.get("GIT_COMMITTER_NAME") self.assertIsNone(original_committer_name) + original_author_name = os.environ.get("GIT_AUTHOR_NAME") + self.assertIsNone(original_author_name) def test_get_tracked_files(self): # Create a temporary directory From b9c008c31b1cf4648a7553ef1dec42efc3a3167f Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 13:07:00 -0700 Subject: [PATCH 19/45] copy --- website/docs/dotenv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/dotenv.md b/website/docs/dotenv.md index 71d2f1e50..7167655cc 100644 --- a/website/docs/dotenv.md +++ b/website/docs/dotenv.md @@ -4,7 +4,7 @@ nav_order: 900 description: Using a .env file to store LLM API keys for aider. --- -# Config with .env +# Config with .env You can use a `.env` file to store API keys and other settings for the models you use with aider From ca6eae293e5f675bb3839254ff41cca1365d506a Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 13:07:17 -0700 Subject: [PATCH 20/45] copy --- website/assets/sample.env | 6 +++--- website/docs/dotenv.md | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/website/assets/sample.env b/website/assets/sample.env index ac7c100ee..02251c4b9 100644 --- a/website/assets/sample.env +++ b/website/assets/sample.env @@ -1,7 +1,7 @@ ########################################################## -# Sample aider .env file -# This file lists *all* the valid configuration entries. -# Place in your home dir, or at the root of your git repo. +# Sample aider .env file. +# Place at the root of your git repo. +# Or use `aider --env ` to specify. ########################################################## ################# diff --git a/website/docs/dotenv.md b/website/docs/dotenv.md index 7167655cc..fd32e1a13 100644 --- a/website/docs/dotenv.md +++ b/website/docs/dotenv.md @@ -7,7 +7,7 @@ description: Using a .env file to store LLM API keys for aider. # Config with .env You can use a `.env` file to store API keys and other settings for the -models you use with aider +models you use with aider. You can also set many general aider options in the `.env` file. @@ -32,9 +32,9 @@ cog.outl("```") ]]]--> ``` ########################################################## -# Sample aider .env file -# This file lists *all* the valid configuration entries. -# Place in your home dir, or at the root of your git repo. +# Sample aider .env file. +# Place at the root of your git repo. +# Or use `aider --env ` to specify. ########################################################## ################# From 82b6f83a9886d37ba4adc2dd831a5baac5e2f2bf Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 13:14:33 -0700 Subject: [PATCH 21/45] cleanup test --- aider/tests/test_repo.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aider/tests/test_repo.py b/aider/tests/test_repo.py index e4497d72a..b8cc3b06a 100644 --- a/aider/tests/test_repo.py +++ b/aider/tests/test_repo.py @@ -178,6 +178,9 @@ class TestRepo(unittest.TestCase): original_author_name = os.environ.get("GIT_AUTHOR_NAME") self.assertIsNone(original_author_name) + del raw_repo + del git_repo + def test_get_tracked_files(self): # Create a temporary directory tempdir = Path(tempfile.mkdtemp()) From 0d66f803b4fa96da36da0482bae99a8a9645e25a Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 17:17:05 -0700 Subject: [PATCH 22/45] cleanup test --- aider/tests/test_repo.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/aider/tests/test_repo.py b/aider/tests/test_repo.py index b8cc3b06a..087827c31 100644 --- a/aider/tests/test_repo.py +++ b/aider/tests/test_repo.py @@ -152,7 +152,8 @@ class TestRepo(unittest.TestCase): raw_repo.git.add(str(fname)) raw_repo.git.commit("-m", "initial commit") - git_repo = GitRepo(InputOutput(), None, None) + io = InputOutput() + git_repo = GitRepo(io, None, None) # commit a change fname.write_text("new content") @@ -178,8 +179,10 @@ class TestRepo(unittest.TestCase): original_author_name = os.environ.get("GIT_AUTHOR_NAME") self.assertIsNone(original_author_name) - del raw_repo + del fname del git_repo + del raw_repo + del io def test_get_tracked_files(self): # Create a temporary directory From eaaac4d65dd77a1a870afa75e2a8ad194729a773 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 17:32:09 -0700 Subject: [PATCH 23/45] turn off test --- aider/tests/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/tests/test_repo.py b/aider/tests/test_repo.py index 087827c31..b1f20f838 100644 --- a/aider/tests/test_repo.py +++ b/aider/tests/test_repo.py @@ -138,7 +138,7 @@ class TestRepo(unittest.TestCase): self.assertEqual(result, 'a good "commit message"') @patch("aider.repo.GitRepo.get_commit_message") - def test_commit_with_custom_committer_name(self, mock_send): + def notest_commit_with_custom_committer_name(self, mock_send): mock_send.return_value = '"a good commit message"' with GitTemporaryDirectory(): From 4e6a546efd9a2a2d0a7b9872c4aa63aae05274db Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 18 Jun 2024 17:39:55 -0700 Subject: [PATCH 24/45] disable test on windows --- aider/tests/test_repo.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aider/tests/test_repo.py b/aider/tests/test_repo.py index b1f20f838..92d074b9a 100644 --- a/aider/tests/test_repo.py +++ b/aider/tests/test_repo.py @@ -1,4 +1,5 @@ import os +import platform import tempfile import unittest from pathlib import Path @@ -138,9 +139,13 @@ class TestRepo(unittest.TestCase): self.assertEqual(result, 'a good "commit message"') @patch("aider.repo.GitRepo.get_commit_message") - def notest_commit_with_custom_committer_name(self, mock_send): + def test_commit_with_custom_committer_name(self, mock_send): mock_send.return_value = '"a good commit message"' + # Cleanup of the git temp dir explodes on windows + if platform.system() == "Windows": + return + with GitTemporaryDirectory(): # new repo raw_repo = git.Repo() @@ -179,11 +184,6 @@ class TestRepo(unittest.TestCase): original_author_name = os.environ.get("GIT_AUTHOR_NAME") self.assertIsNone(original_author_name) - del fname - del git_repo - del raw_repo - del io - def test_get_tracked_files(self): # Create a temporary directory tempdir = Path(tempfile.mkdtemp()) From 6c10b611761b45e3a2d2251c6e37d90b6064b32a Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 07:22:44 -0700 Subject: [PATCH 25/45] copy --- website/docs/troubleshooting/edit-errors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/troubleshooting/edit-errors.md b/website/docs/troubleshooting/edit-errors.md index 7c7a4a359..dbbd527dd 100644 --- a/website/docs/troubleshooting/edit-errors.md +++ b/website/docs/troubleshooting/edit-errors.md @@ -33,8 +33,8 @@ so editing errors are probably unavoidable. ## Reduce distractions Many LLM now have very large context windows, -but filling them with irrelevant code often -cofuses the model. +but filling them with irrelevant code or conversation +can cofuse the model. - Don't add too many files to the chat, *just* add the files you think need to be edited. Aider also sends the LLM a [map of your entire git repo](https://aider.chat/docs/repomap.html), so other relevant code will be included automatically. From 068609e4effc3f25c330a7bac49e723493df7bc8 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Thu, 20 Jun 2024 07:34:15 -0700 Subject: [PATCH 26/45] Added main entry point file. --- aider/__main__.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 aider/__main__.py diff --git a/aider/__main__.py b/aider/__main__.py new file mode 100644 index 000000000..40e2b013f --- /dev/null +++ b/aider/__main__.py @@ -0,0 +1,4 @@ +from .main import main + +if __name__ == "__main__": + main() From 090e0cdcfeec1b21d63f6508902db091b0e7c18c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 08:26:35 -0700 Subject: [PATCH 27/45] Added 3.5 sonnet --- aider/models.py | 12 ++++++++ website/_data/edit_leaderboard.yml | 49 +++++++++++++++++++++++++++++- website/docs/leaderboards/index.md | 22 +++++--------- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/aider/models.py b/aider/models.py index f51b38bc4..6470727d0 100644 --- a/aider/models.py +++ b/aider/models.py @@ -178,6 +178,18 @@ MODEL_SETTINGS = [ "whole", weak_model_name="claude-3-haiku-20240307", ), + ModelSettings( + "anthropic/claude-3.5-sonnet", + "diff", + weak_model_name="claude-3-haiku-20240307", + use_repo_map=True, + ), + ModelSettings( + "openrouter/anthropic/claude-3.5-sonnet", + "diff", + weak_model_name="openrouter/anthropic/claude-3-haiku-20240307", + use_repo_map=True, + ), # Cohere ModelSettings( "command-r-plus", diff --git a/website/_data/edit_leaderboard.yml b/website/_data/edit_leaderboard.yml index 82119110a..240e017fd 100644 --- a/website/_data/edit_leaderboard.yml +++ b/website/_data/edit_leaderboard.yml @@ -611,4 +611,51 @@ date: 2024-06-08 versions: 0.37.1-dev seconds_per_case: 280.6 - total_cost: 0.0000 \ No newline at end of file + total_cost: 0.0000 + +- dirname: 2024-06-20-15-09-26--claude-3.5-sonnet-whole + test_cases: 133 + model: claude-3.5-sonnet (whole) + edit_format: whole + commit_hash: 068609e + pass_rate_1: 61.7 + pass_rate_2: 78.2 + percent_cases_well_formed: 100.0 + error_outputs: 4 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 2 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 0 + command: aider --model openrouter/anthropic/claude-3.5-sonnet + date: 2024-06-20 + versions: 0.38.1-dev + seconds_per_case: 15.4 + total_cost: 0.0000 + +- dirname: 2024-06-20-15-16-41--claude-3.5-sonnet-diff + test_cases: 133 + model: openrouter/anthropic/claude-3.5-sonnet + edit_format: diff + commit_hash: 068609e-dirty + pass_rate_1: 57.9 + pass_rate_2: 74.4 + percent_cases_well_formed: 97.0 + error_outputs: 48 + num_malformed_responses: 11 + num_with_malformed_responses: 4 + user_asks: 0 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 1 + command: aider --model openrouter/anthropic/claude-3.5-sonnet + date: 2024-06-20 + versions: 0.38.1-dev + seconds_per_case: 21.6 + total_cost: 0.0000 + \ No newline at end of file diff --git a/website/docs/leaderboards/index.md b/website/docs/leaderboards/index.md index 4e3a2a59a..bc6d72c12 100644 --- a/website/docs/leaderboards/index.md +++ b/website/docs/leaderboards/index.md @@ -16,22 +16,16 @@ While [aider can connect to almost any LLM](/docs/llms.html), it works best with models that score well on the benchmarks. -## DeepSeek Coder V2 beats GPT-4o, Opus +## Claude 3.5 Sonnet takes the top spot -The new -[DeepSeek Coder V2](https://aider.chat/docs/llms/deepseek.html) -model is now atop aider's code editing leaderboard! - -It's worth noting that DeepSeek Coder V2 is only capable of using aider's "whole" edit format. -This means it returns a modified full copy of each file when it makes changes. -Most other strong models are able to use aider's "diff" editing format, -which allows them to return diffs of edits -- saving time and token costs. - -Models which use the "whole" edit format can only edit files -which fit within their output token limits. -These output limits are often as low as 4k tokens, even for models -with very large context windows. +Claude 3.5 Sonnet is now the top ranked model on aider's code editing leaderboard. +DeepSeek Coder V2 previously took the #1 spot, only 4 days ago. +Sonnet ranked #1 when using the "whole" editing format, +but it also scored very well with +aider's "diff" editing format. +This format allows it to return code changes as diffs -- saving time and token costs, +and making it practical to work with larger source files. ## Code editing leaderboard From e5e07f9507ad42d9d40e49b4dd7b15fc75bd1634 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 08:29:16 -0700 Subject: [PATCH 28/45] copy --- website/_data/edit_leaderboard.yml | 4 ++-- website/docs/leaderboards/index.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/website/_data/edit_leaderboard.yml b/website/_data/edit_leaderboard.yml index 240e017fd..1b5bf476d 100644 --- a/website/_data/edit_leaderboard.yml +++ b/website/_data/edit_leaderboard.yml @@ -630,7 +630,7 @@ indentation_errors: 0 exhausted_context_windows: 0 test_timeouts: 0 - command: aider --model openrouter/anthropic/claude-3.5-sonnet + command: aider --model openrouter/anthropic/claude-3.5-sonnet --edit-format whole date: 2024-06-20 versions: 0.38.1-dev seconds_per_case: 15.4 @@ -638,7 +638,7 @@ - dirname: 2024-06-20-15-16-41--claude-3.5-sonnet-diff test_cases: 133 - model: openrouter/anthropic/claude-3.5-sonnet + model: claude-3.5-sonnet (diff) edit_format: diff commit_hash: 068609e-dirty pass_rate_1: 57.9 diff --git a/website/docs/leaderboards/index.md b/website/docs/leaderboards/index.md index bc6d72c12..9993c665e 100644 --- a/website/docs/leaderboards/index.md +++ b/website/docs/leaderboards/index.md @@ -19,13 +19,14 @@ it works best with models that score well on the benchmarks. ## Claude 3.5 Sonnet takes the top spot Claude 3.5 Sonnet is now the top ranked model on aider's code editing leaderboard. -DeepSeek Coder V2 previously took the #1 spot, only 4 days ago. +DeepSeek Coder V2 took the #1 spot only 4 days ago. Sonnet ranked #1 when using the "whole" editing format, but it also scored very well with aider's "diff" editing format. This format allows it to return code changes as diffs -- saving time and token costs, and making it practical to work with larger source files. +As such, aider uses "diff" by default with this new Sonnet model. ## Code editing leaderboard From 559279c781dc0ac94ed7ea1b4bbd70ecf0304d94 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 09:56:18 -0700 Subject: [PATCH 29/45] copy --- website/_data/refactor_leaderboard.yml | 23 ++++++++++++++++++++++- website/docs/leaderboards/index.md | 4 +++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/website/_data/refactor_leaderboard.yml b/website/_data/refactor_leaderboard.yml index db4d3483f..11773ac39 100644 --- a/website/_data/refactor_leaderboard.yml +++ b/website/_data/refactor_leaderboard.yml @@ -143,4 +143,25 @@ seconds_per_case: 67.8 total_cost: 20.4889 - \ No newline at end of file + +- dirname: 2024-06-20-16-39-18--refac-claude-3.5-sonnet-diff + test_cases: 89 + model: claude-3.5-sonnet (diff) + edit_format: diff + commit_hash: e5e07f9 + pass_rate_1: 55.1 + percent_cases_well_formed: 70.8 + error_outputs: 240 + num_malformed_responses: 54 + num_with_malformed_responses: 26 + user_asks: 10 + lazy_comments: 2 + syntax_errors: 0 + indentation_errors: 3 + exhausted_context_windows: 0 + test_timeouts: 0 + command: aider --model openrouter/anthropic/claude-3.5-sonnet + date: 2024-06-20 + versions: 0.38.1-dev + seconds_per_case: 51.9 + total_cost: 0.0000 \ No newline at end of file diff --git a/website/docs/leaderboards/index.md b/website/docs/leaderboards/index.md index 9993c665e..78d2abafc 100644 --- a/website/docs/leaderboards/index.md +++ b/website/docs/leaderboards/index.md @@ -19,7 +19,9 @@ it works best with models that score well on the benchmarks. ## Claude 3.5 Sonnet takes the top spot Claude 3.5 Sonnet is now the top ranked model on aider's code editing leaderboard. -DeepSeek Coder V2 took the #1 spot only 4 days ago. +DeepSeek Coder V2 only spent 4 days in the top spot. + +The new Sonnet came in 3rd on aider's refactoring leaderboard, behind GPT-4o and Opus. Sonnet ranked #1 when using the "whole" editing format, but it also scored very well with From 6623110fb0a1554c980d808dbc38bbc5bf50c25c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 14:12:51 -0700 Subject: [PATCH 30/45] Updated --sonnet to use Claude 3.5 Sonnet --- README.md | 4 ++-- aider/args.py | 16 +++++++++------- website/assets/sample.aider.conf.yml | 2 +- website/assets/sample.env | 2 +- website/docs/aider_conf.md | 2 +- website/docs/dotenv.md | 2 +- website/docs/llms.md | 4 ++-- website/docs/llms/anthropic.md | 2 +- website/docs/options.md | 2 +- website/index.md | 4 ++-- 10 files changed, 21 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 6c30587c5..d750ae543 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ Aider lets you pair program with LLMs, to edit code in your local git repository. Start a new project or work with an existing git repo. -Aider works best with GPT-4o and Claude 3 Opus -and can [connect to almost any LLM](https://aider.chat/docs/llms.html). +Aider can [connect to almost any LLM](https://aider.chat/docs/llms.html). +and works best with GPT-4o, Claude 3.5 Sonnet and Claude 3 Opus.

# Windows # Claude 3 Opus aider --opus -# Claude 3 Sonnet +# Claude 3.5 Sonnet aider --sonnet # List models available from Anthropic diff --git a/website/docs/options.md b/website/docs/options.md index 300330894..a71d3f00c 100644 --- a/website/docs/options.md +++ b/website/docs/options.md @@ -75,7 +75,7 @@ Use claude-3-opus-20240229 model for the main chat Environment variable: `AIDER_OPUS` ### `--sonnet` -Use claude-3-sonnet-20240229 model for the main chat +Use claude-3-5-sonnet-20240620 model for the main chat Environment variable: `AIDER_SONNET` ### `--4` diff --git a/website/index.md b/website/index.md index 0a362d291..98a08a5b0 100644 --- a/website/index.md +++ b/website/index.md @@ -20,8 +20,8 @@ cog.out(text) Aider lets you pair program with LLMs, to edit code in your local git repository. Start a new project or work with an existing git repo. -Aider works best with GPT-4o and Claude 3 Opus -and can [connect to almost any LLM](https://aider.chat/docs/llms.html). +Aider can [connect to almost any LLM](https://aider.chat/docs/llms.html). +and works best with GPT-4o, Claude 3.5 Sonnet and Claude 3 Opus.

Date: Thu, 20 Jun 2024 14:23:10 -0700 Subject: [PATCH 31/45] Updated HISTORY --- HISTORY.md | 7 +++++++ README.md | 7 ++++++- aider/models.py | 8 +++++++- website/_includes/get-started.md | 7 ++++++- website/index.md | 7 ++++++- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b942f392b..257018ed3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,13 @@ # Release history +### v0.39.0 + +- Use `--sonnet` for Claude 3.5 Sonnet, which is the top model on [aider's LLM code editing leaderboard](https://aider.chat/docs/leaderboards/#claude-35-sonnet-takes-the-top-spot). +- All `AIDER_xxx` environment variables can now be set in `.env` (by @jpshack-at-palomar). +- Commit messages are no longer prefixed with "aider:". Instead the git author and committer names have "(aider)" added to them. +- Use `--llm-history-file` to log raw messages sent to the LLM (by @daniel-vainsencher). + ### v0.38.0 - Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat. diff --git a/README.md b/README.md index d750ae543..78af92915 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,14 @@ $ cd /to/your/git/repo $ export OPENAI_API_KEY=your-key-goes-here $ aider -# Or, work with Claude 3 Opus on your repo +# Or, work with Anthropic's models $ export ANTHROPIC_API_KEY=your-key-goes-here + +# Claude 3 Opus $ aider --opus + +# Claude 3.5 Sonnet +$ aider --sonnet ``` diff --git a/aider/models.py b/aider/models.py index 6470727d0..ac150d546 100644 --- a/aider/models.py +++ b/aider/models.py @@ -179,7 +179,13 @@ MODEL_SETTINGS = [ weak_model_name="claude-3-haiku-20240307", ), ModelSettings( - "anthropic/claude-3.5-sonnet", + "claude-3-5-sonnet-20240620", + "diff", + weak_model_name="claude-3-haiku-20240307", + use_repo_map=True, + ), + ModelSettings( + "anthropic/claude-3-5-sonnet-20240620", "diff", weak_model_name="claude-3-haiku-20240307", use_repo_map=True, diff --git a/website/_includes/get-started.md b/website/_includes/get-started.md index 498d310dc..e31d2ca3a 100644 --- a/website/_includes/get-started.md +++ b/website/_includes/get-started.md @@ -10,7 +10,12 @@ $ cd /to/your/git/repo $ export OPENAI_API_KEY=your-key-goes-here $ aider -# Or, work with Claude 3 Opus on your repo +# Or, work with Anthropic's models $ export ANTHROPIC_API_KEY=your-key-goes-here + +# Claude 3 Opus $ aider --opus + +# Claude 3.5 Sonnet +$ aider --sonnet ``` diff --git a/website/index.md b/website/index.md index 98a08a5b0..7d847f65d 100644 --- a/website/index.md +++ b/website/index.md @@ -57,9 +57,14 @@ $ cd /to/your/git/repo $ export OPENAI_API_KEY=your-key-goes-here $ aider -# Or, work with Claude 3 Opus on your repo +# Or, work with Anthropic's models $ export ANTHROPIC_API_KEY=your-key-goes-here + +# Claude 3 Opus $ aider --opus + +# Claude 3.5 Sonnet +$ aider --sonnet ``` From 5648cd54191c5d860f4f3351e7ddd0e602c85f94 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 14:36:52 -0700 Subject: [PATCH 32/45] copy --- website/HISTORY.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/website/HISTORY.md b/website/HISTORY.md index dc52bc7ff..38edb9513 100644 --- a/website/HISTORY.md +++ b/website/HISTORY.md @@ -11,6 +11,13 @@ cog.out(text) # Release history +### v0.39.0 + +- Use `--sonnet` for Claude 3.5 Sonnet, which is the top model on [aider's LLM code editing leaderboard](https://aider.chat/docs/leaderboards/#claude-35-sonnet-takes-the-top-spot). +- All `AIDER_xxx` environment variables can now be set in `.env` (by @jpshack-at-palomar). +- Commit messages are no longer prefixed with "aider:". Instead the git author and committer names have "(aider)" added to them. +- Use `--llm-history-file` to log raw messages sent to the LLM (by @daniel-vainsencher). + ### v0.38.0 - Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat. From 7e83e6b8f523657a49ad73d048c245b2bf0860ac Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 14:38:02 -0700 Subject: [PATCH 33/45] copy --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 257018ed3..70f86560a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,8 +5,8 @@ - Use `--sonnet` for Claude 3.5 Sonnet, which is the top model on [aider's LLM code editing leaderboard](https://aider.chat/docs/leaderboards/#claude-35-sonnet-takes-the-top-spot). - All `AIDER_xxx` environment variables can now be set in `.env` (by @jpshack-at-palomar). -- Commit messages are no longer prefixed with "aider:". Instead the git author and committer names have "(aider)" added to them. - Use `--llm-history-file` to log raw messages sent to the LLM (by @daniel-vainsencher). +- Commit messages are no longer prefixed with "aider:". Instead the git author and committer names have "(aider)" added. ### v0.38.0 From f030ec7f8487ce27375f506080e3ea12d7296493 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 14:47:27 -0700 Subject: [PATCH 34/45] copy --- website/HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/HISTORY.md b/website/HISTORY.md index 38edb9513..044c1652c 100644 --- a/website/HISTORY.md +++ b/website/HISTORY.md @@ -15,8 +15,8 @@ cog.out(text) - Use `--sonnet` for Claude 3.5 Sonnet, which is the top model on [aider's LLM code editing leaderboard](https://aider.chat/docs/leaderboards/#claude-35-sonnet-takes-the-top-spot). - All `AIDER_xxx` environment variables can now be set in `.env` (by @jpshack-at-palomar). -- Commit messages are no longer prefixed with "aider:". Instead the git author and committer names have "(aider)" added to them. - Use `--llm-history-file` to log raw messages sent to the LLM (by @daniel-vainsencher). +- Commit messages are no longer prefixed with "aider:". Instead the git author and committer names have "(aider)" added. ### v0.38.0 From 3128aa853bd69ef85db55e66b3c36072bf21a372 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 14:48:10 -0700 Subject: [PATCH 35/45] version bump to 0.39.0 --- aider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/__init__.py b/aider/__init__.py index b56245168..e72781a79 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1 +1 @@ -__version__ = "0.38.1-dev" +__version__ = "0.39.0" From 5f0f9daa3a15789b809ea6f1130d55e0ad798d3e Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 14:48:58 -0700 Subject: [PATCH 36/45] set version to 0.39.1-dev --- aider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/__init__.py b/aider/__init__.py index e72781a79..57bacca7f 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1 +1 @@ -__version__ = "0.39.0" +__version__ = "0.39.1-dev" From fb26174357c7ca90b3b24279668e08b7708004d7 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Thu, 20 Jun 2024 16:17:13 -0700 Subject: [PATCH 37/45] print token counts with commas --- aider/coders/base_coder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index b529636ca..76df78985 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -913,9 +913,9 @@ class Coder: res = ["", ""] res.append(f"Model {self.main_model.name} has hit a token limit!") res.append("") - res.append(f"Input tokens: {input_tokens} of {max_input_tokens}{inp_err}") - res.append(f"Output tokens: {output_tokens} of {max_output_tokens}{out_err}") - res.append(f"Total tokens: {total_tokens} of {max_input_tokens}{tot_err}") + res.append(f"Input tokens: {input_tokens:,} of {max_input_tokens:,}{inp_err}") + res.append(f"Output tokens: {output_tokens:,} of {max_output_tokens:,}{out_err}") + res.append(f"Total tokens: {total_tokens:,} of {max_input_tokens:,}{tot_err}") if output_tokens >= max_output_tokens: res.append("") From b03d73906560a98172e58002d4ba37f86a933001 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Fri, 21 Jun 2024 07:33:14 -0700 Subject: [PATCH 38/45] Added RSS feed functionality and link to the website. --- website/_config.yml | 2 ++ website/_includes/head_custom.html | 1 + 2 files changed, 3 insertions(+) diff --git a/website/_config.yml b/website/_config.yml index 74021c3fe..15e28ec7f 100644 --- a/website/_config.yml +++ b/website/_config.yml @@ -4,6 +4,7 @@ url: "https://aider.chat" plugins: - jekyll-redirect-from - jekyll-sitemap + - jekyll-feed defaults: - scope: @@ -19,6 +20,7 @@ exclude: - "**/OLD/**" - "OLD/**" - vendor + - feed.xml aux_links: "GitHub": diff --git a/website/_includes/head_custom.html b/website/_includes/head_custom.html index a6d4cca22..95a83cf10 100644 --- a/website/_includes/head_custom.html +++ b/website/_includes/head_custom.html @@ -5,6 +5,7 @@ {% endif %} + From d73fddccb9dd34704fad6ddf52ab46592498dd4c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 21 Jun 2024 07:46:34 -0700 Subject: [PATCH 39/45] Added --verify-ssl #664 --- aider/args.py | 6 ++++++ aider/main.py | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/aider/args.py b/aider/args.py index b0da24dad..48ba2db59 100644 --- a/aider/args.py +++ b/aider/args.py @@ -158,6 +158,12 @@ def get_parser(default_config_files, git_root): env_var="OPENAI_ORGANIZATION_ID", help="Specify the OpenAI organization ID", ) + group.add_argument( + "--verify-ssl", + action=argparse.BooleanOptionalAction, + default=True, + help="Verify the SSL cert when connecting to models (default: True)", + ) group.add_argument( "--model-metadata-file", metavar="MODEL_FILE", diff --git a/aider/main.py b/aider/main.py index ac8281d4d..f9b4b5217 100644 --- a/aider/main.py +++ b/aider/main.py @@ -5,6 +5,7 @@ import sys from pathlib import Path import git +import httpx from dotenv import load_dotenv from prompt_toolkit.enums import EditingMode from streamlit.web import cli @@ -240,6 +241,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F parser = get_parser(default_config_files, git_root) args = parser.parse_args(argv) + if not args.verify_ssl: + litellm.client_session = httpx.Client(verify=False) + if args.gui and not return_coder: launch_gui(argv) return From 93e104f79fc4a6dd86c5237b96ecb4dbc33a62a7 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 21 Jun 2024 07:47:29 -0700 Subject: [PATCH 40/45] copy --- website/assets/sample.aider.conf.yml | 3 +++ website/assets/sample.env | 3 +++ website/docs/aider_conf.md | 3 +++ website/docs/dotenv.md | 3 +++ website/docs/options.md | 13 +++++++++++-- 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/website/assets/sample.aider.conf.yml b/website/assets/sample.aider.conf.yml index ed48f18e1..c7873aecd 100644 --- a/website/assets/sample.aider.conf.yml +++ b/website/assets/sample.aider.conf.yml @@ -64,6 +64,9 @@ ## Specify the OpenAI organization ID #openai-organization-id: +## Verify the SSL cert when connecting to models (default: True) +#verify-ssl: true + ## Specify a file with context window and costs for unknown models #model-metadata-file: diff --git a/website/assets/sample.env b/website/assets/sample.env index 551d76de3..af76039dc 100644 --- a/website/assets/sample.env +++ b/website/assets/sample.env @@ -72,6 +72,9 @@ ## Specify the OpenAI organization ID #OPENAI_ORGANIZATION_ID= +## Verify the SSL cert when connecting to models (default: True) +#AIDER_VERIFY_SSL=true + ## Specify a file with context window and costs for unknown models #AIDER_MODEL_METADATA_FILE= diff --git a/website/docs/aider_conf.md b/website/docs/aider_conf.md index 9e4eed9d3..e6e89fc25 100644 --- a/website/docs/aider_conf.md +++ b/website/docs/aider_conf.md @@ -92,6 +92,9 @@ cog.outl("```") ## Specify the OpenAI organization ID #openai-organization-id: +## Verify the SSL cert when connecting to models (default: True) +#verify-ssl: true + ## Specify a file with context window and costs for unknown models #model-metadata-file: diff --git a/website/docs/dotenv.md b/website/docs/dotenv.md index b7c942923..e1eb3a425 100644 --- a/website/docs/dotenv.md +++ b/website/docs/dotenv.md @@ -105,6 +105,9 @@ cog.outl("```") ## Specify the OpenAI organization ID #OPENAI_ORGANIZATION_ID= +## Verify the SSL cert when connecting to models (default: True) +#AIDER_VERIFY_SSL=true + ## Specify a file with context window and costs for unknown models #AIDER_MODEL_METADATA_FILE= diff --git a/website/docs/options.md b/website/docs/options.md index a71d3f00c..166b2853b 100644 --- a/website/docs/options.md +++ b/website/docs/options.md @@ -19,8 +19,9 @@ usage: aider [-h] [--llm-history-file] [--openai-api-key] [--4] [--4o] [--4-turbo] [--35turbo] [--models] [--openai-api-base] [--openai-api-type] [--openai-api-version] [--openai-api-deployment-id] - [--openai-organization-id] [--model-metadata-file] - [--edit-format] [--weak-model] + [--openai-organization-id] + [--verify-ssl | --no-verify-ssl] + [--model-metadata-file] [--edit-format] [--weak-model] [--show-model-warnings | --no-show-model-warnings] [--map-tokens] [--max-chat-history-tokens] [--env-file] [--input-history-file] [--chat-history-file] @@ -128,6 +129,14 @@ Environment variable: `OPENAI_API_DEPLOYMENT_ID` Specify the OpenAI organization ID Environment variable: `OPENAI_ORGANIZATION_ID` +### `--verify-ssl` +Verify the SSL cert when connecting to models (default: True) +Default: True +Environment variable: `AIDER_VERIFY_SSL` +Aliases: + - `--verify-ssl` + - `--no-verify-ssl` + ### `--model-metadata-file MODEL_FILE` Specify a file with context window and costs for unknown models Environment variable: `AIDER_MODEL_METADATA_FILE` From 4fd61f11121496b9721821215c929414a1dc9011 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 21 Jun 2024 08:29:02 -0700 Subject: [PATCH 41/45] More flexible filename search for deepseek coder v2 --- aider/coders/editblock_coder.py | 41 +++++++++++++++++++++++++-------- aider/models.py | 12 ++++++++-- aider/tests/test_editblock.py | 26 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/aider/coders/editblock_coder.py b/aider/coders/editblock_coder.py index 017e40408..557e692b6 100644 --- a/aider/coders/editblock_coder.py +++ b/aider/coders/editblock_coder.py @@ -414,16 +414,8 @@ def find_original_update_blocks(content, fence=DEFAULT_FENCE): processed.append(cur) # original_marker - filename = strip_filename(processed[-2].splitlines()[-1], fence) - try: - if not filename: - filename = strip_filename(processed[-2].splitlines()[-2], fence) - if not filename: - if current_filename: - filename = current_filename - else: - raise ValueError(missing_filename_err.format(fence=fence)) - except IndexError: + filename = find_filename(processed[-2].splitlines(), fence) + if not filename: if current_filename: filename = current_filename else: @@ -460,6 +452,35 @@ def find_original_update_blocks(content, fence=DEFAULT_FENCE): raise ValueError(f"{processed}\n^^^ Error parsing SEARCH/REPLACE block.") +def find_filename(lines, fence): + """ + Deepseek Coder v2 has been doing this: + + + ```python + word_count.py + ``` + ```python + <<<<<<< SEARCH + ... + + This is a more flexible search back for filenames. + """ + # Go back through the 3 preceding lines + lines.reverse() + lines = lines[:3] + + for line in lines: + # If we find a filename, done + filename = strip_filename(line, fence) + if filename: + return filename + + # Only continue as long as we keep seeing fences + if not line.startswith(fence[0]): + return + + if __name__ == "__main__": edit = """ Here's the change: diff --git a/aider/models.py b/aider/models.py index ac150d546..50548446d 100644 --- a/aider/models.py +++ b/aider/models.py @@ -236,7 +236,7 @@ MODEL_SETTINGS = [ send_undo_reply=True, ), ModelSettings( - "openai/deepseek-chat", + "deepseek/deepseek-chat", "diff", use_repo_map=True, send_undo_reply=True, @@ -244,7 +244,15 @@ MODEL_SETTINGS = [ reminder_as_sys_msg=True, ), ModelSettings( - "deepseek/deepseek-chat", + "deepseek/deepseek-coder", + "diff", + use_repo_map=True, + send_undo_reply=True, + examples_as_sys_msg=True, + reminder_as_sys_msg=True, + ), + ModelSettings( + "openrouter/deepseek/deepseek-coder", "diff", use_repo_map=True, send_undo_reply=True, diff --git a/aider/tests/test_editblock.py b/aider/tests/test_editblock.py index 0c1143232..40a0d4572 100644 --- a/aider/tests/test_editblock.py +++ b/aider/tests/test_editblock.py @@ -398,6 +398,32 @@ Hope you like it! ], ) + def test_deepseek_coder_v2_filename_mangling(self): + edit = """ +Here's the change: + + ```python +foo.txt +``` +```python +<<<<<<< SEARCH +one +======= +two +>>>>>>> REPLACE +``` + +Hope you like it! +""" + + edits = list(eb.find_original_update_blocks(edit)) + self.assertEqual( + edits, + [ + ("foo.txt", "one\n", "two\n"), + ], + ) + if __name__ == "__main__": unittest.main() From 0a95badf3f0f8819064b06f5320d17fc5190f557 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 21 Jun 2024 08:57:30 -0700 Subject: [PATCH 42/45] Updated docs --- README.md | 13 ++---- website/HISTORY.md | 1 + website/_data/edit_leaderboard.yml | 69 ++++++++++++++++++++---------- website/docs/faq.md | 4 +- website/docs/git.md | 1 + website/docs/languages.md | 1 + website/docs/llms.md | 14 +++--- website/docs/more-info.md | 8 ++++ website/docs/repomap.md | 1 + website/docs/scripting.md | 1 + website/index.md | 13 ++---- 11 files changed, 76 insertions(+), 50 deletions(-) create mode 100644 website/docs/more-info.md diff --git a/README.md b/README.md index 78af92915..3bdbc20a4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Aider lets you pair program with LLMs, to edit code in your local git repository. Start a new project or work with an existing git repo. Aider can [connect to almost any LLM](https://aider.chat/docs/llms.html). -and works best with GPT-4o, Claude 3.5 Sonnet and Claude 3 Opus. +and works best with GPT-4o, Claude 3.5 Sonnet, Claude 3 Opus and DeepSeek Coder V2.

- - aider swe bench - -

- ## More info - [Documentation](https://aider.chat/) diff --git a/website/HISTORY.md b/website/HISTORY.md index 044c1652c..4e84bf086 100644 --- a/website/HISTORY.md +++ b/website/HISTORY.md @@ -1,5 +1,6 @@ --- title: Release history +parent: More info nav_order: 999 --- diff --git a/website/_data/edit_leaderboard.yml b/website/_data/edit_leaderboard.yml index 1b5bf476d..c7c4a0efc 100644 --- a/website/_data/edit_leaderboard.yml +++ b/website/_data/edit_leaderboard.yml @@ -44,29 +44,6 @@ seconds_per_case: 23.1 total_cost: 0.0000 -- dirname: 2024-06-17-14-45-54--deepseek-coder2-whole - test_cases: 133 - model: DeepSeek Coder V2 - edit_format: whole - commit_hash: ca8672b - pass_rate_1: 63.9 - pass_rate_2: 75.2 - percent_cases_well_formed: 100.0 - error_outputs: 1 - num_malformed_responses: 0 - num_with_malformed_responses: 0 - user_asks: 1 - lazy_comments: 0 - syntax_errors: 1 - indentation_errors: 0 - exhausted_context_windows: 0 - test_timeouts: 7 - command: aider --model deepseek/deepseek-coder - date: 2024-06-17 - versions: 0.38.1-dev - seconds_per_case: 21.1 - total_cost: 0.0537 - - dirname: 2024-05-03-20-47-24--gemini-1.5-pro-diff-fenced test_cases: 133 model: gemini-1.5-pro-latest @@ -658,4 +635,50 @@ versions: 0.38.1-dev seconds_per_case: 21.6 total_cost: 0.0000 + +- dirname: 2024-06-17-14-45-54--deepseek-coder2-whole + test_cases: 133 + model: DeepSeek Coder V2 (whole) + edit_format: whole + commit_hash: ca8672b + pass_rate_1: 63.9 + pass_rate_2: 75.2 + percent_cases_well_formed: 100.0 + error_outputs: 1 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 1 + lazy_comments: 0 + syntax_errors: 1 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 7 + command: aider --model deepseek/deepseek-coder + date: 2024-06-17 + versions: 0.38.1-dev + seconds_per_case: 21.1 + total_cost: 0.0537 + +- dirname: 2024-06-21-15-29-08--deepseek-coder2-diff-again3 + test_cases: 133 + model: DeepSeek Coder V2 (diff) + edit_format: diff + commit_hash: 515ab3e + pass_rate_1: 58.6 + pass_rate_2: 66.2 + percent_cases_well_formed: 98.5 + error_outputs: 23 + num_malformed_responses: 5 + num_with_malformed_responses: 2 + user_asks: 2 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 1 + exhausted_context_windows: 0 + test_timeouts: 2 + command: aider --model deepseek/deepseek-coder + date: 2024-06-21 + versions: 0.39.1-dev + seconds_per_case: 30.2 + total_cost: 0.0857 \ No newline at end of file diff --git a/website/docs/faq.md b/website/docs/faq.md index a1443b1e8..f32872828 100644 --- a/website/docs/faq.md +++ b/website/docs/faq.md @@ -1,9 +1,9 @@ --- -nav_order: 85 +nav_order: 90 description: Frequently asked questions about aider. --- -# Frequently asked questions +# FAQ {: .no_toc } - TOC diff --git a/website/docs/git.md b/website/docs/git.md index f9c8bb5ad..ea2b145fe 100644 --- a/website/docs/git.md +++ b/website/docs/git.md @@ -1,4 +1,5 @@ --- +parent: More info nav_order: 800 description: Aider is tightly integrated with git. --- diff --git a/website/docs/languages.md b/website/docs/languages.md index 889e4caa9..d74f748c9 100644 --- a/website/docs/languages.md +++ b/website/docs/languages.md @@ -1,4 +1,5 @@ --- +parent: More info nav_order: 900 description: Aider supports pretty much all popular coding languages. --- diff --git a/website/docs/llms.md b/website/docs/llms.md index 76862b2e6..37cd82f7a 100644 --- a/website/docs/llms.md +++ b/website/docs/llms.md @@ -14,17 +14,21 @@ description: Aider can connect to most LLMs for AI pair programming. ## Best models {: .no_toc } -**Aider works best with [GPT-4o](/docs/llms/openai.html), -[Claude 3.5 Sonnet and Claude 3 Opus](/docs/llms/anthropic.html),** -as they are the very best models for editing code. +Aider works best with these models, which are skilled at editing code: + +- [GPT-4o](/docs/llms/openai.html) +- [Claude 3.5 Sonnet](/docs/llms/anthropic.html) +- [Claude 3 Opus](/docs/llms/anthropic.html) +- [DeepSeek Coder V2](/docs/llms/deepseek.html) + ## Free models {: .no_toc } Aider works with a number of **free** API providers: -- The [DeepSeek Coder V2](/docs/llms/deepseek.html) model gets the top score on aider's code editing benchmark. DeepSeek currently offers 5M free tokens of API usage. -- Google's [Gemini 1.5 Pro](/docs/llms/gemini.html) is the most capable free model to use with aider, with +- The [DeepSeek Coder V2](/docs/llms/deepseek.html) model gets the top score on aider's code editing benchmark. DeepSeek has been offering 5M free tokens of API usage. +- Google's [Gemini 1.5 Pro](/docs/llms/gemini.html) works with aider, with code editing capabilities similar to GPT-3.5. - You can use [Llama 3 70B on Groq](/docs/llms/groq.html) which is comparable to GPT-3.5 in code editing performance. - Cohere also offers free API access to their [Command-R+ model](/docs/llms/cohere.html), which works with aider as a *very basic* coding assistant. diff --git a/website/docs/more-info.md b/website/docs/more-info.md new file mode 100644 index 000000000..3b40cb9e1 --- /dev/null +++ b/website/docs/more-info.md @@ -0,0 +1,8 @@ +--- +has_children: true +nav_order: 85 +--- + +# More info + +See below for more info about aider, including some advanced topics. diff --git a/website/docs/repomap.md b/website/docs/repomap.md index aefedc5dc..359243103 100644 --- a/website/docs/repomap.md +++ b/website/docs/repomap.md @@ -1,4 +1,5 @@ --- +parent: More info highlight_image: /assets/robot-ast.png nav_order: 900 description: Aider uses a map of your git repository to provide code context to LLMs. diff --git a/website/docs/scripting.md b/website/docs/scripting.md index 2d6149d31..984ecb864 100644 --- a/website/docs/scripting.md +++ b/website/docs/scripting.md @@ -1,4 +1,5 @@ --- +parent: More info nav_order: 900 description: You can script aider via the command line or python. --- diff --git a/website/index.md b/website/index.md index 7d847f65d..cbf8498df 100644 --- a/website/index.md +++ b/website/index.md @@ -21,7 +21,7 @@ Aider lets you pair program with LLMs, to edit code in your local git repository. Start a new project or work with an existing git repo. Aider can [connect to almost any LLM](https://aider.chat/docs/llms.html). -and works best with GPT-4o, Claude 3.5 Sonnet and Claude 3 Opus. +and works best with GPT-4o, Claude 3.5 Sonnet, Claude 3 Opus and DeepSeek Coder V2.

- - aider swe bench - -

- ## More info - [Documentation](https://aider.chat/) From 6bd325e4322923338ca1745a663975cfb7266cbf Mon Sep 17 00:00:00 2001 From: Dustin Miller <1342542+spdustin@users.noreply.github.com> Date: Fri, 21 Jun 2024 11:31:16 -0500 Subject: [PATCH 43/45] Add support for vertex_ai/claude_* models --- aider/models.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/aider/models.py b/aider/models.py index ac150d546..a16e70340 100644 --- a/aider/models.py +++ b/aider/models.py @@ -196,6 +196,20 @@ MODEL_SETTINGS = [ weak_model_name="openrouter/anthropic/claude-3-haiku-20240307", use_repo_map=True, ), + # Vertex AI Claude models + ModelSettings( + "vertex_ai/claude-3-5-sonnet@20240620", + "diff", + weak_model_name="vertex_ai/claude-3-haiku@20240307", + use_repo_map=True, + ), + ModelSettings( + "vertex_ai/claude-3-opus@20240229", + "diff", + weak_model_name="vertex_ai/claude-3-haiku@20240307", + use_repo_map=True, + send_undo_reply=True, + ), # Cohere ModelSettings( "command-r-plus", From 4fed045f277cda31b912c6e1b7ee6346c70a6eb9 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 21 Jun 2024 16:50:49 -0700 Subject: [PATCH 44/45] Added vertex_ai/claude-3-sonnet@20240229, bumped deps to upgrade litellm #704 --- aider/models.py | 5 +++++ requirements.txt | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/aider/models.py b/aider/models.py index e52267092..003bc1e68 100644 --- a/aider/models.py +++ b/aider/models.py @@ -210,6 +210,11 @@ MODEL_SETTINGS = [ use_repo_map=True, send_undo_reply=True, ), + ModelSettings( + "vertex_ai/claude-3-sonnet@20240229", + "whole", + weak_model_name="vertex_ai/claude-3-haiku@20240307", + ), # Cohere ModelSettings( "command-r-plus", diff --git a/requirements.txt b/requirements.txt index e7bff9826..f99a01346 100644 --- a/requirements.txt +++ b/requirements.txt @@ -54,7 +54,7 @@ diskcache==5.6.3 # via -r requirements.in distro==1.9.0 # via openai -filelock==3.15.1 +filelock==3.15.3 # via huggingface-hub flake8==7.1.0 # via -r requirements.in @@ -70,14 +70,14 @@ gitpython==3.1.43 # via # -r requirements.in # streamlit -google-ai-generativelanguage==0.6.4 +google-ai-generativelanguage==0.6.5 # via google-generativeai google-api-core[grpc]==2.19.0 # via # google-ai-generativelanguage # google-api-python-client # google-generativeai -google-api-python-client==2.133.0 +google-api-python-client==2.134.0 # via google-generativeai google-auth==2.30.0 # via @@ -88,7 +88,7 @@ google-auth==2.30.0 # google-generativeai google-auth-httplib2==0.2.0 # via google-api-python-client -google-generativeai==0.6.0 +google-generativeai==0.7.0 # via -r requirements.in googleapis-common-protos==1.63.1 # via @@ -122,7 +122,9 @@ idna==3.7 # httpx # requests # yarl -importlib-metadata==7.1.0 +ijson==3.3.0 + # via litellm +importlib-metadata==7.2.0 # via litellm jinja2==3.1.4 # via @@ -135,7 +137,7 @@ jsonschema==4.22.0 # altair jsonschema-specifications==2023.12.1 # via jsonschema -litellm==1.40.15 +litellm==1.40.21 # via -r requirements.in markdown-it-py==3.0.0 # via rich @@ -151,7 +153,7 @@ multidict==6.0.5 # yarl networkx==3.2.1 # via -r requirements.in -numpy==1.26.4 +numpy==2.0.0 # via # -r requirements.in # altair @@ -160,7 +162,7 @@ numpy==1.26.4 # pydeck # scipy # streamlit -openai==1.34.0 +openai==1.35.3 # via # -r requirements.in # litellm @@ -186,7 +188,7 @@ playwright==1.44.0 # via -r requirements.in prompt-toolkit==3.0.47 # via -r requirements.in -proto-plus==1.23.0 +proto-plus==1.24.0 # via # google-ai-generativelanguage # google-api-core @@ -280,9 +282,9 @@ soundfile==0.12.1 # via -r requirements.in soupsieve==2.5 # via beautifulsoup4 -streamlit==1.35.0 +streamlit==1.36.0 # via -r requirements.in -tenacity==8.3.0 +tenacity==8.4.1 # via streamlit tiktoken==0.7.0 # via @@ -320,7 +322,7 @@ tzdata==2024.1 # via pandas uritemplate==4.1.1 # via google-api-python-client -urllib3==2.2.1 +urllib3==2.2.2 # via requests watchdog==4.0.1 # via -r requirements.in From 8c5c2d27a4dac78de9ee5cda5d45c91834b56665 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 21 Jun 2024 16:58:18 -0700 Subject: [PATCH 45/45] missing ); update docs --- aider/args.py | 3 ++- website/assets/sample.aider.conf.yml | 7 +++++-- website/assets/sample.env | 7 +++++-- website/docs/aider_conf.md | 7 +++++-- website/docs/dotenv.md | 7 +++++-- website/docs/options.md | 27 ++++++++++----------------- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/aider/args.py b/aider/args.py index 47efeb7ed..fb395e90c 100644 --- a/aider/args.py +++ b/aider/args.py @@ -163,6 +163,7 @@ def get_parser(default_config_files, git_root): metavar="MODEL_SETTINGS_FILE", default=None, help="Specify a file with aider model settings for unknown models", + ) group.add_argument( "--model-metadata-file", metavar="MODEL_METADATA_FILE", @@ -174,7 +175,7 @@ def get_parser(default_config_files, git_root): action=argparse.BooleanOptionalAction, default=True, help="Verify the SSL cert when connecting to models (default: True)", - ) + ) group.add_argument( "--edit-format", metavar="EDIT_FORMAT", diff --git a/website/assets/sample.aider.conf.yml b/website/assets/sample.aider.conf.yml index c7873aecd..08bc54e0f 100644 --- a/website/assets/sample.aider.conf.yml +++ b/website/assets/sample.aider.conf.yml @@ -64,12 +64,15 @@ ## Specify the OpenAI organization ID #openai-organization-id: -## Verify the SSL cert when connecting to models (default: True) -#verify-ssl: true +## Specify a file with aider model settings for unknown models +#model-settings-file: ## Specify a file with context window and costs for unknown models #model-metadata-file: +## Verify the SSL cert when connecting to models (default: True) +#verify-ssl: true + ## Specify what edit format the LLM should use (default depends on model) #edit-format: diff --git a/website/assets/sample.env b/website/assets/sample.env index af76039dc..8ac091b96 100644 --- a/website/assets/sample.env +++ b/website/assets/sample.env @@ -72,12 +72,15 @@ ## Specify the OpenAI organization ID #OPENAI_ORGANIZATION_ID= -## Verify the SSL cert when connecting to models (default: True) -#AIDER_VERIFY_SSL=true +## Specify a file with aider model settings for unknown models +#AIDER_MODEL_SETTINGS_FILE= ## Specify a file with context window and costs for unknown models #AIDER_MODEL_METADATA_FILE= +## Verify the SSL cert when connecting to models (default: True) +#AIDER_VERIFY_SSL=true + ## Specify what edit format the LLM should use (default depends on model) #AIDER_EDIT_FORMAT= diff --git a/website/docs/aider_conf.md b/website/docs/aider_conf.md index e6e89fc25..2751042f4 100644 --- a/website/docs/aider_conf.md +++ b/website/docs/aider_conf.md @@ -92,12 +92,15 @@ cog.outl("```") ## Specify the OpenAI organization ID #openai-organization-id: -## Verify the SSL cert when connecting to models (default: True) -#verify-ssl: true +## Specify a file with aider model settings for unknown models +#model-settings-file: ## Specify a file with context window and costs for unknown models #model-metadata-file: +## Verify the SSL cert when connecting to models (default: True) +#verify-ssl: true + ## Specify what edit format the LLM should use (default depends on model) #edit-format: diff --git a/website/docs/dotenv.md b/website/docs/dotenv.md index e1eb3a425..66c26287c 100644 --- a/website/docs/dotenv.md +++ b/website/docs/dotenv.md @@ -105,12 +105,15 @@ cog.outl("```") ## Specify the OpenAI organization ID #OPENAI_ORGANIZATION_ID= -## Verify the SSL cert when connecting to models (default: True) -#AIDER_VERIFY_SSL=true +## Specify a file with aider model settings for unknown models +#AIDER_MODEL_SETTINGS_FILE= ## Specify a file with context window and costs for unknown models #AIDER_MODEL_METADATA_FILE= +## Verify the SSL cert when connecting to models (default: True) +#AIDER_VERIFY_SSL=true + ## Specify what edit format the LLM should use (default depends on model) #AIDER_EDIT_FORMAT= diff --git a/website/docs/options.md b/website/docs/options.md index 204c68337..5b880ad16 100644 --- a/website/docs/options.md +++ b/website/docs/options.md @@ -14,22 +14,15 @@ from aider.args import get_md_help cog.out(get_md_help()) ]]]--> ``` -usage: aider [-h] [--vim] [--openai-api-key] [--anthropic-api-key] - [--model] [--opus] [--sonnet] [--4] [--4o] [--4-turbo] - [--35turbo] [--models] [--openai-api-base] - [--openai-api-type] [--openai-api-version] - [--openai-api-deployment-id] [--openai-organization-id] - [--model-settings-file] [--model-metadata-file] - [--edit-format] [--weak-model] -======= usage: aider [-h] [--llm-history-file] [--openai-api-key] [--anthropic-api-key] [--model] [--opus] [--sonnet] [--4] [--4o] [--4-turbo] [--35turbo] [--models] [--openai-api-base] [--openai-api-type] [--openai-api-version] [--openai-api-deployment-id] - [--openai-organization-id] - [--verify-ssl | --no-verify-ssl] - [--model-metadata-file] [--edit-format] [--weak-model] + [--openai-organization-id] [--model-settings-file] + [--model-metadata-file] + [--verify-ssl | --no-verify-ssl] [--edit-format] + [--weak-model] [--show-model-warnings | --no-show-model-warnings] [--map-tokens] [--max-chat-history-tokens] [--env-file] [--input-history-file] [--chat-history-file] @@ -137,10 +130,14 @@ Environment variable: `OPENAI_API_DEPLOYMENT_ID` Specify the OpenAI organization ID Environment variable: `OPENAI_ORGANIZATION_ID` -### `--model-settings-file MODEL_FILE` +### `--model-settings-file MODEL_SETTINGS_FILE` Specify a file with aider model settings for unknown models Environment variable: `AIDER_MODEL_SETTINGS_FILE` -======= + +### `--model-metadata-file MODEL_METADATA_FILE` +Specify a file with context window and costs for unknown models +Environment variable: `AIDER_MODEL_METADATA_FILE` + ### `--verify-ssl` Verify the SSL cert when connecting to models (default: True) Default: True @@ -149,10 +146,6 @@ Aliases: - `--verify-ssl` - `--no-verify-ssl` -### `--model-metadata-file MODEL_FILE` -Specify a file with context window and costs for unknown models -Environment variable: `AIDER_MODEL_METADATA_FILE` - ### `--edit-format EDIT_FORMAT` Specify what edit format the LLM should use (default depends on model) Environment variable: `AIDER_EDIT_FORMAT`