auto-coder 0.1.260__py3-none-any.whl → 0.1.261__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.260
3
+ Version: 0.1.261
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -6,17 +6,17 @@ 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=XU9b4SBH7zjPPXaTWWHV4_zJm-XYa6njuLQaplYJH_c,20290
8
8
  autocoder/benchmark.py,sha256=Ypomkdzd1T3GE6dRICY3Hj547dZ6_inqJbBJIp5QMco,4423
9
- autocoder/chat_auto_coder.py,sha256=IfpcOU_ZOJDk4nqsqYaxqXRtwF4LWzP0uyW4aVOSE60,108584
10
- autocoder/chat_auto_coder_lang.py,sha256=sfIa8fZ-zioCtUs1prRQzt_U9aLKHvKx3TbGJ2EQ6eY,18366
9
+ autocoder/chat_auto_coder.py,sha256=Gqt-uZU_bCMfntKUQtwmMSenTYbEjanOxfSsTzNLVm0,110690
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=rG7ckiKlers-XoO1gWxNK-Y-IbqD82WS3qFMPHqvFsc,9072
14
- autocoder/version.py,sha256=QvpfalUuVNrsAIvEk0uBtl3snKZObGKNSGeQi1u2V4s,23
14
+ autocoder/version.py,sha256=FpxoCO0AS-j3bS_c_eu4jbDFzGtgH1JA4ySIzB1dNGY,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
18
18
  autocoder/agent/auto_guess_query.py,sha256=rDSdhpPHcOGE5MuDXvIrhCXAPR4ARS1LqpyoLsx2Jhw,11374
19
- autocoder/agent/auto_review_commit.py,sha256=7na6LiMg9jxtdX5hplJ2m-9tx2HzRBAEZ6h8lcsmasw,7591
19
+ autocoder/agent/auto_review_commit.py,sha256=UvcxsW3UW-bZzbV82ylyf4e8uBoOtF9fkwVdl1YMsRs,9152
20
20
  autocoder/agent/auto_tool.py,sha256=DBzip-P_T6ZtT2eHexPcusmKYD0h7ufzp7TLwXAY10E,11554
21
21
  autocoder/agent/coder.py,sha256=x6bdJwDuETGg9ebQnYlUWCxCtQcDGg73LtI6McpWslQ,72034
22
22
  autocoder/agent/designer.py,sha256=EpRbzO58Xym3GrnppIT1Z8ZFAlnNfgzHbIzZ3PX-Yv8,27037
@@ -24,15 +24,15 @@ autocoder/agent/planner.py,sha256=wvvuX9o6yhWlGm9t7fIT0wiChV5NkXBrYElxKiAjldU,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=ncdR0tXZixRcdvNKus3Z5Lqacb7gr3iyRg6HKE5zDWM,47231
27
+ autocoder/commands/auto_command.py,sha256=nPzTdVJES1MDfBfRuKl7SxKh_8CZGCz-pPAtEijeEtA,49084
28
28
  autocoder/commands/tools.py,sha256=rgZWuTtmn-Ck7G2EkeBRMFh6_TjLzssW1mabQoCrzR0,20327
29
29
  autocoder/common/JupyterClient.py,sha256=O-wi6pXeAEYhAY24kDa0BINrLYvKS6rKyWe98pDClS0,2816
30
30
  autocoder/common/ShellClient.py,sha256=fM1q8t_XMSbLBl2zkCNC2J9xuyKN3eXzGm6hHhqL2WY,2286
31
- autocoder/common/__init__.py,sha256=wJIAB6EOeCmo9UXCGC7E9u_GGWO5DjXW78wUi3hz1lI,12272
31
+ autocoder/common/__init__.py,sha256=ycRfzzb28kqMb1yNRQrJotx833gkuxL9PF9AwtsCTTw,12554
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=xpZ2z8RfarhTE-srSFkNBlnpE2fQVg5E5-KUi-U_F5E,23269
35
+ autocoder/common/auto_coder_lang.py,sha256=nIHI5dSSHDDUWKuEF7TgrDAHaZwO0fubrowxqjQE6Gw,25578
36
36
  autocoder/common/auto_configure.py,sha256=tdEwfycZUjomZAgps1GOCtocYEtfuUgRksYPFHBP_bs,12211
37
37
  autocoder/common/buildin_tokenizer.py,sha256=L7d5t39ZFvUd6EoMPXUhYK1toD0FHlRH1jtjKRGokWU,1236
38
38
  autocoder/common/chunk_validation.py,sha256=BrR_ZWavW8IANuueEE7hS8NFAwEvm8TX34WnPx_1hs8,3030
@@ -42,19 +42,22 @@ autocoder/common/code_auto_generate.py,sha256=74wCscxVEnY_VDkHcr-QA3b79RhDR_OeVP
42
42
  autocoder/common/code_auto_generate_diff.py,sha256=bns5KZq9ozvUtyqIUWsDNUtah-TTOsE7yRXHYGlrtT4,18872
43
43
  autocoder/common/code_auto_generate_editblock.py,sha256=LcGfG4bJVCVsWehex7MYWDF4NX0B2Rp2ALSh-27MclA,20472
