auto-coder 0.1.265__py3-none-any.whl → 0.1.267__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-coder
3
- Version: 0.1.265
3
+ Version: 0.1.267
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -26,7 +26,7 @@ Requires-Dist: tabulate
26
26
  Requires-Dist: jupyter-client
27
27
  Requires-Dist: prompt-toolkit
28
28
  Requires-Dist: tokenizers
29
- Requires-Dist: byzerllm[saas] >=0.1.167
29
+ Requires-Dist: byzerllm[saas] >=0.1.168
30
30
  Requires-Dist: patch
31
31
  Requires-Dist: diff-match-patch
32
32
  Requires-Dist: GitPython
@@ -6,12 +6,12 @@ autocoder/auto_coder_rag_client_mcp.py,sha256=QRxUbjc6A8UmDMQ8lXgZkjgqtq3lgKYeat
6
6
  autocoder/auto_coder_rag_mcp.py,sha256=-RrjNwFaS2e5v8XDIrKR-zlUNUE8UBaeOtojffBrvJo,8521
7
7
  autocoder/auto_coder_server.py,sha256=6YQweNEKUrGAZ3yPvw8_qlNZJYLVSVUXGrn1K6udLts,20413
8
8
  autocoder/benchmark.py,sha256=Ypomkdzd1T3GE6dRICY3Hj547dZ6_inqJbBJIp5QMco,4423
9
- autocoder/chat_auto_coder.py,sha256=fX_VusqljMF6Mq4TIrnFEehksHlJzc_g9S-5ctOXVbk,114803
9
+ autocoder/chat_auto_coder.py,sha256=Yjffft2Jf5JRId8Mo6INQrP15FMruLKe-yNailgz9Sw,115956
10
10
  autocoder/chat_auto_coder_lang.py,sha256=ShOQVOnMA-WlT-fB9OrOer-xQkbcWxJGl-WMPuZcUkM,19572
11
11
  autocoder/command_args.py,sha256=9aYJ-AmPxP1sQh6ciw04FWHjSn31f2W9afXFwo8wgx4,30441
12
12
  autocoder/lang.py,sha256=U6AjVV8Rs1uLyjFCZ8sT6WWuNUxMBqkXXIOs4S120uk,14511
13
13
  autocoder/models.py,sha256=PlG1tKHSHwB57cKLOl5gTl5yTzFUDzCgeHPJU3N9F6Q,9106
14
- autocoder/version.py,sha256=EntDFQhTLlfrujVHW6wuw1ZG6qiMaNd9zEEox9wX600,23
14
+ autocoder/version.py,sha256=eccgJdJnqL5jdebuoipWOlGDIDOxofuVodEEObY4SUg,23
15
15
  autocoder/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  autocoder/agent/auto_demand_organizer.py,sha256=NWSAEsEk94vT3lGjfo25kKLMwYdPcpy9e-i21txPasQ,6942
17
17
  autocoder/agent/auto_filegroup.py,sha256=CW7bqp0FW1GIEMnl-blyAc2UGT7O9Mom0q66ITz1ckM,6635
@@ -24,7 +24,7 @@ autocoder/agent/planner.py,sha256=SZTSZHxHzDmuWZo3K5fs79RwvJLWurg-nbJRRNbX65o,91
24
24
  autocoder/agent/project_reader.py,sha256=tWLaPoLw1gI6kO_NzivQj28KbobU2ceOLuppHMbfGl8,18234
25
25
  autocoder/chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  autocoder/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- autocoder/commands/auto_command.py,sha256=AgKgjPixxiCGbtrOZ88r069-6uQ_SuPSwqXncwxOhtA,51798
27
+ autocoder/commands/auto_command.py,sha256=Pz2srP9TAFV86o-2CbXQ7o6nAkt1yVmNna9d5tzjtBM,52660
28
28
  autocoder/commands/tools.py,sha256=xDhGD1jRN67fGfeck33pM74TxXlAMeo49S3Q9K-VKco,20107
29
29
  autocoder/common/JupyterClient.py,sha256=O-wi6pXeAEYhAY24kDa0BINrLYvKS6rKyWe98pDClS0,2816
30
30
  autocoder/common/ShellClient.py,sha256=fM1q8t_XMSbLBl2zkCNC2J9xuyKN3eXzGm6hHhqL2WY,2286
