auto-coder 0.1.299__py3-none-any.whl → 0.1.301__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.
- {auto_coder-0.1.299.dist-info → auto_coder-0.1.301.dist-info}/METADATA +1 -1
- {auto_coder-0.1.299.dist-info → auto_coder-0.1.301.dist-info}/RECORD +26 -24
- autocoder/agent/auto_learn_from_commit.py +125 -59
- autocoder/agent/auto_review_commit.py +106 -16
- autocoder/auto_coder.py +65 -66
- autocoder/auto_coder_runner.py +23 -40
- autocoder/command_parser.py +280 -0
- autocoder/commands/auto_command.py +130 -40
- autocoder/commands/tools.py +170 -10
- autocoder/common/__init__.py +9 -1
- autocoder/common/action_yml_file_manager.py +432 -0
- autocoder/common/auto_coder_lang.py +8 -2
- autocoder/common/auto_configure.py +6 -0
- autocoder/common/code_auto_merge.py +14 -0
- autocoder/common/code_auto_merge_diff.py +14 -0
- autocoder/common/code_auto_merge_editblock.py +14 -0
- autocoder/common/code_auto_merge_strict_diff.py +13 -0
- autocoder/common/command_completer.py +8 -1
- autocoder/common/memory_manager.py +5 -1
- autocoder/index/entry.py +17 -0
- autocoder/utils/__init__.py +13 -9
- autocoder/version.py +1 -1
- {auto_coder-0.1.299.dist-info → auto_coder-0.1.301.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.299.dist-info → auto_coder-0.1.301.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.299.dist-info → auto_coder-0.1.301.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.299.dist-info → auto_coder-0.1.301.dist-info}/top_level.txt +0 -0
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
autocoder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
autocoder/auto_coder.py,sha256=
|
|
2
|
+
autocoder/auto_coder.py,sha256=R5ONfVwoy7NsK1Uh68U5MZF0SLsOk13rXPm97PKk-OY,66006
|
|
3
3
|
autocoder/auto_coder_lang.py,sha256=Rtupq6N3_HT7JRhDKdgCBcwRaiAnyCOR_Gsp4jUomrI,3229
|
|
4
4
|
autocoder/auto_coder_rag.py,sha256=5TtAfbEBwyt-cB4WcI8eQ1G3AuKij0056wFYRViDhLs,34036
|
|
5
5
|
autocoder/auto_coder_rag_client_mcp.py,sha256=QRxUbjc6A8UmDMQ8lXgZkjgqtq3lgKYeatJbDY6rSo0,6270
|
|
6
6
|
autocoder/auto_coder_rag_mcp.py,sha256=-RrjNwFaS2e5v8XDIrKR-zlUNUE8UBaeOtojffBrvJo,8521
|
|
7
|
-
autocoder/auto_coder_runner.py,sha256=
|
|
7
|
+
autocoder/auto_coder_runner.py,sha256=pILuHRcw4FNT_VkHT9r0iEk4jpeMm1FqGYXWg8rsQus,100749
|
|
8
8
|
autocoder/auto_coder_server.py,sha256=E3Z829TPSooRSNhuh3_x9yaZi0f5G0Lm0ntoZhjGaoQ,20576
|
|
9
9
|
autocoder/benchmark.py,sha256=Ypomkdzd1T3GE6dRICY3Hj547dZ6_inqJbBJIp5QMco,4423
|
|
10
10
|
autocoder/chat_auto_coder.py,sha256=z_Kqd7CAecuNMa77kJn7iko2zTdko-4-o72a58H-_s8,24655
|
|
11
11
|
autocoder/chat_auto_coder_lang.py,sha256=-vyKq02RGn6N275YA06JZqXpfJkNq6PNjQ8wy4MmITE,20833
|
|
12
12
|
autocoder/command_args.py,sha256=9aYJ-AmPxP1sQh6ciw04FWHjSn31f2W9afXFwo8wgx4,30441
|
|
13
|
+
autocoder/command_parser.py,sha256=fx1g9E6GaM273lGTcJqaFQ-hoksS_Ik2glBMnVltPCE,10013
|
|
13
14
|
autocoder/lang.py,sha256=U6AjVV8Rs1uLyjFCZ8sT6WWuNUxMBqkXXIOs4S120uk,14511
|
|
14
15
|
autocoder/models.py,sha256=AyoZ-Pzy0oyYUmWCxOIRiOImsqboSfRET7LO9-UOuxI,11172
|
|
15
|
-
autocoder/version.py,sha256=
|
|
16
|
+
autocoder/version.py,sha256=8vsutezDX7FtnTgUbkxxSCmrd0M5CMXcXZ-buzH5bko,23
|
|
16
17
|
autocoder/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
18
|
autocoder/agent/auto_demand_organizer.py,sha256=NWSAEsEk94vT3lGjfo25kKLMwYdPcpy9e-i21txPasQ,6942
|
|
18
19
|
autocoder/agent/auto_filegroup.py,sha256=CW7bqp0FW1GIEMnl-blyAc2UGT7O9Mom0q66ITz1ckM,6635
|
|
19
20
|
autocoder/agent/auto_guess_query.py,sha256=rDSdhpPHcOGE5MuDXvIrhCXAPR4ARS1LqpyoLsx2Jhw,11374
|
|
20
|
-
autocoder/agent/auto_learn_from_commit.py,sha256=
|
|
21
|
-
autocoder/agent/auto_review_commit.py,sha256=
|
|
21
|
+
autocoder/agent/auto_learn_from_commit.py,sha256=YtiMkdcZ29etZxwU5Zir2LFnvfJlwEbpAaW_JYSa4nk,11465
|
|
22
|
+
autocoder/agent/auto_review_commit.py,sha256=rFADQbBikC8y9GTYXIvT6HONR26pLfrwoqOOhEiL7Ok,13262
|
|
22
23
|
autocoder/agent/auto_tool.py,sha256=DBzip-P_T6ZtT2eHexPcusmKYD0h7ufzp7TLwXAY10E,11554
|
|
23
24
|
autocoder/agent/coder.py,sha256=x6bdJwDuETGg9ebQnYlUWCxCtQcDGg73LtI6McpWslQ,72034
|
|
24
25
|
autocoder/agent/designer.py,sha256=EpRbzO58Xym3GrnppIT1Z8ZFAlnNfgzHbIzZ3PX-Yv8,27037
|
|
@@ -26,17 +27,18 @@ autocoder/agent/planner.py,sha256=SZTSZHxHzDmuWZo3K5fs79RwvJLWurg-nbJRRNbX65o,91
|
|
|
26
27
|
autocoder/agent/project_reader.py,sha256=tWLaPoLw1gI6kO_NzivQj28KbobU2ceOLuppHMbfGl8,18234
|
|
27
28
|
autocoder/chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
29
|
autocoder/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
autocoder/commands/auto_command.py,sha256=
|
|
30
|
+
autocoder/commands/auto_command.py,sha256=OqylAd4lLheVEk0XeYb85uBlWP8R6xQqW8_rKcDVEpQ,57616
|
|
30
31
|
autocoder/commands/auto_web.py,sha256=_449f4rCoRG7Sv0SB0hIBRFLPLPJ5DgWW4DlI22a3XY,39383
|
|
31
|
-
autocoder/commands/tools.py,sha256=
|
|
32
|
+
autocoder/commands/tools.py,sha256=4cNm_Mpjk9WNfSmKU7W0OjA89OqPC1mh8rSoSl8m4OE,27253
|
|
32
33
|
autocoder/common/JupyterClient.py,sha256=O-wi6pXeAEYhAY24kDa0BINrLYvKS6rKyWe98pDClS0,2816
|
|
33
34
|
autocoder/common/ShellClient.py,sha256=fM1q8t_XMSbLBl2zkCNC2J9xuyKN3eXzGm6hHhqL2WY,2286
|
|
34
|
-
autocoder/common/__init__.py,sha256=
|
|
35
|
+
autocoder/common/__init__.py,sha256=Do0ESMUr8OKZgOaD-9HpZh6cNJkWwFfL9QEgB8bxmaA,13893
|
|
36
|
+
autocoder/common/action_yml_file_manager.py,sha256=0hXoG2kyYj_88hOk081TVw-7zm1ZQ3SohGFSTB_IJSE,15252
|
|
35
37
|
autocoder/common/anything2images.py,sha256=0ILBbWzY02M-CiWB-vzuomb_J1hVdxRcenAfIrAXq9M,25283
|
|
36
38
|
autocoder/common/anything2img.py,sha256=iZQmg8srXlD7N5uGl5b_ONKJMBjYoW8kPmokkG6ISF0,10118
|
|
37
39
|
autocoder/common/audio.py,sha256=Kn9nWKQddWnUrAz0a_ZUgjcu4VUU_IcZBigT7n3N3qc,7439
|
|
38
|
-
autocoder/common/auto_coder_lang.py,sha256=
|
|
39
|
-
autocoder/common/auto_configure.py,sha256=
|
|
40
|
+
autocoder/common/auto_coder_lang.py,sha256=i4UE9udQ_fyvqlLYBGpDRpDt2zregE664jSozgisJwU,36383
|
|
41
|
+
autocoder/common/auto_configure.py,sha256=wUPX5urnwg4Y_yzW4HZ91zXFdKwzzgsrI67PjJNC06w,12900
|
|
40
42
|
autocoder/common/buildin_tokenizer.py,sha256=L7d5t39ZFvUd6EoMPXUhYK1toD0FHlRH1jtjKRGokWU,1236
|
|
41
43
|
autocoder/common/chunk_validation.py,sha256=BrR_ZWavW8IANuueEE7hS8NFAwEvm8TX34WnPx_1hs8,3030
|
|
42
44
|
autocoder/common/cleaner.py,sha256=NU72i8C6o9m0vXExab7nao5bstBUsfJFcj11cXa9l4U,1089
|
|
@@ -45,12 +47,12 @@ autocoder/common/code_auto_generate.py,sha256=i0f0BPTvt8QN5-arC2PqfMs4sukGJqFw58
|
|
|
45
47
|
autocoder/common/code_auto_generate_diff.py,sha256=EYGHf24fVAk3M8kXllXukdUvzo2I2Fb8qNrTiU_Qtug,18759
|
|
46
48
|
autocoder/common/code_auto_generate_editblock.py,sha256=1XmoLZl-XrrPOyHkSfqe0pOxi0Lp4d69oDQX6zzqs_c,20523
|
|
47
49
|
autocoder/common/code_auto_generate_strict_diff.py,sha256=68fAks4S6Hz0wAeXrdI1PjdeCiy0gXRhgEeIlgxB04E,17539
|
|
48
|
-
autocoder/common/code_auto_merge.py,sha256=
|
|
49
|
-
autocoder/common/code_auto_merge_diff.py,sha256=
|
|
50
|
-
autocoder/common/code_auto_merge_editblock.py,sha256=
|
|
51
|
-
autocoder/common/code_auto_merge_strict_diff.py,sha256=
|
|
50
|
+
autocoder/common/code_auto_merge.py,sha256=QsK4wdPxmxVDtIuaTGVhCEmLHYSVX0oa-Gq3xCoSd6g,9460
|
|
51
|
+
autocoder/common/code_auto_merge_diff.py,sha256=dHvgVk4V7O2J31d1JVnXezHcfvuhrS68poUvzDLRYUg,18770
|
|
52
|
+
autocoder/common/code_auto_merge_editblock.py,sha256=bx32Ew9Ih-cNqdbUlcczvNi1hAtYnxKyEtle-NqE04E,21229
|
|
53
|
+
autocoder/common/code_auto_merge_strict_diff.py,sha256=z6gt7an81xlE_Xdaw0jZD_qf093_V0FI78hkbdzP980,12921
|
|
52
54
|
autocoder/common/code_modification_ranker.py,sha256=e1i8oNPN_PfG4O8HQnQWxh9tyOd-ur6jFTXfkHPVXYo,13152
|
|
53
|
-
autocoder/common/command_completer.py,sha256=
|
|
55
|
+
autocoder/common/command_completer.py,sha256=xuCxYGKDccaozmzB6p3q0QI6mlzyM180g9mnVG5zvIk,35284
|
|
54
56
|
autocoder/common/command_generator.py,sha256=t1o1d7xEyfnPvY_MpG5usyx0eKW7WCUR0urKoqCex60,2761
|
|
55
57
|
autocoder/common/command_templates.py,sha256=WAixVjue5QmCFAD13K4ElfcOEjdeGr8tFb0atDAbEoo,8658
|
|
56
58
|
autocoder/common/computer_use.py,sha256=Z5RL-DgkcbF55YDsqnJ37loXGcm_1tzTheukjTTayJM,35816
|
|
@@ -69,7 +71,7 @@ autocoder/common/llm_rerank.py,sha256=FbvtCzaR661Mt2wn0qsuiEL1Y3puD6jeIJS4zg_e7B
|
|
|
69
71
|
autocoder/common/mcp_hub.py,sha256=9f55EOViYyhJSE8coZ5USXQBaCjg71nbdy9iwg3q2Z0,16764
|
|
70
72
|
autocoder/common/mcp_server.py,sha256=1SCtpBRmN299xWX-0aV0imWS2CX6zBUOZBocbV_J6B8,17415
|
|
71
73
|
autocoder/common/mcp_tools.py,sha256=YdEhDzRnwAr2J3D-23ExIQFWbrNO-EUpIxg179qs9Sw,12666
|
|
72
|
-
autocoder/common/memory_manager.py,sha256=
|
|
74
|
+
autocoder/common/memory_manager.py,sha256=Xx6Yv0ULxVfcFfmD36hdHFFhxCgRAs-5fTd0fLHJrpQ,3773
|
|
73
75
|
autocoder/common/model_speed_test.py,sha256=U48xUUpOnbwUal1cdij4YAn_H2PD2pNaqrMHaYtQRfI,15200
|
|
74
76
|
autocoder/common/printer.py,sha256=P1WU0QjlfnjqTP5uA55GkHZCpFzRPFkc34DMMandreg,2023
|
|
75
77
|
autocoder/common/recall_validation.py,sha256=Avt9Q9dX3kG6Pf2zsdlOHmsjd-OeSj7U1PFBDp_Cve0,1700
|
|
@@ -98,7 +100,7 @@ autocoder/dispacher/actions/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
|
98
100
|
autocoder/dispacher/actions/plugins/action_regex_project.py,sha256=AqGIkjbqV1eOS3vBoZUTSOpyOlkv1p5h35mI2Kcvekw,6906
|
|
99
101
|
autocoder/dispacher/actions/plugins/action_translate.py,sha256=GEn7dZA22jy5WyzINomjmzzB795p2Olg-CJla97lRF8,7744
|
|
100
102
|
autocoder/index/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
|
-
autocoder/index/entry.py,sha256=
|
|
103
|
+
autocoder/index/entry.py,sha256=_9lEt-yKE29hFeU5St_GdIvkGQkE-Bb7ZUdqMG-PxMY,15111
|
|
102
104
|
autocoder/index/for_command.py,sha256=BFvljE4t6VaMBGboZAuhUCzVK0EitCy_n5D_7FEnihw,3204
|
|
103
105
|
autocoder/index/index.py,sha256=3-SHlmeQMv6SFxNj7vVcNRDAYj9ZshuJJ1zXwBi0cDc,30873
|
|
104
106
|
autocoder/index/symbols_utils.py,sha256=_EP7E_qWXxluAxq3FGZLlLfdrfwx3FmxCdulI8VGuac,2244
|
|
@@ -159,7 +161,7 @@ autocoder/regex_project/__init__.py,sha256=EBZeCL5ORyD_9_5u_UuG4s7XtpXOu0y1sWDmx
|
|
|
159
161
|
autocoder/regexproject/__init__.py,sha256=OGlfVe2yulGIZstACbVePVbNXajvVLRFyubnIc-9Gw0,9758
|
|
160
162
|
autocoder/suffixproject/__init__.py,sha256=EOb8eUqfu3ka8mrggkXUfwX3SWnxqEoiYmDF7Zkf0F8,11143
|
|
161
163
|
autocoder/tsproject/__init__.py,sha256=LPehIUgzFbZ5DT_Pc0a_xCQQXEDxACPTMwXfFF7rcL0,11836
|
|
162
|
-
autocoder/utils/__init__.py,sha256=
|
|
164
|
+
autocoder/utils/__init__.py,sha256=W47ac6IOZhNR1rdbho9fvhHnPI_N1i4oMcZOwxLelbU,1123
|
|
163
165
|
autocoder/utils/_markitdown.py,sha256=RU88qn4eZfYIy0GDrPxlI8oYXIypbi63VRJjdlnE0VU,47431
|
|
164
166
|
autocoder/utils/auto_project_type.py,sha256=9_-wE9aavjbPiNSUVKxttJAdu5i5fu-zHyPYHr5XtWk,4422
|
|
165
167
|
autocoder/utils/coder.py,sha256=rK8e0svQBe0NOP26dIGToUXgha_hUDgxlWoC_p_r7oc,5698
|
|
@@ -183,9 +185,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
183
185
|
autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
184
186
|
autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=lkJ_A-sYU36JMzjFWkk3pR6uos8oZHYt9GPsPe_CPAo,11766
|
|
185
187
|
autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
186
|
-
auto_coder-0.1.
|
|
187
|
-
auto_coder-0.1.
|
|
188
|
-
auto_coder-0.1.
|
|
189
|
-
auto_coder-0.1.
|
|
190
|
-
auto_coder-0.1.
|
|
191
|
-
auto_coder-0.1.
|
|
188
|
+
auto_coder-0.1.301.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
189
|
+
auto_coder-0.1.301.dist-info/METADATA,sha256=U4lqu_7Roy09MdHghi_sNNQy0QSEq69xxPOxzEULgHo,2689
|
|
190
|
+
auto_coder-0.1.301.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
191
|
+
auto_coder-0.1.301.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
|
|
192
|
+
auto_coder-0.1.301.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
|
|
193
|
+
auto_coder-0.1.301.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
|
+
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
11
12
|
import hashlib
|
|
12
13
|
|
|
13
14
|
|
|
@@ -40,13 +41,12 @@ class AutoLearnFromCommit:
|
|
|
40
41
|
self.llm = llm
|
|
41
42
|
self.skip_diff = skip_diff
|
|
42
43
|
self.console = console or Console()
|
|
44
|
+
self.action_manager = ActionYmlFileManager(args.source_dir)
|
|
43
45
|
|
|
44
46
|
@byzerllm.prompt()
|
|
45
47
|
def learn(self, querie_with_urls_and_changes: List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]], query: str) -> Generator[str,None,None]:
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
下面用户对本次的目标以及你需要总结的要求:
|
|
48
|
+
"""
|
|
49
|
+
下面是触发这次代码变更的原始任务需求:
|
|
50
50
|
<goal>
|
|
51
51
|
{{ query }}
|
|
52
52
|
</goal>
|
|
@@ -77,70 +77,53 @@ class AutoLearnFromCommit:
|
|
|
77
77
|
{% endfor %}
|
|
78
78
|
{% endfor %}
|
|
79
79
|
</changes>
|
|
80
|
+
|
|
81
|
+
你的目标是,总结出这次修改重现步骤,要尽可能详细,达到当用户重新提交相同的需求,系统可以根据你这个流程,可以重新实现这一次修改。
|
|
82
|
+
|
|
83
|
+
在描述中,如果涉及到文件请用如下示例的格式:
|
|
84
|
+
@src/autocoder/utils/_markitdown.py
|
|
85
|
+
如果涉及到符号,比如函数名,变量名,类名等等,请用如下示例的格式:
|
|
86
|
+
@@DocxConverter(location: src/autocoder/utils/_markitdown.py)
|
|
80
87
|
|
|
81
|
-
请总结以下内容:
|
|
82
|
-
1. 代码调整模式:描述为了实现这个目标,通常需要对代码做出哪些通用调整
|
|
83
|
-
2. 关键修改点:指出本次提交中最关键或最具代表性的修改点
|
|
84
|
-
3. 潜在扩展:基于这些修改,未来类似需求可能需要进行哪些扩展
|
|
85
|
-
4. 注意事项:在实现类似功能时需要注意哪些问题
|
|
86
|
-
|
|
87
|
-
总结要求:
|
|
88
|
-
1. 总结应该抽象化,不要局限于具体实现细节
|
|
89
|
-
2. 对于每个模式都应该提供明确的适用场景
|
|
90
|
-
3. 应该考虑代码的可维护性和可扩展性
|
|
91
|
-
4. 应该指出在不同技术栈或框架下的通用性
|
|
92
88
|
"""
|
|
93
89
|
pass
|
|
94
90
|
|
|
95
|
-
def parse_history_tasks(self) -> List[Dict]:
|
|
91
|
+
def parse_history_tasks(self, commit_file_name: Optional[str] = None) -> List[Dict]:
|
|
96
92
|
"""
|
|
97
93
|
解析历史任务信息
|
|
98
94
|
|
|
99
95
|
Returns:
|
|
100
96
|
List[Dict]: 每个字典包含一个历史任务的信息
|
|
101
97
|
"""
|
|
102
|
-
#
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def get_seq(name):
|
|
110
|
-
return int(name.split("_")[0])
|
|
111
|
-
|
|
112
|
-
# 获取最新的action文件列表
|
|
113
|
-
action_files = sorted(action_files, key=get_seq)
|
|
114
|
-
action_files.reverse()
|
|
115
|
-
|
|
116
|
-
action_file = action_files[0]
|
|
98
|
+
# 使用 ActionManager 获取文件
|
|
99
|
+
if commit_file_name:
|
|
100
|
+
action_file = commit_file_name
|
|
101
|
+
else:
|
|
102
|
+
action_file = self.action_manager.get_latest_action_file()
|
|
103
|
+
if not action_file:
|
|
104
|
+
return []
|
|
117
105
|
|
|
118
106
|
querie_with_urls_and_changes = []
|
|
119
107
|
repo = git.Repo(self.project_dir)
|
|
120
108
|
|
|
121
109
|
# 收集所有query、urls和对应的文件变化
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
with open(yaml_path, 'r', encoding='utf-8') as f:
|
|
137
|
-
yaml_content = f.read()
|
|
138
|
-
file_md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
|
|
139
|
-
response_id = f"auto_coder_{yaml_file}_{file_md5}"
|
|
140
|
-
# 查找对应的commit
|
|
110
|
+
yaml_content = self.action_manager.load_yaml_content(action_file)
|
|
111
|
+
|
|
112
|
+
if not yaml_content:
|
|
113
|
+
return []
|
|
114
|
+
|
|
115
|
+
query = yaml_content.get('query', '')
|
|
116
|
+
urls = yaml_content.get('urls', [])
|
|
117
|
+
|
|
118
|
+
if query:
|
|
119
|
+
changes = {}
|
|
120
|
+
if not self.skip_diff:
|
|
121
|
+
# 使用 ActionManager 获取 commit ID
|
|
122
|
+
commit_id = self.action_manager.get_commit_id_from_file(action_file)
|
|
123
|
+
if commit_id:
|
|
141
124
|
try:
|
|
142
125
|
for commit in repo.iter_commits():
|
|
143
|
-
if
|
|
126
|
+
if commit_id in commit.message:
|
|
144
127
|
if commit.parents:
|
|
145
128
|
parent = commit.parents[0]
|
|
146
129
|
# 获取所有文件的前后内容
|
|
@@ -172,29 +155,112 @@ class AutoLearnFromCommit:
|
|
|
172
155
|
printer = Printer()
|
|
173
156
|
printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
174
157
|
|
|
175
|
-
|
|
158
|
+
querie_with_urls_and_changes.append((query, urls, changes))
|
|
176
159
|
|
|
177
|
-
return querie_with_urls_and_changes
|
|
160
|
+
return querie_with_urls_and_changes,action_file
|
|
178
161
|
|
|
162
|
+
def get_commit_changes(self, commit_id: str) -> List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]]:
|
|
163
|
+
"""
|
|
164
|
+
直接从Git仓库获取指定commit的变更
|
|
179
165
|
|
|
180
|
-
|
|
166
|
+
Args:
|
|
167
|
+
commit_id: Git commit的ID
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]]: 与parse_history_tasks格式相同的结果
|
|
171
|
+
"""
|
|
172
|
+
printer = Printer()
|
|
173
|
+
querie_with_urls_and_changes = []
|
|
174
|
+
changes = {}
|
|
175
|
+
modified_files = []
|
|
176
|
+
query = f"Review commit: {commit_id}"
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
repo = git.Repo(self.project_dir)
|
|
180
|
+
commit = repo.commit(commit_id)
|
|
181
|
+
|
|
182
|
+
if not commit.parents:
|
|
183
|
+
# 这是首次提交
|
|
184
|
+
printer.print_in_terminal("commit_is_initial", style="yellow", commit_id=commit_id)
|
|
185
|
+
# 获取首次提交的所有文件
|
|
186
|
+
for item in commit.tree.traverse():
|
|
187
|
+
if item.type == 'blob': # 只处理文件,不处理目录
|
|
188
|
+
file_path = item.path
|
|
189
|
+
modified_files.append(file_path)
|
|
190
|
+
# 首次提交前没有内容
|
|
191
|
+
before_content = None
|
|
192
|
+
# 获取提交后的内容
|
|
193
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
194
|
+
changes[file_path] = (before_content, after_content)
|
|
195
|
+
else:
|
|
196
|
+
# 获取parent commit
|
|
197
|
+
parent = commit.parents[0]
|
|
198
|
+
# 获取变更的文件列表
|
|
199
|
+
for diff_item in parent.diff(commit):
|
|
200
|
+
file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
|
|
201
|
+
modified_files.append(file_path)
|
|
202
|
+
|
|
203
|
+
# 获取变更前内容
|
|
204
|
+
before_content = None
|
|
205
|
+
try:
|
|
206
|
+
if diff_item.a_blob:
|
|
207
|
+
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
208
|
+
except git.exc.GitCommandError:
|
|
209
|
+
pass # 文件可能是新增的
|
|
210
|
+
|
|
211
|
+
# 获取变更后内容
|
|
212
|
+
after_content = None
|
|
213
|
+
try:
|
|
214
|
+
if diff_item.b_blob:
|
|
215
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
216
|
+
except git.exc.GitCommandError:
|
|
217
|
+
pass # 文件可能被删除
|
|
218
|
+
|
|
219
|
+
changes[file_path] = (before_content, after_content)
|
|
220
|
+
|
|
221
|
+
# 使用commit消息作为查询内容
|
|
222
|
+
query = commit.message
|
|
223
|
+
querie_with_urls_and_changes.append((query, modified_files, changes))
|
|
224
|
+
|
|
225
|
+
except git.exc.GitCommandError as e:
|
|
226
|
+
printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
227
|
+
except Exception as e:
|
|
228
|
+
printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
229
|
+
|
|
230
|
+
return querie_with_urls_and_changes,None
|
|
231
|
+
|
|
232
|
+
def learn_from_commit(self,query: str, conversations: List[Dict],commit_id: Optional[str] = None) -> Generator[str,None,None]:
|
|
181
233
|
"""
|
|
182
234
|
从最新的代码提交中学习通用模式
|
|
183
235
|
|
|
236
|
+
Args:
|
|
237
|
+
query: 用户的查询/要求
|
|
238
|
+
conversations: 之前的对话历史
|
|
239
|
+
commit_id: 可选的指定commit ID,如果提供则直接学习该commit
|
|
240
|
+
|
|
184
241
|
Returns:
|
|
185
242
|
Optional[Generator]: 学习结果生成器,如果出错则返回None
|
|
186
243
|
"""
|
|
187
244
|
printer = Printer()
|
|
245
|
+
commit_file_name = None
|
|
246
|
+
if commit_id:
|
|
247
|
+
# 使用 ActionManager 从 commit ID 获取文件名
|
|
248
|
+
commit_file_name = self.action_manager.get_file_name_from_commit_id(commit_id)
|
|
249
|
+
|
|
250
|
+
if not commit_file_name:
|
|
251
|
+
raise ValueError(printer.get_message_from_key_with_format("no_commit_file_name", commit_id=commit_id))
|
|
252
|
+
|
|
188
253
|
# 获取最新的提交信息
|
|
189
|
-
changes = self.parse_history_tasks()
|
|
254
|
+
changes,tmp_file_name = self.parse_history_tasks(commit_file_name=commit_file_name)
|
|
255
|
+
commit_file_name = tmp_file_name
|
|
190
256
|
if not changes:
|
|
191
257
|
printer.print_in_terminal("no_latest_commit", style="red")
|
|
192
|
-
return None
|
|
258
|
+
return None, None
|
|
193
259
|
|
|
194
260
|
# 调用LLM进行代码学习
|
|
195
261
|
try:
|
|
196
262
|
# 获取 prompt 内容
|
|
197
|
-
query = self.learn.prompt(changes, query)
|
|
263
|
+
query = self.learn.prompt(changes, query)
|
|
198
264
|
new_conversations = conversations.copy()[0:-1]
|
|
199
265
|
new_conversations.append({"role": "user", "content": query})
|
|
200
266
|
# 构造对话消息
|
|
@@ -203,7 +269,7 @@ class AutoLearnFromCommit:
|
|
|
203
269
|
conversations=new_conversations,
|
|
204
270
|
llm_config={}
|
|
205
271
|
)
|
|
206
|
-
return v
|
|
272
|
+
return v, commit_file_name
|
|
207
273
|
except Exception as e:
|
|
208
274
|
printer.print_in_terminal("code_learn_error", style="red", error=str(e))
|
|
209
|
-
return None
|
|
275
|
+
return None, commit_file_name
|
|
@@ -116,7 +116,7 @@ class AutoReviewCommit:
|
|
|
116
116
|
pass
|
|
117
117
|
|
|
118
118
|
|
|
119
|
-
def parse_history_tasks(self) -> List[Dict]:
|
|
119
|
+
def parse_history_tasks(self,commit_file_name: Optional[str] = None) -> List[Dict]:
|
|
120
120
|
"""
|
|
121
121
|
解析历史任务信息
|
|
122
122
|
|
|
@@ -129,14 +129,17 @@ class AutoReviewCommit:
|
|
|
129
129
|
if f[:3].isdigit() and "_" in f and f.endswith('.yml')
|
|
130
130
|
]
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
action_files.reverse()
|
|
132
|
+
if commit_file_name:
|
|
133
|
+
action_files = [f for f in action_files if f == commit_file_name]
|
|
134
|
+
else:
|
|
135
|
+
# 按序号排序
|
|
136
|
+
def get_seq(name):
|
|
137
|
+
return int(name.split("_")[0])
|
|
139
138
|
|
|
139
|
+
# 获取最新的action文件列表
|
|
140
|
+
action_files = sorted(action_files, key=get_seq)
|
|
141
|
+
action_files.reverse()
|
|
142
|
+
|
|
140
143
|
action_file = action_files[0]
|
|
141
144
|
|
|
142
145
|
querie_with_urls_and_changes = []
|
|
@@ -200,27 +203,114 @@ class AutoReviewCommit:
|
|
|
200
203
|
|
|
201
204
|
return querie_with_urls_and_changes
|
|
202
205
|
|
|
206
|
+
def get_commit_changes(self, commit_id: str) -> List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]]:
|
|
207
|
+
"""
|
|
208
|
+
直接从Git仓库获取指定commit的变更
|
|
203
209
|
|
|
204
|
-
|
|
210
|
+
Args:
|
|
211
|
+
commit_id: Git commit的ID
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]]: 与parse_history_tasks格式相同的结果
|
|
205
215
|
"""
|
|
206
|
-
|
|
216
|
+
printer = Printer()
|
|
217
|
+
querie_with_urls_and_changes = []
|
|
218
|
+
changes = {}
|
|
219
|
+
modified_files = []
|
|
220
|
+
query = f"Review commit: {commit_id}"
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
repo = git.Repo(self.project_dir)
|
|
224
|
+
commit = repo.commit(commit_id)
|
|
225
|
+
|
|
226
|
+
if not commit.parents:
|
|
227
|
+
# 这是首次提交
|
|
228
|
+
printer.print_in_terminal("commit_is_initial", style="yellow", commit_id=commit_id)
|
|
229
|
+
# 获取首次提交的所有文件
|
|
230
|
+
for item in commit.tree.traverse():
|
|
231
|
+
if item.type == 'blob': # 只处理文件,不处理目录
|
|
232
|
+
file_path = item.path
|
|
233
|
+
modified_files.append(file_path)
|
|
234
|
+
# 首次提交前没有内容
|
|
235
|
+
before_content = None
|
|
236
|
+
# 获取提交后的内容
|
|
237
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
238
|
+
changes[file_path] = (before_content, after_content)
|
|
239
|
+
else:
|
|
240
|
+
# 获取parent commit
|
|
241
|
+
parent = commit.parents[0]
|
|
242
|
+
# 获取变更的文件列表
|
|
243
|
+
for diff_item in parent.diff(commit):
|
|
244
|
+
file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
|
|
245
|
+
modified_files.append(file_path)
|
|
246
|
+
|
|
247
|
+
# 获取变更前内容
|
|
248
|
+
before_content = None
|
|
249
|
+
try:
|
|
250
|
+
if diff_item.a_blob:
|
|
251
|
+
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
252
|
+
except git.exc.GitCommandError:
|
|
253
|
+
pass # 文件可能是新增的
|
|
254
|
+
|
|
255
|
+
# 获取变更后内容
|
|
256
|
+
after_content = None
|
|
257
|
+
try:
|
|
258
|
+
if diff_item.b_blob:
|
|
259
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
260
|
+
except git.exc.GitCommandError:
|
|
261
|
+
pass # 文件可能被删除
|
|
262
|
+
|
|
263
|
+
changes[file_path] = (before_content, after_content)
|
|
264
|
+
|
|
265
|
+
# 使用commit消息作为查询内容
|
|
266
|
+
query = commit.message
|
|
267
|
+
querie_with_urls_and_changes.append((query, modified_files, changes))
|
|
268
|
+
|
|
269
|
+
except git.exc.GitCommandError as e:
|
|
270
|
+
printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
271
|
+
except Exception as e:
|
|
272
|
+
printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
273
|
+
|
|
274
|
+
return querie_with_urls_and_changes
|
|
275
|
+
|
|
276
|
+
def review_commit(self,query: str, conversations: List[Dict],commit_id: Optional[str] = None) -> Generator[str,None,None]:
|
|
277
|
+
"""
|
|
278
|
+
审查代码提交
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
query: 用户的查询/要求
|
|
282
|
+
conversations: 之前的对话历史
|
|
283
|
+
commit_id: 可选的指定commit ID,如果提供则直接审查该commit
|
|
207
284
|
|
|
208
285
|
Returns:
|
|
209
|
-
|
|
286
|
+
Generator[str,None,None]: 审查结果的生成器
|
|
210
287
|
"""
|
|
211
288
|
printer = Printer()
|
|
212
|
-
|
|
213
|
-
|
|
289
|
+
commit_file_name = None
|
|
290
|
+
if commit_id:
|
|
291
|
+
repo = git.Repo(self.project_dir)
|
|
292
|
+
commit = repo.commit(commit_id)
|
|
293
|
+
# auto_coder_000000001926_chat_action.yml_88614d5bd4046a068786c252fbc39c13
|
|
294
|
+
msg = commit.message
|
|
295
|
+
commit_file_info = msg.split("_")[0]
|
|
296
|
+
if commit_file_info.startswith("auto_coder_"):
|
|
297
|
+
commit_file_name = "_".join(msg.split("_",)[0:-1])
|
|
298
|
+
|
|
299
|
+
if not commit_file_name:
|
|
300
|
+
raise ValueError(printer.get_message_from_key_with_format("no_commit_file_name",commit_id=commit_id))
|
|
301
|
+
|
|
302
|
+
changes = self.parse_history_tasks(commit_file_name=commit_file_name)
|
|
303
|
+
|
|
214
304
|
if not changes:
|
|
215
|
-
printer.print_in_terminal("
|
|
305
|
+
printer.print_in_terminal("no_commit_found", style="red")
|
|
216
306
|
return None
|
|
217
307
|
|
|
218
308
|
# 调用LLM进行代码审查
|
|
219
309
|
try:
|
|
220
310
|
# 获取 prompt 内容
|
|
221
|
-
|
|
311
|
+
prompt_content = self.review.prompt(changes, query)
|
|
222
312
|
new_conversations = conversations.copy()[0:-1]
|
|
223
|
-
new_conversations.append({"role": "user", "content":
|
|
313
|
+
new_conversations.append({"role": "user", "content": prompt_content})
|
|
224
314
|
# 构造对话消息
|
|
225
315
|
v = stream_chat_with_continue(
|
|
226
316
|
llm=self.llm,
|