44
44
  autocoder/common/code_auto_generate_strict_diff.py,sha256=JvKnD5Ph3JtAiVIO_k_XKUnVBeUxwLw_AHF_xWWtX7c,17488
45
- autocoder/common/code_auto_merge.py,sha256=-ksBjj4ZVcbY_tVH4JLXAMSRtsgaSxrSZ5-MOl9cAgE,7354
46
- autocoder/common/code_auto_merge_diff.py,sha256=qpEuHJEgX6sWK7EDFEKqcYkyI28wOyM4pytyl8BLohY,15350
47
- autocoder/common/code_auto_merge_editblock.py,sha256=sxgYMLMACRwJvw-bABkdDHezPelsDFrOCpGuhtT5Dzs,17504
48
- autocoder/common/code_auto_merge_strict_diff.py,sha256=P0nKNkBrFMybTSZ7kOdA_JixoVmLCZIhAP5q7ILJ9j0,9538
45
+ autocoder/common/code_auto_merge.py,sha256=TJu41wI-YlX_pZ14aN_f1E_34o-laezz_uf5peMk-bI,7414
46
+ autocoder/common/code_auto_merge_diff.py,sha256=THC_zf7QSc7Km5MCBmZprBZr0XdN-uPL4n46wFEIzNk,15410
47
+ autocoder/common/code_auto_merge_editblock.py,sha256=NMXGDHIERbZJ8laRpF7ztdGdGF7_vj5-fCik2Icf4dk,17564
48
+ autocoder/common/code_auto_merge_strict_diff.py,sha256=4sH607wUTi8vRmh3_G2F3K8MGlL6HEguVOQ7hnIaZ7Y,9598
49
49
  autocoder/common/code_modification_ranker.py,sha256=3Ieo1-ADBinbnX8XoBIA2GOf0K56ITokPMoIhQjQaCU,8217
50
- autocoder/common/command_completer.py,sha256=zIhc_l95nrBZWK0X3Wro52DcP69E-tI0VDYDIMbpm6M,35545
50
+ autocoder/common/command_completer.py,sha256=Nd-DdlFd2MMy9jpSI5N5rGKek-zEzI4Wa2g9w7mjQYk,35122
51
51
  autocoder/common/command_generator.py,sha256=-hmbD_AnCa5HxL4BznuEfYAf_l8AxU5fAG5F0sM_fuE,2116
52
52
  autocoder/common/command_templates.py,sha256=lAdr0-iyJKY2dOH2mZ0Tm3GlT_a1Oj8mgdKXmDiQN3A,8654
53
+ autocoder/common/conf_validator.py,sha256=OzwNMRf0EJTamyIQUpgudbBpYMoJ7S6UyEyk8xi9KXU,8596
53
54
  autocoder/common/const.py,sha256=eTjhjh4Aj4CUzviJ81jaf3Y5cwqsLATySn2wJxaS6RQ,2911
55
+ autocoder/common/conversation_pruner.py,sha256=mdMpTpTdPJl8f0UjC1TGKRiYtDc1o6QQD0nYPR9yp1c,5628
54
56
  autocoder/common/files.py,sha256=CguxG9digkWBJpRaILErZmL_G5ryPRahPmPFWGB7X18,1973
55
57
  autocoder/common/git_utils.py,sha256=qeuF_IB3G3M72asHxWokROU3hINCuFA1nar-UtF9wIU,26022
56
58
  autocoder/common/global_cancel.py,sha256=hT7J7J5ChThIhk2x11_v4v9ASIn4HtwyPD26t2s-fwc,418
57
59
  autocoder/common/image_to_page.py,sha256=O0cNO_vHHUP-fP4GXiVojShmNqkPnZXeIyiY1MRLpKg,13936
60
+ autocoder/common/index_import_export.py,sha256=Dg_j-tBaJO_xMXhZUseJcOcA9I79etI_Xri3lUEvYmw,3495
58
61
  autocoder/common/interpreter.py,sha256=62-dIakOunYB4yjmX8SHC0Gdy2h8NtxdgbpdqRZJ5vk,2833
59
62
  autocoder/common/llm_rerank.py,sha256=FbvtCzaR661Mt2wn0qsuiEL1Y3puD6jeIJS4zg_e7Bs,3260
60
63
  autocoder/common/mcp_hub.py,sha256=2ZyJv3Aiv4Y97UHut49oYhIFcu7ICR-mptDEBSgT3uE,14234
@@ -68,7 +71,7 @@ autocoder/common/result_manager.py,sha256=nBcFRj5reBC7vp13M91f4B8iPW8B8OehayHlUd
68
71
  autocoder/common/screenshots.py,sha256=_gA-z1HxGjPShBrtgkdideq58MG6rqFB2qMUJKjrycs,3769
69
72
  autocoder/common/search.py,sha256=245iPFgWhMldoUK3CqCP89ltaxZiNPK73evoG6Fp1h8,16518
70
73
  autocoder/common/search_replace.py,sha256=GphFkc57Hb673CAwmbiocqTbw8vrV7TrZxtOhD0332g,22147
71
- autocoder/common/shells.py,sha256=zOUkGNB0MLLH9FXZfkhyAEoO0h7ZPyY35vjKou5PXf0,6937
74
+ autocoder/common/shells.py,sha256=Lu7JxF49Wi8kJ1WYAxmYnHUxs5JeQLO9N2OU05Gwrj8,7570
72
75
  autocoder/common/sys_prompt.py,sha256=JlexfjZt554faqbgkCmzOJqYUzDHfbnxly5ugFfHfEE,26403
73
76
  autocoder/common/text.py,sha256=KGRQq314GHBmY4MWG8ossRoQi1_DTotvhxchpn78c-k,1003
74
77
  autocoder/common/types.py,sha256=PXTETrsTvhLE49jqAeUKGySvxBN9pjeyCgRHLDYdd9U,664
@@ -81,10 +84,10 @@ autocoder/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
84
  autocoder/db/store.py,sha256=tFT66bP2ZKIqZip-uhLkHRSLaaOAUUDZfozJwcqix3c,1908
82
85
  autocoder/dispacher/__init__.py,sha256=YoA64dIxnx4jcE1pwSfg81sjkQtjDkhddkfac1-cMWo,1230
83
86
  autocoder/dispacher/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
- autocoder/dispacher/actions/action.py,sha256=Wnh6fZeYdyOXTHtRTb5Lm5uJpwjjBYiSOGHYO7OdEuo,23746
87
+ autocoder/dispacher/actions/action.py,sha256=BWdGHhvco005vHvmBlCGS7DgsizBluKyENdK7c4z1NA,25283
85
88
  autocoder/dispacher/actions/copilot.py,sha256=iMh4ckj9hO5Q-iemF3CStXd7DatWai7Eci5zOlKxK9c,13072
86
89
  autocoder/dispacher/actions/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- autocoder/dispacher/actions/plugins/action_regex_project.py,sha256=mD5287a3b406WC6TF-HvxEQsOda9gqlK_1zvvijvAF8,6557
90
+ autocoder/dispacher/actions/plugins/action_regex_project.py,sha256=2Ikj6dlgezXJQC3hnbC5mrDuSGtF20bVbpOrEDOq25s,6984
88
91
  autocoder/dispacher/actions/plugins/action_translate.py,sha256=nVAtRSQpdGNmZxg1R_9zXG3AuTv3CHf2v7ODgj8u65c,7727
89
92
  autocoder/index/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
93
  autocoder/index/entry.py,sha256=iuvORjbmkNXBaN8p-njwETCVN2mWwu_DIgCJeM2rzKs,12799
@@ -94,7 +97,7 @@ autocoder/index/symbols_utils.py,sha256=CjcjUVajmJZB75Ty3a7kMv1BZphrm-tIBAdOJv6u
94
97
  autocoder/index/types.py,sha256=a2s_KV5FJlq7jqA2ELSo9E1sjuLwDB-JJYMhSpzBAhU,596
95
98
  autocoder/index/filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
99
  autocoder/index/filter/normal_filter.py,sha256=APu34iSvWhtlLtWgkj8N3Vo4oW1TegtZQq2bwDX_cs4,8031
97
- autocoder/index/filter/quick_filter.py,sha256=0th3nkcPj6RRaNbgy_7pnfXf2DCEF9xj8E8UsKvDPAE,15805
100
+ autocoder/index/filter/quick_filter.py,sha256=h0JNz_zRMb0dxBD00iH-Qwt_GEnCyHnMXS8FOhqLQEo,16126
98
101
  autocoder/privacy/__init__.py,sha256=LnIVvGu_K66zCE-yhN_-dPO8R80pQyedCsXJ7wRqQaI,72
99
102
  autocoder/privacy/model_filter.py,sha256=-N9ZvxxDKpxU7hkn-tKv-QHyXjvkCopUaKgvJwTOGQs,3369
100
103
  autocoder/pyproject/__init__.py,sha256=bRuGxFV4QyE85xVjDzeMFmlLVqGbbcFs09FI15Uss4Q,14423
@@ -144,6 +147,7 @@ autocoder/utils/model_provider_selector.py,sha256=g5O9frBWkXR7iqjYDdTvhoxzTQx0Na
144
147
  autocoder/utils/multi_turn.py,sha256=unK9OpqVRbK6uIcTKXgggX2wNmyj7s5eyEAQ2xUwHoM,88
145
148
  autocoder/utils/operate_config_api.py,sha256=99YAKsuUFLPwrRvj0CJal_bAPgyiXWMma6ZKMU56thw,5790
146
149
  autocoder/utils/print_table.py,sha256=ZMRhCA9DD0FUfKyJBWd5bDdj1RrtPtgOMWSJwtvZcLs,403
150
+ autocoder/utils/project_structure.py,sha256=4uqmlUyo3LZgn-HX_zv84WmcPqF9jif0n6I8dkmLHt4,601
147
151
  autocoder/utils/queue_communicate.py,sha256=buyEzdvab1QA4i2QKbq35rG5v_9x9PWVLWWMTznWcYM,6832
148
152
  autocoder/utils/request_event_queue.py,sha256=r3lo5qGsB1dIjzVQ05dnr0z_9Z3zOkBdP1vmRciKdi4,2095
149
153
  autocoder/utils/request_queue.py,sha256=nwp6PMtgTCiuwJI24p8OLNZjUiprC-TsefQrhMI-yPE,3889
@@ -154,9 +158,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
158
  autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
159
  autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=lkJ_A-sYU36JMzjFWkk3pR6uos8oZHYt9GPsPe_CPAo,11766
156
160
  autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
- auto_coder-0.1.260.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
158
- auto_coder-0.1.260.dist-info/METADATA,sha256=sXKvFWklT0RoVuKuL57l25BS3SIekLd7bYC4ZTBMrDU,2616
159
- auto_coder-0.1.260.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
160
- auto_coder-0.1.260.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
161
- auto_coder-0.1.260.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
162
- auto_coder-0.1.260.dist-info/RECORD,,
161
+ auto_coder-0.1.261.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
162
+ auto_coder-0.1.261.dist-info/METADATA,sha256=D0OpEZxbCtNshFQP7nMis_IfkK20xjfVBxjeYTsyeq0,2616
163
+ auto_coder-0.1.261.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
164
+ auto_coder-0.1.261.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
165
+ auto_coder-0.1.261.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
166
+ auto_coder-0.1.261.dist-info/RECORD,,
@@ -8,6 +8,7 @@ from rich.console import Console
8
8
  from autocoder.common.printer import Printer
9
9
  from autocoder.common import AutoCoderArgs
10
10
  from autocoder.common.utils_code_auto_generate import stream_chat_with_continue
11
+ import hashlib
11
12
 
12
13
 
13
14
  def load_yaml_config(yaml_file: str) -> Dict:
@@ -41,13 +42,13 @@ class AutoReviewCommit:
41
42
  self.console = console or Console()
42
43
 
43
44
  @byzerllm.prompt()
44
- def review(self, querie_with_urls_and_diffs: List[Tuple[str, List[str], str]], query: str) -> Generator[str,None,None]:
45
+ def review(self, querie_with_urls_and_changes: List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]], query: str) -> Generator[str,None,None]:
45
46
  """
46
47
  如果前面我们对话提供了文档,请参考上面的文档对提交的代码变更进行审查,提供改进建议。
47
48
 
48
49
  下面包含最新一次提交的信息:
49
50
  <commit>
50
- {% for query,urls,diff in querie_with_urls_and_diffs %}
51
+ {% for query,urls,changes in querie_with_urls_and_changes %}
51
52
  ## 任务需求
52
53
  {{ query }}
53
54
 
@@ -57,9 +58,18 @@ class AutoReviewCommit:
57
58
  {% endfor %}
58
59
 
59
60
  代码变更:
60
- ```diff
61
- {{ diff }}
62
- ```
61
+ {% for file_path, (before, after) in changes.items() %}
62
+ ##File: {{ file_path }}
63
+ ##修改前:
64
+
65
+ {{ before or "New file" }}
66
+
67
+ ##File: {{ file_path }}
68
+ ##修改后:
69
+
70
+ {{ after or "File deleted" }}
71
+
72
+ {% endfor %}
63
73
  {% endfor %}
64
74
  </commit>
65
75
 
@@ -70,7 +80,7 @@ class AutoReviewCommit:
70
80
  - 实现逻辑:算法和数据结构的选择是否合适
71
81
 
72
82
  2. 潜在问题检查
73
- - 常见错误:是否存在空指针,数组越界,类型转换,未声明变量,typo等低级错误
83
+ - 常见错误:缩进(比如python),闭合标签(前端vue,reactjs),是否存在空指针,数组越界,类型转换,未声明变量,typo等低级错误
74
84
  - 安全性:是否存在安全隐患
75
85
  - 性能:是否有性能问题
76
86
  - 并发:是否有并发安全问题
@@ -83,8 +93,7 @@ class AutoReviewCommit:
83
93
  - 依赖关系:组件耦合是否合理
84
94
  - 复用性:是否有重复代码
85
95
 
86
- 返回格式说明:
87
- 返回 markdown 格式,包含以下内容:
96
+ 评审结果包含以下内容:
88
97
  1. issues: 发现的具体问题列表
89
98
  2. suggestions: 对应的改进建议列表
90
99
  3. severity: 问题的严重程度(low/medium/high)
@@ -130,10 +139,10 @@ class AutoReviewCommit:
130
139
 
131
140
  action_file = action_files[0]
132
141
 
133
- querie_with_urls_and_diffs = []
142
+ querie_with_urls_and_changes = []
134
143
  repo = git.Repo(self.project_dir)
135
144
 
136
- # 收集所有query、urls和对应的commit diff
145
+ # 收集所有query、urls和对应的文件变化
137
146
  for yaml_file in [action_file]:
138
147
  yaml_path = os.path.join(self.actions_dir, yaml_file)
139
148
  config = load_yaml_config(yaml_path)
@@ -145,11 +154,12 @@ class AutoReviewCommit:
145
154
  urls = config.get('urls', [])
146
155
 
147
156
  if query and urls:
148
- commit_diff = ""
157
+ changes = {}
149
158
  if not self.skip_diff:
150
- # 计算文件的MD5用于匹配commit
151
- import hashlib
152
- file_md5 = hashlib.md5(open(yaml_path, 'rb').read()).hexdigest()
159
+ # 计算文件的MD5用于匹配commit
160
+ with open(yaml_path, 'r', encoding='utf-8') as f:
161
+ yaml_content = f.read()
162
+ file_md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
153
163
  response_id = f"auto_coder_{yaml_file}_{file_md5}"
154
164
  # 查找对应的commit
155
165
  try:
@@ -157,21 +167,38 @@ class AutoReviewCommit:
157
167
  if response_id in commit.message:
158
168
  if commit.parents:
159
169
  parent = commit.parents[0]
160
- commit_diff = repo.git.diff(
161
- parent.hexsha, commit.hexsha)
162
- else:
163
- commit_diff = repo.git.show(commit.hexsha)
170
+ # 获取所有文件的前后内容
171
+ for diff_item in parent.diff(commit):
172
+ file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
173
+
174
+ # 获取变更前内容
175
+ before_content = None
176
+ try:
177
+ if diff_item.a_blob:
178
+ before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
179
+ except git.exc.GitCommandError:
180
+ pass # 文件可能是新增的
181
+
182
+ # 获取变更后内容
183
+ after_content = None
184
+ try:
185
+ if diff_item.b_blob:
186
+ after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
187
+ except git.exc.GitCommandError:
188
+ pass # 文件可能被删除
189
+
190
+ changes[file_path] = (before_content, after_content)
164
191
  break
165
192
  except git.exc.GitCommandError as e:
166
193
  printer = Printer()
167
194
  printer.print_in_terminal("git_command_error", style="red", error=str(e))
168
195
  except Exception as e:
169
196
  printer = Printer()
170
- printer.print_in_terminal("get_commit_diff_error", style="red", error=str(e))
197
+ printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
171
198
 
172
- querie_with_urls_and_diffs.append((query, urls, commit_diff))
199
+ querie_with_urls_and_changes.append((query, urls, changes))
173
200
 
174
- return querie_with_urls_and_diffs
201
+ return querie_with_urls_and_changes
175
202
 
176
203
 
177
204
  def review_commit(self,query: str, conversations: List[Dict]) -> Generator[str,None,None]:
@@ -183,15 +210,15 @@ class AutoReviewCommit:
183
210
  """
