aider-ce 0.88.20__py3-none-any.whl → 0.88.38__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aider/__init__.py +1 -1
- aider/_version.py +2 -2
- aider/args.py +63 -43
- aider/coders/agent_coder.py +331 -79
- aider/coders/agent_prompts.py +3 -15
- aider/coders/architect_coder.py +21 -5
- aider/coders/base_coder.py +661 -413
- aider/coders/base_prompts.py +6 -3
- aider/coders/chat_chunks.py +39 -17
- aider/commands.py +79 -15
- aider/diffs.py +10 -9
- aider/exceptions.py +1 -1
- aider/helpers/coroutines.py +8 -0
- aider/helpers/requests.py +45 -0
- aider/history.py +5 -0
- aider/io.py +179 -25
- aider/main.py +86 -35
- aider/models.py +16 -8
- aider/queries/tree-sitter-language-pack/c-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/clojure-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/commonlisp-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/cpp-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/csharp-tags.scm +6 -0
- aider/queries/tree-sitter-language-pack/dart-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/elixir-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/elm-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/go-tags.scm +7 -0
- aider/queries/tree-sitter-language-pack/java-tags.scm +6 -0
- aider/queries/tree-sitter-language-pack/javascript-tags.scm +8 -0
- aider/queries/tree-sitter-language-pack/lua-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/python-tags.scm +10 -0
- aider/queries/tree-sitter-language-pack/r-tags.scm +6 -0
- aider/queries/tree-sitter-language-pack/ruby-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/rust-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/solidity-tags.scm +1 -1
- aider/queries/tree-sitter-language-pack/swift-tags.scm +4 -1
- aider/queries/tree-sitter-languages/c-tags.scm +3 -0
- aider/queries/tree-sitter-languages/c_sharp-tags.scm +6 -0
- aider/queries/tree-sitter-languages/cpp-tags.scm +3 -0
- aider/queries/tree-sitter-languages/dart-tags.scm +2 -1
- aider/queries/tree-sitter-languages/elixir-tags.scm +5 -0
- aider/queries/tree-sitter-languages/elm-tags.scm +3 -0
- aider/queries/tree-sitter-languages/fortran-tags.scm +3 -0
- aider/queries/tree-sitter-languages/go-tags.scm +6 -0
- aider/queries/tree-sitter-languages/haskell-tags.scm +2 -0
- aider/queries/tree-sitter-languages/java-tags.scm +6 -0
- aider/queries/tree-sitter-languages/javascript-tags.scm +8 -0
- aider/queries/tree-sitter-languages/julia-tags.scm +2 -2
- aider/queries/tree-sitter-languages/kotlin-tags.scm +3 -0
- aider/queries/tree-sitter-languages/ocaml_interface-tags.scm +6 -0
- aider/queries/tree-sitter-languages/php-tags.scm +6 -0
- aider/queries/tree-sitter-languages/python-tags.scm +10 -0
- aider/queries/tree-sitter-languages/ruby-tags.scm +5 -0
- aider/queries/tree-sitter-languages/rust-tags.scm +3 -0
- aider/queries/tree-sitter-languages/scala-tags.scm +2 -3
- aider/queries/tree-sitter-languages/typescript-tags.scm +3 -0
- aider/queries/tree-sitter-languages/zig-tags.scm +20 -3
- aider/repomap.py +71 -11
- aider/resources/model-metadata.json +27335 -635
- aider/resources/model-settings.yml +190 -0
- aider/scrape.py +2 -0
- aider/tools/__init__.py +2 -0
- aider/tools/command.py +84 -94
- aider/tools/command_interactive.py +95 -110
- aider/tools/delete_block.py +131 -159
- aider/tools/delete_line.py +97 -132
- aider/tools/delete_lines.py +120 -160
- aider/tools/extract_lines.py +288 -312
- aider/tools/finished.py +30 -43
- aider/tools/git_branch.py +107 -109
- aider/tools/git_diff.py +44 -56
- aider/tools/git_log.py +39 -53
- aider/tools/git_remote.py +37 -51
- aider/tools/git_show.py +33 -47
- aider/tools/git_status.py +30 -44
- aider/tools/grep.py +214 -242
- aider/tools/indent_lines.py +175 -201
- aider/tools/insert_block.py +220 -253
- aider/tools/list_changes.py +65 -80
- aider/tools/ls.py +64 -80
- aider/tools/make_editable.py +57 -73
- aider/tools/make_readonly.py +50 -66
- aider/tools/remove.py +64 -80
- aider/tools/replace_all.py +96 -109
- aider/tools/replace_line.py +118 -156
- aider/tools/replace_lines.py +160 -197
- aider/tools/replace_text.py +159 -160
- aider/tools/show_numbered_context.py +115 -141
- aider/tools/thinking.py +52 -0
- aider/tools/undo_change.py +78 -91
- aider/tools/update_todo_list.py +130 -138
- aider/tools/utils/base_tool.py +64 -0
- aider/tools/utils/output.py +118 -0
- aider/tools/view.py +38 -54
- aider/tools/view_files_matching.py +131 -134
- aider/tools/view_files_with_symbol.py +108 -120
- aider/urls.py +1 -1
- aider/versioncheck.py +4 -3
- aider/website/docs/config/adv-model-settings.md +237 -0
- aider/website/docs/config/agent-mode.md +36 -3
- aider/website/docs/config/model-aliases.md +2 -1
- aider/website/docs/faq.md +6 -11
- aider/website/docs/languages.md +2 -2
- aider/website/docs/more/infinite-output.md +27 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/METADATA +112 -70
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/RECORD +112 -107
- aider_ce-0.88.38.dist-info/entry_points.txt +6 -0
- aider_ce-0.88.20.dist-info/entry_points.txt +0 -2
- /aider/tools/{tool_utils.py → utils/helpers.py} +0 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/WHEEL +0 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/licenses/LICENSE.txt +0 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def print_tool_response(coder, mcp_server, tool_response):
|
|
6
|
+
"""
|
|
7
|
+
Format the output for display.
|
|
8
|
+
Prints a Header to identify the tool, a body for the relevant information
|
|
9
|
+
for the user and a footer for verbose information
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
coder: An instance of base_coder
|
|
13
|
+
mcp_server: An mcp server instance
|
|
14
|
+
tool_response: a tool_response dictionary
|
|
15
|
+
"""
|
|
16
|
+
tool_header(coder=coder, mcp_server=mcp_server, tool_response=tool_response)
|
|
17
|
+
tool_body(coder=coder, tool_response=tool_response)
|
|
18
|
+
tool_footer(coder=coder, tool_response=tool_response)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def tool_header(coder, mcp_server, tool_response):
|
|
22
|
+
"""
|
|
23
|
+
Prints the header for the tool call output
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
coder: An instance of base_coder
|
|
27
|
+
mcp_server: An mcp server instance
|
|
28
|
+
tool_response: a tool_response dictionary
|
|
29
|
+
"""
|
|
30
|
+
color_start, color_end = color_markers(coder)
|
|
31
|
+
|
|
32
|
+
coder.io.tool_output(
|
|
33
|
+
f"{color_start}Tool Call:{color_end} {mcp_server.name} • {tool_response.function.name}"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def tool_body(coder, tool_response):
|
|
38
|
+
"""
|
|
39
|
+
Prints the output body of a tool call as the raw json returned from the model
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
coder: An instance of base_coder
|
|
43
|
+
tool_response: a tool_response dictionary
|
|
44
|
+
"""
|
|
45
|
+
color_start, color_end = color_markers(coder)
|
|
46
|
+
|
|
47
|
+
# Parse and format arguments as headers with values
|
|
48
|
+
if tool_response.function.arguments:
|
|
49
|
+
# For non-replace tools, show raw arguments
|
|
50
|
+
raw_args = tool_response.function.arguments
|
|
51
|
+
coder.io.tool_output(f"{color_start}Arguments:{color_end} {raw_args}")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def tool_body_unwrapped(coder, tool_response):
|
|
55
|
+
"""
|
|
56
|
+
Prints the output body of a tool call with the argument
|
|
57
|
+
and content sections separated
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
coder: An instance of base_coder
|
|
61
|
+
tool_response: a tool_response dictionary
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
color_start, color_end = color_markers(coder)
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
args_dict = json.loads(tool_response.function.arguments)
|
|
68
|
+
first_key = True
|
|
69
|
+
for key, value in args_dict.items():
|
|
70
|
+
# Convert explicit \\n sequences to actual newlines using regex
|
|
71
|
+
# Only match \\n that is not preceded by any other backslashes
|
|
72
|
+
if isinstance(value, str):
|
|
73
|
+
value = re.sub(r"(?<!\\)\\n", "\n", value)
|
|
74
|
+
# Add extra newline before first key/header
|
|
75
|
+
if first_key:
|
|
76
|
+
coder.io.tool_output("\n")
|
|
77
|
+
first_key = False
|
|
78
|
+
coder.io.tool_output(f"{color_start}{key}:{color_end}")
|
|
79
|
+
# Split the value by newlines and output each line separately
|
|
80
|
+
if isinstance(value, str):
|
|
81
|
+
for line in value.split("\n"):
|
|
82
|
+
coder.io.tool_output(f"{line}")
|
|
83
|
+
else:
|
|
84
|
+
coder.io.tool_output(f"{str(value)}")
|
|
85
|
+
coder.io.tool_output("")
|
|
86
|
+
except json.JSONDecodeError:
|
|
87
|
+
# If JSON parsing fails, show raw arguments
|
|
88
|
+
raw_args = tool_response.function.arguments
|
|
89
|
+
coder.io.tool_output(f"{color_start}Arguments:{color_end} {raw_args}")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def tool_footer(coder, tool_response):
|
|
93
|
+
"""
|
|
94
|
+
Prints the output footer of a tool call, generally a new line
|
|
95
|
+
But can include id's if ran in verbose mode
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
coder: An instance of base_coder
|
|
99
|
+
tool_response: a tool_response dictionary
|
|
100
|
+
"""
|
|
101
|
+
if coder.verbose:
|
|
102
|
+
coder.io.tool_output(f"Tool ID: {tool_response.id}")
|
|
103
|
+
coder.io.tool_output(f"Tool type: {tool_response.type}")
|
|
104
|
+
|
|
105
|
+
coder.io.tool_output("\n")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def color_markers(coder):
|
|
109
|
+
"""
|
|
110
|
+
Rich.console color markers
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
coder: An instance of base_coder
|
|
114
|
+
"""
|
|
115
|
+
color_start = "[blue]" if coder.pretty else ""
|
|
116
|
+
color_end = "[/blue]" if coder.pretty else ""
|
|
117
|
+
|
|
118
|
+
return color_start, color_end
|
aider/tools/view.py
CHANGED
|
@@ -1,57 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
from aider.tools.utils.base_tool import BaseTool
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Tool(BaseTool):
|
|
5
|
+
NORM_NAME = "view"
|
|
6
|
+
SCHEMA = {
|
|
7
|
+
"type": "function",
|
|
8
|
+
"function": {
|
|
9
|
+
"name": "View",
|
|
10
|
+
"description": (
|
|
11
|
+
"View a specific file and add it to context."
|
|
12
|
+
"Only use this when the file is not already in the context "
|
|
13
|
+
"and when editing the file is necessary to accomplish the goal."
|
|
14
|
+
),
|
|
15
|
+
"parameters": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"file_path": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "The path to the file to view.",
|
|
21
|
+
},
|
|
16
22
|
},
|
|
23
|
+
"required": ["file_path"],
|
|
17
24
|
},
|
|
18
|
-
"required": ["file_path"],
|
|
19
25
|
},
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return coder._add_file_to_context(file_path, explicit=True)
|
|
37
|
-
except Exception as e:
|
|
38
|
-
coder.io.tool_error(f"Error viewing file: {str(e)}")
|
|
39
|
-
return f"Error: {str(e)}"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def process_response(coder, params):
|
|
43
|
-
"""
|
|
44
|
-
Process the View tool response.
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
coder: The Coder instance
|
|
48
|
-
params: Dictionary of parameters
|
|
49
|
-
|
|
50
|
-
Returns:
|
|
51
|
-
str: Result message
|
|
52
|
-
"""
|
|
53
|
-
file_path = params.get("file_path")
|
|
54
|
-
if file_path is not None:
|
|
55
|
-
return execute_view(coder, file_path)
|
|
56
|
-
else:
|
|
57
|
-
return "Error: Missing 'file_path' parameter for View"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def execute(cls, coder, file_path):
|
|
30
|
+
"""
|
|
31
|
+
Explicitly add a file to context as read-only.
|
|
32
|
+
|
|
33
|
+
This gives the LLM explicit control over what files to view,
|
|
34
|
+
rather than relying on indirect mentions.
|
|
35
|
+
"""
|
|
36
|
+
try:
|
|
37
|
+
# Use the coder's helper, marking it as an explicit view request
|
|
38
|
+
return coder._add_file_to_context(file_path, explicit=True)
|
|
39
|
+
except Exception as e:
|
|
40
|
+
coder.io.tool_error(f"Error viewing file: {str(e)}")
|
|
41
|
+
return f"Error: {str(e)}"
|
|
@@ -1,141 +1,138 @@
|
|
|
1
1
|
import fnmatch
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
4
|
+
from aider.tools.utils.base_tool import BaseTool
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Tool(BaseTool):
|
|
8
|
+
NORM_NAME = "viewfilesmatching"
|
|
9
|
+
SCHEMA = {
|
|
10
|
+
"type": "function",
|
|
11
|
+
"function": {
|
|
12
|
+
"name": "ViewFilesMatching",
|
|
13
|
+
"description": "View files containing a specific pattern.",
|
|
14
|
+
"parameters": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"pattern": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "The pattern to search for in file contents.",
|
|
20
|
+
},
|
|
21
|
+
"file_pattern": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": (
|
|
24
|
+
"An optional glob pattern to filter which files are searched."
|
|
25
|
+
),
|
|
26
|
+
},
|
|
27
|
+
"regex": {
|
|
28
|
+
"type": "boolean",
|
|
29
|
+
"description": (
|
|
30
|
+
"Whether the pattern is a regular expression. Defaults to False."
|
|
31
|
+
),
|
|
32
|
+
},
|
|
25
33
|
},
|
|
34
|
+
"required": ["pattern"],
|
|
26
35
|
},
|
|
27
|
-
"required": ["pattern"],
|
|
28
36
|
},
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)
|
|
106
|
-
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def execute(cls, coder, pattern, file_pattern=None, regex=False):
|
|
41
|
+
"""
|
|
42
|
+
Search for pattern (literal string or regex) in files and return matching files as text.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
coder: The Coder instance.
|
|
46
|
+
pattern (str): The pattern to search for.
|
|
47
|
+
Treated as a literal string by default.
|
|
48
|
+
file_pattern (str, optional): Glob pattern to filter which files are searched.
|
|
49
|
+
Defaults to None (search all files).
|
|
50
|
+
regex (bool, optional): If True, treat pattern as a regular expression.
|
|
51
|
+
Defaults to False.
|
|
52
|
+
|
|
53
|
+
This tool lets the LLM search for content within files, mimicking
|
|
54
|
+
how a developer would use grep or regex search to find relevant code.
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
# Get list of files to search
|
|
58
|
+
if file_pattern:
|
|
59
|
+
# Use glob pattern to filter files
|
|
60
|
+
all_files = coder.get_all_relative_files()
|
|
61
|
+
files_to_search = []
|
|
62
|
+
for file in all_files:
|
|
63
|
+
if fnmatch.fnmatch(file, file_pattern):
|
|
64
|
+
files_to_search.append(file)
|
|
65
|
+
|
|
66
|
+
if not files_to_search:
|
|
67
|
+
return f"No files matching '{file_pattern}' to search for pattern '{pattern}'"
|
|
68
|
+
else:
|
|
69
|
+
# Search all files if no pattern provided
|
|
70
|
+
files_to_search = coder.get_all_relative_files()
|
|
71
|
+
|
|
72
|
+
# Search for pattern in files
|
|
73
|
+
matches = {}
|
|
74
|
+
num_matches = 0
|
|
75
|
+
inspecific_search_flag = False
|
|
76
|
+
|
|
77
|
+
for file in files_to_search:
|
|
78
|
+
abs_path = coder.abs_root_path(file)
|
|
79
|
+
|
|
80
|
+
if num_matches >= 25:
|
|
81
|
+
inspecific_search_flag = True
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
if coder.repo.ignored_file(abs_path):
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
with open(abs_path, "r", encoding="utf-8") as f:
|
|
88
|
+
content = f.read()
|
|
89
|
+
match_count = 0
|
|
90
|
+
if regex:
|
|
91
|
+
try:
|
|
92
|
+
matches_found = re.findall(pattern, content)
|
|
93
|
+
match_count = len(matches_found)
|
|
94
|
+
except re.error as e:
|
|
95
|
+
# Handle invalid regex patterns gracefully
|
|
96
|
+
coder.io.tool_error(f"Invalid regex pattern '{pattern}': {e}")
|
|
97
|
+
# Skip this file for this search if regex is invalid
|
|
98
|
+
continue
|
|
99
|
+
else:
|
|
100
|
+
# Exact string matching
|
|
101
|
+
match_count = content.count(pattern)
|
|
102
|
+
|
|
103
|
+
if match_count > 0:
|
|
104
|
+
matches[file] = match_count
|
|
105
|
+
num_matches += 1
|
|
106
|
+
except Exception:
|
|
107
|
+
# Skip files that can't be read (binary, etc.)
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
# Return formatted text instead of adding to context
|
|
111
|
+
if matches:
|
|
112
|
+
# Sort by number of matches (most matches first)
|
|
113
|
+
sorted_matches = sorted(matches.items(), key=lambda x: x[1], reverse=True)
|
|
114
|
+
match_list = [f"{file} ({count} matches)" for file, count in sorted_matches]
|
|
115
|
+
|
|
116
|
+
if len(matches) > 10:
|
|
117
|
+
result = (
|
|
118
|
+
f"Found '{pattern}' in {len(matches)} files:"
|
|
119
|
+
f" {', '.join(match_list[:10])} and {len(matches) - 10} more"
|
|
120
|
+
"\nTry more specific search terms going forward"
|
|
121
|
+
if inspecific_search_flag
|
|
122
|
+
else ""
|
|
123
|
+
)
|
|
124
|
+
coder.io.tool_output(f"🔍 Found '{pattern}' in {len(matches)} files")
|
|
125
|
+
else:
|
|
126
|
+
result = f"Found '{pattern}' in {len(matches)} files: {', '.join(match_list)}"
|
|
127
|
+
coder.io.tool_output(
|
|
128
|
+
f"🔍 Found '{pattern}' in:"
|
|
129
|
+
f" {', '.join(match_list[:5])}{' and more' if len(matches) > 5 else ''}"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
return result
|
|
107
133
|
else:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return result
|
|
115
|
-
else:
|
|
116
|
-
coder.io.tool_output(f"⚠️ Pattern '{pattern}' not found in any files")
|
|
117
|
-
return "Pattern not found in any files"
|
|
118
|
-
except Exception as e:
|
|
119
|
-
coder.io.tool_error(f"Error in ViewFilesMatching: {str(e)}")
|
|
120
|
-
return f"Error: {str(e)}"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def process_response(coder, params):
|
|
124
|
-
"""
|
|
125
|
-
Process the ViewFilesMatching tool response.
|
|
126
|
-
|
|
127
|
-
Args:
|
|
128
|
-
coder: The Coder instance
|
|
129
|
-
params: Dictionary of parameters
|
|
130
|
-
|
|
131
|
-
Returns:
|
|
132
|
-
str: Result message
|
|
133
|
-
"""
|
|
134
|
-
pattern = params.get("pattern")
|
|
135
|
-
file_pattern = params.get("file_pattern")
|
|
136
|
-
regex = params.get("regex", False)
|
|
137
|
-
|
|
138
|
-
if pattern is not None:
|
|
139
|
-
return execute_view_files_matching(coder, pattern, file_pattern, regex)
|
|
140
|
-
else:
|
|
141
|
-
return "Error: Missing 'pattern' parameter for ViewFilesMatching"
|
|
134
|
+
coder.io.tool_output(f"⚠️ Pattern '{pattern}' not found in any files")
|
|
135
|
+
return "Pattern not found in any files"
|
|
136
|
+
except Exception as e:
|
|
137
|
+
coder.io.tool_error(f"Error in ViewFilesMatching: {str(e)}")
|
|
138
|
+
return f"Error: {str(e)}"
|