refactor: change tool_error to tool_warning for non-critical messages

This commit is contained in:
Paul Gauthier 2024-09-03 13:30:04 -07:00 committed by Paul Gauthier (aider)
parent 00fa9efba4
commit dff814a7a8
8 changed files with 61 additions and 57 deletions

View file

@ -349,18 +349,18 @@ class Coder:
for fname in fnames: for fname in fnames:
fname = Path(fname) fname = Path(fname)
if self.repo and self.repo.ignored_file(fname): if self.repo and self.repo.ignored_file(fname):
self.io.tool_error(f"Skipping {fname} that matches aiderignore spec.") self.io.tool_warning(f"Skipping {fname} that matches aiderignore spec.")
continue continue
if not fname.exists(): if not fname.exists():
if utils.touch_file(fname): if utils.touch_file(fname):
self.io.tool_output(f"Creating empty file {fname}") self.io.tool_output(f"Creating empty file {fname}")
else: else:
self.io.tool_error(f"Can not create {fname}, skipping.") self.io.tool_warning(f"Can not create {fname}, skipping.")
continue continue
if not fname.is_file(): if not fname.is_file():
self.io.tool_error(f"Skipping {fname} that is not a normal file.") self.io.tool_warning(f"Skipping {fname} that is not a normal file.")
continue continue
fname = str(fname.resolve()) fname = str(fname.resolve())
@ -378,7 +378,7 @@ class Coder:
if os.path.exists(abs_fname): if os.path.exists(abs_fname):
self.abs_read_only_fnames.add(abs_fname) self.abs_read_only_fnames.add(abs_fname)
else: else:
self.io.tool_error(f"Error: Read-only file {fname} does not exist. Skipping.") self.io.tool_warning(f"Error: Read-only file {fname} does not exist. Skipping.")
if map_tokens is None: if map_tokens is None:
use_repo_map = main_model.use_repo_map use_repo_map = main_model.use_repo_map
@ -487,7 +487,7 @@ class Coder:
if content is None: if content is None:
relative_fname = self.get_rel_fname(fname) relative_fname = self.get_rel_fname(fname)
self.io.tool_error(f"Dropping {relative_fname} from the chat.") self.io.tool_warning(f"Dropping {relative_fname} from the chat.")
self.abs_fnames.remove(fname) self.abs_fnames.remove(fname)
else: else:
yield fname, content yield fname, content
@ -512,7 +512,7 @@ class Coder:
self.fence = (fence_open, fence_close) self.fence = (fence_open, fence_close)
else: else:
self.fence = self.fences[0] self.fence = self.fences[0]
self.io.tool_error( self.io.tool_warning(
"Unable to find a fencing strategy! Falling back to:" "Unable to find a fencing strategy! Falling back to:"
f" {self.fence[0]}...{self.fence[1]}" f" {self.fence[0]}...{self.fence[1]}"
) )
@ -776,7 +776,7 @@ class Coder:
break break
if self.num_reflections >= self.max_reflections: if self.num_reflections >= self.max_reflections:
self.io.tool_error(f"Only {self.max_reflections} reflections allowed, stopping.") self.io.tool_warning(f"Only {self.max_reflections} reflections allowed, stopping.")
return return
self.num_reflections += 1 self.num_reflections += 1
@ -803,10 +803,10 @@ class Coder:
thresh = 2 # seconds thresh = 2 # seconds
if self.last_keyboard_interrupt and now - self.last_keyboard_interrupt < thresh: if self.last_keyboard_interrupt and now - self.last_keyboard_interrupt < thresh:
self.io.tool_error("\n\n^C KeyboardInterrupt") self.io.tool_warning("\n\n^C KeyboardInterrupt")
sys.exit() sys.exit()
self.io.tool_error("\n\n^C again to exit") self.io.tool_warning("\n\n^C again to exit")
self.last_keyboard_interrupt = now self.last_keyboard_interrupt = now
@ -826,7 +826,7 @@ class Coder:
try: try:
self.summarized_done_messages = self.summarizer.summarize(self.done_messages) self.summarized_done_messages = self.summarizer.summarize(self.done_messages)
except ValueError as err: except ValueError as err:
self.io.tool_error(err.args[0]) self.io.tool_warning(err.args[0])
if self.verbose: if self.verbose:
self.io.tool_output("Finished summarizing chat history.") self.io.tool_output("Finished summarizing chat history.")
@ -1059,7 +1059,7 @@ class Coder:
extra_headers=self.main_model.extra_headers, extra_headers=self.main_model.extra_headers,
) )
except Exception as err: except Exception as err:
self.io.tool_error(f"Cache warming error: {str(err)}") self.io.tool_warning(f"Cache warming error: {str(err)}")
continue continue
cache_hit_tokens = getattr( cache_hit_tokens = getattr(
@ -1105,7 +1105,7 @@ class Coder:
yield from self.send(messages, functions=self.functions) yield from self.send(messages, functions=self.functions)
break break
except retry_exceptions() as err: except retry_exceptions() as err:
self.io.tool_error(str(err)) self.io.tool_warning(str(err))
retry_delay *= 2 retry_delay *= 2
if retry_delay > 60: if retry_delay > 60:
break break
@ -1293,7 +1293,7 @@ class Coder:
res += "\n" res += "\n"
if res: if res:
self.io.tool_error(res) self.io.tool_warning(res)
return res return res
@ -1687,7 +1687,7 @@ class Coder:
if not Path(full_path).exists(): if not Path(full_path).exists():
if not self.io.confirm_ask("Create new file?", subject=path): if not self.io.confirm_ask("Create new file?", subject=path):
self.io.tool_error(f"Skipping edits to {path}") self.io.tool_output(f"Skipping edits to {path}")
return return
if not self.dry_run: if not self.dry_run:
@ -1709,7 +1709,7 @@ class Coder:
"Allow edits to file that has not been added to the chat?", "Allow edits to file that has not been added to the chat?",
subject=path, subject=path,
): ):
self.io.tool_error(f"Skipping edits to {path}") self.io.tool_output(f"Skipping edits to {path}")
return return
if need_to_add: if need_to_add:
@ -1744,8 +1744,8 @@ class Coder:
if tokens < warn_number_of_tokens: if tokens < warn_number_of_tokens:
return return
self.io.tool_error("Warning: it's best to only add files that need changes to the chat.") self.io.tool_warning("Warning: it's best to only add files that need changes to the chat.")
self.io.tool_error(urls.edit_errors) self.io.tool_warning(urls.edit_errors)
self.warning_given = True self.warning_given = True
def prepare_to_edit(self, edits): def prepare_to_edit(self, edits):
@ -1788,9 +1788,9 @@ class Coder:
err = err.args[0] err = err.args[0]
self.io.tool_error("The LLM did not conform to the edit format.") self.io.tool_error("The LLM did not conform to the edit format.")
self.io.tool_error(urls.edit_errors) self.io.tool_output(urls.edit_errors)
self.io.tool_error() self.io.tool_output()
self.io.tool_error(str(err), strip=False) self.io.tool_output(str(err), strip=False)
self.reflected_message = str(err) self.reflected_message = str(err)
return edited return edited

