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.
Files changed (113) hide show
  1. aider/__init__.py +1 -1
  2. aider/_version.py +2 -2
  3. aider/args.py +63 -43
  4. aider/coders/agent_coder.py +331 -79
  5. aider/coders/agent_prompts.py +3 -15
  6. aider/coders/architect_coder.py +21 -5
  7. aider/coders/base_coder.py +661 -413
  8. aider/coders/base_prompts.py +6 -3
  9. aider/coders/chat_chunks.py +39 -17
  10. aider/commands.py +79 -15
  11. aider/diffs.py +10 -9
  12. aider/exceptions.py +1 -1
  13. aider/helpers/coroutines.py +8 -0
  14. aider/helpers/requests.py +45 -0
  15. aider/history.py +5 -0
  16. aider/io.py +179 -25
  17. aider/main.py +86 -35
  18. aider/models.py +16 -8
  19. aider/queries/tree-sitter-language-pack/c-tags.scm +3 -0
  20. aider/queries/tree-sitter-language-pack/clojure-tags.scm +5 -0
  21. aider/queries/tree-sitter-language-pack/commonlisp-tags.scm +5 -0
  22. aider/queries/tree-sitter-language-pack/cpp-tags.scm +3 -0
  23. aider/queries/tree-sitter-language-pack/csharp-tags.scm +6 -0
  24. aider/queries/tree-sitter-language-pack/dart-tags.scm +5 -0
  25. aider/queries/tree-sitter-language-pack/elixir-tags.scm +5 -0
  26. aider/queries/tree-sitter-language-pack/elm-tags.scm +3 -0
  27. aider/queries/tree-sitter-language-pack/go-tags.scm +7 -0
  28. aider/queries/tree-sitter-language-pack/java-tags.scm +6 -0
  29. aider/queries/tree-sitter-language-pack/javascript-tags.scm +8 -0
  30. aider/queries/tree-sitter-language-pack/lua-tags.scm +5 -0
  31. aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +3 -0
  32. aider/queries/tree-sitter-language-pack/python-tags.scm +10 -0
  33. aider/queries/tree-sitter-language-pack/r-tags.scm +6 -0
  34. aider/queries/tree-sitter-language-pack/ruby-tags.scm +5 -0
  35. aider/queries/tree-sitter-language-pack/rust-tags.scm +3 -0
  36. aider/queries/tree-sitter-language-pack/solidity-tags.scm +1 -1
  37. aider/queries/tree-sitter-language-pack/swift-tags.scm +4 -1
  38. aider/queries/tree-sitter-languages/c-tags.scm +3 -0
  39. aider/queries/tree-sitter-languages/c_sharp-tags.scm +6 -0
  40. aider/queries/tree-sitter-languages/cpp-tags.scm +3 -0
  41. aider/queries/tree-sitter-languages/dart-tags.scm +2 -1
  42. aider/queries/tree-sitter-languages/elixir-tags.scm +5 -0
  43. aider/queries/tree-sitter-languages/elm-tags.scm +3 -0
  44. aider/queries/tree-sitter-languages/fortran-tags.scm +3 -0
  45. aider/queries/tree-sitter-languages/go-tags.scm +6 -0
  46. aider/queries/tree-sitter-languages/haskell-tags.scm +2 -0
  47. aider/queries/tree-sitter-languages/java-tags.scm +6 -0
  48. aider/queries/tree-sitter-languages/javascript-tags.scm +8 -0
  49. aider/queries/tree-sitter-languages/julia-tags.scm +2 -2
  50. aider/queries/tree-sitter-languages/kotlin-tags.scm +3 -0
  51. aider/queries/tree-sitter-languages/ocaml_interface-tags.scm +6 -0
  52. aider/queries/tree-sitter-languages/php-tags.scm +6 -0
  53. aider/queries/tree-sitter-languages/python-tags.scm +10 -0
  54. aider/queries/tree-sitter-languages/ruby-tags.scm +5 -0
  55. aider/queries/tree-sitter-languages/rust-tags.scm +3 -0
  56. aider/queries/tree-sitter-languages/scala-tags.scm +2 -3
  57. aider/queries/tree-sitter-languages/typescript-tags.scm +3 -0
  58. aider/queries/tree-sitter-languages/zig-tags.scm +20 -3
  59. aider/repomap.py +71 -11
  60. aider/resources/model-metadata.json +27335 -635
  61. aider/resources/model-settings.yml +190 -0
  62. aider/scrape.py +2 -0
  63. aider/tools/__init__.py +2 -0
  64. aider/tools/command.py +84 -94
  65. aider/tools/command_interactive.py +95 -110
  66. aider/tools/delete_block.py +131 -159
  67. aider/tools/delete_line.py +97 -132
  68. aider/tools/delete_lines.py +120 -160
  69. aider/tools/extract_lines.py +288 -312
  70. aider/tools/finished.py +30 -43
  71. aider/tools/git_branch.py +107 -109
  72. aider/tools/git_diff.py +44 -56
  73. aider/tools/git_log.py +39 -53
  74. aider/tools/git_remote.py +37 -51
  75. aider/tools/git_show.py +33 -47
  76. aider/tools/git_status.py +30 -44
  77. aider/tools/grep.py +214 -242
  78. aider/tools/indent_lines.py +175 -201
  79. aider/tools/insert_block.py +220 -253
  80. aider/tools/list_changes.py +65 -80
  81. aider/tools/ls.py +64 -80
  82. aider/tools/make_editable.py +57 -73
  83. aider/tools/make_readonly.py +50 -66
  84. aider/tools/remove.py +64 -80
  85. aider/tools/replace_all.py +96 -109
  86. aider/tools/replace_line.py +118 -156
  87. aider/tools/replace_lines.py +160 -197
  88. aider/tools/replace_text.py +159 -160
  89. aider/tools/show_numbered_context.py +115 -141
  90. aider/tools/thinking.py +52 -0
  91. aider/tools/undo_change.py +78 -91
  92. aider/tools/update_todo_list.py +130 -138
  93. aider/tools/utils/base_tool.py +64 -0
  94. aider/tools/utils/output.py +118 -0
  95. aider/tools/view.py +38 -54
  96. aider/tools/view_files_matching.py +131 -134
  97. aider/tools/view_files_with_symbol.py +108 -120
  98. aider/urls.py +1 -1
  99. aider/versioncheck.py +4 -3
  100. aider/website/docs/config/adv-model-settings.md +237 -0
  101. aider/website/docs/config/agent-mode.md +36 -3
  102. aider/website/docs/config/model-aliases.md +2 -1
  103. aider/website/docs/faq.md +6 -11
  104. aider/website/docs/languages.md +2 -2
  105. aider/website/docs/more/infinite-output.md +27 -0
  106. {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/METADATA +112 -70
  107. {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/RECORD +112 -107
  108. aider_ce-0.88.38.dist-info/entry_points.txt +6 -0
  109. aider_ce-0.88.20.dist-info/entry_points.txt +0 -2
  110. /aider/tools/{tool_utils.py → utils/helpers.py} +0 -0
  111. {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/WHEEL +0 -0
  112. {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/licenses/LICENSE.txt +0 -0
  113. {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
- from .tool_utils import (
1
+ from aider.tools.utils.base_tool import BaseTool
2
+ from aider.tools.utils.helpers import (
2
3
  ToolError,
3
4
  apply_change,
4
5
  determine_line_range,
@@ -10,212 +11,185 @@ from .tool_utils import (
10
11
  validate_file_for_edit,
11
12
  )
12
13
 
13
- schema = {
14
- "type": "function",
15
- "function": {
16
- "name": "IndentLines",
17
- "description": "Indent a block of lines in a file.",
18
- "parameters": {
19
- "type": "object",
20
- "properties": {
21
- "file_path": {"type": "string"},
22
- "start_pattern": {"type": "string"},
23
- "end_pattern": {"type": "string"},
24
- "line_count": {"type": "integer"},
25
- "indent_levels": {"type": "integer", "default": 1},
26
- "near_context": {"type": "string"},
27
- "occurrence": {"type": "integer", "default": 1},
28
- "change_id": {"type": "string"},
29
- "dry_run": {"type": "boolean", "default": False},
14
+
15
+ class Tool(BaseTool):
16
+ NORM_NAME = "indentlines"
17
+ SCHEMA = {
18
+ "type": "function",
19
+ "function": {
20
+ "name": "IndentLines",
21
+ "description": "Indent a block of lines in a file.",
22
+ "parameters": {
23
+ "type": "object",
24
+ "properties": {
25
+ "file_path": {"type": "string"},
26
+ "start_pattern": {"type": "string"},
27
+ "end_pattern": {"type": "string"},
28
+ "line_count": {"type": "integer"},
29
+ "indent_levels": {"type": "integer", "default": 1},
30
+ "near_context": {"type": "string"},
31
+ "occurrence": {"type": "integer", "default": 1},
32
+ "change_id": {"type": "string"},
33
+ "dry_run": {"type": "boolean", "default": False},
34
+ },
35
+ "required": ["file_path", "start_pattern"],
30
36
  },
31
- "required": ["file_path", "start_pattern"],
32
37
  },
33
- },
34
- }
35
-
36
- # Normalized tool name for lookup
37
- NORM_NAME = "indentlines"
38
-
39
-
40
- def _execute_indent_lines(
41
- coder,
42
- file_path,
43
- start_pattern,
44
- end_pattern=None,
45
- line_count=None,
46
- indent_levels=1,
47
- near_context=None,
48
- occurrence=1,
49
- change_id=None,
50
- dry_run=False,
51
- ):
52
- """
53
- Indent or unindent a block of lines in a file using utility functions.
54
-
55
- Parameters:
56
- - coder: The Coder instance
57
- - file_path: Path to the file to modify
58
- - start_pattern: Pattern marking the start of the block to indent (line containing this pattern)
59
- - end_pattern: Optional pattern marking the end of the block (line containing this pattern)
60
- - line_count: Optional number of lines to indent (alternative to end_pattern)
61
- - indent_levels: Number of levels to indent (positive) or unindent (negative)
62
- - near_context: Optional text nearby to help locate the correct instance of the start_pattern
63
- - occurrence: Which occurrence of the start_pattern to use (1-based index, or -1 for last)
64
- - change_id: Optional ID for tracking the change
65
- - dry_run: If True, simulate the change without modifying the file
66
-
67
- Returns a result message.
68
- """
69
- tool_name = "IndentLines"
70
- try:
71
- # 1. Validate file and get content
72
- abs_path, rel_path, original_content = validate_file_for_edit(coder, file_path)
73
- lines = original_content.splitlines()
74
-
75
- # 2. Find the start line
76
- pattern_desc = f"Start pattern '{start_pattern}'"
77
- if near_context:
78
- pattern_desc += f" near context '{near_context}'"
79
- start_pattern_indices = find_pattern_indices(lines, start_pattern, near_context)
80
- start_line_idx = select_occurrence_index(start_pattern_indices, occurrence, pattern_desc)
81
-
82
- # 3. Determine the end line
83
- start_line, end_line = determine_line_range(
84
- coder=coder,
85
- file_path=rel_path,
86
- lines=lines,
87
- start_pattern_line_index=start_line_idx,
88
- end_pattern=end_pattern,
89
- line_count=line_count,
90
- target_symbol=None, # IndentLines uses patterns, not symbols
91
- pattern_desc=pattern_desc,
92
- )
93
-
94
- # 4. Validate and prepare indentation
38
+ }
39
+
40
+ @classmethod
41
+ def execute(
42
+ cls,
43
+ coder,
44
+ file_path,
45
+ start_pattern,
46
+ end_pattern=None,
47
+ line_count=None,
48
+ indent_levels=1,
49
+ near_context=None,
50
+ occurrence=1,
51
+ change_id=None,
52
+ dry_run=False,
53
+ ):
54
+ """
55
+ Indent or unindent a block of lines in a file using utility functions.
56
+
57
+ Parameters:
58
+ - coder: The Coder instance
59
+ - file_path: Path to the file to modify
60
+ - start_pattern: Pattern marking the start of the block to indent (line containing this pattern)
61
+ - end_pattern: Optional pattern marking the end of the block (line containing this pattern)
62
+ - line_count: Optional number of lines to indent (alternative to end_pattern)
63
+ - indent_levels: Number of levels to indent (positive) or unindent (negative)
64
+ - near_context: Optional text nearby to help locate the correct instance of the start_pattern
65
+ - occurrence: Which occurrence of the start_pattern to use (1-based index, or -1 for last)
66
+ - change_id: Optional ID for tracking the change
67
+ - dry_run: If True, simulate the change without modifying the file
68
+
69
+ Returns a result message.
70
+ """
71
+ tool_name = "IndentLines"
95
72
  try:
96
- indent_levels = int(indent_levels)
97
- except ValueError:
98
- raise ToolError(f"Invalid indent_levels value: '{indent_levels}'. Must be an integer.")
99
-
100
- indent_str = " " * 4 # Assume 4 spaces per level
101
- modified_lines = list(lines)
102
-
103
- # Apply indentation logic (core logic remains)
104
- for i in range(start_line, end_line + 1):
105
- if indent_levels > 0:
106
- modified_lines[i] = (indent_str * indent_levels) + modified_lines[i]
107
- elif indent_levels < 0:
108
- spaces_to_remove = abs(indent_levels) * len(indent_str)
109
- current_leading_spaces = len(modified_lines[i]) - len(modified_lines[i].lstrip(" "))
110
- actual_remove = min(spaces_to_remove, current_leading_spaces)
111
- if actual_remove > 0:
112
- modified_lines[i] = modified_lines[i][actual_remove:]
113
-
114
- new_content = "\n".join(modified_lines)
115
-
116
- if original_content == new_content:
117
- coder.io.tool_warning("No changes made: indentation would not change file")
118
- return "Warning: No changes made (indentation would not change file)"
119
-
120
- # 5. Generate diff for feedback
121
- diff_snippet = generate_unified_diff_snippet(original_content, new_content, rel_path)
122
- num_occurrences = len(start_pattern_indices)
123
- occurrence_str = f"occurrence {occurrence} of " if num_occurrences > 1 else ""
124
- action = "indent" if indent_levels > 0 else "unindent"
125
- levels = abs(indent_levels)
126
- level_text = "level" if levels == 1 else "levels"
127
- num_lines = end_line - start_line + 1
128
-
129
- # 6. Handle dry run
130
- if dry_run:
131
- dry_run_message = (
132
- f"Dry run: Would {action} {num_lines} lines ({start_line + 1}-{end_line + 1}) by"
133
- f" {levels} {level_text} (based on {occurrence_str}start pattern '{start_pattern}')"
134
- f" in {file_path}."
73
+ # 1. Validate file and get content
74
+ abs_path, rel_path, original_content = validate_file_for_edit(coder, file_path)
75
+ lines = original_content.splitlines()
76
+
77
+ # 2. Find the start line
78
+ pattern_desc = f"Start pattern '{start_pattern}'"
79
+ if near_context:
80
+ pattern_desc += f" near context '{near_context}'"
81
+ start_pattern_indices = find_pattern_indices(lines, start_pattern, near_context)
82
+ start_line_idx = select_occurrence_index(
83
+ start_pattern_indices, occurrence, pattern_desc
84
+ )
85
+
86
+ # 3. Determine the end line
87
+ start_line, end_line = determine_line_range(
88
+ coder=coder,
89
+ file_path=rel_path,
90
+ lines=lines,
91
+ start_pattern_line_index=start_line_idx,
92
+ end_pattern=end_pattern,
93
+ line_count=line_count,
94
+ target_symbol=None, # IndentLines uses patterns, not symbols
95
+ pattern_desc=pattern_desc,
96
+ )
97
+
98
+ # 4. Validate and prepare indentation
99
+ try:
100
+ indent_levels = int(indent_levels)
101
+ except ValueError:
102
+ raise ToolError(
103
+ f"Invalid indent_levels value: '{indent_levels}'. Must be an integer."
104
+ )
105
+
106
+ indent_str = " " * 4 # Assume 4 spaces per level
107
+ modified_lines = list(lines)
108
+
109
+ # Apply indentation logic (core logic remains)
110
+ for i in range(start_line, end_line + 1):
111
+ if indent_levels > 0:
112
+ modified_lines[i] = (indent_str * indent_levels) + modified_lines[i]
113
+ elif indent_levels < 0:
114
+ spaces_to_remove = abs(indent_levels) * len(indent_str)
115
+ current_leading_spaces = len(modified_lines[i]) - len(
116
+ modified_lines[i].lstrip(" ")
117
+ )
118
+ actual_remove = min(spaces_to_remove, current_leading_spaces)
119
+ if actual_remove > 0:
120
+ modified_lines[i] = modified_lines[i][actual_remove:]
121
+
122
+ new_content = "\n".join(modified_lines)
123
+
124
+ if original_content == new_content:
125
+ coder.io.tool_warning("No changes made: indentation would not change file")
126
+ return "Warning: No changes made (indentation would not change file)"
127
+
128
+ # 5. Generate diff for feedback
129
+ diff_snippet = generate_unified_diff_snippet(original_content, new_content, rel_path)
130
+ num_occurrences = len(start_pattern_indices)
131
+ occurrence_str = f"occurrence {occurrence} of " if num_occurrences > 1 else ""
132
+ action = "indent" if indent_levels > 0 else "unindent"
133
+ levels = abs(indent_levels)
134
+ level_text = "level" if levels == 1 else "levels"
135
+ num_lines = end_line - start_line + 1
136
+
137
+ # 6. Handle dry run
138
+ if dry_run:
139
+ dry_run_message = (
140
+ f"Dry run: Would {action} {num_lines} lines ({start_line + 1}-{end_line + 1})"
141
+ f" by {levels} {level_text} (based on {occurrence_str}start pattern"
142
+ f" '{start_pattern}') in {file_path}."
143
+ )
144
+ return format_tool_result(
145
+ coder,
146
+ tool_name,
147
+ "",
148
+ dry_run=True,
149
+ dry_run_message=dry_run_message,
150
+ diff_snippet=diff_snippet,
151
+ )
152
+
153
+ # 7. Apply Change (Not dry run)
154
+ metadata = {
155
+ "start_line": start_line + 1,
156
+ "end_line": end_line + 1,
157
+ "start_pattern": start_pattern,
158
+ "end_pattern": end_pattern,
159
+ "line_count": line_count,
160
+ "indent_levels": indent_levels,
161
+ "near_context": near_context,
162
+ "occurrence": occurrence,
163
+ }
164
+ final_change_id = apply_change(
165
+ coder,
166
+ abs_path,
167
+ rel_path,
168
+ original_content,
169
+ new_content,
170
+ "indentlines",
171
+ metadata,
172
+ change_id,
173
+ )
174
+
175
+ coder.files_edited_by_tools.add(rel_path)
176
+
177
+ # 8. Format and return result
178
+ action_past = "Indented" if indent_levels > 0 else "Unindented"
179
+ success_message = (
180
+ f"{action_past} {num_lines} lines by {levels} {level_text} (from"
181
+ f" {occurrence_str}start pattern) in {file_path}"
135
182
  )
136
183
  return format_tool_result(
137
184
  coder,
138
185
  tool_name,
139
- "",
140
- dry_run=True,
141
- dry_run_message=dry_run_message,
186
+ success_message,
187
+ change_id=final_change_id,
142
188
  diff_snippet=diff_snippet,
143
189
  )
144
-
145
- # 7. Apply Change (Not dry run)
146
- metadata = {
147
- "start_line": start_line + 1,
148
- "end_line": end_line + 1,
149
- "start_pattern": start_pattern,
150
- "end_pattern": end_pattern,
151
- "line_count": line_count,
152
- "indent_levels": indent_levels,
153
- "near_context": near_context,
154
- "occurrence": occurrence,
155
- }
156
- final_change_id = apply_change(
157
- coder,
158
- abs_path,
159
- rel_path,
160
- original_content,
161
- new_content,
162
- "indentlines",
163
- metadata,
164
- change_id,
165
- )
166
-
167
- coder.files_edited_by_tools.add(rel_path)
168
-
169
- # 8. Format and return result
170
- action_past = "Indented" if indent_levels > 0 else "Unindented"
171
- success_message = (
172
- f"{action_past} {num_lines} lines by {levels} {level_text} (from {occurrence_str}start"
173
- f" pattern) in {file_path}"
174
- )
175
- return format_tool_result(
176
- coder, tool_name, success_message, change_id=final_change_id, diff_snippet=diff_snippet
177
- )
178
- except ToolError as e:
179
- # Handle errors raised by utility functions (expected errors)
180
- return handle_tool_error(coder, tool_name, e, add_traceback=False)
181
- except Exception as e:
182
- # Handle unexpected errors
183
- return handle_tool_error(coder, tool_name, e)
184
-
185
-
186
- def process_response(coder, params):
187
- """
188
- Process the IndentLines tool response.
189
-
190
- Args:
191
- coder: The Coder instance
192
- params: Dictionary of parameters
193
-
194
- Returns:
195
- str: Result message
196
- """
197
- file_path = params.get("file_path")
198
- start_pattern = params.get("start_pattern")
199
- end_pattern = params.get("end_pattern")
200
- line_count = params.get("line_count")
201
- indent_levels = params.get("indent_levels", 1)
202
- near_context = params.get("near_context")
203
- occurrence = params.get("occurrence", 1)
204
- change_id = params.get("change_id")
205
- dry_run = params.get("dry_run", False)
206
-
207
- if file_path is not None and start_pattern is not None:
208
- return _execute_indent_lines(
209
- coder,
210
- file_path,
211
- start_pattern,
212
- end_pattern,
213
- line_count,
214
- indent_levels,
215
- near_context,
216
- occurrence,
217
- change_id,
218
- dry_run,
219
- )
220
- else:
221
- return "Error: Missing required parameters for IndentLines (file_path, start_pattern)"
190
+ except ToolError as e:
191
+ # Handle errors raised by utility functions (expected errors)
192
+ return handle_tool_error(coder, tool_name, e, add_traceback=False)
193
+ except Exception as e:
194
+ # Handle unexpected errors
195
+ return handle_tool_error(coder, tool_name, e)