@@ -32,8 +32,8 @@ autocoder/common/__init__.py,sha256=eH5NyEsiCzJaNzsxI-Y8TJbB5kpFzuwBgbTrWz9Uthk,
32
32
  autocoder/common/anything2images.py,sha256=0ILBbWzY02M-CiWB-vzuomb_J1hVdxRcenAfIrAXq9M,25283
33
33
  autocoder/common/anything2img.py,sha256=4TREa-sOA-iargieUy7MpyCYVUE-9Mmq0wJtwomPqnE,7662
34
34
  autocoder/common/audio.py,sha256=Kn9nWKQddWnUrAz0a_ZUgjcu4VUU_IcZBigT7n3N3qc,7439
35
- autocoder/common/auto_coder_lang.py,sha256=sAHM_ne0oy49iLuO1fdzRHLVTvolyVVoeBSF25nWClM,28874
36
- autocoder/common/auto_configure.py,sha256=tdEwfycZUjomZAgps1GOCtocYEtfuUgRksYPFHBP_bs,12211
35
+ autocoder/common/auto_coder_lang.py,sha256=z_tI1eNJQiSRy_RL-x4KeQDByGvUE4OJxthoTkBXKyQ,29125
36
+ autocoder/common/auto_configure.py,sha256=y0fTplwUdtzVF91iOdZh8zl10MdYFjAquO_Kmj1BWqs,12300
37
37
  autocoder/common/buildin_tokenizer.py,sha256=L7d5t39ZFvUd6EoMPXUhYK1toD0FHlRH1jtjKRGokWU,1236
38
38
  autocoder/common/chunk_validation.py,sha256=BrR_ZWavW8IANuueEE7hS8NFAwEvm8TX34WnPx_1hs8,3030
39
39
  autocoder/common/cleaner.py,sha256=NU72i8C6o9m0vXExab7nao5bstBUsfJFcj11cXa9l4U,1089
@@ -43,9 +43,9 @@ autocoder/common/code_auto_generate_diff.py,sha256=EYGHf24fVAk3M8kXllXukdUvzo2I2
43
43
  autocoder/common/code_auto_generate_editblock.py,sha256=1XmoLZl-XrrPOyHkSfqe0pOxi0Lp4d69oDQX6zzqs_c,20523
44
44
  autocoder/common/code_auto_generate_strict_diff.py,sha256=68fAks4S6Hz0wAeXrdI1PjdeCiy0gXRhgEeIlgxB04E,17539
45
45
  autocoder/common/code_auto_merge.py,sha256=cMEX44QT59iMPEo5B8OQKU9fAzn4iIahEPk2n3rNFvg,8643
46
- autocoder/common/code_auto_merge_diff.py,sha256=6jy4udNovMKq0MNhjiU4wZzX-wzRWVVLBkD0qLFZhKY,16799
47
- autocoder/common/code_auto_merge_editblock.py,sha256=B5lNgUKu9xJXx_H_6BiGdc49Yc-2MQCPHiC4tEo1tos,18801
48
- autocoder/common/code_auto_merge_strict_diff.py,sha256=n-szSE3ye07tB-5SFUVC7PrsL_7Y2qJ9C6yMKbPrd1s,10854
46
+ autocoder/common/code_auto_merge_diff.py,sha256=jl6rYvioAuN5CWaYRPY4uBFKsDB0_yW6g6KeVlIxPJA,17948
47
+ autocoder/common/code_auto_merge_editblock.py,sha256=D8petP0X74lScsVktFXEQ4_9u5UDVBRDFF16nkjWGZg,20310
48
+ autocoder/common/code_auto_merge_strict_diff.py,sha256=VxasaD8IcxOEEilXmxT0WeLLA16JDlvvI7cV5GyyHAI,12086
49
49
  autocoder/common/code_modification_ranker.py,sha256=sRNIPIsQP8FucxSuBeAHKJ7RWB_iB5Pb_cd0BAhvgGc,10926
50
50
  autocoder/common/command_completer.py,sha256=Nw_EFXLDuVXbOKGlmzTODNRJUV9mSUEWV73GUmO_WLw,35166
51
51
  autocoder/common/command_generator.py,sha256=Je7OKJvyzeb4krdEspUJx2tyM2tjk-PkNpkc6bZ7PbA,2563
@@ -93,14 +93,14 @@ autocoder/dispacher/actions/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
93
93
  autocoder/dispacher/actions/plugins/action_regex_project.py,sha256=AqGIkjbqV1eOS3vBoZUTSOpyOlkv1p5h35mI2Kcvekw,6906
94
94
  autocoder/dispacher/actions/plugins/action_translate.py,sha256=GEn7dZA22jy5WyzINomjmzzB795p2Olg-CJla97lRF8,7744
95
95
  autocoder/index/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
- autocoder/index/entry.py,sha256=XCq1GCBq1mDK8xo35VzixTwodx4mPytY0gqPoz6EvzU,13401
96
+ autocoder/index/entry.py,sha256=WsJrOf586GAiHacFCdcXQx5MmGKQXIIeEqo5h46AHpE,13474
97
97
  autocoder/index/for_command.py,sha256=BFvljE4t6VaMBGboZAuhUCzVK0EitCy_n5D_7FEnihw,3204
98
98
  autocoder/index/index.py,sha256=lott5kcNN0Q5iyfl2dgkOSeDnsMpODKVWV3H54ISaiI,25507
99
99
  autocoder/index/symbols_utils.py,sha256=_EP7E_qWXxluAxq3FGZLlLfdrfwx3FmxCdulI8VGuac,2244
100
100
  autocoder/index/types.py,sha256=a2s_KV5FJlq7jqA2ELSo9E1sjuLwDB-JJYMhSpzBAhU,596
101
101
  autocoder/index/filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
- autocoder/index/filter/normal_filter.py,sha256=QrG3YJU5F9CjmVm6kjfce_3_pYhvw_Q65betD0Vhryg,8356
103
- autocoder/index/filter/quick_filter.py,sha256=FL-Hn8Cz0IC4e752dKpOKLXO92V7yOGl_crFmRGqwhE,22552
102
+ autocoder/index/filter/normal_filter.py,sha256=MI-8xdXCrniaxYCHVTLkq5tafvcUiauD3LN0b3ymRXI,8361
103
+ autocoder/index/filter/quick_filter.py,sha256=D6B8zz9TGAFPOp-OBm7UwuAEtg1DYQ8jEq4tHgZocbo,22572
104
104
  autocoder/privacy/__init__.py,sha256=LnIVvGu_K66zCE-yhN_-dPO8R80pQyedCsXJ7wRqQaI,72
105
105
  autocoder/privacy/model_filter.py,sha256=-N9ZvxxDKpxU7hkn-tKv-QHyXjvkCopUaKgvJwTOGQs,3369
106
106
  autocoder/pyproject/__init__.py,sha256=ms-A_pocgGv0oZPEW8JAdXi7G-VSVhkQ6CnWFe535Ec,14477
@@ -161,9 +161,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
161
  autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
162
  autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=lkJ_A-sYU36JMzjFWkk3pR6uos8oZHYt9GPsPe_CPAo,11766
163
163
  autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
- auto_coder-0.1.265.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
165
- auto_coder-0.1.265.dist-info/METADATA,sha256=LhsjMk8LZ10QZiODlTP-iZ9uvGmw32G07-hzcv1mDAg,2616
166
- auto_coder-0.1.265.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
167
- auto_coder-0.1.265.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
168
- auto_coder-0.1.265.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
169
- auto_coder-0.1.265.dist-info/RECORD,,
164
+ auto_coder-0.1.267.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
165
+ auto_coder-0.1.267.dist-info/METADATA,sha256=QYBe3pOuKPfbkK5A91iCVBoyj5L8MJsaBFyk51MMolQ,2616
166
+ auto_coder-0.1.267.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
167
+ auto_coder-0.1.267.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
168
+ auto_coder-0.1.267.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
169
+ auto_coder-0.1.267.dist-info/RECORD,,
@@ -133,8 +133,7 @@ commands = [
133
133
  "/index/build",
134
134
  "/index/export",
135
135
  "/index/import",
136
- "/exclude_dirs",
137
- "/exclude_files",
136
+ "/exclude_files",
138
137
  "/help",
139
138
  "/shell",
140
139
  "/voice_input",
@@ -148,6 +147,7 @@ commands = [
148
147
  "/auto",
149
148
  "/conf/export",
150
149
  "/conf/import",
150
+ "/exclude_dirs",
151
151
  ]
152
152
 
153
153
 
@@ -2284,10 +2284,44 @@ def exclude_dirs(dir_names: List[str]):
2284
2284
  save_memory()
2285
2285
  completer.refresh_files()
2286
2286
 
2287
- def exclude_files(file_patterns: List[str]):
2287
+ def exclude_files(query: str):
2288
2288
  result_manager = ResultManager()
2289
2289
  printer = Printer()
2290
- new_file_patterns = file_patterns
2290
+ if "/list" in query:
2291
+ query = query.replace("/list", "", 1).strip()
2292
+ existing_file_patterns = memory.get("exclude_files", [])
2293
+ console = Console()
2294
+ # 打印表格
2295
+ table = Table(title="Exclude Files")
2296
+ table.add_column("File Pattern")
2297
+ for file_pattern in existing_file_patterns:
2298
+ table.add_row(file_pattern)
2299
+ console.print(table)
2300
+ result_manager.add_result(content=f"Exclude files: {existing_file_patterns}",meta={
2301
+ "action": "exclude_files",
2302
+ "input": {
2303
+ "query": query
2304
+ }
2305
+ })
2306
+ return
2307
+
2308
+ if "/drop" in query:
2309
+ query = query.replace("/drop", "", 1).strip()
2310
+ existing_file_patterns = memory.get("exclude_files", [])
2311
+ existing_file_patterns.remove(query.strip())
2312
+ memory["exclude_files"] = existing_file_patterns
2313
+ save_memory()
2314
+ completer.refresh_files()
2315
+ result_manager.add_result(content=f"Dropped exclude files: {query}",meta={
2316
+ "action": "exclude_files",
2317
+ "input": {
2318
+ "query": query
2319
+ }
2320
+ })
2321
+ return
2322
+
2323
+ new_file_patterns = query.strip().split(",")
2324
+
2291
2325
  existing_file_patterns = memory.get("exclude_files", [])
2292
2326
  file_patterns_to_add = [f for f in new_file_patterns if f not in existing_file_patterns]
2293
2327
 
@@ -2383,7 +2417,7 @@ def help(query: str):
2383
2417
  args = get_final_config()
2384
2418
  product_mode = memory.get("product_mode", "lite")
2385
2419
  llm = get_single_llm(args.chat_model or args.model, product_mode=product_mode)
2386
- auto_config_tuner = ConfigAutoTuner(llm=llm, memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory))
2420
+ auto_config_tuner = ConfigAutoTuner(args=args, llm=llm, memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory))
2387
2421
  auto_config_tuner.tune(AutoConfigRequest(query=query))
2388
2422
 
2389
2423
  @run_in_raw_thread()
@@ -2924,9 +2958,8 @@ def main():
2924
2958
  exclude_dirs(dir_names)
2925
2959
 
2926
2960
  elif user_input.startswith("/exclude_files"):
2927
- file_patterns = user_input[len(
2928
- "/exclude_files"):].strip().split(",")
2929
- exclude_files(file_patterns)
2961
+ query = user_input[len("/exclude_files"):].strip()
2962
+ exclude_files(query)
2930
2963
 
2931
2964
  elif user_input.startswith("/ask"):
2932
2965
  query = user_input[len("/ask"):].strip()
@@ -302,8 +302,7 @@ class CommandAutoTuner:
302
302
  # 提取 JSON 并转换为 AutoCommandResponse
303
303
  try:
304
304
  response = to_model(content, AutoCommandResponse)
305
- if response.suggestions:
306
- print(response)
305
+ if response.suggestions:
307
306
  command = response.suggestions[0].command
308
307
  parameters = response.suggestions[0].parameters
309
308
  if parameters:
@@ -507,11 +506,21 @@ class CommandAutoTuner:
507
506
  如果你检测到用户的coding执行结果,缺少必要的文件修改,可以尝试使用该函数先添加文件再执行coding。
508
507
  </description>
509
508
  <usage>
510
- 该方法只有一个参数 args,args 是一个列表,列表的元素是字符串。会包含子指令,例如
511
-
512
- add_files(args=["/refresh"])
513
-
514
- 会刷新文件列表。下面是常见的子指令:
509
+ 该方法只有一个参数 args,args 是一个列表,列表的元素是字符串。
510
+
511
+ 如果没有包含子指令,单纯的添加文件,那么 args 列表的元素是文件路径,注意我们需要使用绝对路径。
512
+
513
+ 使用例子:
514
+
515
+ add_files(args=["/absolute/path/to/file1.py"])
516
+
517
+ 也支持glob 语法,例如:
518
+
519
+ add_files(args=["**/*.py"])
520
+
521
+ 这样会把项目根目录下的所有.py文件添加到活跃区,尽量确保少的添加文件。
522
+
523
+ 如果是有子指令,参考下面是常见的子指令说明。
515
524
 
