From f748ac78299034298afedd14052d0c6d5ca95ecc Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 08:18:00 +0200 Subject: [PATCH 01/13] feat: add git_branch and git_remote tools Co-authored-by: aider (deepseek/deepseek-reasoner) --- aider/tools/__init__.py | 4 +++ aider/tools/git_branch.py | 52 ++++++++++++++++++++++++++++++++++++++ aider/tools/git_remote.py | 53 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 aider/tools/git_branch.py create mode 100644 aider/tools/git_remote.py diff --git a/aider/tools/__init__.py b/aider/tools/__init__.py index c1b2f6c710d..60b3b06c5af 100644 --- a/aider/tools/__init__.py +++ b/aider/tools/__init__.py @@ -10,8 +10,10 @@ delete_lines, extract_lines, finished, + git_branch, git_diff, git_log, + git_remote, git_show, git_status, grep, @@ -43,8 +45,10 @@ delete_lines, extract_lines, finished, + git_branch, git_diff, git_log, + git_remote, git_show, git_status, grep, diff --git a/aider/tools/git_branch.py b/aider/tools/git_branch.py new file mode 100644 index 00000000000..c43615b6493 --- /dev/null +++ b/aider/tools/git_branch.py @@ -0,0 +1,52 @@ +from aider.repo import ANY_GIT_ERROR + +schema = { + "type": "function", + "function": { + "name": "GitBranch", + "description": "List branches in the repository.", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + }, + }, +} + +# Normalized tool name for lookup +NORM_NAME = "gitbranch" + + +def _execute_git_branch(coder): + """ + List branches in the repository. + """ + if not coder.repo: + return "Not in a git repository." + + try: + # Get all branches and current branch + branches = [] + current_branch = coder.repo.repo.active_branch.name + for branch in coder.repo.repo.heads: + prefix = "* " if branch.name == current_branch else " " + branches.append(f"{prefix}{branch.name}") + return "\n".join(branches) + except ANY_GIT_ERROR as e: + coder.io.tool_error(f"Error running git branch: {e}") + return f"Error running git branch: {e}" + + +def process_response(coder, params): + """ + Process the GitBranch tool response. + + Args: + coder: The Coder instance + params: Dictionary of parameters (should be empty for GitBranch) + + Returns: + str: Result message + """ + # GitBranch tool has no parameters to validate + return _execute_git_branch(coder) \ No newline at end of file diff --git a/aider/tools/git_remote.py b/aider/tools/git_remote.py new file mode 100644 index 00000000000..d5813972e5f --- /dev/null +++ b/aider/tools/git_remote.py @@ -0,0 +1,53 @@ +from aider.repo import ANY_GIT_ERROR + +schema = { + "type": "function", + "function": { + "name": "GitRemote", + "description": "List remote repositories.", + "parameters": { + "type": "object", + "properties": {}, + "required": [], + }, + }, +} + +# Normalized tool name for lookup +NORM_NAME = "gitremote" + + +def _execute_git_remote(coder): + """ + List remote repositories. + """ + if not coder.repo: + return "Not in a git repository." + + try: + remotes = coder.repo.repo.remotes + if not remotes: + return "No remotes configured." + + result = [] + for remote in remotes: + result.append(f"{remote.name}\t{remote.url}") + return "\n".join(result) + except ANY_GIT_ERROR as e: + coder.io.tool_error(f"Error running git remote: {e}") + return f"Error running git remote: {e}" + + +def process_response(coder, params): + """ + Process the GitRemote tool response. + + Args: + coder: The Coder instance + params: Dictionary of parameters (should be empty for GitRemote) + + Returns: + str: Result message + """ + # GitRemote tool has no parameters to validate + return _execute_git_remote(coder) \ No newline at end of file From 32317fb5525fbf86cf3097210f6aae9b7b196cb5 Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 08:21:36 +0200 Subject: [PATCH 02/13] Nicer looking code with black --- aider/tools/git_branch.py | 2 +- aider/tools/git_remote.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/tools/git_branch.py b/aider/tools/git_branch.py index c43615b6493..cdb20ced6df 100644 --- a/aider/tools/git_branch.py +++ b/aider/tools/git_branch.py @@ -49,4 +49,4 @@ def process_response(coder, params): str: Result message """ # GitBranch tool has no parameters to validate - return _execute_git_branch(coder) \ No newline at end of file + return _execute_git_branch(coder) diff --git a/aider/tools/git_remote.py b/aider/tools/git_remote.py index d5813972e5f..5f839683c17 100644 --- a/aider/tools/git_remote.py +++ b/aider/tools/git_remote.py @@ -50,4 +50,4 @@ def process_response(coder, params): str: Result message """ # GitRemote tool has no parameters to validate - return _execute_git_remote(coder) \ No newline at end of file + return _execute_git_remote(coder) From 878253914137b3d5bc9025e6cc805446bc4cb4ce Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 08:32:21 +0200 Subject: [PATCH 03/13] feat: add git_branch and git_remote tools to agent_coder Co-authored-by: aider (deepseek/deepseek-reasoner) --- aider/coders/agent_coder.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/aider/coders/agent_coder.py b/aider/coders/agent_coder.py index c97bd041410..1ce15b86162 100644 --- a/aider/coders/agent_coder.py +++ b/aider/coders/agent_coder.py @@ -23,6 +23,7 @@ from aider.mcp.server import LocalServer from aider.repo import ANY_GIT_ERROR +# Import tool modules for registry # Import tool modules for registry from aider.tools import ( command, @@ -32,8 +33,10 @@ delete_lines, extract_lines, finished, + git_branch, git_diff, git_log, + git_remote, git_show, git_status, grep, @@ -159,8 +162,10 @@ def _build_tool_registry(self): delete_lines, extract_lines, finished, + git_branch, git_diff, git_log, + git_remote, git_show, git_status, grep, @@ -2158,4 +2163,4 @@ def cmd_context_blocks(self, args=""): self.context_blocks_cache = {} self.tokens_calculated = False - return True + return True \ No newline at end of file From b0788a7c08c3f4cf985b7035f734adec11c22e8e Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 08:39:22 +0200 Subject: [PATCH 04/13] code formatting with black --- aider/coders/agent_coder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/coders/agent_coder.py b/aider/coders/agent_coder.py index 1ce15b86162..f11de0976a1 100644 --- a/aider/coders/agent_coder.py +++ b/aider/coders/agent_coder.py @@ -2163,4 +2163,4 @@ def cmd_context_blocks(self, args=""): self.context_blocks_cache = {} self.tokens_calculated = False - return True \ No newline at end of file + return True From 3ec9bc5b7d6ae7aee475d9340ed640cb19c251d7 Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 08:56:58 +0200 Subject: [PATCH 05/13] feat: add support for critical git branch flags Co-authored-by: aider (deepseek/deepseek-reasoner) --- aider/tools/git_branch.py | 94 +++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 14 deletions(-) diff --git a/aider/tools/git_branch.py b/aider/tools/git_branch.py index cdb20ced6df..6c935828a04 100644 --- a/aider/tools/git_branch.py +++ b/aider/tools/git_branch.py @@ -4,10 +4,47 @@ "type": "function", "function": { "name": "GitBranch", - "description": "List branches in the repository.", + "description": "List branches in the repository with various filtering and formatting options.", "parameters": { "type": "object", - "properties": {}, + "properties": { + "remotes": { + "type": "boolean", + "description": "List remote-tracking branches (-r/--remotes flag)", + }, + "all": { + "type": "boolean", + "description": "List both local and remote branches (-a/--all flag)", + }, + "verbose": { + "type": "boolean", + "description": "Show verbose information including commit hash and subject (-v flag)", + }, + "very_verbose": { + "type": "boolean", + "description": "Show very verbose information including upstream branch (-vv flag)", + }, + "merged": { + "type": "string", + "description": "Show branches merged into specified commit (--merged flag)", + }, + "no_merged": { + "type": "string", + "description": "Show branches not merged into specified commit (--no-merged flag)", + }, + "sort": { + "type": "string", + "description": "Sort branches by key (committerdate, authordate, refname, etc.) (--sort flag)", + }, + "format": { + "type": "string", + "description": "Custom output format using placeholders (--format flag)", + }, + "show_current": { + "type": "boolean", + "description": "Show only current branch name (--show-current flag)", + }, + }, "required": [], }, }, @@ -17,21 +54,51 @@ NORM_NAME = "gitbranch" -def _execute_git_branch(coder): +def _execute_git_branch(coder, params=None): """ - List branches in the repository. + List branches in the repository with various filtering and formatting options. """ if not coder.repo: return "Not in a git repository." try: - # Get all branches and current branch - branches = [] - current_branch = coder.repo.repo.active_branch.name - for branch in coder.repo.repo.heads: - prefix = "* " if branch.name == current_branch else " " - branches.append(f"{prefix}{branch.name}") - return "\n".join(branches) + # Build git command arguments + args = ["branch"] + + # Handle boolean flags + if params: + if params.get("remotes"): + args.append("--remotes") + if params.get("all"): + args.append("--all") + if params.get("verbose"): + args.append("--verbose") + if params.get("very_verbose"): + args.append("--verbose") + args.append("--verbose") + if params.get("show_current"): + args.append("--show-current") + + # Handle string parameters + if params.get("merged"): + args.extend(["--merged", params["merged"]]) + if params.get("no_merged"): + args.extend(["--no-merged", params["no_merged"]]) + if params.get("sort"): + args.extend(["--sort", params["sort"]]) + if params.get("format"): + args.extend(["--format", params["format"]]) + + # Execute git command + result = coder.repo.repo.git.branch(*args) + + # If no result and show_current was used, get current branch directly + if not result and params and params.get("show_current"): + current_branch = coder.repo.repo.active_branch.name + return current_branch + + return result if result else "No branches found matching the criteria." + except ANY_GIT_ERROR as e: coder.io.tool_error(f"Error running git branch: {e}") return f"Error running git branch: {e}" @@ -43,10 +110,9 @@ def process_response(coder, params): Args: coder: The Coder instance - params: Dictionary of parameters (should be empty for GitBranch) + params: Dictionary of parameters for GitBranch Returns: str: Result message """ - # GitBranch tool has no parameters to validate - return _execute_git_branch(coder) + return _execute_git_branch(coder, params) From e840585c36e66354718a4c33535e280a42088b2c Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 08:57:39 +0200 Subject: [PATCH 06/13] ran black code formatter --- aider/tools/git_branch.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/aider/tools/git_branch.py b/aider/tools/git_branch.py index 6c935828a04..6ce2460f601 100644 --- a/aider/tools/git_branch.py +++ b/aider/tools/git_branch.py @@ -4,7 +4,9 @@ "type": "function", "function": { "name": "GitBranch", - "description": "List branches in the repository with various filtering and formatting options.", + "description": ( + "List branches in the repository with various filtering and formatting options." + ), "parameters": { "type": "object", "properties": { @@ -13,28 +15,37 @@ "description": "List remote-tracking branches (-r/--remotes flag)", }, "all": { - "type": "boolean", + "type": "boolean", "description": "List both local and remote branches (-a/--all flag)", }, "verbose": { "type": "boolean", - "description": "Show verbose information including commit hash and subject (-v flag)", + "description": ( + "Show verbose information including commit hash and subject (-v flag)" + ), }, "very_verbose": { "type": "boolean", - "description": "Show very verbose information including upstream branch (-vv flag)", + "description": ( + "Show very verbose information including upstream branch (-vv flag)" + ), }, "merged": { "type": "string", "description": "Show branches merged into specified commit (--merged flag)", }, "no_merged": { - "type": "string", - "description": "Show branches not merged into specified commit (--no-merged flag)", + "type": "string", + "description": ( + "Show branches not merged into specified commit (--no-merged flag)" + ), }, "sort": { "type": "string", - "description": "Sort branches by key (committerdate, authordate, refname, etc.) (--sort flag)", + "description": ( + "Sort branches by key (committerdate, authordate, refname, etc.) (--sort" + " flag)" + ), }, "format": { "type": "string", @@ -64,7 +75,7 @@ def _execute_git_branch(coder, params=None): try: # Build git command arguments args = ["branch"] - + # Handle boolean flags if params: if params.get("remotes"): @@ -78,7 +89,7 @@ def _execute_git_branch(coder, params=None): args.append("--verbose") if params.get("show_current"): args.append("--show-current") - + # Handle string parameters if params.get("merged"): args.extend(["--merged", params["merged"]]) @@ -88,17 +99,17 @@ def _execute_git_branch(coder, params=None): args.extend(["--sort", params["sort"]]) if params.get("format"): args.extend(["--format", params["format"]]) - + # Execute git command result = coder.repo.repo.git.branch(*args) - + # If no result and show_current was used, get current branch directly if not result and params and params.get("show_current"): current_branch = coder.repo.repo.active_branch.name return current_branch - + return result if result else "No branches found matching the criteria." - + except ANY_GIT_ERROR as e: coder.io.tool_error(f"Error running git branch: {e}") return f"Error running git branch: {e}" From 4bcab112f5ba39eff6bf57f159c8e3f1f8d29a37 Mon Sep 17 00:00:00 2001 From: tomjuggler Date: Mon, 10 Nov 2025 09:06:49 +0200 Subject: [PATCH 07/13] fix: remove incorrect 'branch' argument from git branch command Co-authored-by: aider (deepseek/deepseek-reasoner) --- aider/tools/git_branch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/tools/git_branch.py b/aider/tools/git_branch.py index 6ce2460f601..6a8d2c75d3d 100644 --- a/aider/tools/git_branch.py +++ b/aider/tools/git_branch.py @@ -74,7 +74,7 @@ def _execute_git_branch(coder, params=None): try: # Build git command arguments - args = ["branch"] + args = [] # Handle boolean flags if params: From 4f5947f9ba497f0db36bf620863752668f04552e Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Mon, 10 Nov 2025 23:52:01 -0500 Subject: [PATCH 08/13] Bump Version --- aider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/__init__.py b/aider/__init__.py index 89edca9d96d..a9686a84cb3 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1,6 +1,6 @@ from packaging import version -__version__ = "0.88.13.dev" +__version__ = "0.88.14.dev" safe_version = __version__ try: From 2b45433f7a80beec22654245606a808801160065 Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Mon, 10 Nov 2025 23:53:24 -0500 Subject: [PATCH 09/13] Centralize input recreation logic --- aider/coders/base_coder.py | 15 ++++----------- aider/io.py | 19 +++++++++---------- aider/tools/command.py | 7 +------ aider/tools/command_interactive.py | 5 +---- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index f48b3ec2cb2..2ba89f1fabb 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -1097,8 +1097,7 @@ async def _run_linear(self, with_message=None, preproc=True): self.show_announcements() self.suppress_announcements_for_next_prompt = True - self.io.input_task = asyncio.create_task(self.get_input()) - await asyncio.sleep(0) + await self.io.recreate_input() await self.io.input_task user_message = self.io.input_task.result() @@ -1161,10 +1160,7 @@ async def _run_patched(self, with_message=None, preproc=True): # Stop spinner before showing announcements or getting input self.io.stop_spinner() self.copy_context() - self.io.input_task = asyncio.create_task(self.get_input()) - - # Yield Control so input can actually get properly set up - await asyncio.sleep(0) + await self.io.recreate_input() if self.user_message: self.io.processing_task = asyncio.create_task( @@ -1232,11 +1228,8 @@ async def _run_patched(self, with_message=None, preproc=True): tasks.add(self.io.processing_task) # We just did a confirmation so add a new input task - if ( - not self.io.input_task - and self.io.get_confirmation_acknowledgement() - ): - self.io.input_task = asyncio.create_task(self.get_input()) + if self.io.get_confirmation_acknowledgement(): + await self.io.recreate_input() tasks.add(self.io.input_task) done, pending = await asyncio.wait( diff --git a/aider/io.py b/aider/io.py index ae27a9ff3ab..a6c03fa555a 100644 --- a/aider/io.py +++ b/aider/io.py @@ -695,6 +695,14 @@ def reject_outstanding_confirmations(self): # This method is now a no-op since we removed the confirmation_future logic pass + async def recreate_input(self, future=None): + if not self.input_task or self.input_task.done() or self.input_task.cancelled(): + coder = self.coder() if self.coder else None + + if coder: + self.input_task = asyncio.create_task(coder.get_input()) + await asyncio.sleep(0) + async def get_input( self, root, @@ -1126,16 +1134,7 @@ async def _confirm_ask( while True: try: if self.prompt_session: - if ( - not self.input_task - or self.input_task.done() - or self.input_task.cancelled() - ): - coder = self.coder() if self.coder else None - - if coder: - self.input_task = asyncio.create_task(coder.get_input()) - await asyncio.sleep(0) + await self.recreate_input() if ( self.input_task diff --git a/aider/tools/command.py b/aider/tools/command.py index 6c7427a117c..a052327aef9 100644 --- a/aider/tools/command.py +++ b/aider/tools/command.py @@ -1,6 +1,4 @@ # Import necessary functions -import asyncio - from aider.run_cmd import run_cmd_subprocess schema = { @@ -46,10 +44,7 @@ async def _execute_command(coder, command_string): ) ) - if not coder.io.input_task or coder.io.input_task.done() or coder.io.input_task.cancelled(): - coder.io.input_task = asyncio.create_task(coder.get_input()) - - await asyncio.sleep(0) + await coder.io.recreate_input() if not confirmed: # This happens if the user explicitly says 'no' this time. diff --git a/aider/tools/command_interactive.py b/aider/tools/command_interactive.py index 0af5b1488df..eae1b94e1ae 100644 --- a/aider/tools/command_interactive.py +++ b/aider/tools/command_interactive.py @@ -69,10 +69,7 @@ async def _execute_command_interactive(coder, command_string): coder.io.tool_output(" \n") coder.io.tool_output(">>> Interactive command finished <<<") - if not coder.io.input_task or coder.io.input_task.done() or coder.io.input_task.cancelled(): - coder.io.input_task = asyncio.create_task(coder.get_input()) - - await asyncio.sleep(0) + await coder.io.recreate_input() # Format the output for the result message, include more content output_content = combined_output or "" From cfd51d183fc0dfa6fda1b07639a36ee842b71e9f Mon Sep 17 00:00:00 2001 From: Erich Schulz Date: Tue, 11 Nov 2025 14:39:42 +1000 Subject: [PATCH 10/13] fix: Strip whitespace from user input in preproc_user_input Co-authored-by: aider (deepseek/deepseek-coder) --- aider/coders/base_coder.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index f48b3ec2cb2..97faeb0d764 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -1331,6 +1331,9 @@ async def preproc_user_input(self, inp): if not inp: return + # Strip whitespace from beginning and end + inp = inp.strip() + if self.commands.is_command(inp): if inp[0] in "!": inp = f"/run {inp[1:]}" From b8f0674d416268127e2a3f0a82485986dad4c761 Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Tue, 11 Nov 2025 07:45:37 -0500 Subject: [PATCH 11/13] #129: Actually save and load models with session system --- aider/sessions.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/aider/sessions.py b/aider/sessions.py index cfff99fe98a..f4a29771981 100644 --- a/aider/sessions.py +++ b/aider/sessions.py @@ -5,6 +5,8 @@ from pathlib import Path from typing import Dict, List, Optional +from aider import models + class SessionManager: """Manages chat session saving, listing, and loading.""" @@ -128,6 +130,9 @@ def _build_session_data(self, session_name) -> Dict: "version": 1, "session_name": session_name, "model": self.coder.main_model.name, + "weak_model": self.coder.main_model.weak_model.name, + "editor_model": self.coder.main_model.editor_model.name, + "editor_edit_format": self.coder.main_model.editor_edit_format, "edit_format": self.coder.edit_format, "chat_history": { "done_messages": self.coder.done_messages, @@ -207,6 +212,17 @@ def _apply_session_data(self, session_data: Dict, session_file: Path) -> bool: else: self.io.tool_warning(f"File not found, skipping: {rel_fname}") + if session_data.get("model"): + self.coder.main_model = models.Model( + session_data.get("model", self.coder.args.model), + weak_model=session_data.get("weak_model", self.coder.args.weak_model), + editor_model=session_data.get("editor_model", self.coder.args.editor_model), + editor_edit_format=session_data.get( + "editor_edit_format", self.coder.args.editor_edit_format + ), + verbose=self.coder.args.verbose, + ) + # Load settings settings = session_data.get("settings", {}) if "auto_commits" in settings: From 25f8b1d197c21eac975ac7600216d2723bf94552 Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Tue, 11 Nov 2025 07:57:45 -0500 Subject: [PATCH 12/13] #130: Allow offer_url to work in main.py, pre coder prompt initialization --- aider/io.py | 12 +++++++++--- aider/main.py | 31 ++++++++++++++++++------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/aider/io.py b/aider/io.py index a6c03fa555a..c2d8641e1bf 100644 --- a/aider/io.py +++ b/aider/io.py @@ -1031,11 +1031,15 @@ def ai_output(self, content): hist = "\n" + content.strip() + "\n\n" self.append_chat_history(hist) - async def offer_url(self, url, prompt="Open URL for more info?", allow_never=True): + async def offer_url( + self, url, prompt="Open URL for more info?", allow_never=True, acknowledge=False + ): """Offer to open a URL in the browser, returns True if opened.""" if url in self.never_prompts: return False - if await self.confirm_ask(prompt, subject=url, allow_never=allow_never): + if await self.confirm_ask( + prompt, subject=url, allow_never=allow_never, acknowledge=acknowledge + ): webbrowser.open(url) return True return False @@ -1076,6 +1080,7 @@ async def _confirm_ask( group=None, group_response=None, allow_never=False, + acknowledge=False, ): self.num_user_asks += 1 @@ -1167,7 +1172,8 @@ async def _confirm_ask( good = any(valid_response.startswith(res) for valid_response in valid_responses) if good: - self.set_confirmation_acknowledgement() + if not acknowledge: + self.set_confirmation_acknowledgement() self.start_spinner(self.last_spinner_text) break diff --git a/aider/main.py b/aider/main.py index 0c58da839eb..46f613bb2f7 100644 --- a/aider/main.py +++ b/aider/main.py @@ -971,19 +971,6 @@ def get_io(pretty): analytics.event("exit", reason="Invalid lint command format") return 1 - if args.show_model_warnings: - problem = await models.sanity_check_models(io, main_model) - if problem: - analytics.event("model warning", main_model=main_model) - io.tool_output("You can skip this check with --no-show-model-warnings") - - try: - await 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") - return 1 - repo = None if args.git: try: @@ -1113,6 +1100,24 @@ def get_io(pretty): preserve_todo_list=args.preserve_todo_list, linear_output=args.linear_output, ) + + if args.show_model_warnings: + problem = await models.sanity_check_models(io, main_model) + if problem: + analytics.event("model warning", main_model=main_model) + io.tool_output("You can skip this check with --no-show-model-warnings") + + try: + await io.offer_url( + urls.model_warnings, + "Open documentation url for more info?", + acknowledge=True, + ) + io.tool_output() + except KeyboardInterrupt: + analytics.event("exit", reason="Keyboard interrupt during model warnings") + return 1 + except UnknownEditFormat as err: io.tool_error(str(err)) await io.offer_url(urls.edit_formats, "Open documentation about edit formats?") From 8226c49a6f28570f4535929e7fb3a80a5c07f4f8 Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Tue, 11 Nov 2025 08:42:00 -0500 Subject: [PATCH 13/13] #120: Fix input interruption logic so watch files works again --- aider/io.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/aider/io.py b/aider/io.py index c2d8641e1bf..35d9fdb083f 100644 --- a/aider/io.py +++ b/aider/io.py @@ -677,9 +677,6 @@ def rule(self): print() def interrupt_input(self): - if self.input_task and not self.input_task.done(): - self.input_task.cancel() - if self.prompt_session and self.prompt_session.app: # Store any partial input before interrupting self.placeholder = self.prompt_session.app.current_buffer.text