mirror of
https://github.com/Aider-AI/aider.git
synced 2025-06-01 02:05:00 +00:00
Merge branch 'main' into fix-flake8
This commit is contained in:
commit
10ab57779a
44 changed files with 1249 additions and 188 deletions
|
@ -1,5 +1,5 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.12.0
|
rev: 5.12.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
|
||||||
# Release history
|
# 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
|
### v0.38.0
|
||||||
|
|
||||||
- Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat.
|
- Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat.
|
||||||
|
|
22
README.md
22
README.md
|
@ -6,8 +6,8 @@
|
||||||
Aider lets you pair program with LLMs,
|
Aider lets you pair program with LLMs,
|
||||||
to edit code in your local git repository.
|
to edit code in your local git repository.
|
||||||
Start a new project or work with an existing git repo.
|
Start a new project or work with an existing git repo.
|
||||||
Aider works best with GPT-4o and Claude 3 Opus
|
Aider can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||||
and 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.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img
|
<img
|
||||||
|
@ -43,9 +43,14 @@ $ cd /to/your/git/repo
|
||||||
$ export OPENAI_API_KEY=your-key-goes-here
|
$ export OPENAI_API_KEY=your-key-goes-here
|
||||||
$ aider
|
$ aider
|
||||||
|
|
||||||
# Or, work with Claude 3 Opus on your repo
|
# Or, work with Anthropic's models
|
||||||
$ export ANTHROPIC_API_KEY=your-key-goes-here
|
$ export ANTHROPIC_API_KEY=your-key-goes-here
|
||||||
|
|
||||||
|
# Claude 3 Opus
|
||||||
$ aider --opus
|
$ aider --opus
|
||||||
|
|
||||||
|
# Claude 3.5 Sonnet
|
||||||
|
$ aider --sonnet
|
||||||
```
|
```
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
|
@ -79,20 +84,13 @@ Pair program with AI.
|
||||||
- [Code with your voice](https://aider.chat/docs/voice.html).
|
- [Code with your voice](https://aider.chat/docs/voice.html).
|
||||||
|
|
||||||
|
|
||||||
## State of the art
|
## Top tier performance
|
||||||
|
|
||||||
Aider has the
|
[Aider has the one of the top scores on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
|
||||||
[top score on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
|
|
||||||
SWE Bench is a challenging software engineering benchmark where aider
|
SWE Bench is a challenging software engineering benchmark where aider
|
||||||
solved *real* GitHub issues from popular open source
|
solved *real* GitHub issues from popular open source
|
||||||
projects like django, scikitlearn, matplotlib, etc.
|
projects like django, scikitlearn, matplotlib, etc.
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://aider.chat/2024/06/02/main-swe-bench.html">
|
|
||||||
<img src="https://aider.chat/assets/swe_bench.svg" alt="aider swe bench">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## More info
|
## More info
|
||||||
|
|
||||||
- [Documentation](https://aider.chat/)
|
- [Documentation](https://aider.chat/)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "0.38.1-dev"
|
__version__ = "0.39.1-dev"
|
||||||
|
|
4
aider/__main__.py
Normal file
4
aider/__main__.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from .main import main
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -7,11 +7,30 @@ import sys
|
||||||
import configargparse
|
import configargparse
|
||||||
|
|
||||||
from aider import __version__, models
|
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
|
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):
|
def get_parser(default_config_files, git_root):
|
||||||
parser = configargparse.ArgumentParser(
|
parser = configargparse.ArgumentParser(
|
||||||
description="aider is GPT powered coding in your terminal",
|
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)",
|
help="Log the conversation with the LLM to this file (for example, .aider.llm.history)",
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"files",
|
"files", metavar="FILE", nargs="*", help="files to edit with an LLM (optional)"
|
||||||
metavar="FILE",
|
|
||||||
nargs="*",
|
|
||||||
help="files to edit with an LLM (optional)"
|
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--openai-api-key",
|
"--openai-api-key",
|
||||||
|
@ -60,7 +76,7 @@ def get_parser(default_config_files, git_root):
|
||||||
const=opus_model,
|
const=opus_model,
|
||||||
help=f"Use {opus_model} model for the main chat",
|
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(
|
group.add_argument(
|
||||||
"--sonnet",
|
"--sonnet",
|
||||||
action="store_const",
|
action="store_const",
|
||||||
|
@ -142,12 +158,24 @@ def get_parser(default_config_files, git_root):
|
||||||
env_var="OPENAI_ORGANIZATION_ID",
|
env_var="OPENAI_ORGANIZATION_ID",
|
||||||
help="Specify the 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(
|
group.add_argument(
|
||||||
"--model-metadata-file",
|
"--model-metadata-file",
|
||||||
metavar="MODEL_FILE",
|
metavar="MODEL_METADATA_FILE",
|
||||||
default=None,
|
default=None,
|
||||||
help="Specify a file with context window and costs for unknown models",
|
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(
|
group.add_argument(
|
||||||
"--edit-format",
|
"--edit-format",
|
||||||
metavar="EDIT_FORMAT",
|
metavar="EDIT_FORMAT",
|
||||||
|
@ -184,11 +212,12 @@ def get_parser(default_config_files, git_root):
|
||||||
" max_chat_history_tokens."
|
" 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(
|
group.add_argument(
|
||||||
"--env-file",
|
"--env-file",
|
||||||
metavar="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)",
|
help="Specify the .env file to load (default: .env in git root)",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -501,11 +530,27 @@ def get_sample_yaml():
|
||||||
return parser.format_help()
|
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():
|
def main():
|
||||||
arg = sys.argv[1] if len(sys.argv[1:]) else None
|
arg = sys.argv[1] if len(sys.argv[1:]) else None
|
||||||
|
|
||||||
if arg == "md":
|
if arg == "md":
|
||||||
print(get_md_help())
|
print(get_md_help())
|
||||||
|
elif arg == "dotenv":
|
||||||
|
print(get_sample_dotenv())
|
||||||
else:
|
else:
|
||||||
print(get_sample_yaml())
|
print(get_sample_yaml())
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,83 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
from aider import urls
|
||||||
|
|
||||||
from .dump import dump # noqa: F401
|
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 <fname>` 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):
|
class YamlHelpFormatter(argparse.HelpFormatter):
|
||||||
def start_section(self, heading):
|
def start_section(self, heading):
|
||||||
res = "\n\n"
|
res = "\n\n"
|
||||||
|
|
|
@ -913,9 +913,9 @@ class Coder:
|
||||||
res = ["", ""]
|
res = ["", ""]
|
||||||
res.append(f"Model {self.main_model.name} has hit a token limit!")
|
res.append(f"Model {self.main_model.name} has hit a token limit!")
|
||||||
res.append("")
|
res.append("")
|
||||||
res.append(f"Input tokens: {input_tokens} of {max_input_tokens}{inp_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"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"Total tokens: {total_tokens:,} of {max_input_tokens:,}{tot_err}")
|
||||||
|
|
||||||
if output_tokens >= max_output_tokens:
|
if output_tokens >= max_output_tokens:
|
||||||
res.append("")
|
res.append("")
|
||||||
|
|
|
@ -414,16 +414,8 @@ def find_original_update_blocks(content, fence=DEFAULT_FENCE):
|
||||||
|
|
||||||
processed.append(cur) # original_marker
|
processed.append(cur) # original_marker
|
||||||
|
|
||||||
filename = strip_filename(processed[-2].splitlines()[-1], fence)
|
filename = find_filename(processed[-2].splitlines(), fence)
|
||||||
try:
|
if not filename:
|
||||||
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:
|
|
||||||
if current_filename:
|
if current_filename:
|
||||||
filename = current_filename
|
filename = current_filename
|
||||||
else:
|
else:
|
||||||
|
@ -460,6 +452,35 @@ def find_original_update_blocks(content, fence=DEFAULT_FENCE):
|
||||||
raise ValueError(f"{processed}\n^^^ Error parsing SEARCH/REPLACE block.")
|
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__":
|
if __name__ == "__main__":
|
||||||
edit = """
|
edit = """
|
||||||
Here's the change:
|
Here's the change:
|
||||||
|
|
|
@ -332,7 +332,7 @@ class Commands:
|
||||||
|
|
||||||
last_commit = self.coder.repo.repo.head.commit
|
last_commit = self.coder.repo.repo.head.commit
|
||||||
if (
|
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
|
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.")
|
self.io.tool_error("The last commit was not made by aider in this chat session.")
|
||||||
|
|
|
@ -5,12 +5,13 @@ import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import git
|
import git
|
||||||
|
import httpx
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from prompt_toolkit.enums import EditingMode
|
from prompt_toolkit.enums import EditingMode
|
||||||
from streamlit.web import cli
|
from streamlit.web import cli
|
||||||
|
|
||||||
from aider import __version__, models, utils
|
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.coders import Coder
|
||||||
from aider.commands import SwitchModel
|
from aider.commands import SwitchModel
|
||||||
from aider.io import InputOutput
|
from aider.io import InputOutput
|
||||||
|
@ -124,12 +125,18 @@ def check_gitignore(git_root, io, ask=True):
|
||||||
|
|
||||||
def format_settings(parser, args):
|
def format_settings(parser, args):
|
||||||
show = scrub_sensitive_info(args, parser.format_values())
|
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 += "\n"
|
||||||
show += "Option settings:\n"
|
show += "Option settings:\n"
|
||||||
for arg, val in sorted(vars(args).items()):
|
for arg, val in sorted(vars(args).items()):
|
||||||
if val:
|
if val:
|
||||||
val = scrub_sensitive_info(args, str(val))
|
val = scrub_sensitive_info(args, str(val))
|
||||||
show += f" - {arg}: {val}\n"
|
show += f" - {arg}: {val}\n" # noqa: E221
|
||||||
return show
|
return show
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +212,48 @@ def parse_lint_cmds(lint_cmds, io):
|
||||||
return
|
return
|
||||||
return res
|
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):
|
def main(argv=None, input=None, output=None, force_git_root=None, return_coder=False):
|
||||||
if argv is None:
|
if argv is None:
|
||||||
argv = sys.argv[1:]
|
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.append(Path.home() / conf_fname) # homedir
|
||||||
default_config_files = list(map(str, default_config_files))
|
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)
|
parser = get_parser(default_config_files, git_root)
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
|
if not args.verify_ssl:
|
||||||
|
litellm.client_session = httpx.Client(verify=False)
|
||||||
|
|
||||||
if args.gui and not return_coder:
|
if args.gui and not return_coder:
|
||||||
launch_gui(argv)
|
launch_gui(argv)
|
||||||
return
|
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)
|
cmd_line = scrub_sensitive_info(args, cmd_line)
|
||||||
io.tool_output(cmd_line, log_only=True)
|
io.tool_output(cmd_line, log_only=True)
|
||||||
|
|
||||||
if args.env_file:
|
|
||||||
load_dotenv(args.env_file)
|
|
||||||
|
|
||||||
if args.anthropic_api_key:
|
if args.anthropic_api_key:
|
||||||
os.environ["ANTHROPIC_API_KEY"] = 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:
|
if args.openai_organization_id:
|
||||||
os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id
|
os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id
|
||||||
|
|
||||||
model_def_files = []
|
register_models(git_root, args.model_settings_file, io)
|
||||||
model_def_fname = Path(".aider.models.json")
|
register_litellm_models(git_root, args.model_metadata_file, io)
|
||||||
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
|
|
||||||
|
|
||||||
main_model = models.Model(args.model, weak_model=args.weak_model)
|
main_model = models.Model(args.model, weak_model=args.weak_model)
|
||||||
|
|
||||||
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
|
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
|
||||||
|
|
100
aider/models.py
100
aider/models.py
|
@ -1,5 +1,6 @@
|
||||||
import difflib
|
import difflib
|
||||||
import json
|
import json
|
||||||
|
import yaml
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -178,6 +179,43 @@ MODEL_SETTINGS = [
|
||||||
"whole",
|
"whole",
|
||||||
weak_model_name="claude-3-haiku-20240307",
|
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
|
# Cohere
|
||||||
ModelSettings(
|
ModelSettings(
|
||||||
"command-r-plus",
|
"command-r-plus",
|
||||||
|
@ -218,7 +256,7 @@ MODEL_SETTINGS = [
|
||||||
send_undo_reply=True,
|
send_undo_reply=True,
|
||||||
),
|
),
|
||||||
ModelSettings(
|
ModelSettings(
|
||||||
"openai/deepseek-chat",
|
"deepseek/deepseek-chat",
|
||||||
"diff",
|
"diff",
|
||||||
use_repo_map=True,
|
use_repo_map=True,
|
||||||
send_undo_reply=True,
|
send_undo_reply=True,
|
||||||
|
@ -226,7 +264,15 @@ MODEL_SETTINGS = [
|
||||||
reminder_as_sys_msg=True,
|
reminder_as_sys_msg=True,
|
||||||
),
|
),
|
||||||
ModelSettings(
|
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",
|
"diff",
|
||||||
use_repo_map=True,
|
use_repo_map=True,
|
||||||
send_undo_reply=True,
|
send_undo_reply=True,
|
||||||
|
@ -425,23 +471,47 @@ class Model:
|
||||||
return validate_variables(["GROQ_API_KEY"])
|
return validate_variables(["GROQ_API_KEY"])
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def register_models(model_settings_fnames):
|
||||||
def register_models(model_def_fnames):
|
files_loaded = []
|
||||||
model_metadata_files_loaded = []
|
for model_settings_fname in model_settings_fnames:
|
||||||
for model_def_fname in model_def_fnames:
|
if not os.path.exists(model_settings_fname):
|
||||||
if not os.path.exists(model_def_fname):
|
|
||||||
continue
|
continue
|
||||||
model_metadata_files_loaded.append(model_def_fname)
|
|
||||||
try:
|
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)
|
model_def = json.load(model_def_file)
|
||||||
except json.JSONDecodeError as e:
|
litellm.register_model(model_def)
|
||||||
raise Exception(f"Error loading model definition from {model_def_fname}: {e}")
|
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 files_loaded
|
||||||
|
|
||||||
return model_metadata_files_loaded
|
|
||||||
|
|
||||||
|
|
||||||
def validate_variables(vars):
|
def validate_variables(vars):
|
||||||
|
|
|
@ -88,11 +88,15 @@ class GitRepo:
|
||||||
else:
|
else:
|
||||||
cmd += ["-a"]
|
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:
|
if aider_edits:
|
||||||
user_name = self.repo.config_reader().get_value("user", "name")
|
original_auther_name_env = os.environ.get("GIT_AUTHOR_NAME")
|
||||||
committer_name = f"{user_name} (aider)"
|
os.environ["GIT_AUTHOR_NAME"] = committer_name
|
||||||
original_committer_name = os.environ.get("GIT_COMMITTER_NAME")
|
|
||||||
os.environ["GIT_COMMITTER_NAME"] = committer_name
|
|
||||||
|
|
||||||
self.repo.git.commit(cmd)
|
self.repo.git.commit(cmd)
|
||||||
commit_hash = self.repo.head.commit.hexsha[:7]
|
commit_hash = self.repo.head.commit.hexsha[:7]
|
||||||
|
@ -100,10 +104,15 @@ class GitRepo:
|
||||||
|
|
||||||
# Restore the original GIT_COMMITTER_NAME
|
# Restore the original GIT_COMMITTER_NAME
|
||||||
if aider_edits:
|
if aider_edits:
|
||||||
if original_committer_name is not None:
|
if original_auther_name_env is not None:
|
||||||
os.environ["GIT_COMMITTER_NAME"] = original_committer_name
|
os.environ["GIT_AUTHOR_NAME"] = original_auther_name_env
|
||||||
else:
|
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
|
return commit_hash, commit_message
|
||||||
|
|
||||||
|
|
|
@ -523,16 +523,20 @@ class TestCommands(TestCase):
|
||||||
other_path.write_text("other content")
|
other_path.write_text("other content")
|
||||||
repo.git.add(str(other_path))
|
repo.git.add(str(other_path))
|
||||||
|
|
||||||
|
os.environ["GIT_AUTHOR_NAME"] = "Foo (aider)"
|
||||||
|
|
||||||
# Create and commit a file
|
# Create and commit a file
|
||||||
filename = "test_file.txt"
|
filename = "test_file.txt"
|
||||||
file_path = Path(repo_dir) / filename
|
file_path = Path(repo_dir) / filename
|
||||||
file_path.write_text("first content")
|
file_path.write_text("first content")
|
||||||
repo.git.add(filename)
|
repo.git.add(filename)
|
||||||
repo.git.commit("-m", "aider: first commit")
|
repo.git.commit("-m", "first commit")
|
||||||
|
|
||||||
file_path.write_text("second content")
|
file_path.write_text("second content")
|
||||||
repo.git.add(filename)
|
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
|
# Store the commit hash
|
||||||
last_commit_hash = repo.head.commit.hexsha[:7]
|
last_commit_hash = repo.head.commit.hexsha[:7]
|
||||||
|
|
|
@ -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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from io import StringIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import MagicMock, patch
|
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.dump import dump # noqa: F401
|
||||||
from aider.io import InputOutput
|
from aider.io import InputOutput
|
||||||
from aider.main import check_gitignore, main, setup_git
|
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):
|
class TestMain(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
self.original_env = os.environ.copy()
|
||||||
os.environ["OPENAI_API_KEY"] = "deadbeef"
|
os.environ["OPENAI_API_KEY"] = "deadbeef"
|
||||||
self.original_cwd = os.getcwd()
|
self.original_cwd = os.getcwd()
|
||||||
self.tempdir = tempfile.mkdtemp()
|
self.tempdir_obj = IgnorantTemporaryDirectory()
|
||||||
|
self.tempdir = self.tempdir_obj.name
|
||||||
os.chdir(self.tempdir)
|
os.chdir(self.tempdir)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
os.chdir(self.original_cwd)
|
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):
|
def test_main_with_empty_dir_no_files_on_command(self):
|
||||||
main(["--no-git"], input=DummyInput(), output=DummyOutput())
|
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())
|
main(["foo.txt", "--yes", "--no-git"], input=DummyInput(), output=DummyOutput())
|
||||||
self.assertTrue(os.path.exists("foo.txt"))
|
self.assertTrue(os.path.exists("foo.txt"))
|
||||||
|
|
||||||
|
@ -237,3 +241,82 @@ class TestMain(TestCase):
|
||||||
main(["--message", test_message])
|
main(["--message", test_message])
|
||||||
args, kwargs = MockInputOutput.call_args
|
args, kwargs = MockInputOutput.call_args
|
||||||
self.assertEqual(args[1], None)
|
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")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -141,6 +142,10 @@ class TestRepo(unittest.TestCase):
|
||||||
def test_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"'
|
mock_send.return_value = '"a good commit message"'
|
||||||
|
|
||||||
|
# Cleanup of the git temp dir explodes on windows
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
return
|
||||||
|
|
||||||
with GitTemporaryDirectory():
|
with GitTemporaryDirectory():
|
||||||
# new repo
|
# new repo
|
||||||
raw_repo = git.Repo()
|
raw_repo = git.Repo()
|
||||||
|
@ -152,7 +157,8 @@ class TestRepo(unittest.TestCase):
|
||||||
raw_repo.git.add(str(fname))
|
raw_repo.git.add(str(fname))
|
||||||
raw_repo.git.commit("-m", "initial commit")
|
raw_repo.git.commit("-m", "initial commit")
|
||||||
|
|
||||||
git_repo = GitRepo(InputOutput(), None, None)
|
io = InputOutput()
|
||||||
|
git_repo = GitRepo(io, None, None)
|
||||||
|
|
||||||
# commit a change
|
# commit a change
|
||||||
fname.write_text("new content")
|
fname.write_text("new content")
|
||||||
|
@ -160,11 +166,23 @@ class TestRepo(unittest.TestCase):
|
||||||
|
|
||||||
# check the committer name
|
# check the committer name
|
||||||
commit = raw_repo.head.commit
|
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)")
|
self.assertEqual(commit.committer.name, "Test User (aider)")
|
||||||
|
|
||||||
# check that the original committer name is restored
|
# check that the original committer name is restored
|
||||||
original_committer_name = os.environ.get("GIT_COMMITTER_NAME")
|
original_committer_name = os.environ.get("GIT_COMMITTER_NAME")
|
||||||
self.assertIsNone(original_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):
|
def test_get_tracked_files(self):
|
||||||
# Create a temporary directory
|
# Create a temporary directory
|
||||||
|
|
|
@ -6,3 +6,4 @@ enable_playwright = "https://aider.chat/docs/install/optional.html#enable-playwr
|
||||||
favicon = "https://aider.chat/assets/icons/favicon-32x32.png"
|
favicon = "https://aider.chat/assets/icons/favicon-32x32.png"
|
||||||
model_warnings = "https://aider.chat/docs/llms/warnings.html"
|
model_warnings = "https://aider.chat/docs/llms/warnings.html"
|
||||||
token_limits = "https://aider.chat/docs/troubleshooting/token-limits.html"
|
token_limits = "https://aider.chat/docs/troubleshooting/token-limits.html"
|
||||||
|
llms = "https://aider.chat/docs/llms.html"
|
||||||
|
|
|
@ -17,11 +17,17 @@ class IgnorantTemporaryDirectory:
|
||||||
return self.temp_dir.__enter__()
|
return self.temp_dir.__enter__()
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
self.cleanup()
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
try:
|
try:
|
||||||
self.temp_dir.__exit__(exc_type, exc_val, exc_tb)
|
self.temp_dir.cleanup()
|
||||||
except (OSError, PermissionError):
|
except (OSError, PermissionError):
|
||||||
pass # Ignore errors (Windows)
|
pass # Ignore errors (Windows)
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
return getattr(self.temp_dir, item)
|
||||||
|
|
||||||
|
|
||||||
class ChdirTemporaryDirectory(IgnorantTemporaryDirectory):
|
class ChdirTemporaryDirectory(IgnorantTemporaryDirectory):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -54,7 +54,7 @@ diskcache==5.6.3
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
distro==1.9.0
|
distro==1.9.0
|
||||||
# via openai
|
# via openai
|
||||||
filelock==3.15.1
|
filelock==3.15.3
|
||||||
# via huggingface-hub
|
# via huggingface-hub
|
||||||
flake8==7.1.0
|
flake8==7.1.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
@ -70,14 +70,14 @@ gitpython==3.1.43
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
# streamlit
|
# streamlit
|
||||||
google-ai-generativelanguage==0.6.4
|
google-ai-generativelanguage==0.6.5
|
||||||
# via google-generativeai
|
# via google-generativeai
|
||||||
google-api-core[grpc]==2.19.0
|
google-api-core[grpc]==2.19.0
|
||||||
# via
|
# via
|
||||||
# google-ai-generativelanguage
|
# google-ai-generativelanguage
|
||||||
# google-api-python-client
|
# google-api-python-client
|
||||||
# google-generativeai
|
# google-generativeai
|
||||||
google-api-python-client==2.133.0
|
google-api-python-client==2.134.0
|
||||||
# via google-generativeai
|
# via google-generativeai
|
||||||
google-auth==2.30.0
|
google-auth==2.30.0
|
||||||
# via
|
# via
|
||||||
|
@ -88,7 +88,7 @@ google-auth==2.30.0
|
||||||
# google-generativeai
|
# google-generativeai
|
||||||
google-auth-httplib2==0.2.0
|
google-auth-httplib2==0.2.0
|
||||||
# via google-api-python-client
|
# via google-api-python-client
|
||||||
google-generativeai==0.6.0
|
google-generativeai==0.7.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
googleapis-common-protos==1.63.1
|
googleapis-common-protos==1.63.1
|
||||||
# via
|
# via
|
||||||
|
@ -122,7 +122,9 @@ idna==3.7
|
||||||
# httpx
|
# httpx
|
||||||
# requests
|
# requests
|
||||||
# yarl
|
# yarl
|
||||||
importlib-metadata==7.1.0
|
ijson==3.3.0
|
||||||
|
# via litellm
|
||||||
|
importlib-metadata==7.2.0
|
||||||
# via litellm
|
# via litellm
|
||||||
jinja2==3.1.4
|
jinja2==3.1.4
|
||||||
# via
|
# via
|
||||||
|
@ -135,7 +137,7 @@ jsonschema==4.22.0
|
||||||
# altair
|
# altair
|
||||||
jsonschema-specifications==2023.12.1
|
jsonschema-specifications==2023.12.1
|
||||||
# via jsonschema
|
# via jsonschema
|
||||||
litellm==1.40.15
|
litellm==1.40.21
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
markdown-it-py==3.0.0
|
markdown-it-py==3.0.0
|
||||||
# via rich
|
# via rich
|
||||||
|
@ -151,7 +153,7 @@ multidict==6.0.5
|
||||||
# yarl
|
# yarl
|
||||||
networkx==3.2.1
|
networkx==3.2.1
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
numpy==1.26.4
|
numpy==2.0.0
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
# altair
|
# altair
|
||||||
|
@ -160,7 +162,7 @@ numpy==1.26.4
|
||||||
# pydeck
|
# pydeck
|
||||||
# scipy
|
# scipy
|
||||||
# streamlit
|
# streamlit
|
||||||
openai==1.34.0
|
openai==1.35.3
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
# litellm
|
# litellm
|
||||||
|
@ -186,7 +188,7 @@ playwright==1.44.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
prompt-toolkit==3.0.47
|
prompt-toolkit==3.0.47
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
proto-plus==1.23.0
|
proto-plus==1.24.0
|
||||||
# via
|
# via
|
||||||
# google-ai-generativelanguage
|
# google-ai-generativelanguage
|
||||||
# google-api-core
|
# google-api-core
|
||||||
|
@ -280,9 +282,9 @@ soundfile==0.12.1
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
soupsieve==2.5
|
soupsieve==2.5
|
||||||
# via beautifulsoup4
|
# via beautifulsoup4
|
||||||
streamlit==1.35.0
|
streamlit==1.36.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
tenacity==8.3.0
|
tenacity==8.4.1
|
||||||
# via streamlit
|
# via streamlit
|
||||||
tiktoken==0.7.0
|
tiktoken==0.7.0
|
||||||
# via
|
# via
|
||||||
|
@ -320,7 +322,7 @@ tzdata==2024.1
|
||||||
# via pandas
|
# via pandas
|
||||||
uritemplate==4.1.1
|
uritemplate==4.1.1
|
||||||
# via google-api-python-client
|
# via google-api-python-client
|
||||||
urllib3==2.2.1
|
urllib3==2.2.2
|
||||||
# via requests
|
# via requests
|
||||||
watchdog==4.0.1
|
watchdog==4.0.1
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
|
|
@ -14,6 +14,7 @@ cog $ARG \
|
||||||
README.md \
|
README.md \
|
||||||
website/index.md \
|
website/index.md \
|
||||||
website/HISTORY.md \
|
website/HISTORY.md \
|
||||||
|
website/docs/dotenv.md \
|
||||||
website/docs/commands.md \
|
website/docs/commands.md \
|
||||||
website/docs/languages.md \
|
website/docs/languages.md \
|
||||||
website/docs/options.md \
|
website/docs/options.md \
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Release history
|
title: Release history
|
||||||
|
parent: More info
|
||||||
nav_order: 999
|
nav_order: 999
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -11,6 +12,13 @@ cog.out(text)
|
||||||
|
|
||||||
# Release history
|
# 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
|
### v0.38.0
|
||||||
|
|
||||||
- Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat.
|
- Use `--vim` for [vim keybindings](https://aider.chat/docs/commands.html#vi) in the chat.
|
||||||
|
|
|
@ -4,6 +4,7 @@ url: "https://aider.chat"
|
||||||
plugins:
|
plugins:
|
||||||
- jekyll-redirect-from
|
- jekyll-redirect-from
|
||||||
- jekyll-sitemap
|
- jekyll-sitemap
|
||||||
|
- jekyll-feed
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
- scope:
|
- scope:
|
||||||
|
@ -19,6 +20,7 @@ exclude:
|
||||||
- "**/OLD/**"
|
- "**/OLD/**"
|
||||||
- "OLD/**"
|
- "OLD/**"
|
||||||
- vendor
|
- vendor
|
||||||
|
- feed.xml
|
||||||
|
|
||||||
aux_links:
|
aux_links:
|
||||||
"GitHub":
|
"GitHub":
|
||||||
|
|
|
@ -44,29 +44,6 @@
|
||||||
seconds_per_case: 23.1
|
seconds_per_case: 23.1
|
||||||
total_cost: 0.0000
|
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
|
- dirname: 2024-05-03-20-47-24--gemini-1.5-pro-diff-fenced
|
||||||
test_cases: 133
|
test_cases: 133
|
||||||
model: gemini-1.5-pro-latest
|
model: gemini-1.5-pro-latest
|
||||||
|
@ -611,4 +588,97 @@
|
||||||
date: 2024-06-08
|
date: 2024-06-08
|
||||||
versions: 0.37.1-dev
|
versions: 0.37.1-dev
|
||||||
seconds_per_case: 280.6
|
seconds_per_case: 280.6
|
||||||
total_cost: 0.0000
|
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
|
||||||
|
|
|
@ -143,4 +143,25 @@
|
||||||
seconds_per_case: 67.8
|
seconds_per_case: 67.8
|
||||||
total_cost: 20.4889
|
total_cost: 20.4889
|
||||||
|
|
||||||
|
|
||||||
|
- 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
|
|
@ -10,7 +10,12 @@ $ cd /to/your/git/repo
|
||||||
$ export OPENAI_API_KEY=your-key-goes-here
|
$ export OPENAI_API_KEY=your-key-goes-here
|
||||||
$ aider
|
$ aider
|
||||||
|
|
||||||
# Or, work with Claude 3 Opus on your repo
|
# Or, work with Anthropic's models
|
||||||
$ export ANTHROPIC_API_KEY=your-key-goes-here
|
$ export ANTHROPIC_API_KEY=your-key-goes-here
|
||||||
|
|
||||||
|
# Claude 3 Opus
|
||||||
$ aider --opus
|
$ aider --opus
|
||||||
|
|
||||||
|
# Claude 3.5 Sonnet
|
||||||
|
$ aider --sonnet
|
||||||
```
|
```
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<meta property="og:image" content="{{ site.url }}/assets/aider.jpg">
|
<meta property="og:image" content="{{ site.url }}/assets/aider.jpg">
|
||||||
<meta property="twitter:image" content="{{ site.url }}/assets/aider-square.jpg">
|
<meta property="twitter:image" content="{{ site.url }}/assets/aider-square.jpg">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="{{ site.url }}/feed.xml">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
<link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap" as="style" type="text/css" crossorigin>
|
<link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap" as="style" type="text/css" crossorigin>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
## Use claude-3-opus-20240229 model for the main chat
|
## Use claude-3-opus-20240229 model for the main chat
|
||||||
#opus: false
|
#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
|
#sonnet: false
|
||||||
|
|
||||||
## Use gpt-4-0613 model for the main chat
|
## Use gpt-4-0613 model for the main chat
|
||||||
|
@ -64,9 +64,15 @@
|
||||||
## Specify the OpenAI organization ID
|
## Specify the OpenAI organization ID
|
||||||
#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
|
## Specify a file with context window and costs for unknown models
|
||||||
#model-metadata-file:
|
#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)
|
## Specify what edit format the LLM should use (default depends on model)
|
||||||
#edit-format:
|
#edit-format:
|
||||||
|
|
||||||
|
|
232
website/assets/sample.env
Normal file
232
website/assets/sample.env
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
##########################################################
|
||||||
|
# Sample aider .env file.
|
||||||
|
# Place at the root of your git repo.
|
||||||
|
# Or use `aider --env <fname>` 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
|
|
@ -56,7 +56,7 @@ cog.outl("```")
|
||||||
## Use claude-3-opus-20240229 model for the main chat
|
## Use claude-3-opus-20240229 model for the main chat
|
||||||
#opus: false
|
#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
|
#sonnet: false
|
||||||
|
|
||||||
## Use gpt-4-0613 model for the main chat
|
## Use gpt-4-0613 model for the main chat
|
||||||
|
@ -92,9 +92,15 @@ cog.outl("```")
|
||||||
## Specify the OpenAI organization ID
|
## Specify the OpenAI organization ID
|
||||||
#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
|
## Specify a file with context window and costs for unknown models
|
||||||
#model-metadata-file:
|
#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)
|
## Specify what edit format the LLM should use (default depends on model)
|
||||||
#edit-format:
|
#edit-format:
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@ nav_order: 900
|
||||||
description: Using a .env file to store LLM API keys for aider.
|
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
|
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 currently can not set general aider options
|
You can also set many general aider options
|
||||||
in the `.env` file, only LLM environment variables.
|
in the `.env` file.
|
||||||
|
|
||||||
{% include special-keys.md %}
|
{% 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.
|
root of your git repo or in the current directory.
|
||||||
You can give it an explicit file to load with the `--env-file <filename>` parameter.
|
You can give it an explicit file to load with the `--env-file <filename>` 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).
|
||||||
|
|
||||||
|
<!--[[[cog
|
||||||
|
from aider.args import get_sample_dotenv
|
||||||
|
from pathlib import Path
|
||||||
|
text=get_sample_dotenv()
|
||||||
|
Path("website/assets/sample.env").write_text(text)
|
||||||
|
cog.outl("```")
|
||||||
|
cog.out(text)
|
||||||
|
cog.outl("```")
|
||||||
|
]]]-->
|
||||||
```
|
```
|
||||||
OPENAI_API_KEY=<key>
|
##########################################################
|
||||||
ANTHROPIC_API_KEY=<key>
|
# Sample aider .env file.
|
||||||
GROQ_API_KEY=<key>
|
# Place at the root of your git repo.
|
||||||
OPENROUTER_API_KEY=<key>
|
# Or use `aider --env <fname>` to specify.
|
||||||
|
##########################################################
|
||||||
|
|
||||||
AZURE_API_KEY=<key>
|
#################
|
||||||
AZURE_API_VERSION=2023-05-15
|
# LLM parameters:
|
||||||
AZURE_API_BASE=https://example-endpoint.openai.azure.com
|
#
|
||||||
|
# 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
|
||||||
```
|
```
|
||||||
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
nav_order: 85
|
nav_order: 90
|
||||||
description: Frequently asked questions about aider.
|
description: Frequently asked questions about aider.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Frequently asked questions
|
# FAQ
|
||||||
{: .no_toc }
|
{: .no_toc }
|
||||||
|
|
||||||
- TOC
|
- TOC
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
parent: More info
|
||||||
nav_order: 800
|
nav_order: 800
|
||||||
description: Aider is tightly integrated with git.
|
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:
|
Aider specifically uses git in these ways:
|
||||||
|
|
||||||
- It asks to create a git repo if you launch it in a directory without one.
|
- 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.
|
- 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.
|
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.
|
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,
|
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.
|
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:
|
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.
|
- `--no-auto-commits` will stop aider from git committing each of its changes.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
parent: More info
|
||||||
nav_order: 900
|
nav_order: 900
|
||||||
description: Aider supports pretty much all popular coding languages.
|
description: Aider supports pretty much all popular coding languages.
|
||||||
---
|
---
|
||||||
|
|
|
@ -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.
|
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
|
Claude 3.5 Sonnet is now the top ranked model on aider's code editing leaderboard.
|
||||||
[DeepSeek Coder V2](https://aider.chat/docs/llms/deepseek.html)
|
DeepSeek Coder V2 only spent 4 days in the top spot.
|
||||||
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.
|
The new Sonnet came in 3rd on aider's refactoring leaderboard, behind GPT-4o and Opus.
|
||||||
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.
|
|
||||||
|
|
||||||
|
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
|
## Code editing leaderboard
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,21 @@ description: Aider can connect to most LLMs for AI pair programming.
|
||||||
## Best models
|
## Best models
|
||||||
{: .no_toc }
|
{: .no_toc }
|
||||||
|
|
||||||
**Aider works best with [GPT-4o](/docs/llms/openai.html) and
|
Aider works best with these models, which are skilled at editing code:
|
||||||
[Claude 3 Opus](/docs/llms/anthropic.html),**
|
|
||||||
as they are the very best models for 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
|
## Free models
|
||||||
{: .no_toc }
|
{: .no_toc }
|
||||||
|
|
||||||
Aider works with a number of **free** API providers:
|
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.
|
- 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) is the most capable free model to use with aider, with
|
- Google's [Gemini 1.5 Pro](/docs/llms/gemini.html) works with aider, with
|
||||||
code editing capabilities similar to GPT-3.5.
|
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.
|
- 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.
|
- 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.
|
||||||
|
|
|
@ -22,7 +22,7 @@ setx ANTHROPIC_API_KEY <key> # Windows
|
||||||
# Claude 3 Opus
|
# Claude 3 Opus
|
||||||
aider --opus
|
aider --opus
|
||||||
|
|
||||||
# Claude 3 Sonnet
|
# Claude 3.5 Sonnet
|
||||||
aider --sonnet
|
aider --sonnet
|
||||||
|
|
||||||
# List models available from Anthropic
|
# List models available from Anthropic
|
||||||
|
|
|
@ -8,10 +8,45 @@ nav_order: 900
|
||||||
{% include model-warnings.md %}
|
{% 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 <filename>` 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
|
## Specifying context window size and token costs
|
||||||
|
|
||||||
You can register context window limits and costs for models that aren't known
|
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.
|
- Your home directory.
|
||||||
- The root if your git repo.
|
- The root if your git repo.
|
||||||
|
|
8
website/docs/more-info.md
Normal file
8
website/docs/more-info.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
has_children: true
|
||||||
|
nav_order: 85
|
||||||
|
---
|
||||||
|
|
||||||
|
# More info
|
||||||
|
|
||||||
|
See below for more info about aider, including some advanced topics.
|
|
@ -19,8 +19,10 @@ usage: aider [-h] [--llm-history-file] [--openai-api-key]
|
||||||
[--4] [--4o] [--4-turbo] [--35turbo] [--models]
|
[--4] [--4o] [--4-turbo] [--35turbo] [--models]
|
||||||
[--openai-api-base] [--openai-api-type]
|
[--openai-api-base] [--openai-api-type]
|
||||||
[--openai-api-version] [--openai-api-deployment-id]
|
[--openai-api-version] [--openai-api-deployment-id]
|
||||||
[--openai-organization-id] [--model-metadata-file]
|
[--openai-organization-id] [--model-settings-file]
|
||||||
[--edit-format] [--weak-model]
|
[--model-metadata-file]
|
||||||
|
[--verify-ssl | --no-verify-ssl] [--edit-format]
|
||||||
|
[--weak-model]
|
||||||
[--show-model-warnings | --no-show-model-warnings]
|
[--show-model-warnings | --no-show-model-warnings]
|
||||||
[--map-tokens] [--max-chat-history-tokens] [--env-file]
|
[--map-tokens] [--max-chat-history-tokens] [--env-file]
|
||||||
[--input-history-file] [--chat-history-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`
|
Environment variable: `AIDER_OPUS`
|
||||||
|
|
||||||
### `--sonnet`
|
### `--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`
|
Environment variable: `AIDER_SONNET`
|
||||||
|
|
||||||
### `--4`
|
### `--4`
|
||||||
|
@ -128,10 +130,22 @@ Environment variable: `OPENAI_API_DEPLOYMENT_ID`
|
||||||
Specify the OpenAI organization ID
|
Specify the OpenAI organization ID
|
||||||
Environment variable: `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
|
Specify a file with context window and costs for unknown models
|
||||||
Environment variable: `AIDER_MODEL_METADATA_FILE`
|
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`
|
### `--edit-format EDIT_FORMAT`
|
||||||
Specify what edit format the LLM should use (default depends on model)
|
Specify what edit format the LLM should use (default depends on model)
|
||||||
Environment variable: `AIDER_EDIT_FORMAT`
|
Environment variable: `AIDER_EDIT_FORMAT`
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
parent: More info
|
||||||
highlight_image: /assets/robot-ast.png
|
highlight_image: /assets/robot-ast.png
|
||||||
nav_order: 900
|
nav_order: 900
|
||||||
description: Aider uses a map of your git repository to provide code context to LLMs.
|
description: Aider uses a map of your git repository to provide code context to LLMs.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
parent: More info
|
||||||
nav_order: 900
|
nav_order: 900
|
||||||
description: You can script aider via the command line or python.
|
description: You can script aider via the command line or python.
|
||||||
---
|
---
|
||||||
|
|
|
@ -33,8 +33,8 @@ so editing errors are probably unavoidable.
|
||||||
## Reduce distractions
|
## Reduce distractions
|
||||||
|
|
||||||
Many LLM now have very large context windows,
|
Many LLM now have very large context windows,
|
||||||
but filling them with irrelevant code often
|
but filling them with irrelevant code or conversation
|
||||||
cofuses the model.
|
can cofuse the model.
|
||||||
|
|
||||||
- Don't add too many files to the chat, *just* add the files you think need to be edited.
|
- 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.
|
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.
|
||||||
|
|
|
@ -20,8 +20,8 @@ cog.out(text)
|
||||||
Aider lets you pair program with LLMs,
|
Aider lets you pair program with LLMs,
|
||||||
to edit code in your local git repository.
|
to edit code in your local git repository.
|
||||||
Start a new project or work with an existing git repo.
|
Start a new project or work with an existing git repo.
|
||||||
Aider works best with GPT-4o and Claude 3 Opus
|
Aider can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||||
and 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.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img
|
<img
|
||||||
|
@ -57,9 +57,14 @@ $ cd /to/your/git/repo
|
||||||
$ export OPENAI_API_KEY=your-key-goes-here
|
$ export OPENAI_API_KEY=your-key-goes-here
|
||||||
$ aider
|
$ aider
|
||||||
|
|
||||||
# Or, work with Claude 3 Opus on your repo
|
# Or, work with Anthropic's models
|
||||||
$ export ANTHROPIC_API_KEY=your-key-goes-here
|
$ export ANTHROPIC_API_KEY=your-key-goes-here
|
||||||
|
|
||||||
|
# Claude 3 Opus
|
||||||
$ aider --opus
|
$ aider --opus
|
||||||
|
|
||||||
|
# Claude 3.5 Sonnet
|
||||||
|
$ aider --sonnet
|
||||||
```
|
```
|
||||||
<!-- NOOP -->
|
<!-- NOOP -->
|
||||||
|
|
||||||
|
@ -93,20 +98,13 @@ Pair program with AI.
|
||||||
- [Code with your voice](https://aider.chat/docs/voice.html).
|
- [Code with your voice](https://aider.chat/docs/voice.html).
|
||||||
|
|
||||||
|
|
||||||
## State of the art
|
## Top tier performance
|
||||||
|
|
||||||
Aider has the
|
[Aider has the one of the top scores on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
|
||||||
[top score on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html).
|
|
||||||
SWE Bench is a challenging software engineering benchmark where aider
|
SWE Bench is a challenging software engineering benchmark where aider
|
||||||
solved *real* GitHub issues from popular open source
|
solved *real* GitHub issues from popular open source
|
||||||
projects like django, scikitlearn, matplotlib, etc.
|
projects like django, scikitlearn, matplotlib, etc.
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://aider.chat/2024/06/02/main-swe-bench.html">
|
|
||||||
<img src="https://aider.chat/assets/swe_bench.svg" alt="aider swe bench">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## More info
|
## More info
|
||||||
|
|
||||||
- [Documentation](https://aider.chat/)
|
- [Documentation](https://aider.chat/)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue