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/HISTORY.md b/HISTORY.md
index b942f392b..70f86560a 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).
+- 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
- Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat.
diff --git a/README.md b/README.md
index 6c30587c5..3bdbc20a4 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, Claude 3 Opus and DeepSeek Coder V2.
@@ -79,20 +84,13 @@ Pair program with AI.
- [Code with your voice](https://aider.chat/docs/voice.html).
-## State of the art
+## Top tier performance
-Aider has the
-[top score on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
+[Aider has the one of the top scores on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
SWE Bench is a challenging software engineering benchmark where aider
solved *real* GitHub issues from popular open source
projects like django, scikitlearn, matplotlib, etc.
-
-
## More info
- [Documentation](https://aider.chat/)
diff --git a/aider/__init__.py b/aider/__init__.py
index b56245168..57bacca7f 100644
--- a/aider/__init__.py
+++ b/aider/__init__.py
@@ -1 +1 @@
-__version__ = "0.38.1-dev"
+__version__ = "0.39.1-dev"
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()
diff --git a/aider/args.py b/aider/args.py
index 070905bb4..fb395e90c 100644
--- a/aider/args.py
+++ b/aider/args.py
@@ -7,11 +7,30 @@ import sys
import configargparse
from aider import __version__, models
-from aider.args_formatter import MarkdownHelpFormatter, YamlHelpFormatter
+from aider.args_formatter import (
+ DotEnvFormatter,
+ 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",
@@ -28,10 +47,7 @@ def get_parser(default_config_files, git_root):
help="Log the conversation with the LLM to this file (for example, .aider.llm.history)",
)
group.add_argument(
- "files",
- metavar="FILE",
- nargs="*",
- help="files to edit with an LLM (optional)"
+ "files", metavar="FILE", nargs="*", help="files to edit with an LLM (optional)"
)
group.add_argument(
"--openai-api-key",
@@ -60,7 +76,7 @@ def get_parser(default_config_files, git_root):
const=opus_model,
help=f"Use {opus_model} model for the main chat",
)
- sonnet_model = "claude-3-sonnet-20240229"
+ sonnet_model = "claude-3-5-sonnet-20240620"
group.add_argument(
"--sonnet",
action="store_const",
@@ -142,12 +158,24 @@ 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",
)
+ group.add_argument(
+ "--verify-ssl",
+ action=argparse.BooleanOptionalAction,
+ default=True,
+ help="Verify the SSL cert when connecting to models (default: True)",
+ )
group.add_argument(
"--edit-format",
metavar="EDIT_FORMAT",
@@ -184,11 +212,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)",
)
@@ -501,11 +530,27 @@ def get_sample_yaml():
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())
diff --git a/aider/args_formatter.py b/aider/args_formatter.py
index 2503cd007..cc7e3e73d 100644
--- a/aider/args_formatter.py
+++ b/aider/args_formatter.py
@@ -1,8 +1,83 @@
import argparse
+from aider import urls
+
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 f"""
+##########################################################
+# Sample aider .env file.
+# Place at the root of your git repo.
+# Or use `aider --env ` to specify.
+##########################################################
+
+#################
+# 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 ""
+
+ if not action.env_var:
+ return
+
+ parts = [""]
+
+ 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}")
+
+ 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")
+
+ 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"
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("")
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/commands.py b/aider/commands.py
index f6b0c3cba..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 (
- not last_commit.message.startswith("aider:")
+ 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/main.py b/aider/main.py
index c4d211fc7..3acaf5afc 100644
--- a/aider/main.py
+++ b/aider/main.py
@@ -5,12 +5,13 @@ 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
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
@@ -124,12 +125,18 @@ 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()):
if val:
val = scrub_sensitive_info(args, str(val))
- show += f" - {arg}: {val}\n"
+ show += f" - {arg}: {val}\n" # noqa: E221
return show
@@ -205,7 +212,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:]
@@ -225,9 +273,18 @@ 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(argv)
+
+ # 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)
+ if not args.verify_ssl:
+ litellm.client_session = httpx.Client(verify=False)
+
if args.gui and not return_coder:
launch_gui(argv)
return
@@ -320,9 +377,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
@@ -337,26 +391,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..bed59ea7e 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
@@ -178,6 +179,43 @@ MODEL_SETTINGS = [
"whole",
weak_model_name="claude-3-haiku-20240307",
),
+ ModelSettings(
+ "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,
+ ),
+ ModelSettings(
+ "openrouter/anthropic/claude-3.5-sonnet",
+ "diff",
+ 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,
+ ),
+ ModelSettings(
+ "vertex_ai/claude-3-sonnet@20240229",
+ "whole",
+ weak_model_name="vertex_ai/claude-3-haiku@20240307",
+ ),
# Cohere
ModelSettings(
"command-r-plus",
@@ -218,7 +256,7 @@ MODEL_SETTINGS = [
send_undo_reply=True,
),
ModelSettings(
- "openai/deepseek-chat",
+ "deepseek/deepseek-chat",
"diff",
use_repo_map=True,
send_undo_reply=True,
@@ -226,7 +264,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,
@@ -425,23 +471,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/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 8cc67b6d8..f6629f481 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_AUTHOR_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_AUTHOR_NAME"]
# Store the commit hash
last_commit_hash = repo.head.commit.hexsha[:7]
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()
diff --git a/aider/tests/test_main.py b/aider/tests/test_main.py
index d319a78dd..b576d3754 100644
--- a/aider/tests/test_main.py
+++ b/aider/tests/test_main.py
@@ -1,7 +1,7 @@
import os
-import shutil
import subprocess
import tempfile
+from io import StringIO
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
@@ -13,24 +13,28 @@ 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):
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 = IgnorantTemporaryDirectory()
+ 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())
- 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"))
@@ -237,3 +241,82 @@ 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 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):
+ 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(),
+ )
+ 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):
+ 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
+ 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_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)
+
+ 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")
diff --git a/aider/tests/test_repo.py b/aider/tests/test_repo.py
index 961fe8ee9..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
@@ -141,6 +142,10 @@ class TestRepo(unittest.TestCase):
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()
@@ -152,7 +157,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")
@@ -160,11 +166,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
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/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):
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
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/HISTORY.md b/website/HISTORY.md
index dc52bc7ff..4e84bf086 100644
--- a/website/HISTORY.md
+++ b/website/HISTORY.md
@@ -1,5 +1,6 @@
---
title: Release history
+parent: More info
nav_order: 999
---
@@ -11,6 +12,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).
+- 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
- Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat.
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/_data/edit_leaderboard.yml b/website/_data/edit_leaderboard.yml
index 82119110a..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
@@ -611,4 +588,97 @@
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 --edit-format whole
+ 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: claude-3.5-sonnet (diff)
+ 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
+
+- 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/_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/_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/_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 %}
+
diff --git a/website/assets/sample.aider.conf.yml b/website/assets/sample.aider.conf.yml
index 896cda62a..08bc54e0f 100644
--- a/website/assets/sample.aider.conf.yml
+++ b/website/assets/sample.aider.conf.yml
@@ -28,7 +28,7 @@
## Use claude-3-opus-20240229 model for the main chat
#opus: false
-## Use claude-3-sonnet-20240229 model for the main chat
+## Use claude-3-5-sonnet-20240620 model for the main chat
#sonnet: false
## Use gpt-4-0613 model for the main chat
@@ -64,9 +64,15 @@
## Specify the OpenAI organization ID
#openai-organization-id:
+## 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
new file mode 100644
index 000000000..8ac091b96
--- /dev/null
+++ b/website/assets/sample.env
@@ -0,0 +1,232 @@
+##########################################################
+# Sample aider .env file.
+# Place at the root of your git repo.
+# Or use `aider --env ` to specify.
+##########################################################
+
+#################
+# 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-5-sonnet-20240620 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 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=
+
+## 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/aider_conf.md b/website/docs/aider_conf.md
index b13208cc7..2751042f4 100644
--- a/website/docs/aider_conf.md
+++ b/website/docs/aider_conf.md
@@ -56,7 +56,7 @@ cog.outl("```")
## Use claude-3-opus-20240229 model for the main chat
#opus: false
-## Use claude-3-sonnet-20240229 model for the main chat
+## Use claude-3-5-sonnet-20240620 model for the main chat
#sonnet: false
## Use gpt-4-0613 model for the main chat
@@ -92,9 +92,15 @@ cog.outl("```")
## Specify the OpenAI organization ID
#openai-organization-id:
+## 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 e45fc5783..66c26287c 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.
+You can also set many general aider options
+in the `.env` file.
{% include special-keys.md %}
@@ -17,17 +17,253 @@ 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).
+
```
-OPENAI_API_KEY=
-ANTHROPIC_API_KEY=
-GROQ_API_KEY=
-OPENROUTER_API_KEY=
+##########################################################
+# Sample aider .env file.
+# Place at the root of your git repo.
+# Or use `aider --env ` to specify.
+##########################################################
-AZURE_API_KEY=
-AZURE_API_VERSION=2023-05-15
-AZURE_API_BASE=https://example-endpoint.openai.azure.com
+#################
+# LLM parameters:
+#
+# Include xxx_API_KEY parameters and other params needed for your LLMs.
+# See https://aider.chat/docs/llms.html for details.
-OLLAMA_API_BASE=http://127.0.0.1:11434
+## 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-5-sonnet-20240620 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 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=
+
+## 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/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 b25418b93..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.
---
@@ -14,14 +15,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.
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/leaderboards/index.md b/website/docs/leaderboards/index.md
index 4e3a2a59a..78d2abafc 100644
--- a/website/docs/leaderboards/index.md
+++ b/website/docs/leaderboards/index.md
@@ -16,22 +16,19 @@ 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!
+Claude 3.5 Sonnet is now the top ranked model on aider's code editing leaderboard.
+DeepSeek Coder V2 only spent 4 days in the top spot.
-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.
+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
+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
diff --git a/website/docs/llms.md b/website/docs/llms.md
index aecb49f27..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) 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/llms/anthropic.md b/website/docs/llms/anthropic.md
index c2d2ff78f..027feef44 100644
--- a/website/docs/llms/anthropic.md
+++ b/website/docs/llms/anthropic.md
@@ -22,7 +22,7 @@ setx ANTHROPIC_API_KEY # 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/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/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/options.md b/website/docs/options.md
index 300330894..5b880ad16 100644
--- a/website/docs/options.md
+++ b/website/docs/options.md
@@ -19,8 +19,10 @@ 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] [--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]
@@ -75,7 +77,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`
@@ -128,10 +130,22 @@ Environment variable: `OPENAI_API_DEPLOYMENT_ID`
Specify the OpenAI organization ID
Environment variable: `OPENAI_ORGANIZATION_ID`
-### `--model-metadata-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
+Environment variable: `AIDER_VERIFY_SSL`
+Aliases:
+ - `--verify-ssl`
+ - `--no-verify-ssl`
+
### `--edit-format EDIT_FORMAT`
Specify what edit format the LLM should use (default depends on model)
Environment variable: `AIDER_EDIT_FORMAT`
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/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.
diff --git a/website/index.md b/website/index.md
index 0a362d291..cbf8498df 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, Claude 3 Opus and DeepSeek Coder V2.
@@ -93,20 +98,13 @@ Pair program with AI.
- [Code with your voice](https://aider.chat/docs/voice.html).
-## State of the art
+## Top tier performance
-Aider has the
-[top score on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
+[Aider has the one of the top scores on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
SWE Bench is a challenging software engineering benchmark where aider
solved *real* GitHub issues from popular open source
projects like django, scikitlearn, matplotlib, etc.
-