516
525
  ## /refresh 刷新文件列表
517
526
  刷新文件列表
@@ -641,9 +650,10 @@ class CommandAutoTuner:
641
650
  ## editblock_similarity: editblock相似度阈值
642
651
  - editblock相似度阈值,取值范围为0-1,默认值为0.9。如果设置的太低,虽然能合并进去,但是会引入错误。推荐不要修改该值。
643
652
 
644
- ## generate_times_same_model: 相同模型生成次数
653
+ ## generate_times_same_model: 相同模型生成次数,也叫采样数
645
654
  当进行生成代码时,大模型会对同一个需求生成多份代码,然后会使用 generate_rerank_model 模型对多份代码进行重排序,
646
655
  然后选择得分最高的代码。一般次数越多,最终得到正确的代码概率越高。默认值为1,推荐设置为3。但是设置值越多,可能速度就越慢,消耗的token也越多。
656
+ 当用户提到,帮我采样数设置为3, 那么你就设置该参数即可。
647
657
 
648
658
  ## skip_filter_index: 是否跳过索引过滤
649
659
  是否跳过根据用户的query 自动查找上下文。推荐设置为 false
@@ -756,6 +766,8 @@ class CommandAutoTuner:
756
766
  coding(query="@auth.py 添加JWT认证")
757
767
  coding(query="@@login 优化错误处理")
758
768
  coding(query="<img>design/flow.png</img> 实现这个流程图的功能")
769
+
770
+ 在使用 coding 函数时,建议通过 ask_user 来确认是否执行 coding 函数,除非用户明确说不要询问,直接执行。
759
771
  </usage>
760
772
  </command>
761
773
 
@@ -1169,15 +1181,23 @@ class CommandAutoTuner:
1169
1181
  <name>exclude_files</name>
1170
1182
  <description>排除指定文件。</description>
1171
1183
  <usage>
1172
- 该命令接受一个参数 file_patterns, 为要排除的文件模式字符串列表。
1184
+ 该命令接受一个参数 query, 为要排除的文件模式字符串,多个文件模式用逗号分隔。
1173
1185
 
1174
1186
  使用例子,比如你想要排除 package-lock.json 文件,你可以这样调用:
1175
1187
 
1176
- exclude_files(file_patterns=["regex://.*/package-lock\.json"])
1188
+ exclude_files(query="regex://.*/package-lock\.json")
1177
1189
 
1178
1190
  注意:
1179
1191
  - 文件模式字符串必须以 regex:// 开头
1180
1192
  - regex:// 后面部分是标准的正则表达式
1193
+
1194
+ 也支持子命令:
1195
+ /list 列出当前排除的文件模式
1196
+ /drop 删除指定的文件模式
1197
+
1198
+ 使用例子:
1199
+ exclude_files(query="/list")
1200
+ exclude_files(query="/drop regex://.*/package-lock\.json")
1181
1201
  </usage>
1182
1202
  </command>
1183
1203
  </commands>
@@ -117,6 +117,7 @@ MESSAGES = {
117
117
  "quick_filter_stats": "{{ model_names }} Quick filter completed in {{ elapsed_time }} seconds, input tokens: {{ input_tokens }}, output tokens: {{ output_tokens }}, input cost: {{ input_cost }}, output cost: {{ output_cost }} speed: {{ speed }} tokens/s",
118
118
  "upsert_file": "✅ Updated file: {{ file_path }}",
119
119
  "unmerged_blocks_title": "Unmerged Blocks",
120
+ "merged_blocks_title": "Merged Changes",
120
121
  "quick_filter_title": "{{ model_name }} is analyzing how to filter context...",
121
122
  "quick_filter_failed": "❌ Quick filter failed: {{ error }}. ",
122
123
  "unmerged_file_path": "File: {{file_path}}",
@@ -157,6 +158,8 @@ MESSAGES = {
157
158
  "conf_not_found": "Configuration file not found: {{path}}",
158
159
  "index_export_success": "Index exported successfully: {{path}}",
159
160
  "index_import_success": "Index imported successfully: {{path}}",
161
+ "edits_title": "edits",
162
+ "diff_blocks_title":"diff blocks"
160
163
  },
161
164
  "zh": {
162
165
  "invalid_file_pattern": "无效的文件模式: {{file_pattern}}. 例如: regex://.*/package-lock\\.json",
@@ -273,6 +276,7 @@ MESSAGES = {
273
276
  "merge_success": "✅ 成功合并了 {{ num_files }} 个文件中的更改 {{ num_changes }}/{{ total_blocks }} 个代码块。",
274
277
  "no_changes_made": "⚠️ 未对任何文件进行更改。这个原因可能是因为coding函数生成的文本块格式有问题,导致无法合并进项目",
275
278
  "unmerged_blocks_title": "未合并代码块",
279
+ "merged_blocks_title": "合并的更改",
276
280
  "unmerged_file_path": "文件: {{file_path}}",
277
281
  "unmerged_search_block": "Search Block({{similarity}}):",
278
282
  "unmerged_replace_block": "Replace Block:",
@@ -311,6 +315,8 @@ MESSAGES = {
311
315
  "only_one_merge_result_success": "✅ 只有一个合并结果成功,返回该候选",
312
316
  "index_export_success": "索引导出成功: {{path}}",
313
317
  "index_import_success": "索引导入成功: {{path}}",
318
+ "edits_title": "编辑块",
319
+ "diff_blocks_title": "差异块",
314
320
  }}
315
321
 
316
322
 
@@ -14,6 +14,8 @@ from byzerllm.utils.str2model import to_model
14
14
  from autocoder.utils.auto_coder_utils.chat_stream_out import stream_out
15
15
  from autocoder.common.result_manager import ResultManager
16
16
  from autocoder.utils import llms as llms_utils
17
+ from autocoder.common import AutoCoderArgs
18
+
17
19
  logger = logging.getLogger(__name__)
18
20
 
19
21
  class ConfigMessage(BaseModel):
@@ -120,9 +122,10 @@ class AutoConfigResponse(BaseModel):
120
122
  reasoning: str = ""
121
123
 
122
124
  class ConfigAutoTuner:
123
- def __init__(self, llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM], memory_config: MemoryConfig):
125
+ def __init__(self,args: AutoCoderArgs, llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM], memory_config: MemoryConfig):
124
126
  self.llm = llm
125
127
  self.memory_config = memory_config
128
+ self.args = args
126
129
 
127
130
 
128
131
  def configure(self, conf: str, skip_print: bool = False) -> None:
@@ -528,6 +528,37 @@ class CodeAutoMergeDiff:
528
528
  failed_blocks=failed_blocks
529
529
  )
530
530
 
531
+ def print_edits(self, edits: List[Tuple[str, List[str]]]):
532
+ """Print diffs for user review using rich library"""
533
+ from rich.syntax import Syntax
534
+ from rich.panel import Panel
535
+
536
+ # Group edits by file path
537
+ file_edits = {}
538
+ for path, hunk in edits:
539
+ if path not in file_edits:
540
+ file_edits[path] = []
541
+ file_edits[path].append(hunk)
542
+
543
+ # Generate formatted text for each file
544
+ formatted_text = ""
545
+ for path, hunks in file_edits.items():
546
+ formatted_text += f"##File: {path}\n"
547
+ for hunk in hunks:
548
+ formatted_text += "".join(hunk)
549
+ formatted_text += "\n"
550
+
551
+ # Print with rich panel
552
+ self.printer.print_in_terminal("edits_title", style="bold green")
553
+ self.printer.console.print(
554
+ Panel(
555
+ Syntax(formatted_text, "diff", theme="monokai"),
556
+ title="Edits",
557
+ border_style="green",
558
+ expand=False
559
+ )
560
+ )
561
+
531
562
  def _merge_code(self, content: str,force_skip_git:bool=False):
532
563
  total = 0
533
564
 
@@ -544,9 +575,12 @@ class CodeAutoMergeDiff:
544
575
  return
545
576
 
546
577
  edits = self.get_edits(content)
547
- self.apply_edits(edits)
578
+ self.apply_edits(edits)
548
579
 
549
580
  self.printer.print_in_terminal("files_merged_total", total=total)
550
581
  if not force_skip_git and not self.args.skip_commit:
551
582
  commit_result = git_utils.commit_changes(self.args.source_dir, f"auto_coder_{file_name}_{md5}\n{self.args.query}")
552
583
  git_utils.print_commit_info(commit_result=commit_result)
584
+ else:
585
+ # Print edits for review
586
+ self.print_edits(edits)
@@ -287,6 +287,7 @@ class CodeAutoMergeEditBlock:
287
287
  for path, content in file_content_mapping.items()],
288
288
  failed_blocks=failed_blocks
289
289
  )
290
+
290
291
 
