From da75263f67c57d36e2dff1ac4e9d19c516a0ffe6 Mon Sep 17 00:00:00 2001 From: RL <4619406+Netzvamp@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:48:47 +0100 Subject: [PATCH 1/5] Update pyproject.toml Remove "aider" so it doesn't overwrite the original "aider" command. We can still call it with "aider-ce". --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c39e82e813d..10413f42fbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,6 @@ dynamic = ["dependencies", "optional-dependencies", "version"] Homepage = "https://github.com/dwash96/aider-ce" [project.scripts] -aider = "aider.main:main" aider-ce = "aider.main:main" [tool.setuptools.dynamic] From 94efaba78df41606d73ef2812bf52f4c9423536e Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Wed, 29 Oct 2025 00:16:26 -0400 Subject: [PATCH 2/5] Bump Version --- aider/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/__init__.py b/aider/__init__.py index c41ed70f912..8d341f89783 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1,6 +1,6 @@ from packaging import version -__version__ = "0.88.1.dev" +__version__ = "0.88.2.dev" safe_version = __version__ try: From 282fc4333fd0d1019be5915fad5a3cde34a1228d Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Wed, 29 Oct 2025 00:47:23 -0400 Subject: [PATCH 3/5] #60, #61 Fix (Really a hack to just provide a default MCP server since the actual super loop --- aider/coders/base_coder.py | 6 ++---- aider/mcp/__init__.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 848cb3b2bf5..85d4446f8ec 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -616,9 +616,6 @@ def __init__( except Exception as e: self.io.tool_warning(f"Could not remove todo list file {todo_file_path}: {e}") - # Instantiate MCP tools - if self.mcp_servers: - pass # validate the functions jsonschema if self.functions: from jsonschema import Draft7Validator @@ -2352,7 +2349,8 @@ async def get_server_tools(server): ) return (server.name, server_tools) except Exception as e: - self.io.tool_warning(f"Error initializing MCP server {server.name}:\n{e}") + if server.name != "unnamed-server": + self.io.tool_warning(f"Error initializing MCP server {server.name}:\n{e}") return None async def get_all_server_tools(): diff --git a/aider/mcp/__init__.py b/aider/mcp/__init__.py index 17903017745..eea87122003 100644 --- a/aider/mcp/__init__.py +++ b/aider/mcp/__init__.py @@ -154,4 +154,21 @@ def load_mcp_servers(mcp_servers, mcp_servers_file, io, verbose=False, mcp_trans if mcp_servers_file: servers = _parse_mcp_servers_from_file(mcp_servers_file, io, verbose, mcp_transport) + if not servers: + # A default MCP server is actually now necessary for the overall agentic loop + # and a dummy server does suffice for the job + # because I am not smart enough to figure out why + # on coder switch, the agent actually initializes the prompt area twice + # once immediately after input for the old coder + # and immediately again for the new target coder + # which causes a race condition where we are awaiting a coroutine + # that can no longer yield control (somehow?) + # but somehow having to run through the MCP server checks + # allows control to be yielded again somehow + # and I cannot figure out just how that is happening + # and maybe it is actually prompt_toolkit's fault + # but this hack works swimmingly because ??? + # so sure! why not + servers = [McpServer(json.loads('{"aider_default": {}}'))] + return servers From 6275b56cea6de444a5b89528febaad2a63d96c7f Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Wed, 29 Oct 2025 02:15:46 -0400 Subject: [PATCH 4/5] #58: Fix pretty printing in --no-stream mode --- aider/coders/base_coder.py | 6 +++++- aider/io.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 85d4446f8ec..0989227cf71 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -2602,7 +2602,7 @@ async def send(self, messages, model=None, functions=None, tools=None): ) self.chat_completion_call_hashes.append(hash_object.hexdigest()) - if self.stream: + if not isinstance(completion, ModelResponse): async for chunk in self.show_send_output_stream(completion): yield chunk else: @@ -2638,6 +2638,10 @@ def show_send_output(self, completion): if self.verbose: print(completion) + if not isinstance(completion, ModelResponse): + self.io.tool_error(str(completion)) + return + if not completion.choices: self.io.tool_error(str(completion)) return diff --git a/aider/io.py b/aider/io.py index b721d848abb..a570c2125f6 100644 --- a/aider/io.py +++ b/aider/io.py @@ -1301,7 +1301,7 @@ def assistant_output(self, message, pretty=None): else: show_resp = Text(message or "(empty response)") - self.stream_print(show_resp) + self.console.print(show_resp) def render_markdown(self, text): output = StringIO() From 0e93254b2aa8b923a91ed951c936d7061b84303b Mon Sep 17 00:00:00 2001 From: Dustin Washington Date: Wed, 29 Oct 2025 02:27:56 -0400 Subject: [PATCH 5/5] Address Comment: https://github.com/dwash96/aider-ce/issues/48#issuecomment-3453777604 --- aider/coders/architect_coder.py | 2 +- aider/coders/base_coder.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/aider/coders/architect_coder.py b/aider/coders/architect_coder.py index a7cba79eb2e..d681316c1c0 100644 --- a/aider/coders/architect_coder.py +++ b/aider/coders/architect_coder.py @@ -14,7 +14,7 @@ async def reply_completed(self): if not content or not content.strip(): return - if not self.auto_accept_architect and not self.io.confirm_ask("Edit the files?"): + if not self.auto_accept_architect and not await self.io.confirm_ask("Edit the files?"): return kwargs = dict() diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 0989227cf71..16a1cb8410b 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -1752,7 +1752,7 @@ def warm_cache_worker(): return chunks - def check_tokens(self, messages): + async def check_tokens(self, messages): """Check if the messages will fit within the model's token limits.""" input_tokens = self.main_model.token_count(messages) max_input_tokens = self.main_model.info.get("max_input_tokens") or 0 @@ -1771,7 +1771,7 @@ def check_tokens(self, messages): " the context limit is exceeded." ) - if not self.io.confirm_ask("Try to proceed anyway?"): + if not await self.io.confirm_ask("Try to proceed anyway?"): return False return True @@ -1789,7 +1789,7 @@ async def send_message(self, inp): chunks = self.format_messages() messages = chunks.all_messages() - if not self.check_tokens(messages): + if not await self.check_tokens(messages): return self.warm_cache(chunks) @@ -3094,7 +3094,7 @@ async def allowed_to_edit(self, path): return if not Path(full_path).exists(): - if not self.io.confirm_ask("Create new file?", subject=path): + if not await self.io.confirm_ask("Create new file?", subject=path): self.io.tool_output(f"Skipping edits to {path}") return