184
211
  printer = Printer()
185
212
  # 获取最新的提交信息
186
- commits = self.parse_history_tasks()
187
- if not commits:
213
+ changes = self.parse_history_tasks()
214
+ if not changes:
188
215
  printer.print_in_terminal("no_latest_commit", style="red")
189
216
  return None
190
217
 
191
218
  # 调用LLM进行代码审查
192
219
  try:
193
220
  # 获取 prompt 内容
194
- query = self.review.prompt(commits, query)
221
+ query = self.review.prompt(changes, query)
195
222
  new_conversations = conversations.copy()[0:-1]
196
223
  new_conversations.append({"role": "user", "content": query})
197
224
  # 构造对话消息
@@ -1,3 +1,4 @@
1
+ from itertools import product
1
2
  from prompt_toolkit.formatted_text import HTML
2
3
  from prompt_toolkit.shortcuts import radiolist_dialog
3
4
  from prompt_toolkit import prompt
@@ -57,6 +58,7 @@ import pkg_resources
57
58
  from autocoder.common.printer import Printer
58
59
  from autocoder.utils.thread_utils import run_in_thread,run_in_raw_thread
59
60
  from autocoder.common.command_completer import CommandCompleter,FileSystemModel as CCFileSystemModel,MemoryConfig as CCMemoryModel
61
+ from autocoder.common.conf_validator import ConfigValidator
60
62
 
61
63
  class SymbolItem(BaseModel):
62
64
  symbol_name: str
@@ -129,6 +131,8 @@ commands = [
129
131
  "/revert",
130
132
  "/index/query",
131
133
  "/index/build",
134
+ "/index/export",
135
+ "/index/import",
132
136
  "/exclude_dirs",
133
137
  "/help",
134
138
  "/shell",
@@ -584,6 +588,9 @@ def configure(conf: str, skip_print=False):
584
588
  if not value:
585
589
  printer.print_in_terminal("config_value_empty", style="red")
586
590
  return
591
+ product_mode = memory["conf"].get("product_mode",None)
592
+ if product_mode:
593
+ ConfigValidator.validate(key, value, product_mode)
587
594
  memory["conf"][key] = value
588
595
  save_memory()
589
596
  if not skip_print:
@@ -1863,6 +1870,13 @@ def generate_shell_command(input_text):
1863
1870
  auto_coder_main(["agent", "generate_command", "--file", execute_file])
1864
1871
  with open(os.path.join(".auto-coder", "exchange.txt"), "r") as f:
1865
1872
  shell_script = f.read()
1873
+ result_manager = ResultManager()
1874
+ result_manager.add_result(content=shell_script,meta={
1875
+ "action": "generate_shell_command",
1876
+ "input": {
1877
+ "query": input_text
1878
+ }
1879
+ })
1866
1880
  return shell_script
1867
1881
  finally:
1868
1882
  os.remove(execute_file)
@@ -2323,6 +2337,28 @@ def help(query: str):
2323
2337
  auto_config_tuner = ConfigAutoTuner(llm=llm, memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory))
2324
2338
  auto_config_tuner.tune(AutoConfigRequest(query=query))
2325
2339
 
2340
+ @run_in_raw_thread()
2341
+ def index_export(export_path: str):
2342
+ from autocoder.common.index_import_export import export_index
2343
+ from autocoder.common.printer import Printer
2344
+ printer = Printer()
2345
+ project_root = os.getcwd()
2346
+ if export_index(project_root, export_path):
2347
+ printer.print_in_terminal("index_export_success", path=export_path)
2348
+ else:
2349
+ printer.print_in_terminal("index_export_fail", path=export_path)
2350
+
2351
+ @run_in_raw_thread()
2352
+ def index_import(import_path: str):
2353
+ from autocoder.common.index_import_export import import_index
2354
+ from autocoder.common.printer import Printer
2355
+ printer = Printer()
2356
+ project_root = os.getcwd()
2357
+ if import_index(project_root, import_path):
2358
+ printer.print_in_terminal("index_import_success", path=import_path)
2359
+ else:
2360
+ printer.print_in_terminal("index_import_fail", path=import_path)
2361
+
2326
2362
  @run_in_raw_thread()
2327
2363
  def index_query(query: str):
2328
2364
  conf = memory.get("conf", {})
@@ -2547,15 +2583,15 @@ def auto_command(params,query: str):
2547
2583
 
2548
2584
  # 生成建议
2549
2585
  response = tuner.analyze(request)
2550
-
2586
+ printer = Printer()
2551
2587
  # 显示建议
2552
- console = Console()
2588
+ console = Console()
2553
2589
  console.print(Panel(
2554
2590
  Markdown(response.reasoning or ""),
2555
- title="Reasoning",
2591
+ title=printer.get_message_from_key_with_format("auto_command_reasoning_title"),
2556
2592
  border_style="blue",
2557
2593
  padding=(1, 2)
2558
- ))
2594
+ ))
2559
2595
 
2560
2596
 
2561
2597
  def main():
@@ -2736,6 +2772,20 @@ def main():
2736
2772
 
2737
2773
  elif user_input.startswith("/index/build"):
2738
2774
  index_build()
2775
+
2776
+ elif user_input.startswith("/index/export"):
2777
+ export_path = user_input[len("/index/export"):].strip()
2778
+ if not export_path:
2779
+ print("Please specify the export path")
2780
+ else:
2781
+ index_export(export_path)
2782
+
2783
+ elif user_input.startswith("/index/import"):
2784
+ import_path = user_input[len("/index/import"):].strip()
2785
+ if not import_path:
2786
+ print("Please specify the import path")
2787
+ else:
2788
+ index_import(import_path)
2739
2789
 
2740
2790
  elif user_input.startswith("/list_files"):
2741
2791
  list_files()