View file

@ -147,7 +147,7 @@ class Commands:
if not self.scraper: if not self.scraper:
res = install_playwright(self.io) res = install_playwright(self.io)
if not res: if not res:
self.io.tool_error("Unable to initialize playwright.") self.io.tool_warning("Unable to initialize playwright.")
self.scraper = Scraper( self.scraper = Scraper(
print_error=self.io.tool_error, playwright_available=res, verify_ssl=self.verify_ssl print_error=self.io.tool_error, playwright_available=res, verify_ssl=self.verify_ssl
@ -237,7 +237,7 @@ class Commands:
return return
if not self.coder.repo.is_dirty(): if not self.coder.repo.is_dirty():
self.io.tool_error("No more changes to commit.") self.io.tool_warning("No more changes to commit.")
return return
commit_message = args.strip() if args else None commit_message = args.strip() if args else None
@ -258,7 +258,7 @@ class Commands:
fnames = self.coder.repo.get_dirty_files() fnames = self.coder.repo.get_dirty_files()
if not fnames: if not fnames:
self.io.tool_error("No dirty files to lint.") self.io.tool_warning("No dirty files to lint.")
return return
fnames = [self.coder.abs_root_path(fname) for fname in fnames] fnames = [self.coder.abs_root_path(fname) for fname in fnames]
@ -269,13 +269,13 @@ class Commands:
errors = self.coder.linter.lint(fname) errors = self.coder.linter.lint(fname)
except FileNotFoundError as err: except FileNotFoundError as err:
self.io.tool_error(f"Unable to lint {fname}") self.io.tool_error(f"Unable to lint {fname}")
self.io.tool_error(str(err)) self.io.tool_output(str(err))
continue continue
if not errors: if not errors:
continue continue
self.io.tool_error(errors) self.io.tool_output(errors)
if not self.io.confirm_ask(f"Fix lint errors in {fname}?", default="y"): if not self.io.confirm_ask(f"Fix lint errors in {fname}?", default="y"):
continue continue
@ -436,7 +436,7 @@ class Commands:
last_commit_message = self.coder.repo.get_head_commit_message("(unknown)").strip() last_commit_message = self.coder.repo.get_head_commit_message("(unknown)").strip()
if last_commit_hash not in self.coder.aider_commit_hashes: if last_commit_hash not in self.coder.aider_commit_hashes:
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.")
self.io.tool_error( self.io.tool_output(
"You could try `/git reset --hard HEAD^` but be aware that this is a destructive" "You could try `/git reset --hard HEAD^` but be aware that this is a destructive"
" command!" " command!"
) )
@ -496,12 +496,12 @@ class Commands:
if unrestored: if unrestored:
self.io.tool_error(f"Error restoring {file_path}, aborting undo.") self.io.tool_error(f"Error restoring {file_path}, aborting undo.")
self.io.tool_error("Restored files:") self.io.tool_output("Restored files:")
for file in restored: for file in restored:
self.io.tool_error(f" {file}") self.io.tool_output(f" {file}")
self.io.tool_error("Unable to restore files:") self.io.tool_output("Unable to restore files:")
for file in unrestored: for file in unrestored:
self.io.tool_error(f" {file}") self.io.tool_output(f" {file}")
return return
# Move the HEAD back before the latest commit # Move the HEAD back before the latest commit
@ -534,7 +534,7 @@ class Commands:
commit_before_message = self.coder.commit_before_message[-2] commit_before_message = self.coder.commit_before_message[-2]
if not commit_before_message or commit_before_message == current_head: if not commit_before_message or commit_before_message == current_head:
self.io.tool_error("No changes to display since the last message.") self.io.tool_warning("No changes to display since the last message.")
return return
self.io.tool_output(f"Diff since {commit_before_message[:7]}...") self.io.tool_output(f"Diff since {commit_before_message[:7]}...")
@ -609,7 +609,7 @@ class Commands:
fname = Path(self.coder.root) / word fname = Path(self.coder.root) / word
if self.coder.repo and self.coder.repo.ignored_file(fname): if self.coder.repo and self.coder.repo.ignored_file(fname):
self.io.tool_error(f"Skipping {fname} due to aiderignore or --subtree-only.") self.io.tool_warning(f"Skipping {fname} due to aiderignore or --subtree-only.")
continue continue
if fname.exists(): if fname.exists():
@ -632,7 +632,7 @@ class Commands:
if fname.exists() and fname.is_dir() and self.coder.repo: if fname.exists() and fname.is_dir() and self.coder.repo:
self.io.tool_error(f"Directory {fname} is not in git.") self.io.tool_error(f"Directory {fname} is not in git.")
self.io.tool_error(f"You can add to git with: /git add {fname}") self.io.tool_output(f"You can add to git with: /git add {fname}")
continue continue
if self.io.confirm_ask(f"No files matched '{word}'. Do you want to create {fname}?"): if self.io.confirm_ask(f"No files matched '{word}'. Do you want to create {fname}?"):
@ -652,7 +652,7 @@ class Commands:
continue continue
if abs_file_path in self.coder.abs_fnames: if abs_file_path in self.coder.abs_fnames:
self.io.tool_error(f"{matched_file} is already in the chat") self.io.tool_warning(f"{matched_file} is already in the chat")
elif abs_file_path in self.coder.abs_read_only_fnames: elif abs_file_path in self.coder.abs_read_only_fnames:
if self.coder.repo and self.coder.repo.path_in_repo(matched_file): if self.coder.repo and self.coder.repo.path_in_repo(matched_file):
self.coder.abs_read_only_fnames.remove(abs_file_path) self.coder.abs_read_only_fnames.remove(abs_file_path)
@ -756,7 +756,7 @@ class Commands:
if not errors: if not errors:
return return
self.io.tool_error(errors, strip=False) self.io.tool_output(errors, strip=False)
return errors return errors
def cmd_run(self, args, add_on_nonzero_exit=False): def cmd_run(self, args, add_on_nonzero_exit=False):

View file

@ -26,6 +26,10 @@ class CaptureIO(InputOutput):
self.lines.append(msg) self.lines.append(msg)
super().tool_error(msg) super().tool_error(msg)
def tool_warning(self, msg):
self.lines.append(msg)
super().tool_warning(msg)
def get_captured_lines(self): def get_captured_lines(self):
lines = self.lines lines = self.lines
self.lines = [] self.lines = []

View file

@ -58,7 +58,7 @@ def make_new_repo(git_root, io):
check_gitignore(git_root, io, False) check_gitignore(git_root, io, False)
except ANY_GIT_ERROR as err: # issue #1233 except ANY_GIT_ERROR as err: # issue #1233
io.tool_error(f"Unable to create git repo in {git_root}") io.tool_error(f"Unable to create git repo in {git_root}")
io.tool_error(str(err)) io.tool_output(str(err))
return return
io.tool_output(f"Git repository created in {git_root}") io.tool_output(f"Git repository created in {git_root}")
@ -71,7 +71,7 @@ def setup_git(git_root, io):
if git_root: if git_root:
repo = git.Repo(git_root) repo = git.Repo(git_root)
elif Path.cwd() == Path.home(): elif Path.cwd() == Path.home():
io.tool_error("You should probably run aider in a directory, not your home dir.") io.tool_warning("You should probably run aider in a directory, not your home dir.")
return return
elif io.confirm_ask("No git repo found, create one to track aider's changes (recommended)?"): elif io.confirm_ask("No git repo found, create one to track aider's changes (recommended)?"):
git_root = str(Path.cwd().resolve()) git_root = str(Path.cwd().resolve())
@ -98,10 +98,10 @@ def setup_git(git_root, io):
with repo.config_writer() as git_config: with repo.config_writer() as git_config:
if not user_name: if not user_name:
git_config.set_value("user", "name", "Your Name") git_config.set_value("user", "name", "Your Name")
io.tool_error('Update git name with: git config user.name "Your Name"') io.tool_warning('Update git name with: git config user.name "Your Name"')
if not user_email: if not user_email:
git_config.set_value("user", "email", "you@example.com") git_config.set_value("user", "email", "you@example.com")
io.tool_error('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 return repo.working_tree_dir
@ -207,8 +207,8 @@ def parse_lint_cmds(lint_cmds, io):
res[lang] = cmd res[lang] = cmd
else: else:
io.tool_error(f'Unable to parse --lint-cmd "{lint_cmd}"') io.tool_error(f'Unable to parse --lint-cmd "{lint_cmd}"')
io.tool_error('The arg should be "language: cmd --args ..."') io.tool_output('The arg should be "language: cmd --args ..."')
io.tool_error('For example: --lint-cmd "python: flake8 --select=E9"') io.tool_output('For example: --lint-cmd "python: flake8 --select=E9"')
err = True err = True
if err: if err:
return return
@ -306,15 +306,15 @@ def sanity_check_repo(repo, io):
if "version in (1, 2)" in error_msg: if "version in (1, 2)" in error_msg:
io.tool_error("Aider only works with git repos with version number 1 or 2.") io.tool_error("Aider only works with git repos with version number 1 or 2.")
io.tool_error( io.tool_output(
"You may be able to convert your repo: git update-index --index-version=2" "You may be able to convert your repo: git update-index --index-version=2"
) )
io.tool_error("Or run aider --no-git to proceed without using git.") io.tool_output("Or run aider --no-git to proceed without using git.")
io.tool_error("https://github.com/paul-gauthier/aider/issues/211") io.tool_output("https://github.com/paul-gauthier/aider/issues/211")
return False return False
io.tool_error("Unable to read git repository, it may be corrupt?") io.tool_error("Unable to read git repository, it may be corrupt?")
io.tool_error(error_msg) io.tool_output(error_msg)
return False return False
@ -406,7 +406,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
except UnicodeEncodeError as err: except UnicodeEncodeError as err:
if io.pretty: if io.pretty:
io.pretty = False io.pretty = False
io.tool_error("Terminal does not support pretty output (UnicodeDecodeError)") io.tool_warning("Terminal does not support pretty output (UnicodeDecodeError)")
else: else:
raise err raise err
@ -430,7 +430,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io.tool_error(f"{fname} is a directory, not provided alone.") io.tool_error(f"{fname} is a directory, not provided alone.")
good = False good = False
if not good: if not good:
io.tool_error( io.tool_output(
"Provide either a single directory of a git repo, or a list of one or more files." "Provide either a single directory of a git repo, or a list of one or more files."
) )
return 1 return 1
@ -651,13 +651,13 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io.tool_output('Use /help <question> for help, run "aider --help" to see cmd line args') io.tool_output('Use /help <question> for help, run "aider --help" to see cmd line args')
if git_root and Path.cwd().resolve() != Path(git_root).resolve(): if git_root and Path.cwd().resolve() != Path(git_root).resolve():
io.tool_error( io.tool_warning(
"Note: in-chat filenames are always relative to the git working dir, not the current" "Note: in-chat filenames are always relative to the git working dir, not the current"
" working dir." " working dir."
) )
io.tool_error(f"Cur working dir: {Path.cwd()}") io.tool_output(f"Cur working dir: {Path.cwd()}")
io.tool_error(f"Git working dir: {git_root}") io.tool_output(f"Git working dir: {git_root}")
if args.message: if args.message:
io.add_to_input_history(args.message) io.add_to_input_history(args.message)

View file

@ -742,11 +742,11 @@ def sanity_check_model(io, model):
if model.missing_keys: if model.missing_keys:
show = True show = True
io.tool_error(f"Model {model}: Environment variables status:") io.tool_warning(f"Model {model}: Environment variables status:")
for key in model.missing_keys: for key in model.missing_keys:
value = os.environ.get(key, "") value = os.environ.get(key, "")
status = "✓ Set" if value else "✗ Not set" status = "✓ Set" if value else "✗ Not set"
io.tool_error(f"- {key}: {status}") io.tool_warning(f"- {key}: {status}")
if platform.system() == "Windows" or True: if platform.system() == "Windows" or True:
io.tool_output( io.tool_output(

View file

@ -168,7 +168,7 @@ class RepoMap:
try: try:
self.TAGS_CACHE = Cache(path) self.TAGS_CACHE = Cache(path)
except sqlite3.OperationalError: except sqlite3.OperationalError:
self.io.tool_error(f"Unable to use tags cache, delete {path} to resolve.") self.io.tool_warning(f"Unable to use tags cache, delete {path} to resolve.")
self.TAGS_CACHE = dict() self.TAGS_CACHE = dict()
def save_tags_cache(self): def save_tags_cache(self):
@ -178,7 +178,7 @@ class RepoMap:
try: try:
return os.path.getmtime(fname) return os.path.getmtime(fname)
except FileNotFoundError: except FileNotFoundError:
self.io.tool_error(f"File not found error: {fname}") self.io.tool_warning(f"File not found error: {fname}")
def get_tags(self, fname, rel_fname): def get_tags(self, fname, rel_fname):
# Check if the file is in the cache and if the modification time has not changed # Check if the file is in the cache and if the modification time has not changed
@ -315,7 +315,7 @@ class RepoMap:
if not file_ok: if not file_ok:
if fname not in self.warned_files: if fname not in self.warned_files:
self.io.tool_error(f"Repo-map can't include {fname}") self.io.tool_warning(f"Repo-map can't include {fname}")
self.warned_files.add(fname) self.warned_files.add(fname)
continue continue

View file

@ -330,7 +330,7 @@ def check_pip_install_extra(io, module, prompt, pip_install_cmd, self_update=Fal
cmd = get_pip_install(pip_install_cmd) cmd = get_pip_install(pip_install_cmd)
if prompt: if prompt:
io.tool_error(prompt) io.tool_warning(prompt)
if self_update and platform.system() == "Windows": if self_update and platform.system() == "Windows":
io.tool_output("Run this command to update:") io.tool_output("Run this command to update:")

View file

@ -43,7 +43,7 @@ def install_upgrade(io, latest_version=None):
docker pull {docker_image} docker pull {docker_image}
""" """
io.tool_error(text) io.tool_warning(text)
return True return True
success = utils.check_pip_install_extra( success = utils.check_pip_install_extra(