291
292
  def _merge_code(self, content: str, force_skip_git: bool = False):
292
293
  file_content = FileUtils.read_file(self.args.file)
@@ -391,6 +392,7 @@ class CodeAutoMergeEditBlock:
391
392
  style="red"
392
393
  )
393
394
  return
395
+
394
396
  # Now, apply the changes
395
397
  for file_path, new_content in file_content_mapping.items():
396
398
  os.makedirs(os.path.dirname(file_path), exist_ok=True)
@@ -431,10 +433,14 @@ class CodeAutoMergeEditBlock:
431
433
  self.git_require_msg(source_dir=self.args.source_dir, error=str(e)),
432
434
  style="red"
433
435
  )
436
+ else:
437
+ self.print_merged_blocks(merged_blocks)
438
+
434
439
  self.printer.print_in_terminal("merge_success",
435
440
  num_files=len(file_content_mapping.keys()),
436
441
  num_changes=len(changes_to_make),
437
442
  total_blocks=len(codes))
443
+
438
444
  else:
439
445
  self.printer.print_in_terminal("no_changes_made")
440
446
 
@@ -455,3 +461,39 @@ class CodeAutoMergeEditBlock:
455
461
  syntax = Syntax(update, "python", theme="monokai", line_numbers=True)
456
462
  self.printer.console.print(Panel(syntax, expand=False))
457
463
  self.printer.print_in_terminal("unmerged_blocks_total", num_blocks=len(unmerged_blocks), style="bold red")
464
+
465
+
466
+ def print_merged_blocks(self, merged_blocks: List[tuple]):
467
+ """Print search/replace blocks for user review using rich library"""
468
+ from rich.syntax import Syntax
469
+ from rich.panel import Panel
470
+
471
+ # Group blocks by file path
472
+ file_blocks = {}
473
+ for file_path, head, update, similarity in merged_blocks:
474
+ if file_path not in file_blocks:
475
+ file_blocks[file_path] = []
476
+ file_blocks[file_path].append((head, update, similarity))
477
+
478
+ # Generate formatted text for each file
479
+ formatted_text = ""
480
+ for file_path, blocks in file_blocks.items():
481
+ formatted_text += f"##File: {file_path}\n"
482
+ for head, update, similarity in blocks:
483
+ formatted_text += "<<<<<<< SEARCH\n"
484
+ formatted_text += head + "\n"
485
+ formatted_text += "=======\n"
486
+ formatted_text += update + "\n"
487
+ formatted_text += ">>>>>>> REPLACE\n"
488
+ formatted_text += "\n"
489
+
490
+ # Print with rich panel
491
+ self.printer.print_in_terminal("merged_blocks_title", style="bold green")
492
+ self.printer.console.print(
493
+ Panel(
494
+ Syntax(formatted_text, "diff", theme="monokai"),
495
+ title="Merged Changes",
496
+ border_style="green",
497
+ expand=False
498
+ )
499
+ )
@@ -221,6 +221,37 @@ class CodeAutoMergeStrictDiff:
221
221
  failed_blocks=failed_blocks
222
222
  )
223
223
 
224
+ def print_diff_blocks(self, diff_blocks: List[PathAndCode]):
225
+ """Print diff blocks for user review using rich library"""
226
+ from rich.syntax import Syntax
227
+ from rich.panel import Panel
228
+
229
+ # Group blocks by file path
230
+ file_blocks = {}
231
+ for block in diff_blocks:
232
+ if block.path not in file_blocks:
233
+ file_blocks[block.path] = []
234
+ file_blocks[block.path].append(block.content)
235
+
236
+ # Generate formatted text for each file
237
+ formatted_text = ""
238
+ for path, contents in file_blocks.items():
239
+ formatted_text += f"##File: {path}\n"
240
+ for content in contents:
241
+ formatted_text += content + "\n"
242
+ formatted_text += "\n"
243
+
244
+ # Print with rich panel
245
+ self.printer.print_in_terminal("diff_blocks_title", style="bold green")
246
+ self.printer.console.print(
247
+ Panel(
248
+ Syntax(formatted_text, "diff", theme="monokai"),
249
+ title="Diff Blocks",
250
+ border_style="green",
251
+ expand=False
252
+ )
253
+ )
254
+
224
255
  def _merge_code(self, content: str, force_skip_git: bool = False):
225
256
  total = 0
226
257
 
@@ -236,7 +267,8 @@ class CodeAutoMergeStrictDiff:
236
267
  self.printer.print_in_terminal("git_init_required", style="red", source_dir=self.args.source_dir, error=str(e))
