mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-29 00:35:00 +00:00
Config can use .yaml as well as .yml, duplicate defaults to .yml
This commit is contained in:
parent
3caab85931
commit
e16aa4f141
1 changed files with 84 additions and 29 deletions
113
aider/main.py
113
aider/main.py
|
@ -49,8 +49,12 @@ def check_config_files_for_yes(config_files):
|
|||
for line in f:
|
||||
if line.strip().startswith("yes:"):
|
||||
print("Configuration error detected.")
|
||||
print(f"The file {config_file} contains a line starting with 'yes:'")
|
||||
print("Please replace 'yes:' with 'yes-always:' in this file.")
|
||||
print(
|
||||
f"The file {config_file} contains a line starting with 'yes:'"
|
||||
)
|
||||
print(
|
||||
"Please replace 'yes:' with 'yes-always:' in this file."
|
||||
)
|
||||
found = True
|
||||
except Exception:
|
||||
pass
|
||||
|
@ -147,7 +151,9 @@ def setup_git(git_root, io):
|
|||
io.tool_warning('Update git name with: git config user.name "Your Name"')
|
||||
if not user_email:
|
||||
git_config.set_value("user", "email", "you@example.com")
|
||||
io.tool_warning('Update git email with: git config user.email "you@example.com"')
|
||||
io.tool_warning(
|
||||
'Update git email with: git config user.email "you@example.com"'
|
||||
)
|
||||
|
||||
return repo.working_tree_dir
|
||||
|
||||
|
@ -188,7 +194,9 @@ def check_gitignore(git_root, io, ask=True):
|
|||
|
||||
if ask:
|
||||
io.tool_output("You can skip this check with --no-gitignore")
|
||||
if not io.confirm_ask(f"Add {', '.join(patterns_to_add)} to .gitignore (recommended)?"):
|
||||
if not io.confirm_ask(
|
||||
f"Add {', '.join(patterns_to_add)} to .gitignore (recommended)?"
|
||||
):
|
||||
return
|
||||
|
||||
content += "\n".join(patterns_to_add) + "\n"
|
||||
|
@ -391,7 +399,9 @@ def register_litellm_models(git_root, model_metadata_fname, io, verbose=False):
|
|||
model_metadata_files = []
|
||||
|
||||
# Add the resource file path
|
||||
resource_metadata = importlib_resources.files("aider.resources").joinpath("model-metadata.json")
|
||||
resource_metadata = importlib_resources.files("aider.resources").joinpath(
|
||||
"model-metadata.json"
|
||||
)
|
||||
model_metadata_files.append(str(resource_metadata))
|
||||
|
||||
model_metadata_files += generate_search_path_list(
|
||||
|
@ -399,7 +409,9 @@ def register_litellm_models(git_root, model_metadata_fname, io, verbose=False):
|
|||
)
|
||||
|
||||
try:
|
||||
model_metadata_files_loaded = models.register_litellm_models(model_metadata_files)
|
||||
model_metadata_files_loaded = models.register_litellm_models(
|
||||
model_metadata_files
|
||||
)
|
||||
if len(model_metadata_files_loaded) > 0 and verbose:
|
||||
io.tool_output("Loaded model metadata from:")
|
||||
for model_metadata_file in model_metadata_files_loaded:
|
||||
|
@ -438,7 +450,9 @@ def sanity_check_repo(repo, io):
|
|||
|
||||
if bad_ver:
|
||||
io.tool_error("Aider only works with git repos with version number 1 or 2.")
|
||||
io.tool_output("You may be able to convert your repo: git update-index --index-version=2")
|
||||
io.tool_output(
|
||||
"You may be able to convert your repo: git update-index --index-version=2"
|
||||
)
|
||||
io.tool_output("Or run aider --no-git to proceed without using git.")
|
||||
io.offer_url(urls.git_index_version, "Open documentation url for more info?")
|
||||
return False
|
||||
|
@ -448,6 +462,19 @@ def sanity_check_repo(repo, io):
|
|||
return False
|
||||
|
||||
|
||||
def get_config_file(prefix: Path | None = None):
|
||||
conf_files = [
|
||||
prefix / name if prefix else Path(name)
|
||||
for name in [".aider.conf.yml", ".aider.conf.yaml"]
|
||||
if (prefix / name if prefix else Path(name)).exists()
|
||||
]
|
||||
if len(conf_files) > 1:
|
||||
print(
|
||||
f"Warning: Both .aider.conf.yml and .aider.conf.yaml are present at {prefix}. Defaulting to .aider.conf.yml."
|
||||
)
|
||||
return conf_files[0] if conf_files else None
|
||||
|
||||
|
||||
def main(argv=None, input=None, output=None, force_git_root=None, return_coder=False):
|
||||
report_uncaught_exceptions()
|
||||
|
||||
|
@ -461,26 +488,32 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
else:
|
||||
git_root = get_git_root()
|
||||
|
||||
conf_fname = Path(".aider.conf.yml")
|
||||
conf_fname = get_config_file()
|
||||
|
||||
default_config_files = []
|
||||
try:
|
||||
default_config_files += [conf_fname.resolve()] # CWD
|
||||
except OSError:
|
||||
pass
|
||||
if conf_fname:
|
||||
try:
|
||||
default_config_files += [conf_fname.resolve()] # CWD
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if git_root:
|
||||
git_conf = Path(git_root) / conf_fname # git root
|
||||
if git_conf not in default_config_files:
|
||||
default_config_files.append(git_conf)
|
||||
default_config_files.append(Path.home() / conf_fname) # homedir
|
||||
git_conf = get_config_file(Path(git_root)) # git root
|
||||
if git_conf and git_conf not in default_config_files:
|
||||
default_config_files.append(git_conf.resolve())
|
||||
home_conf = get_config_file(Path.home()) # home dir
|
||||
if home_conf and home_conf not in default_config_files:
|
||||
default_config_files.append(home_conf.resolve())
|
||||
default_config_files = list(map(str, default_config_files))
|
||||
|
||||
parser = get_parser(default_config_files, git_root)
|
||||
try:
|
||||
args, unknown = parser.parse_known_args(argv)
|
||||
except AttributeError as e:
|
||||
if all(word in str(e) for word in ["bool", "object", "has", "no", "attribute", "strip"]):
|
||||
if all(
|
||||
word in str(e)
|
||||
for word in ["bool", "object", "has", "no", "attribute", "strip"]
|
||||
):
|
||||
if check_config_files_for_yes(default_config_files):
|
||||
return 1
|
||||
raise e
|
||||
|
@ -625,7 +658,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
)
|
||||
os.environ["OPENAI_API_VERSION"] = args.openai_api_version
|
||||
if args.openai_api_type:
|
||||
io.tool_warning("--openai-api-type is deprecated, use --set-env OPENAI_API_TYPE=<value>")
|
||||
io.tool_warning(
|
||||
"--openai-api-type is deprecated, use --set-env OPENAI_API_TYPE=<value>"
|
||||
)
|
||||
os.environ["OPENAI_API_TYPE"] = args.openai_api_type
|
||||
if args.openai_organization_id:
|
||||
io.tool_warning(
|
||||
|
@ -633,7 +668,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
)
|
||||
os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id
|
||||
|
||||
analytics = Analytics(logfile=args.analytics_log, permanently_disable=args.analytics_disable)
|
||||
analytics = Analytics(
|
||||
logfile=args.analytics_log, permanently_disable=args.analytics_disable
|
||||
)
|
||||
if args.analytics is not False:
|
||||
if analytics.need_to_ask(args.analytics):
|
||||
io.tool_output(
|
||||
|
@ -749,7 +786,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
check_and_load_imports(io, is_first_run, verbose=args.verbose)
|
||||
|
||||
register_models(git_root, args.model_settings_file, io, verbose=args.verbose)
|
||||
register_litellm_models(git_root, args.model_metadata_file, io, verbose=args.verbose)
|
||||
register_litellm_models(
|
||||
git_root, args.model_metadata_file, io, verbose=args.verbose
|
||||
)
|
||||
|
||||
if args.list_models:
|
||||
models.print_matching_models(io, args.list_models)
|
||||
|
@ -778,7 +817,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
args.model = selected_model_name # Update args with the selected model
|
||||
|
||||
# Check if an OpenRouter model was selected/specified but the key is missing
|
||||
if args.model.startswith("openrouter/") and not os.environ.get("OPENROUTER_API_KEY"):
|
||||
if args.model.startswith("openrouter/") and not os.environ.get(
|
||||
"OPENROUTER_API_KEY"
|
||||
):
|
||||
io.tool_warning(
|
||||
f"The specified model '{args.model}' requires an OpenRouter API key, which was not"
|
||||
" found."
|
||||
|
@ -832,14 +873,16 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
if args.reasoning_effort is not None:
|
||||
# Apply if check is disabled or model explicitly supports it
|
||||
if not args.check_model_accepts_settings or (
|
||||
main_model.accepts_settings and "reasoning_effort" in main_model.accepts_settings
|
||||
main_model.accepts_settings
|
||||
and "reasoning_effort" in main_model.accepts_settings
|
||||
):
|
||||
main_model.set_reasoning_effort(args.reasoning_effort)
|
||||
|
||||
if args.thinking_tokens is not None:
|
||||
# Apply if check is disabled or model explicitly supports it
|
||||
if not args.check_model_accepts_settings or (
|
||||
main_model.accepts_settings and "thinking_tokens" in main_model.accepts_settings
|
||||
main_model.accepts_settings
|
||||
and "thinking_tokens" in main_model.accepts_settings
|
||||
):
|
||||
main_model.set_thinking_tokens(args.thinking_tokens)
|
||||
|
||||
|
@ -889,10 +932,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
io.tool_output("You can skip this check with --no-show-model-warnings")
|
||||
|
||||
try:
|
||||
io.offer_url(urls.model_warnings, "Open documentation url for more info?")
|
||||
io.offer_url(
|
||||
urls.model_warnings, "Open documentation url for more info?"
|
||||
)
|
||||
io.tool_output()
|
||||
except KeyboardInterrupt:
|
||||
analytics.event("exit", reason="Keyboard interrupt during model warnings")
|
||||
analytics.event(
|
||||
"exit", reason="Keyboard interrupt during model warnings"
|
||||
)
|
||||
return 1
|
||||
|
||||
repo = None
|
||||
|
@ -1110,7 +1157,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
io.tool_output(f"Git working dir: {git_root}")
|
||||
|
||||
if args.stream and args.cache_prompts:
|
||||
io.tool_warning("Cost estimates may be inaccurate when using streaming and caching.")
|
||||
io.tool_warning(
|
||||
"Cost estimates may be inaccurate when using streaming and caching."
|
||||
)
|
||||
|
||||
if args.load:
|
||||
commands.cmd_load(args.load)
|
||||
|
@ -1146,7 +1195,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
analytics.event("exit", reason="Exit flag set")
|
||||
return
|
||||
|
||||
analytics.event("cli session", main_model=main_model, edit_format=main_model.edit_format)
|
||||
analytics.event(
|
||||
"cli session", main_model=main_model, edit_format=main_model.edit_format
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
|
@ -1226,8 +1277,12 @@ def check_and_load_imports(io, is_first_run, verbose=False):
|
|||
load_slow_imports(swallow=False)
|
||||
except Exception as err:
|
||||
io.tool_error(str(err))
|
||||
io.tool_output("Error loading required imports. Did you install aider properly?")
|
||||
io.offer_url(urls.install_properly, "Open documentation url for more info?")
|
||||
io.tool_output(
|
||||
"Error loading required imports. Did you install aider properly?"
|
||||
)
|
||||
io.offer_url(
|
||||
urls.install_properly, "Open documentation url for more info?"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
if verbose:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue