auto-coder 0.1.316__py3-none-any.whl → 0.1.317__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 auto-coder might be problematic. Click here for more details.

Files changed (41) hide show
  1. {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/METADATA +1 -1
  2. {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/RECORD +41 -20
  3. autocoder/auto_coder_runner.py +1 -2
  4. autocoder/common/__init__.py +3 -0
  5. autocoder/common/auto_coder_lang.py +24 -0
  6. autocoder/common/code_auto_merge_editblock.py +2 -42
  7. autocoder/common/git_utils.py +2 -2
  8. autocoder/common/token_cost_caculate.py +103 -42
  9. autocoder/common/v2/__init__.py +0 -0
  10. autocoder/common/v2/code_auto_generate.py +199 -0
  11. autocoder/common/v2/code_auto_generate_diff.py +361 -0
  12. autocoder/common/v2/code_auto_generate_editblock.py +380 -0
  13. autocoder/common/v2/code_auto_generate_strict_diff.py +269 -0
  14. autocoder/common/v2/code_auto_merge.py +211 -0
  15. autocoder/common/v2/code_auto_merge_diff.py +354 -0
  16. autocoder/common/v2/code_auto_merge_editblock.py +523 -0
  17. autocoder/common/v2/code_auto_merge_strict_diff.py +259 -0
  18. autocoder/common/v2/code_diff_manager.py +266 -0
  19. autocoder/common/v2/code_editblock_manager.py +275 -0
  20. autocoder/common/v2/code_manager.py +238 -0
  21. autocoder/common/v2/code_strict_diff_manager.py +241 -0
  22. autocoder/dispacher/actions/action.py +16 -0
  23. autocoder/dispacher/actions/plugins/action_regex_project.py +6 -0
  24. autocoder/events/event_manager_singleton.py +2 -2
  25. autocoder/helper/__init__.py +0 -0
  26. autocoder/helper/project_creator.py +570 -0
  27. autocoder/linters/linter_factory.py +44 -25
  28. autocoder/linters/models.py +220 -0
  29. autocoder/linters/python_linter.py +1 -7
  30. autocoder/linters/reactjs_linter.py +580 -0
  31. autocoder/linters/shadow_linter.py +390 -0
  32. autocoder/linters/vue_linter.py +576 -0
  33. autocoder/memory/active_context_manager.py +0 -4
  34. autocoder/memory/active_package.py +12 -12
  35. autocoder/shadows/__init__.py +0 -0
  36. autocoder/shadows/shadow_manager.py +235 -0
  37. autocoder/version.py +1 -1
  38. {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/LICENSE +0 -0
  39. {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/WHEEL +0 -0
  40. {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/entry_points.txt +0 -0
  41. {auto_coder-0.1.316.dist-info → auto_coder-0.1.317.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,380 @@
1
+ from typing import List, Dict, Tuple
2
+ from autocoder.common.types import Mode, CodeGenerateResult
3
+ from autocoder.common import AutoCoderArgs
4
+ import byzerllm
5
+ from autocoder.common import sys_prompt
6
+ from autocoder.privacy.model_filter import ModelPathFilter
7
+ import json
8
+ from concurrent.futures import ThreadPoolExecutor
9
+ from autocoder.common.utils_code_auto_generate import chat_with_continue,stream_chat_with_continue,ChatWithContinueResult
10
+ from autocoder.utils.auto_coder_utils.chat_stream_out import stream_out
11
+ from autocoder.common.stream_out_type import CodeGenerateStreamOutType
12
+ from autocoder.common.auto_coder_lang import get_message_with_format
13
+ from autocoder.common.printer import Printer
14
+ from autocoder.rag.token_counter import count_tokens
15
+ from autocoder.utils import llms as llm_utils
16
+ from autocoder.common import SourceCodeList
17
+ from autocoder.memory.active_context_manager import ActiveContextManager
18
+
19
+
20
+
21
+ class CodeAutoGenerateEditBlock:
22
+ def __init__(
23
+ self,
24
+ llm: byzerllm.ByzerLLM,
25
+ args: AutoCoderArgs,
26
+ action=None,
27
+ fence_0: str = "```",
28
+ fence_1: str = "```",
29
+ ) -> None:
30
+ self.llm = llm
31
+ self.args = args
32
+ self.action = action
33
+ self.fence_0 = fence_0
34
+ self.fence_1 = fence_1
35
+ self.generate_times_same_model = args.generate_times_same_model
36
+ if not self.llm:
37
+ raise ValueError(
38
+ "Please provide a valid model instance to use for code generation."
39
+ )
40
+ self.llms = self.llm.get_sub_client("code_model") or [self.llm]
41
+ if not isinstance(self.llms, list):
42
+ self.llms = [self.llms]
43
+
44
+
45
+ @byzerllm.prompt()
46
+ def single_round_instruction(self, instruction: str,
47
+ content: str,
48
+ context: str = "",
49
+ package_context: str = ""
50
+ ) -> str:
51
+ """
52
+ 如果你需要生成代码,对于每个需要更改的文件,你需要按 *SEARCH/REPLACE block* 的格式进行生成。
53
+
54
+ # *SEARCH/REPLACE block* Rules:
55
+
56
+ Every *SEARCH/REPLACE block* must use this format:
57
+ 1. The opening fence and code language, eg: {{ fence_0 }}python
58
+ 2. The file path alone on a line, starting with "##File:" and verbatim. No bold asterisks, no quotes around it, no escaping of characters, etc.
59
+ 3. The start of search block: <<<<<<< SEARCH
60
+ 4. A contiguous chunk of lines to search for in the existing source code
61
+ 5. The dividing line: =======
62
+ 6. The lines to replace into the source code
63
+ 7. The end of the replace block: >>>>>>> REPLACE
64
+ 8. The closing fence: {{ fence_1 }}
65
+
66
+ Every *SEARCH* section must *EXACTLY MATCH* the existing source code, character for character, including all comments, docstrings, etc.
67
+
68
+ *SEARCH/REPLACE* blocks will replace *all* matching occurrences.
69
+ Include enough lines to make the SEARCH blocks unique.
70
+
71
+ Include *ALL* the code being searched and replaced!
72
+
73
+ To move code within a file, use 2 *SEARCH/REPLACE* blocks: 1 to delete it from its current location, 1 to insert it in the new location.
74
+
75
+ If you want to put code in a new file, use a *SEARCH/REPLACE block* with:
76
+ - A new file path, including dir name if needed
77
+ - An empty `SEARCH` section
78
+ - The new file's contents in the `REPLACE` section
79
+
80
+ ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
81
+
82
+ 下面我们来看一个例子:
83
+
84
+ 当前项目目录结构:
85
+ 1. 项目根目录: /tmp/projects/mathweb
86
+ 2. 项目子目录/文件列表(类似tree 命令输出)
87
+ flask/
88
+ app.py
89
+ templates/
90
+ index.html
91
+ static/
92
+ style.css
93
+
94
+ 用户需求: Change get_factorial() to use math.factorial
95
+
96
+ 回答: To make this change we need to modify `/tmp/projects/mathweb/flask/app.py` to:
97
+
98
+ 1. Import the math package.
99
+ 2. Remove the existing factorial() function.
100
+ 3. Update get_factorial() to call math.factorial instead.
101
+
102
+ Here are the *SEARCH/REPLACE* blocks:
103
+
104
+ {{ fence_0 }}python
105
+ ##File: /tmp/projects/mathweb/flask/app.py
106
+ <<<<<<< SEARCH
107
+ from flask import Flask
108
+ =======
109
+ import math
110
+ from flask import Flask
111
+ >>>>>>> REPLACE
112
+ {{ fence_1 }}
113
+
114
+ {{ fence_0 }}python
115
+ ##File: /tmp/projects/mathweb/flask/app.py
116
+ <<<<<<< SEARCH
117
+ def factorial(n):
118
+ "compute factorial"
119
+
120
+ if n == 0:
121
+ return 1
122
+ else:
123
+ return n * factorial(n-1)
124
+
125
+ =======
126
+ >>>>>>> REPLACE
127
+ {{ fence_1 }}
128
+
129
+ {{ fence_0 }}python
130
+ ##File: /tmp/projects/mathweb/flask/app.py
131
+ <<<<<<< SEARCH
132
+ return str(factorial(n))
133
+ =======
134
+ return str(math.factorial(n))
135
+ >>>>>>> REPLACE
136
+ {{ fence_1 }}
137
+
138
+ 用户需求: Refactor hello() into its own file.
139
+
140
+ 回答:To make this change we need to modify `main.py` and make a new file `hello.py`:
141
+
142
+ 1. Make a new hello.py file with hello() in it.
143
+ 2. Remove hello() from main.py and replace it with an import.
144
+
145
+ Here are the *SEARCH/REPLACE* blocks:
146
+
147
+ {{ fence_0 }}python
148
+ ##File: /tmp/projects/mathweb/hello.py
149
+ <<<<<<< SEARCH
150
+ =======
151
+ def hello():
152
+ "print a greeting"
153
+
154
+ print("hello")
155
+ >>>>>>> REPLACE
156
+ {{ fence_1 }}
157
+
158
+ {{ fence_0 }}python
159
+ ##File: /tmp/projects/mathweb/main.py
160
+ <<<<<<< SEARCH
161
+ def hello():
162
+ "print a greeting"
163
+
164
+ print("hello")
165
+ =======
166
+ from hello import hello
167
+ >>>>>>> REPLACE
168
+ {{ fence_1 }}
169
+
170
+ 现在让我们开始一个新的任务:
171
+
172
+ {%- if structure %}
173
+ {{ structure }}
174
+ {%- endif %}
175
+
176
+ {%- if content %}
177
+ 下面是一些文件路径以及每个文件对应的源码:
178
+ <files>
179
+ {{ content }}
180
+ </files>
181
+ {%- endif %}
182
+
183
+ {%- if package_context %}
184
+ 下面是上面文件的一些信息(包括最近的变更情况):
185
+ <package_context>
186
+ {{ package_context }}
187
+ </package_context>
188
+ {%- endif %}
189
+
190
+ {%- if context %}
191
+ <extra_context>
192
+ {{ context }}
193
+ </extra_context>
194
+ {%- endif %}
195
+
196
+ 下面是用户的需求:
197
+
198
+ {{ instruction }}
199
+
200
+ """
201
+ if not self.args.include_project_structure:
202
+ return {
203
+ "structure": "",
204
+ "fence_0": self.fence_0,
205
+ "fence_1": self.fence_1,
206
+ }
207
+
208
+ return {
209
+ "structure": (
210
+ self.action.pp.get_tree_like_directory_structure()
211
+ if self.action
212
+ else ""
213
+ ),
214
+ "fence_0": self.fence_0,
215
+ "fence_1": self.fence_1,
216
+ }
217
+
218
+ def single_round_run(
219
+ self, query: str, source_code_list: SourceCodeList
220
+ ) -> CodeGenerateResult:
221
+
222
+ # Apply model filter for code_llm
223
+ printer = Printer()
224
+ for llm in self.llms:
225
+ model_filter = ModelPathFilter.from_model_object(llm, self.args)
226
+ filtered_sources = []
227
+ for source in source_code_list.sources:
228
+ if model_filter.is_accessible(source.module_name):
229
+ filtered_sources.append(source)
230
+ else:
231
+ printer.print_in_terminal("index_file_filtered",
232
+ style="yellow",
233
+ file_path=source.module_name,
234
+ model_name=",".join(llm_utils.get_llm_names(llm)))
235
+
236
+ source_code_list = SourceCodeList(filtered_sources)
237
+
238
+ llm_config = {"human_as_model": self.args.human_as_model}
239
+
240
+ source_content = source_code_list.to_str()
241
+
242
+ active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
243
+
244
+ # 获取包上下文信息
245
+ package_context = ""
246
+
247
+ if self.args.enable_active_context:
248
+ # 获取活动上下文信息
249
+ result = active_context_manager.load_active_contexts_for_files(
250
+ [source.module_name for source in source_code_list.sources]
251
+ )
252
+ # 将活动上下文信息格式化为文本
253
+ if result.contexts:
254
+ package_context_parts = []
255
+ for dir_path, context in result.contexts.items():
256
+ package_context_parts.append(f"<package_info>{context.content}</package_info>")
257
+
258
+ package_context = "\n".join(package_context_parts)
259
+
260
+ init_prompt = self.single_round_instruction.prompt(
261
+ instruction=query, content=source_content, context=self.args.context,
262
+ package_context=package_context
263
+ )
264
+
265
+ with open(self.args.target_file, "w",encoding="utf-8") as file:
266
+ file.write(init_prompt)
267
+
268
+ conversations = []
269
+
270
+ if self.args.system_prompt and self.args.system_prompt.strip() == "claude":
271
+ conversations.append(
272
+ {"role": "system", "content": sys_prompt.claude_sys_prompt.prompt()})
273
+ elif self.args.system_prompt:
274
+ conversations.append(
275
+ {"role": "system", "content": self.args.system_prompt})
276
+
277
+ conversations.append({"role": "user", "content": init_prompt})
278
+
279
+ conversations_list = []
280
+ results = []
281
+ input_tokens_count = 0
282
+ generated_tokens_count = 0
283
+
284
+ input_tokens_cost = 0
285
+ generated_tokens_cost = 0
286
+
287
+ model_names = []
288
+
289
+ printer = Printer()
290
+ estimated_input_tokens = count_tokens(
291
+ json.dumps(conversations, ensure_ascii=False))
292
+ printer.print_in_terminal("estimated_input_tokens_in_generate",
293
+ style="yellow",
294
+ estimated_input_tokens_in_generate=estimated_input_tokens,
295
+ generate_mode="editblock"
296
+ )
297
+
298
+ if not self.args.human_as_model:
299
+ with ThreadPoolExecutor(max_workers=len(self.llms) * self.generate_times_same_model) as executor:
300
+ futures = []
301
+ for llm in self.llms:
302
+
303
+ model_names_list = llm_utils.get_llm_names(llm)
304
+ model_name = None
305
+ if model_names_list:
306
+ model_name = model_names_list[0]
307
+
308
+ for i in range(self.generate_times_same_model):
309
+ model_names.append(model_name)
310
+ if i==0:
311
+ def job():
312
+ stream_generator = stream_chat_with_continue(
313
+ llm=llm,
314
+ conversations=conversations,
315
+ llm_config=llm_config,
316
+ args=self.args
317
+ )
318
+ full_response, last_meta = stream_out(
319
+ stream_generator,
320
+ model_name=model_name,
321
+ title=get_message_with_format(
322
+ "code_generate_title", model_name=model_name),
323
+ args=self.args,
324
+ extra_meta={
325
+ "stream_out_type": CodeGenerateStreamOutType.CODE_GENERATE.value
326
+ })
327
+ return ChatWithContinueResult(
328
+ content=full_response,
329
+ input_tokens_count=last_meta.input_tokens_count,
330
+ generated_tokens_count=last_meta.generated_tokens_count
331
+ )
332
+ futures.append(executor.submit(job))
333
+ else:
334
+ futures.append(executor.submit(
335
+ chat_with_continue,
336
+ llm=llm,
337
+ conversations=conversations,
338
+ llm_config=llm_config,
339
+ args=self.args
340
+ ))
341
+
342
+ temp_results = [future.result() for future in futures]
343
+
344
+ for result,model_name in zip(temp_results,model_names):
345
+ results.append(result.content)
346
+ input_tokens_count += result.input_tokens_count
347
+ generated_tokens_count += result.generated_tokens_count
348
+ model_info = llm_utils.get_model_info(model_name,self.args.product_mode)
349
+ input_cost = model_info.get("input_price", 0) if model_info else 0
350
+ output_cost = model_info.get("output_price", 0) if model_info else 0
351
+ input_tokens_cost += input_cost * result.input_tokens_count / 1000000
352
+ generated_tokens_cost += output_cost * result.generated_tokens_count / 1000000
353
+
354
+ for result in results:
355
+ conversations_list.append(
356
+ conversations + [{"role": "assistant", "content": result}])
357
+ else:
358
+ for _ in range(self.args.human_model_num):
359
+ single_result = chat_with_continue(
360
+ llm=self.llms[0],
361
+ conversations=conversations,
362
+ llm_config=llm_config,
363
+ args=self.args
364
+ )
365
+ results.append(single_result.content)
366
+ input_tokens_count += single_result.input_tokens_count
367
+ generated_tokens_count += single_result.generated_tokens_count
368
+ conversations_list.append(
369
+ conversations + [{"role": "assistant", "content": single_result.content}])
370
+
371
+ statistics = {
372
+ "input_tokens_count": input_tokens_count,
373
+ "generated_tokens_count": generated_tokens_count,
374
+ "input_tokens_cost": input_tokens_cost,
375
+ "generated_tokens_cost": generated_tokens_cost
376
+ }
377
+
378
+ return CodeGenerateResult(contents=results, conversations=conversations_list, metadata=statistics)
379
+
380
+
@@ -0,0 +1,269 @@
1
+ from typing import List, Dict, Tuple
2
+ from autocoder.common.types import Mode, CodeGenerateResult
3
+ from autocoder.common import AutoCoderArgs
4
+ import byzerllm
5
+ from autocoder.common import sys_prompt
6
+ from autocoder.common.v2.code_auto_generate import CodeAutoGenerate
7
+ from autocoder.common import SourceCodeList
8
+
9
+ class CodeAutoGenerateStrictDiff(CodeAutoGenerate):
10
+ """
11
+ A class that handles code generation in strict diff format.
12
+ """
13
+
14
+ @byzerllm.prompt(llm=lambda self: self.llm)
15
+ def single_round_instruction(
16
+ self, instruction: str, content: str, context: str = "", package_context: str = ""
17
+ ) -> str:
18
+ """
19
+ 如果你需要生成代码,对于每个需要更改的文件,写出类似于 unified diff 的更改,就像`diff -U0`会产生的那样。
20
+ 下面是一些生成diff的要求:
21
+ Make sure you include the first 2 lines with the file paths.
22
+ Don't include timestamps with the file paths.
23
+
24
+ Start each hunk of changes with a `@@ ... @@` line.
25
+ Must include line numbers like `diff -U0` does.
26
+ The user's patch tool need them.
27
+
28
+ The user's patch tool needs CORRECT patches that apply cleanly against the current contents of the file!
29
+ Think carefully and make sure you include and mark all lines that need to be removed or changed as `-` lines.
30
+ Make sure you mark all new or modified lines with `+`.
31
+ Don't leave out any lines or the diff patch won't apply correctly.
32
+
33
+ Indentation matters in the diffs!
34
+
35
+ To make a new file, show a diff from `--- /dev/null` to `+++ path/to/new/file.ext`.
36
+ The code part of the diff content should not contains any line number.
37
+
38
+ The path start with `---` or `+++` should be the absolute path of the file or relative path from the project root.
39
+
40
+ 下面我们来看一个例子:
41
+
42
+ 当前项目目录结构:
43
+ 1. 项目根目录: /tmp/projects/mathweb
44
+ 2. 项目子目录/文件列表(类似tree 命令输出)
45
+ flask/
46
+ app.py
47
+ templates/
48
+ index.html
49
+ static/
50
+ style.css
51
+
52
+ 用户需求: 请将下面的代码中的is_prime()函数替换为sympy。
53
+ 回答:
54
+ 好的,我会先罗列出需要的修改步骤,然后再列出diff。
55
+ 修改步骤:
56
+ 1. 添加sympy的import 语句。
57
+ 2. 删除is_prime()函数。
58
+ 3. 将现有对is_prime()的调用替换为sympy.isprime()。
59
+
60
+ 下面是这些变更的diff:
61
+
62
+ ```diff
63
+ --- /tmp/projects/mathweb/flask/app.py
64
+ +++ /tmp/projects/mathweb/flask/app.py
65
+ @@ ... @@
66
+ -class MathWeb:
67
+ +import sympy
68
+ +
69
+ +class MathWeb:
70
+ @@ ... @@
71
+ -def is_prime(x):
72
+ - if x < 2:
73
+ - return False
74
+ - for i in range(2, int(math.sqrt(x)) + 1):
75
+ - if x % i == 0:
76
+ - return False
77
+ - return True
78
+ @@ ... @@
79
+ -@app.route('/prime/<int:n>')
80
+ -def nth_prime(n):
81
+ - count = 0
82
+ - num = 1
83
+ - while count < n:
84
+ - num += 1
85
+ - if is_prime(num):
86
+ - count += 1
87
+ - return str(num)
88
+ +@app.route('/prime/<int:n>')
89
+ +def nth_prime(n):
90
+ + count = 0
91
+ + num = 1
92
+ + while count < n:
93
+ + num += 1
94
+ + if sympy.isprime(num):
95
+ + count += 1
96
+ + return str(num)
97
+ ```
98
+
99
+ 现在让我们开始一个新的任务:
100
+
101
+ {%- if structure %}
102
+ {{ structure }}
103
+ {%- endif %}
104
+
105
+ {%- if content %}
106
+ 下面是一些文件路径以及每个文件对应的源码:
107
+ <files>
108
+ {{ content }}
109
+ </files>
110
+ {%- endif %}
111
+
112
+ {%- if package_context %}
113
+ 下面是上面文件的一些信息(包括最近的变更情况):
114
+ <package_context>
115
+ {{ package_context }}
116
+ </package_context>
117
+ {%- endif %}
118
+
119
+ {%- if context %}
120
+ <extra_context>
121
+ {{ context }}
122
+ </extra_context>
123
+ {%- endif %}
124
+
125
+ 下面是用户的需求:
126
+
127
+ {{ instruction }}
128
+ """
129
+
130
+ if not self.args.include_project_structure:
131
+ return {
132
+ "structure": "",
133
+ }
134
+
135
+ return {
136
+ "structure": (
137
+ self.action.pp.get_tree_like_directory_structure()
138
+ if self.action
139
+ else ""
140
+ )
141
+ }
142
+
143
+ @byzerllm.prompt(llm=lambda self: self.llm)
144
+ def multi_round_instruction(
145
+ self, instruction: str, content: str, context: str = "", package_context: str = ""
146
+ ) -> str:
147
+ """
148
+ 如果你需要生成代码,对于每个需要更改的文件,写出类似于 unified diff 的更改,就像`diff -U0`会产生的那样。
149
+ 下面是一些生成diff的要求:
150
+ Make sure you include the first 2 lines with the file paths.
151
+ Don't include timestamps with the file paths.
152
+
153
+ Start each hunk of changes with a `@@ ... @@` line.
154
+ Must include line numbers like `diff -U0` does.
155
+ The user's patch tool need them.
156
+
157
+ The user's patch tool needs CORRECT patches that apply cleanly against the current contents of the file!
158
+ Think carefully and make sure you include and mark all lines that need to be removed or changed as `-` lines.
159
+ Make sure you mark all new or modified lines with `+`.
160
+ Don't leave out any lines or the diff patch won't apply correctly.
161
+
162
+ Indentation matters in the diffs!
163
+
164
+ To make a new file, show a diff from `--- /dev/null` to `+++ path/to/new/file.ext`.
165
+
166
+ 下面我们来看一个例子:
167
+
168
+ 当前项目目录结构:
169
+ 1. 项目根目录: /tmp/projects/mathweb
170
+ 2. 项目子目录/文件列表(类似tree 命令输出)
171
+ flask/
172
+ app.py
173
+ templates/
174
+ index.html
175
+ static/
176
+ style.css
177
+
178
+ 用户需求: 请将下面的代码中的is_prime()函数替换为sympy。
179
+ 回答:
180
+ 好的,我会先罗列出需要的修改步骤,然后再列出diff。
181
+ 修改步骤:
182
+ 1. 添加sympy的import 语句。
183
+ 2. 删除is_prime()函数。
184
+ 3. 将现有对is_prime()的调用替换为sympy.isprime()。
185
+
186
+ 下面是这些变更的diff:
187
+
188
+ ```diff
189
+ --- /tmp/projects/mathweb/flask/app.py
190
+ +++ /tmp/projects/mathweb/flask/app.py
191
+ @@ ... @@
192
+ -class MathWeb:
193
+ +import sympy
194
+ +
195
+ +class MathWeb:
196
+ @@ ... @@
197
+ -def is_prime(x):
198
+ - if x < 2:
199
+ - return False
200
+ - for i in range(2, int(math.sqrt(x)) + 1):
201
+ - if x % i == 0:
202
+ - return False
203
+ - return True
204
+ @@ ... @@
205
+ -@app.route('/prime/<int:n>')
206
+ -def nth_prime(n):
207
+ - count = 0
208
+ - num = 1
209
+ - while count < n:
210
+ - num += 1
211
+ - if is_prime(num):
212
+ - count += 1
213
+ - return str(num)
214
+ +@app.route('/prime/<int:n>')
215
+ +def nth_prime(n):
216
+ + count = 0
217
+ + num = 1
218
+ + while count < n:
219
+ + num += 1
220
+ + if sympy.isprime(num):
221
+ + count += 1
222
+ + return str(num)
223
+ ```
224
+
225
+ 现在让我们开始一个新的任务:
226
+
227
+ {%- if structure %}
228
+ {{ structure }}
229
+ {%- endif %}
230
+
231
+ {%- if content %}
232
+ 下面是一些文件路径以及每个文件对应的源码:
233
+ <files>
234
+ {{ content }}
235
+ </files>
236
+ {%- endif %}
237
+
238
+ {%- if package_context %}
239
+ 下面是上面文件的一些信息(包括最近的变更情况):
240
+ <package_context>
241
+ {{ package_context }}
242
+ </package_context>
243
+ {%- endif %}
244
+
245
+ {%- if context %}
246
+ <extra_context>
247
+ {{ context }}
248
+ </extra_context>
249
+ {%- endif %}
250
+
251
+ 下面是用户的需求:
252
+
253
+ {{ instruction }}
254
+
255
+ 每次生成一个文件的diff,然后询问我是否继续,当我回复继续,继续生成下一个文件的diff。当没有后续任务时,请回复 "__完成__" 或者 "__EOF__"。
256
+ """
257
+
258
+ if not self.args.include_project_structure:
259
+ return {
260
+ "structure": "",
261
+ }
262
+
263
+ return {
264
+ "structure": (
265
+ self.action.pp.get_tree_like_directory_structure()
266
+ if self.action
267
+ else ""
268
+ )
269
+ }