aider-ce 0.87.2.dev9__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.

Potentially problematic release.


This version of aider-ce might be problematic. Click here for more details.

Files changed (264) hide show
  1. aider/__init__.py +20 -0
  2. aider/__main__.py +4 -0
  3. aider/_version.py +34 -0
  4. aider/analytics.py +258 -0
  5. aider/args.py +1014 -0
  6. aider/args_formatter.py +228 -0
  7. aider/change_tracker.py +133 -0
  8. aider/coders/__init__.py +36 -0
  9. aider/coders/architect_coder.py +48 -0
  10. aider/coders/architect_prompts.py +40 -0
  11. aider/coders/ask_coder.py +9 -0
  12. aider/coders/ask_prompts.py +35 -0
  13. aider/coders/base_coder.py +3013 -0
  14. aider/coders/base_prompts.py +87 -0
  15. aider/coders/chat_chunks.py +64 -0
  16. aider/coders/context_coder.py +53 -0
  17. aider/coders/context_prompts.py +75 -0
  18. aider/coders/editblock_coder.py +657 -0
  19. aider/coders/editblock_fenced_coder.py +10 -0
  20. aider/coders/editblock_fenced_prompts.py +143 -0
  21. aider/coders/editblock_func_coder.py +141 -0
  22. aider/coders/editblock_func_prompts.py +27 -0
  23. aider/coders/editblock_prompts.py +177 -0
  24. aider/coders/editor_diff_fenced_coder.py +9 -0
  25. aider/coders/editor_diff_fenced_prompts.py +11 -0
  26. aider/coders/editor_editblock_coder.py +9 -0
  27. aider/coders/editor_editblock_prompts.py +21 -0
  28. aider/coders/editor_whole_coder.py +9 -0
  29. aider/coders/editor_whole_prompts.py +12 -0
  30. aider/coders/help_coder.py +16 -0
  31. aider/coders/help_prompts.py +46 -0
  32. aider/coders/navigator_coder.py +2711 -0
  33. aider/coders/navigator_legacy_prompts.py +338 -0
  34. aider/coders/navigator_prompts.py +530 -0
  35. aider/coders/patch_coder.py +706 -0
  36. aider/coders/patch_prompts.py +161 -0
  37. aider/coders/search_replace.py +757 -0
  38. aider/coders/shell.py +37 -0
  39. aider/coders/single_wholefile_func_coder.py +102 -0
  40. aider/coders/single_wholefile_func_prompts.py +27 -0
  41. aider/coders/udiff_coder.py +429 -0
  42. aider/coders/udiff_prompts.py +117 -0
  43. aider/coders/udiff_simple.py +14 -0
  44. aider/coders/udiff_simple_prompts.py +25 -0
  45. aider/coders/wholefile_coder.py +144 -0
  46. aider/coders/wholefile_func_coder.py +134 -0
  47. aider/coders/wholefile_func_prompts.py +27 -0
  48. aider/coders/wholefile_prompts.py +70 -0
  49. aider/commands.py +1946 -0
  50. aider/copypaste.py +72 -0
  51. aider/deprecated.py +126 -0
  52. aider/diffs.py +128 -0
  53. aider/dump.py +29 -0
  54. aider/editor.py +147 -0
  55. aider/exceptions.py +107 -0
  56. aider/format_settings.py +26 -0
  57. aider/gui.py +545 -0
  58. aider/help.py +163 -0
  59. aider/help_pats.py +19 -0
  60. aider/history.py +178 -0
  61. aider/io.py +1257 -0
  62. aider/linter.py +304 -0
  63. aider/llm.py +47 -0
  64. aider/main.py +1297 -0
  65. aider/mcp/__init__.py +94 -0
  66. aider/mcp/server.py +119 -0
  67. aider/mdstream.py +243 -0
  68. aider/models.py +1344 -0
  69. aider/onboarding.py +428 -0
  70. aider/openrouter.py +129 -0
  71. aider/prompts.py +56 -0
  72. aider/queries/tree-sitter-language-pack/README.md +7 -0
  73. aider/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
  74. aider/queries/tree-sitter-language-pack/c-tags.scm +9 -0
  75. aider/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
  76. aider/queries/tree-sitter-language-pack/clojure-tags.scm +7 -0
  77. aider/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
  78. aider/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
  79. aider/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
  80. aider/queries/tree-sitter-language-pack/d-tags.scm +26 -0
  81. aider/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
  82. aider/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
  83. aider/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
  84. aider/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
  85. aider/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
  86. aider/queries/tree-sitter-language-pack/go-tags.scm +42 -0
  87. aider/queries/tree-sitter-language-pack/java-tags.scm +20 -0
  88. aider/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
  89. aider/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
  90. aider/queries/tree-sitter-language-pack/matlab-tags.scm +10 -0
  91. aider/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
  92. aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
  93. aider/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
  94. aider/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
  95. aider/queries/tree-sitter-language-pack/python-tags.scm +14 -0
  96. aider/queries/tree-sitter-language-pack/r-tags.scm +21 -0
  97. aider/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
  98. aider/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
  99. aider/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
  100. aider/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
  101. aider/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
  102. aider/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
  103. aider/queries/tree-sitter-languages/README.md +23 -0
  104. aider/queries/tree-sitter-languages/c-tags.scm +9 -0
  105. aider/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
  106. aider/queries/tree-sitter-languages/cpp-tags.scm +15 -0
  107. aider/queries/tree-sitter-languages/dart-tags.scm +91 -0
  108. aider/queries/tree-sitter-languages/elisp-tags.scm +8 -0
  109. aider/queries/tree-sitter-languages/elixir-tags.scm +54 -0
  110. aider/queries/tree-sitter-languages/elm-tags.scm +19 -0
  111. aider/queries/tree-sitter-languages/go-tags.scm +30 -0
  112. aider/queries/tree-sitter-languages/hcl-tags.scm +77 -0
  113. aider/queries/tree-sitter-languages/java-tags.scm +20 -0
  114. aider/queries/tree-sitter-languages/javascript-tags.scm +88 -0
  115. aider/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
  116. aider/queries/tree-sitter-languages/matlab-tags.scm +10 -0
  117. aider/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
  118. aider/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
  119. aider/queries/tree-sitter-languages/php-tags.scm +26 -0
  120. aider/queries/tree-sitter-languages/python-tags.scm +12 -0
  121. aider/queries/tree-sitter-languages/ql-tags.scm +26 -0
  122. aider/queries/tree-sitter-languages/ruby-tags.scm +64 -0
  123. aider/queries/tree-sitter-languages/rust-tags.scm +60 -0
  124. aider/queries/tree-sitter-languages/scala-tags.scm +65 -0
  125. aider/queries/tree-sitter-languages/typescript-tags.scm +41 -0
  126. aider/reasoning_tags.py +82 -0
  127. aider/repo.py +621 -0
  128. aider/repomap.py +988 -0
  129. aider/report.py +200 -0
  130. aider/resources/__init__.py +3 -0
  131. aider/resources/model-metadata.json +699 -0
  132. aider/resources/model-settings.yml +2046 -0
  133. aider/run_cmd.py +132 -0
  134. aider/scrape.py +284 -0
  135. aider/sendchat.py +61 -0
  136. aider/special.py +203 -0
  137. aider/tools/__init__.py +26 -0
  138. aider/tools/command.py +58 -0
  139. aider/tools/command_interactive.py +53 -0
  140. aider/tools/delete_block.py +120 -0
  141. aider/tools/delete_line.py +112 -0
  142. aider/tools/delete_lines.py +137 -0
  143. aider/tools/extract_lines.py +276 -0
  144. aider/tools/grep.py +171 -0
  145. aider/tools/indent_lines.py +155 -0
  146. aider/tools/insert_block.py +211 -0
  147. aider/tools/list_changes.py +51 -0
  148. aider/tools/ls.py +49 -0
  149. aider/tools/make_editable.py +46 -0
  150. aider/tools/make_readonly.py +29 -0
  151. aider/tools/remove.py +48 -0
  152. aider/tools/replace_all.py +77 -0
  153. aider/tools/replace_line.py +125 -0
  154. aider/tools/replace_lines.py +160 -0
  155. aider/tools/replace_text.py +125 -0
  156. aider/tools/show_numbered_context.py +101 -0
  157. aider/tools/tool_utils.py +313 -0
  158. aider/tools/undo_change.py +60 -0
  159. aider/tools/view.py +13 -0
  160. aider/tools/view_files_at_glob.py +65 -0
  161. aider/tools/view_files_matching.py +103 -0
  162. aider/tools/view_files_with_symbol.py +121 -0
  163. aider/urls.py +17 -0
  164. aider/utils.py +454 -0
  165. aider/versioncheck.py +113 -0
  166. aider/voice.py +187 -0
  167. aider/waiting.py +221 -0
  168. aider/watch.py +318 -0
  169. aider/watch_prompts.py +12 -0
  170. aider/website/Gemfile +8 -0
  171. aider/website/_includes/blame.md +162 -0
  172. aider/website/_includes/get-started.md +22 -0
  173. aider/website/_includes/help-tip.md +5 -0
  174. aider/website/_includes/help.md +24 -0
  175. aider/website/_includes/install.md +5 -0
  176. aider/website/_includes/keys.md +4 -0
  177. aider/website/_includes/model-warnings.md +67 -0
  178. aider/website/_includes/multi-line.md +22 -0
  179. aider/website/_includes/python-m-aider.md +5 -0
  180. aider/website/_includes/recording.css +228 -0
  181. aider/website/_includes/recording.md +34 -0
  182. aider/website/_includes/replit-pipx.md +9 -0
  183. aider/website/_includes/works-best.md +1 -0
  184. aider/website/_sass/custom/custom.scss +103 -0
  185. aider/website/docs/config/adv-model-settings.md +2260 -0
  186. aider/website/docs/config/aider_conf.md +548 -0
  187. aider/website/docs/config/api-keys.md +90 -0
  188. aider/website/docs/config/dotenv.md +493 -0
  189. aider/website/docs/config/editor.md +127 -0
  190. aider/website/docs/config/mcp.md +95 -0
  191. aider/website/docs/config/model-aliases.md +104 -0
  192. aider/website/docs/config/options.md +890 -0
  193. aider/website/docs/config/reasoning.md +210 -0
  194. aider/website/docs/config.md +44 -0
  195. aider/website/docs/faq.md +384 -0
  196. aider/website/docs/git.md +76 -0
  197. aider/website/docs/index.md +47 -0
  198. aider/website/docs/install/codespaces.md +39 -0
  199. aider/website/docs/install/docker.md +57 -0
  200. aider/website/docs/install/optional.md +100 -0
  201. aider/website/docs/install/replit.md +8 -0
  202. aider/website/docs/install.md +115 -0
  203. aider/website/docs/languages.md +264 -0
  204. aider/website/docs/legal/contributor-agreement.md +111 -0
  205. aider/website/docs/legal/privacy.md +104 -0
  206. aider/website/docs/llms/anthropic.md +77 -0
  207. aider/website/docs/llms/azure.md +48 -0
  208. aider/website/docs/llms/bedrock.md +132 -0
  209. aider/website/docs/llms/cohere.md +34 -0
  210. aider/website/docs/llms/deepseek.md +32 -0
  211. aider/website/docs/llms/gemini.md +49 -0
  212. aider/website/docs/llms/github.md +111 -0
  213. aider/website/docs/llms/groq.md +36 -0
  214. aider/website/docs/llms/lm-studio.md +39 -0
  215. aider/website/docs/llms/ollama.md +75 -0
  216. aider/website/docs/llms/openai-compat.md +39 -0
  217. aider/website/docs/llms/openai.md +58 -0
  218. aider/website/docs/llms/openrouter.md +78 -0
  219. aider/website/docs/llms/other.md +111 -0
  220. aider/website/docs/llms/vertex.md +50 -0
  221. aider/website/docs/llms/warnings.md +10 -0
  222. aider/website/docs/llms/xai.md +53 -0
  223. aider/website/docs/llms.md +54 -0
  224. aider/website/docs/more/analytics.md +127 -0
  225. aider/website/docs/more/edit-formats.md +116 -0
  226. aider/website/docs/more/infinite-output.md +159 -0
  227. aider/website/docs/more-info.md +8 -0
  228. aider/website/docs/recordings/auto-accept-architect.md +31 -0
  229. aider/website/docs/recordings/dont-drop-original-read-files.md +35 -0
  230. aider/website/docs/recordings/index.md +21 -0
  231. aider/website/docs/recordings/model-accepts-settings.md +69 -0
  232. aider/website/docs/recordings/tree-sitter-language-pack.md +80 -0
  233. aider/website/docs/repomap.md +112 -0
  234. aider/website/docs/scripting.md +100 -0
  235. aider/website/docs/troubleshooting/aider-not-found.md +24 -0
  236. aider/website/docs/troubleshooting/edit-errors.md +76 -0
  237. aider/website/docs/troubleshooting/imports.md +62 -0
  238. aider/website/docs/troubleshooting/models-and-keys.md +54 -0
  239. aider/website/docs/troubleshooting/support.md +79 -0
  240. aider/website/docs/troubleshooting/token-limits.md +96 -0
  241. aider/website/docs/troubleshooting/warnings.md +12 -0
  242. aider/website/docs/troubleshooting.md +11 -0
  243. aider/website/docs/usage/browser.md +57 -0
  244. aider/website/docs/usage/caching.md +49 -0
  245. aider/website/docs/usage/commands.md +133 -0
  246. aider/website/docs/usage/conventions.md +119 -0
  247. aider/website/docs/usage/copypaste.md +121 -0
  248. aider/website/docs/usage/images-urls.md +48 -0
  249. aider/website/docs/usage/lint-test.md +118 -0
  250. aider/website/docs/usage/modes.md +211 -0
  251. aider/website/docs/usage/not-code.md +179 -0
  252. aider/website/docs/usage/notifications.md +87 -0
  253. aider/website/docs/usage/tips.md +79 -0
  254. aider/website/docs/usage/tutorials.md +30 -0
  255. aider/website/docs/usage/voice.md +121 -0
  256. aider/website/docs/usage/watch.md +294 -0
  257. aider/website/docs/usage.md +102 -0
  258. aider/website/share/index.md +101 -0
  259. aider_ce-0.87.2.dev9.dist-info/METADATA +543 -0
  260. aider_ce-0.87.2.dev9.dist-info/RECORD +264 -0
  261. aider_ce-0.87.2.dev9.dist-info/WHEEL +5 -0
  262. aider_ce-0.87.2.dev9.dist-info/entry_points.txt +3 -0
  263. aider_ce-0.87.2.dev9.dist-info/licenses/LICENSE.txt +202 -0
  264. aider_ce-0.87.2.dev9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,228 @@
