Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
!/requirements.txt

# Ignore specific files
.aider*
aider/__version__.py
aider/_version.py
*.pyc
.aider*
env/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ agent: true
analytics: false
auto-commits: true
auto-save: true
auto-load: true
auto-load: false
cache-prompts: true
check-update: true
debug: false
Expand All @@ -49,7 +49,7 @@ env-file: .aider.env
multiline: true
preserve-todo-list: true
show-model-warnings: true
watch-files: true
watch-files: false
agent-config: |
{
"large_file_token_threshold": 12500,
Expand Down
2 changes: 1 addition & 1 deletion aider/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from packaging import version

__version__ = "0.88.33.dev"
__version__ = "0.88.34.dev"
safe_version = __version__

try:
Expand Down
6 changes: 6 additions & 0 deletions aider/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,12 @@ def get_parser(default_config_files, git_root):

######
group = parser.add_argument_group("Other settings")
group.add_argument(
"--tweak-responses",
action="store_true",
help="Allow manual edits to model responses (default: False)",
default=False,
)
group.add_argument(
"--yes-always",
action="store_true",
Expand Down
56 changes: 49 additions & 7 deletions aider/coders/agent_coder.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ def __init__(self, *args, **kwargs):
# Enable enhanced context blocks by default
self.use_enhanced_context = True

# Caching efficiency attributes
self._last_edited_file = None
self._cur_message_divider = None

# Initialize empty token tracking dictionary and cache structures
# but don't populate yet to avoid startup delay
self.allowed_context_blocks = set()
Expand Down Expand Up @@ -696,8 +700,9 @@ def format_chat_chunks(self):
"examples",
"readonly_files",
"repo",
"done",
"chat_files",
"done",
"edit_files",
"cur",
"reminder",
]
Expand All @@ -719,16 +724,22 @@ def format_chat_chunks(self):
cur_messages_list = list(self.cur_messages)
cur_messages_pre = []
cur_messages_post = cur_messages_list
chunks.readonly_files = self.get_readonly_files_messages()

if len(cur_messages_list) > 32:
divider = len(cur_messages_list) % 32
if divider:
divider = -1 * divider
# Handle the dictionary structure from get_chat_files_messages()
chat_files_result = self.get_chat_files_messages()
chunks.chat_files = chat_files_result.get("chat_files", [])
chunks.edit_files = chat_files_result.get("edit_files", [])
edit_file_names = chat_files_result.get("edit_file_names", set())

# Update edit file tracking for caching efficiency
divider = self._update_edit_file_tracking(edit_file_names)
if divider is not None:
# Split cur_messages using the divider
if divider > 0 and divider < len(cur_messages_list):
cur_messages_pre = cur_messages_list[:divider]
cur_messages_post = cur_messages_list[divider:]

chunks.readonly_files = self.get_readonly_files_messages()
chunks.chat_files = self.get_chat_files_messages()
chunks.repo = self.get_repo_messages()
chunks.done = list(self.done_messages) + cur_messages_pre

Expand Down Expand Up @@ -846,6 +857,37 @@ def format_chat_chunks(self):

return chunks

def _update_edit_file_tracking(self, edit_file_names):
"""
Update tracking for last edited file and message divider for caching efficiency.

When the last edited file changes, we store the current message index minus 4
as a divider to split cur_messages, moving older messages to done_messages
for better caching.
"""
kept_messages = 8
if not edit_file_names:
self._cur_message_divider = 0

# Get the most recently edited file from the edit_file_names set
# We assume the first file in the sorted set is the most recent
sorted_edit_files = sorted(edit_file_names)
current_edited_file = sorted_edit_files[0] if sorted_edit_files else None

# Check if the last edited file has changed
if current_edited_file != self._last_edited_file:
# Store the new last edited file
self._last_edited_file = current_edited_file

# Calculate divider: current index minus last n messages
cur_messages_list = list(self.cur_messages)
if len(cur_messages_list) > kept_messages:
self._cur_message_divider = len(cur_messages_list) - kept_messages
else:
self._cur_message_divider = 0

return self._cur_message_divider

def get_context_summary(self):
"""
Generate a summary of the current context, including file content tokens and additional context blocks,
Expand Down
13 changes: 12 additions & 1 deletion aider/coders/architect_coder.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import asyncio

from ..commands import SwitchCoder
from .architect_prompts import ArchitectPrompts
from .ask_coder import AskCoder
Expand All @@ -15,16 +17,25 @@ async def reply_completed(self):
if not content or not content.strip():
return

if not self.auto_accept_architect and not await self.io.confirm_ask("Edit the files?"):
tweak_responses = getattr(self.args, "tweak_responses", False)
confirmation = await self.io.confirm_ask("Edit the files?", allow_tweak=tweak_responses)

if not self.auto_accept_architect and not confirmation:
return

if confirmation == "tweak":
content = self.io.edit_in_editor(content)

await asyncio.sleep(0.1)

kwargs = dict()

# Use the editor_model from the main_model if it exists, otherwise use the main_model itself
editor_model = self.main_model.editor_model or self.main_model

kwargs["main_model"] = editor_model
kwargs["edit_format"] = self.main_model.editor_edit_format
kwargs["args"] = self.args
kwargs["suggest_shell_commands"] = False
kwargs["map_tokens"] = 0
kwargs["total_cost"] = self.total_cost
Expand Down
Loading
Loading