237
268
  return
238
269
 
239
- diff_blocks = self.parse_diff_block(content)
270
+ diff_blocks = self.parse_diff_block(content)
271
+
240
272
  for diff_blocks in diff_blocks:
241
273
  path = diff_blocks.path
242
274
  content = diff_blocks.content
@@ -255,6 +287,9 @@ class CodeAutoMergeStrictDiff:
255
287
  if not force_skip_git and not self.args.skip_commit:
256
288
  commit_result = git_utils.commit_changes(self.args.source_dir, f"auto_coder_{file_name}_{md5}\n{self.args.query}")
257
289
  git_utils.print_commit_info(commit_result=commit_result)
290
+ else:
291
+ # Print diff blocks for review
292
+ self.print_diff_blocks(diff_blocks)
258
293
 
259
294
  @byzerllm.prompt(render="jinja2")
260
295
  def git_require_msg(self, source_dir: str, error: str) -> str:
autocoder/index/entry.py CHANGED
@@ -110,8 +110,8 @@ def build_index_and_filter_files(
110
110
  printer.print_in_terminal("quick_filter_start", style="blue", model_name=model_name)
111
111
  quick_filter = QuickFilter(index_manager,stats,sources)
112
112
  quick_filter_result = quick_filter.filter(index_manager.read_index(),args.query)
113
- if quick_filter_result.has_error:
114
- raise KeyboardInterrupt(printer.get_message_from_key_with_format("quick_filter_failed",error=quick_filter_result.error_message))
113
+ # if quick_filter_result.has_error:
114
+ # raise KeyboardInterrupt(printer.get_message_from_key_with_format("quick_filter_failed",error=quick_filter_result.error_message))
115
115
 
116
116
  # Merge quick filter results into final_files
117
117
  if args.context_prune:
@@ -128,8 +128,9 @@ def build_index_and_filter_files(
128
128
  model_name = "unknown(without default model name)"
129
129
  printer.print_in_terminal("normal_filter_start", style="blue",model_name=model_name)
130
130
  normal_filter = NormalFilter(index_manager,stats,sources)
131
+ normal_filter_result = normal_filter.filter(index_manager.read_index(),args.query)
131
132
  # Merge normal filter results into final_files
132
- final_files.update(normal_filter.filter(index_manager.read_index(),args.query))
133
+ final_files.update(normal_filter_result.files)
133
134
 
134
135
 
135
136
  def display_table_and_get_selections(data):
@@ -212,7 +213,7 @@ def build_index_and_filter_files(
212
213
 
213
214
  # Phase 6: File selection and limitation
214
215
  printer.print_in_terminal("phase6_file_selection")
215
- phase_start = time.monotonic()
216
+ phase_start = time.monotonic()
216
217
 
217
218
  if args.index_filter_file_num > 0:
218
219
  logger.info(
@@ -278,7 +279,7 @@ def build_index_and_filter_files(
278
279
  event=CommunicateEvent(
279
280
  event_type=CommunicateEventType.CODE_INDEX_FILTER_FILE_SELECTED.value,
280
281
  data=json.dumps([
281
- (file.file_path, file.reason)
282
+ (file["file_path"], file.reason)
282
283
  for file in final_files.values()
283
284
  if file.file_path in depulicated_sources
284
285
  ])
@@ -31,7 +31,7 @@ class NormalFilterResult(BaseModel):
31
31
  files: Dict[str, TargetFile]
32
32
  has_error: bool
33
33
  error_message: Optional[str] = None
34
- file_positions: Optional[Dict[str, int]]
34
+ file_positions: Optional[Dict[str, int]] = {}
35
35
 
36
36
  class NormalFilter():
37
37
  def __init__(self, index_manager: IndexManager,stats:Dict[str,Any],sources:List[SourceCode]):
@@ -154,7 +154,7 @@ class QuickFilter():
154
154
  else:
155
155
  # 其他chunks直接使用with_llm
156
156
  meta_holder = MetaHolder()
157
- start_time = time.monotonic()
157
+ start_time = time.monotonic()
158
158
  file_number_list = self.quick_filter_files.with_llm(self.index_manager.index_filter_llm).with_meta(
159
159
  meta_holder).with_return_type(FileNumberList).run(chunk, self.args.query)
160
160
  end_time = time.monotonic()
autocoder/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.265"
1
+ __version__ = "0.1.267"