1
+ import argparse
2
+
3
+ from aider import urls
4
+
5
+ from .dump import dump # noqa: F401
6
+
7
+
8
+ class DotEnvFormatter(argparse.HelpFormatter):
9
+ def start_section(self, heading):
10
+ res = "\n\n"
11
+ res += "#" * (len(heading) + 3)
12
+ res += f"\n# {heading}"
13
+ super().start_section(res)
14
+
15
+ def _format_usage(self, usage, actions, groups, prefix):
16
+ return ""
17
+
18
+ def _format_text(self, text):
19
+ return f"""
20
+ ##########################################################
21
+ # Sample aider .env file.
22
+ # Place at the root of your git repo.
23
+ # Or use `aider --env <fname>` to specify.
24
+ ##########################################################
25
+
26
+ #################
27
+ # LLM parameters:
28
+ #
29
+ # Include xxx_API_KEY parameters and other params needed for your LLMs.
30
+ # See {urls.llms} for details.
31
+
32
+ ## OpenAI
33
+ #OPENAI_API_KEY=
34
+
35
+ ## Anthropic
36
+ #ANTHROPIC_API_KEY=
37
+
38
+ ##...
39
+ """
40
+
41
+ def _format_action(self, action):
42
+ if not action.option_strings:
43
+ return ""
44
+
45
+ if not action.env_var:
46
+ return
47
+
48
+ parts = [""]
49
+
50
+ default = action.default
51
+ if default == argparse.SUPPRESS:
52
+ default = ""
53
+ elif isinstance(default, str):
54
+ pass
55
+ elif isinstance(default, list) and not default:
56
+ default = ""
57
+ elif action.default is not None:
58
+ default = "true" if default else "false"
59
+ else:
60
+ default = ""
61
+
62
+ if action.help:
63
+ parts.append(f"## {action.help}")
64
+
65
+ if action.env_var:
66
+ env_var = action.env_var
67
+ if default:
68
+ parts.append(f"#{env_var}={default}\n")
69
+ else:
70
+ parts.append(f"#{env_var}=\n")
71
+
72
+ return "\n".join(parts) + "\n"
73
+
74
+ def _format_action_invocation(self, action):
75
+ return ""
76
+
77
+ def _format_args(self, action, default_metavar):
78
+ return ""
79
+
80
+
81
+ class YamlHelpFormatter(argparse.HelpFormatter):
82
+ def start_section(self, heading):
83
+ res = "\n\n"
84
+ res += "#" * (len(heading) + 3)
85
+ res += f"\n# {heading}"
86
+ super().start_section(res)
87
+
88
+ def _format_usage(self, usage, actions, groups, prefix):
89
+ return ""
90
+
91
+ def _format_text(self, text):
92
+ return """
93
+ ##########################################################
94
+ # Sample .aider.conf.yml
95
+ # This file lists *all* the valid configuration entries.
96
+ # Place in your home dir, or at the root of your git repo.
97
+ ##########################################################
98
+
99
+ # Note: You can only put OpenAI and Anthropic API keys in the YAML
100
+ # config file. Keys for all APIs can be stored in a .env file
101
+ # https://aider.chat/docs/config/dotenv.html
102
+
103
+ """
104
+
105
+ def _format_action(self, action):
106
+ if not action.option_strings:
107
+ return ""
108
+
109
+ parts = [""]
110
+
111
+ metavar = action.metavar
112
+ if not metavar and isinstance(action, argparse._StoreAction):
113
+ metavar = "VALUE"
114
+
115
+ default = action.default
116
+ if default == argparse.SUPPRESS:
117
+ default = ""
118
+ elif isinstance(default, str):
119
+ pass
120
+ elif isinstance(default, list) and not default:
121
+ default = ""
122
+ elif action.default is not None:
123
+ default = "true" if default else "false"
124
+ else:
125
+ default = ""
126
+
127
+ if action.help:
128
+ parts.append(f"## {action.help}")
129
+
130
+ for switch in action.option_strings:
131
+ if switch.startswith("--"):
132
+ break
133
+ switch = switch.lstrip("-")
134
+
135
+ if isinstance(action, argparse._StoreTrueAction):
136
+ default = False
137
+ elif isinstance(action, argparse._StoreConstAction):
138
+ default = False
139
+
140
+ if default is False:
141
+ default = "false"
142
+ if default is True:
143
+ default = "true"
144
+
145
+ if default:
146
+ if "#" in default:
147
+ parts.append(f'#{switch}: "{default}"\n')
148
+ else:
149
+ parts.append(f"#{switch}: {default}\n")
150
+ elif action.nargs in ("*", "+") or isinstance(action, argparse._AppendAction):
151
+ parts.append(f"#{switch}: xxx")
152
+ parts.append("## Specify multiple values like this:")
153
+ parts.append(f"#{switch}:")
154
+ parts.append("# - xxx")
155
+ parts.append("# - yyy")
156
+ parts.append("# - zzz")
157
+ else:
158
+ if switch.endswith("color"):
159
+ parts.append(f'#{switch}: "xxx"\n')
160
+ else:
161
+ parts.append(f"#{switch}: xxx\n")
162
+
163
+ ###
164
+ # parts.append(str(action))
165
+
166
+ return "\n".join(parts) + "\n"
167
+
168
+ def _format_action_invocation(self, action):
169
+ return ""
170
+
171
+ def _format_args(self, action, default_metavar):
172
+ return ""
173
+
174
+
175
+ class MarkdownHelpFormatter(argparse.HelpFormatter):
176
+ def start_section(self, heading):
177
+ super().start_section(f"## {heading}")
178
+
179
+ def _format_usage(self, usage, actions, groups, prefix):
180
+ res = super()._format_usage(usage, actions, groups, prefix)
181
+ quote = "```\n"
182
+ return quote + res + quote
183
+
184
+ def _format_text(self, text):
185
+ return ""
186
+
187
+ def _format_action(self, action):
188
+ if not action.option_strings:
189
+ return ""
190
+
191
+ parts = [""]
192
+
193
+ metavar = action.metavar
194
+ if not metavar and isinstance(action, argparse._StoreAction):
195
+ metavar = "VALUE"
196
+
197
+ for switch in action.option_strings:
198
+ if switch.startswith("--"):
199
+ break
200
+
201
+ if metavar:
202
+ parts.append(f"### `{switch} {metavar}`")
203
+ else:
204
+ parts.append(f"### `{switch}`")
205
+ if action.help:
206
+ parts.append(action.help + " ")
207
+
208
+ if action.default not in (argparse.SUPPRESS, None):
209
+ parts.append(f"Default: {action.default} ")
210
+
211
+ if action.env_var:
212
+ parts.append(f"Environment variable: `{action.env_var}` ")
213
+
214
+ if len(action.option_strings) > 1:
215
+ parts.append("Aliases:")
216
+ for switch in action.option_strings:
217
+ if metavar:
218
+ parts.append(f" - `{switch} {metavar}`")
219
+ else:
220
+ parts.append(f" - `{switch}`")
221
+
222
+ return "\n".join(parts) + "\n"
223
+
224
+ def _format_action_invocation(self, action):
225
+ return ""
226
+
227
+ def _format_args(self, action, default_metavar):
228
+ return ""
@@ -0,0 +1,133 @@
1
+ import time
2
+ import uuid
3
+ from collections import defaultdict
4
+
5
+
6
+ class ChangeTracker:
7
+ """
8
+ Tracks changes made to files for the undo functionality.
9
+ This enables granular editing operations with the ability to undo specific changes.
10
+ """
11
+
12
+ def __init__(self):
13
+ self.changes = {} # change_id -> change_info
14
+ self.files_changed = defaultdict(list) # file_path -> [change_ids]
15
+
16
+ def track_change(
17
+ self, file_path, change_type, original_content, new_content, metadata=None, change_id=None
18
+ ):
19
+ """
20
+ Record a change to enable future undo operations.
21
+
22
+ Parameters:
23
+ - file_path: Path to the file that was changed
24
+ - change_type: Type of change (e.g., 'replacetext', 'insertlines')
25
+ - original_content: Original content before the change
26
+ - new_content: New content after the change
27
+ - metadata: Additional information about the change (line numbers, positions, etc.)
28
+ - change_id: Optional custom ID for the change (if None, one will be generated)
29
+
30
+ Returns:
31
+ - change_id: Unique identifier for the change
32
+ """
33
+ if change_id is None:
34
+ generated_id = self._generate_change_id()
35
+ # Ensure the generated ID is treated as a string
36
+ current_change_id = str(generated_id)
37
+ else:
38
+ # If an ID is provided, ensure it's treated as a string key/value
39
+ current_change_id = str(change_id)
40
+
41
+ # Defensive check: Ensure the ID isn't literally the string 'False' or boolean False
42
+ # which might indicate an upstream issue or unexpected input.
43
+ if current_change_id == "False" or current_change_id is False:
44
+ # Log a warning? For now, generate a new ID to prevent storing False.
45
+ print(f"Warning: change_id evaluated to False for {file_path}. Generating new ID.")
46
+ current_change_id = self._generate_change_id()
47
+
48
+ change = {
49
+ # Use the confirmed string ID here
50
+ "id": current_change_id,
51
+ "file_path": file_path,
52
+ "type": change_type,
53
+ "original": original_content,
54
+ "new": new_content,
55
+ "metadata": metadata or {},
56
+ "timestamp": time.time(),
57
+ }
58
+
59
+ # Use the confirmed string ID for storage and return
60
+ self.changes[current_change_id] = change
61
+ self.files_changed[file_path].append(current_change_id)
62
+ return current_change_id
63
+
64
+ def undo_change(self, change_id):
65
+ """
66
+ Get information needed to reverse a specific change by ID.
67
+
68
+ Parameters:
69
+ - change_id: ID of the change to undo
70
+
71
+ Returns:
72
+ - (success, message, change_info): Tuple with success flag, message, and change information
73
+ """
74
+ if change_id not in self.changes:
75
+ return False, f"Change ID {change_id} not found", None
76
+
77
+ change = self.changes[change_id]
78
+
79
+ # Mark this change as undone by removing it from the tracking dictionaries
80
+ self.files_changed[change["file_path"]].remove(change_id)
81
+ if not self.files_changed[change["file_path"]]:
82
+ del self.files_changed[change["file_path"]]
83
+
84
+ # Keep the change in the changes dict but mark it as undone
85
+ change["undone"] = True
86
+ change["undone_at"] = time.time()
87
+
88
+ return True, f"Undid change {change_id} in {change['file_path']}", change
89
+
90
+ def get_last_change(self, file_path):
91
+ """
92
+ Get the most recent change for a specific file.
93
+
94
+ Parameters:
95
+ - file_path: Path to the file
96
+
97
+ Returns:
98
+ - change_id or None if no changes found
99
+ """
100
+ changes = self.files_changed.get(file_path, [])
101
+ if not changes:
102
+ return None
103
+ return changes[-1]
104
+
105
+ def list_changes(self, file_path=None, limit=10):
106
+ """
107
+ List recent changes, optionally filtered by file.
108
+
109
+ Parameters:
110
+ - file_path: Optional path to filter changes by file
111
+ - limit: Maximum number of changes to list
112
+
113
+ Returns:
114
+ - List of change dictionaries
115
+ """
116
+ if file_path:
117
+ # Get changes only for the specified file
118
+ change_ids = self.files_changed.get(file_path, [])
119
+ changes = [self.changes[cid] for cid in change_ids if cid in self.changes]
120
+ else:
121
+ # Get all changes
122
+ changes = list(self.changes.values())
123
+
124
+ # Filter out undone changes and sort by timestamp (most recent first)
125
+ changes = [c for c in changes if not c.get("undone", False)]
126
+ changes = sorted(changes, key=lambda c: c["timestamp"], reverse=True)
127
+
128
+ # Apply limit
129
+ return changes[:limit]
130
+
131
+ def _generate_change_id(self):
132
+ """Generate a unique ID for a change."""
133
+ return str(uuid.uuid4())[:8] # Short, readable ID
@@ -0,0 +1,36 @@
1
+ from .architect_coder import ArchitectCoder
2
+ from .ask_coder import AskCoder
3
+ from .base_coder import Coder
4
+ from .context_coder import ContextCoder
5
+ from .editblock_coder import EditBlockCoder
6
+ from .editblock_fenced_coder import EditBlockFencedCoder
7
+ from .editor_diff_fenced_coder import EditorDiffFencedCoder
8
+ from .editor_editblock_coder import EditorEditBlockCoder
9
+ from .editor_whole_coder import EditorWholeFileCoder
10
+ from .help_coder import HelpCoder
11
+ from .navigator_coder import NavigatorCoder
12
+ from .patch_coder import PatchCoder
13
+ from .udiff_coder import UnifiedDiffCoder
14
+ from .udiff_simple import UnifiedDiffSimpleCoder
15
+ from .wholefile_coder import WholeFileCoder
16
+
17
+ # from .single_wholefile_func_coder import SingleWholeFileFunctionCoder
18
+
19
+ __all__ = [
20
+ HelpCoder,
21
+ AskCoder,
22
+ Coder,
23
+ EditBlockCoder,
24
+ EditBlockFencedCoder,
25
+ WholeFileCoder,
26
+ PatchCoder,
27
+ UnifiedDiffCoder,
28
+ UnifiedDiffSimpleCoder,
29
+ # SingleWholeFileFunctionCoder,
30
+ ArchitectCoder,
31
+ EditorEditBlockCoder,
32
+ EditorWholeFileCoder,
33
+ EditorDiffFencedCoder,
34
+ ContextCoder,
35
+ NavigatorCoder,
36
+ ]
@@ -0,0 +1,48 @@
1
+ from .architect_prompts import ArchitectPrompts
2
+ from .ask_coder import AskCoder
3
+ from .base_coder import Coder
4
+
5
+
6
+ class ArchitectCoder(AskCoder):
7
+ edit_format = "architect"
8
+ gpt_prompts = ArchitectPrompts()
9
+ auto_accept_architect = False
10
+
11
+ def reply_completed(self):
12
+ content = self.partial_response_content
13
+
14
+ if not content or not content.strip():
15
+ return
16
+
17
+ if not self.auto_accept_architect and not self.io.confirm_ask("Edit the files?"):
18
+ return
19
+
20
+ kwargs = dict()
21
+
22
+ # Use the editor_model from the main_model if it exists, otherwise use the main_model itself
23
+ editor_model = self.main_model.editor_model or self.main_model
24
+
25
+ kwargs["main_model"] = editor_model
26
+ kwargs["edit_format"] = self.main_model.editor_edit_format
27
+ kwargs["suggest_shell_commands"] = False
28
+ kwargs["map_tokens"] = 0
29
+ kwargs["total_cost"] = self.total_cost
30
+ kwargs["cache_prompts"] = False
31
+ kwargs["num_cache_warming_pings"] = 0
32
+ kwargs["summarize_from_coder"] = False
33
+
34
+ new_kwargs = dict(io=self.io, from_coder=self)
35
+ new_kwargs.update(kwargs)
36
+
37
+ editor_coder = Coder.create(**new_kwargs)
38
+ editor_coder.cur_messages = []
39
+ editor_coder.done_messages = []
40
+
41
+ if self.verbose:
42
+ editor_coder.show_announcements()
43
+
44
+ editor_coder.run(with_message=content, preproc=False)
45
+
46
+ self.move_back_cur_messages("I made those changes to the files.")
47
+ self.total_cost = editor_coder.total_cost
48
+ self.aider_commit_hashes = editor_coder.aider_commit_hashes
@@ -0,0 +1,40 @@
1
+ # flake8: noqa: E501
2
+
3
+ from .base_prompts import CoderPrompts
4
+
5
+
6
+ class ArchitectPrompts(CoderPrompts):
7
+ main_system = """Act as an expert architect engineer providing direction to an editor engineer.
8
+ Deeply understand the user's change request and the provided code context.
9
+ Think step-by-step to develop a clear plan for the required code modifications.
10
+ Consider potential edge cases and how the changes should be verified.
11
+ Describe the plan and the necessary modifications to the editor engineer. Your instructions must be unambiguous, complete, and concise as the editor will rely solely on them.
12
+ Focus on *what* needs to change and *why*.
13
+
14
+ DO NOT show large blocks of code or the entire updated file content. Explain the changes conceptually.
15
+
16
+ Always reply to the user in {language}.
17
+ """
18
+
19
+ example_messages = []
20
+
21
+ files_content_prefix = """I have *added these files to the chat* so you see all of their contents.
22
+ *Trust this message as the true contents of the files!*
23
+ Other messages in the chat may contain outdated versions of the files' contents.
24
+ """ # noqa: E501
25
+
26
+ files_content_assistant_reply = (
27
+ "Ok, I will use that as the true, current contents of the files."
28
+ )
29
+
30
+ files_no_full_files = "I am not sharing the full contents of any files with you yet."
31
+
32
+ files_no_full_files_with_repo_map = ""
33
+ files_no_full_files_with_repo_map_reply = ""
34
+
35
+ repo_content_prefix = """I am working with you on code in a git repository.
36
+ Here are summaries of some files present in my git repo.
37
+ If you need to see the full contents of any files to answer my questions, ask me to *add them to the chat*.
38
+ """
39
+
40
+ system_reminder = ""
@@ -0,0 +1,9 @@
1
+ from .ask_prompts import AskPrompts
2
+ from .base_coder import Coder
3
+
4
+
5
+ class AskCoder(Coder):
6
+ """Ask questions about code without making any changes."""
7
+
8
+ edit_format = "ask"
9
+ gpt_prompts = AskPrompts()
@@ -0,0 +1,35 @@
1
+ # flake8: noqa: E501
2
+
3
+ from .base_prompts import CoderPrompts
4
+
5
+
6
+ class AskPrompts(CoderPrompts):
7
+ main_system = """Act as an expert code analyst.
8
+ Answer questions about the supplied code.
9
+ Always reply to the user in {language}.
10
+
11
+ If you need to describe code changes, do so *briefly*.
12
+ """
13
+
14
+ example_messages = []
15
+
16
+ files_content_prefix = """I have *added these files to the chat* so you see all of their contents.
17
+ *Trust this message as the true contents of the files!*
18
+ Other messages in the chat may contain outdated versions of the files' contents.
19
+ """ # noqa: E501
20
+
21
+ files_content_assistant_reply = (
22
+ "Ok, I will use that as the true, current contents of the files."
23
+ )
24
+
25
+ files_no_full_files = "I am not sharing the full contents of any files with you yet."
26
+
27
+ files_no_full_files_with_repo_map = ""
28
+ files_no_full_files_with_repo_map_reply = ""
29
+
30
+ repo_content_prefix = """I am working with you on code in a git repository.
31
+ Here are summaries of some files present in my git repo.
32
+ If you need to see the full contents of any files to answer my questions, ask me to *add them to the chat*.
33
+ """
34
+
35
+ system_reminder = "{final_reminders}"