@@ -75,6 +75,14 @@ MESSAGES = {
75
75
  "help_desc": "Show this help message",
76
76
  "exclude_dirs_desc": "Add directories to exclude from project",
77
77
  "shell_desc": "Execute a shell command",
78
+ "index_export_success": "Successfully exported index to {{ path }}",
79
+ "index_export_fail": "Failed to export index to {{ path }}",
80
+ "index_import_success": "Successfully imported index from {{ path }}",
81
+ "index_import_fail": "Failed to import index from {{ path }}",
82
+ "index_not_found": "Index file not found at {{ path }}",
83
+ "index_backup_success": "Backed up existing index to {{ path }}",
84
+ "index_convert_path_fail": "Could not convert path {{ path }}",
85
+ "index_error": "Error in index operation: {{ error }}",
78
86
  "voice_input_desc": "Convert voice input to text",
79
87
  "mode_desc": "Switch input mode",
80
88
  "conf_key": "Key",
@@ -123,6 +131,7 @@ MESSAGES = {
123
131
  "files_removed": "Files Removed",
124
132
  "models_api_key_empty": "Warning : {{name}} API key is empty. Please set a valid API key.",
125
133
  "commit_generating": "{{ model_name }} Generating commit message...",
134
+ "auto_command_reasoning_title": "Reply",
126
135
  "commit_message": "{{ model_name }} Generated commit message: {{ message }}",
127
136
  "commit_failed": "{{ model_name }} Failed to generate commit message: {{ error }}",
128
137
  "confirm_execute": "Do you want to execute this script?",
@@ -131,6 +140,7 @@ MESSAGES = {
131
140
  "zh": {
132
141
  "auto_command_analyzing": "正在分析命令请求",
133
142
  "commit_generating": "{{ model_name }} 正在生成提交信息...",
143
+ "auto_command_reasoning_title": "回复",
134
144
  "commit_message": "{{ model_name }} 生成的提交信息: {{ message }}",
135
145
  "commit_failed": "{{ model_name }} 生成提交信息失败: {{ error }}",
136
146
  "mcp_remove_error": "移除 MCP 服务器时出错:{error}",
@@ -204,6 +214,14 @@ MESSAGES = {
204
214
  "help_desc": "显示此帮助消息",
205
215
  "exclude_dirs_desc": "添加要从项目中排除的目录",
206
216
  "shell_desc": "执行shell命令",
217
+ "index_export_success": "成功导出索引到 {{ path }}",
218
+ "index_export_fail": "导出索引到 {{ path }} 失败",
219
+ "index_import_success": "成功从 {{ path }} 导入索引",
220
+ "index_import_fail": "从 {{ path }} 导入索引失败",
221
+ "index_not_found": "在 {{ path }} 未找到索引文件",
222
+ "index_backup_success": "已备份现有索引到 {{ path }}",
223
+ "index_convert_path_fail": "无法转换路径 {{ path }}",
224
+ "index_error": "索引操作出错:{{ error }}",
207
225
  "voice_input_desc": "将语音输入转换为文本",
208
226
  "mode_desc": "切换输入模式",
209
227
  "lib_desc": "管理库",
@@ -7,7 +7,6 @@ from typing import List, Dict, Any, Union, Callable, Optional
7
7
  from autocoder.common.printer import Printer
8
8
  from rich.console import Console
9
9
  from rich.panel import Panel
10
- from rich.markdown import Markdown
11
10
  from pydantic import SkipValidation
12
11
 
13
12
  from autocoder.common.result_manager import ResultManager
@@ -19,8 +18,9 @@ from autocoder.auto_coder import AutoCoderArgs
19
18
  from autocoder.common import detect_env
20
19
  from autocoder.common import shells
21
20
  from loguru import logger
22
- from autocoder.common import auto_coder_lang
23
21
  from autocoder.utils import llms as llms_utils
22
+ from autocoder.rag.token_counter import count_tokens
23
+ from autocoder.common.global_cancel import global_cancel
24
24
 
25
25
  class CommandMessage(BaseModel):
26
26
  role: str
@@ -197,6 +197,7 @@ class CommandAutoTuner:
197
197
  函数组合说明:
198
198
  <function_combination_readme>
199
199
  如果用户是一个编码需求,你可以先简单观察当前活跃区文件列表:
200
+ 0. 关注下当前软件的配置,诸如索引开启关闭。如果有觉得不合理的可以通过 help 函数来修改。
200
201
  1. 如果你觉得这些文件不够满足用户的需求,而当前的索引配置关闭的,那么你可以通过help("将skip_filter_index 和 skip_build_index 设置为 false") 让
201
202
  chat,coding 函数来获取更多文件,或者你也可以自己通过调用 get_project_structure 函数来获取项目结构,然后通过 get_project_map 函数来获取某个文件的用途,符号列表,以及
202
203
  文件大小(tokens数),最后再通过 read_files/read_file_with_keyword_ranges 函数来读取文件内容, 最后通过 add_files 函数来添加文件到活跃区。
@@ -207,6 +208,7 @@ class CommandAutoTuner:
207
208
  通过 get_project_structure 来获取项目结构,然后通过 get_project_map 来获取你想看的某个文件的用途,符号列表,最后再通过 read_files/read_file_with_keyword_ranges 函数来读取文件内容,确认对应的功能是否在相关的文件里。
208
209
  5. 调用 coding 函数的时候,尽可能多的 @文件和@@符号,让需求更加清晰明了,建议多描述具体怎么完成对应的需求。
209
210
  6. 对于代码需求设计,尽可能使用 chat 函数。
211
+ 7. 如果成功执行了 coding 函数,最好再调用一次 chat("/review /commit")
210
212
  </function_combination_readme>
211
213
 
212
214
 
@@ -273,8 +275,11 @@ class CommandAutoTuner:
273
275
 
274
276
  *** 非常非常重要的提示 ***
275
277
  1. 如果已经满足要求,则不要返回任何函数,确保 suggestions 为空。
276
- 2. 你最多尝试10次,如果10次都没有满足要求,则不要返回任何函数,确保 suggestions 为空。
277
- '''
278
+ 2. 你最多尝试 {{ auto_command_max_iterations }} 次,如果 {{ auto_command_max_iterations }} 次都没有满足要求,则不要返回任何函数,确保 suggestions 为空。
279
+ '''
280
+ return {
281
+ "auto_command_max_iterations": self.args.auto_command_max_iterations
282
+ }
278
283
 
279
284
  def analyze(self, request: AutoCommandRequest) -> AutoCommandResponse:
280
285
  # 获取 prompt 内容
@@ -317,8 +322,7 @@ class CommandAutoTuner:
317
322
  )
318
323
 
319
324
  if last_meta:
320
- elapsed_time = time.monotonic() - start_time
321
- printer = Printer()
325
+ elapsed_time = time.monotonic() - start_time
322
326
  speed = last_meta.generated_tokens_count / elapsed_time
323
327
 
324
328
  # Get model info for pricing
@@ -355,6 +359,10 @@ class CommandAutoTuner:
355
359
  result_manager = ResultManager()
356
360
 
357
361
  while True:
362
+ if global_cancel.requested:
363
+ printer = Printer(console)
364
+ printer.print_in_terminal("generation_cancelled")
365
+ break
358
366
  # 执行命令
359
367
  command = response.suggestions[0].command
360
368
  parameters = response.suggestions[0].parameters
@@ -376,8 +384,10 @@ class CommandAutoTuner:
376
384
  changes = git_utils.get_changes_by_commit_message("", last_result.meta["commit_message"])
377
385
  if changes.success:
378
386
  for file_path, change in changes.changes.items():
379
- if change.before:
380
- content += f"## File: {file_path}[更改前]\n{change.before}\n\nFile: {file_path}\n\n[更改后]\n{change.after}\n\n"
387
+ if change:
388
+ content += f"## File: {file_path}[更改前]\n{change.before or 'New File'}\n\nFile: {file_path}\n\n[更改后]\n{change.after or 'Deleted File'}\n\n"
389
+ else:
390
+ content = printer.get_message_from_key_with_format("no_changes_made")
381
391
  else:
382
392
  # 其他的直接获取执行结果
383
393
  content = last_result.content
@@ -403,9 +413,26 @@ class CommandAutoTuner:
403
413
  ))
404
414
  # 保持原content不变,继续后续处理
405
415
 
406
- conversations.append({"role": "user", "content": self._execute_command_result.prompt(content)})
407
- title = printer.get_message_from_key("auto_command_analyzing")
416
+ # 添加新的对话内容
417
+ new_content = self._execute_command_result.prompt(content)
418
+ conversations.append({"role": "user", "content": new_content})
419
+
420
+ # 统计 token 数量
421
+ total_tokens = count_tokens(json.dumps(conversations,ensure_ascii=False))
422
+
423
+ # 如果对话过长,使用默认策略进行修剪
424
+ if total_tokens > self.args.conversation_prune_safe_zone_tokens:
425
+ self.printer.print_in_terminal(
426
+ "conversation_pruning_start",
427
+ style="yellow",
428
+ total_tokens=total_tokens,
429
+ safe_zone=self.args.conversation_prune_safe_zone_tokens
430
+ )
431
+ from autocoder.common.conversation_pruner import ConversationPruner
432
+ pruner = ConversationPruner(self.llm)
433
+ conversations = pruner.prune_conversations(conversations)
408
434
 
435
+ title = printer.get_message_from_key("auto_command_analyzing")
409
436
  model_name = ",".join(llms_utils.get_llm_names(self.llm))
410
437
 
411
438
  start_time = time.monotonic()
@@ -453,7 +480,7 @@ class CommandAutoTuner:
453
480
  response=response.model_dump_json(indent=2)
454
481
  )
455
482
 
456
- else:
483
+ else:
457
484
  self.printer.print_in_terminal("auto_command_break", style="yellow", command=command)
458
485
  break
459
486
 
@@ -555,7 +582,7 @@ class CommandAutoTuner:
555
582
  <name>revert</name>
556
583
  <description>
557
584
  撤销最后一次代码修改,恢复到修改前的状态。同时会删除对应的操作记录文件,
558
- 如果很明显你对上一次coding执行后的效果觉得不满意,可以使用该函数来撤销上一次的代码修改。
585
+ 如果很明显你对上一次coding函数执行后的效果觉得不满意,可以使用该函数来撤销上一次的代码修改。
559
586
  </description>
560
587
  <usage>
561
588
  该命令不需要任何参数,直接使用即可。会撤销最近一次的代码修改操作。
@@ -1107,6 +1134,7 @@ class CommandAutoTuner:
1107
1134
  "lib": self.command_config.lib,
1108
1135
  "models": self.command_config.models,
1109
1136
  "execute_shell_command": self.command_config.execute_shell_command,
1137
+ "generate_shell_command": self.command_config.generate_shell_command,
1110
1138
 
1111
1139
  "run_python": self.tools.run_python_code,
1112
1140
  "get_related_files_by_symbols": self.tools.get_related_files_by_symbols,
@@ -1117,7 +1145,8 @@ class CommandAutoTuner:
1117
1145
  "find_files_by_content": self.tools.find_files_by_content,
1118
1146
  "get_project_related_files": self.tools.get_project_related_files,
1119
1147
  "ask_user":self.tools.ask_user,
1120
- "read_file_with_keyword_ranges": self.tools.read_file_with_keyword_ranges
1148
+ "read_file_with_keyword_ranges": self.tools.read_file_with_keyword_ranges,
1149
+
1121
1150
 
1122
1151
  }
1123
1152
 
@@ -370,6 +370,14 @@ class AutoCoderArgs(pydantic.BaseModel):
370
370
  in_code_apply: bool = False
371
371
  model_filter_path: Optional[str] = None
372
372
 
373
+ conversation_prune_safe_zone_tokens: Optional[int] = 50*1024
374
+ conversation_prune_group_size: Optional[int] = 4
375
+ conversation_prune_strategy: Optional[str] = "summarize"
376
+
377
+ auto_command_max_iterations: Optional[int] = 10
378
+
379
+ skip_commit: Optional[bool] = False
380
+
373
381
  class Config:
374
382
  protected_namespaces = ()
375
383