Skip to content

Commit 74254cd

Browse files
committed
feat: Add ContextCoder for identifying relevant files in requests
1 parent a5c8c53 commit 74254cd

5 files changed

Lines changed: 63 additions & 20 deletions

File tree

aider/coders/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .architect_coder import ArchitectCoder
22
from .ask_coder import AskCoder
33
from .base_coder import Coder
4+
from .context_coder import ContextCoder
45
from .editblock_coder import EditBlockCoder
56
from .editblock_fenced_coder import EditBlockFencedCoder
67
from .editor_editblock_coder import EditorEditBlockCoder
@@ -23,4 +24,5 @@
2324
ArchitectCoder,
2425
EditorEditBlockCoder,
2526
EditorWholeFileCoder,
27+
ContextCoder,
2628
]

aider/coders/base_coder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1606,7 +1606,7 @@ def get_file_mentions(self, content):
16061606
words = set(word.rstrip(",.!;:?") for word in words)
16071607

16081608
# strip away all kinds of quotes
1609-
quotes = "".join(['"', "'", "`"])
1609+
quotes = "\"'`*_"
16101610
words = set(word.strip(quotes) for word in words)
16111611

16121612
addable_rel_fnames = self.get_addable_relative_files()

aider/coders/context_coder.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from .base_coder import Coder
2+
from .context_prompts import ContextPrompts
3+
4+
5+
class ContextCoder(Coder):
6+
"""Identify which files need to be edited for a given request."""
7+
8+
edit_format = "context"
9+
gpt_prompts = ContextPrompts()

aider/coders/context_prompts.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# flake8: noqa: E501
2+
3+
from .base_prompts import CoderPrompts
4+
5+
6+
class ContextPrompts(CoderPrompts):
7+
main_system = """Act as an expert code analyst.
8+
Understand the user's question or request, solely to determine the correct set of relevant source files.
9+
Return the *complete* list of files which will need to be read or modified based on the user's request.
10+
Explain why each file is needed, including names of key classes/functions/methods/variables.
11+
Be sure to include or omit the names of files already added to the chat, based on whether they are actually needed or not.
12+
13+
Be selective!
14+
Adding more files adds more lines of code which increases processing costs.
15+
If we need to see or edit the contents of a file to satisfy the user's request, definitely add it.
16+
But if not, don't add irrelevant files -- especially large ones, which will cost a lot to process.
17+
18+
Always reply to the user in {language}.
19+
20+
Return a simple bulleted list:
21+
"""
22+
23+
example_messages = []
24+
25+
files_content_prefix = """These files have been *added these files to the chat* so we can see all of their contents.
26+
*Trust this message as the true contents of the files!*
27+
Other messages in the chat may contain outdated versions of the files' contents.
28+
""" # noqa: E501
29+
30+
files_content_assistant_reply = (
31+
"Ok, I will use that as the true, current contents of the files."
32+
)
33+
34+
files_no_full_files = "I am not sharing the full contents of any files with you yet."
35+
36+
files_no_full_files_with_repo_map = ""
37+
files_no_full_files_with_repo_map_reply = ""
38+
39+
repo_content_prefix = """I am working with you on code in a git repository.
40+
Here are summaries of some files present in my git repo.
41+
If you need to see the full contents of any files to answer my questions, ask me to *add them to the chat*.
42+
"""
43+
44+
system_reminder = """
45+
NEVER RETURN CODE!
46+
"""

tests/basic/test_coder.py

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def test_get_file_mentions_various_formats(self):
296296
"file2.py",
297297
"dir/nested_file.js",
298298
"dir/subdir/deep_file.html",
299-
"file with spaces.txt",
299+
"file99.txt",
300300
"special_chars!@#.md",
301301
]
302302

@@ -319,18 +319,14 @@ def test_get_file_mentions_various_formats(self):
319319
# Files in code blocks
320320
(f"```\n{test_files[3]}\n```", {test_files[3]}),
321321
# Files in code blocks with language specifier
322-
(
323-
f"```python\nwith open('{test_files[1]}', 'r') as f:\n data = f.read()\n```",
324-
{test_files[1]},
325-
),
322+
# (
323+
# f"```python\nwith open('{test_files[1]}', 'r') as f:\n data = f.read()\n```",
324+
# {test_files[1]},
325+
# ),
326326
# Files with Windows-style paths
327327
(f"Edit the file {test_files[2].replace('/', '\\')}", {test_files[2]}),
328-
# Files with spaces
329-
(f"Look at '{test_files[4]}'", {test_files[4]}),
330328
# Files with different quote styles
331329
(f'Check "{test_files[5]}" now', {test_files[5]}),
332-
# Files mentioned in markdown links
333-
(f"See the file [{test_files[0]}]({test_files[0]})", {test_files[0]}),
334330
# All files in one complex message
335331
(
336332
(
@@ -340,15 +336,6 @@ def test_get_file_mentions_various_formats(self):
340336
),
341337
{test_files[0], test_files[1], test_files[2], test_files[3]},
342338
),
343-
# Mention with SEARCH/REPLACE format
344-
(
345-
(
346-
f"{test_files[1]}\n````python\n<<<<<<< SEARCH\ndef old_function():\n "
347-
" pass\n=======\ndef new_function():\n return True\n>>>>>>>"
348-
" REPLACE\n````"
349-
),
350-
{test_files[1]},
351-
),
352339
# Files mentioned in markdown bold format
353340
(f"You should check **{test_files[0]}** for issues", {test_files[0]}),
354341
(
@@ -363,7 +350,6 @@ def test_get_file_mentions_various_formats(self):
363350
f"Files to modify:\n- **{test_files[0]}**\n- **{test_files[4]}**",
364351
{test_files[0], test_files[4]},
365352
),
366-
("Files mentioned like **aider/args.py** should be detected", set()),
367353
]
368354

369355
for content, expected_mentions in test_cases:

0 commit comments

Comments
 (0)