auto-coder 0.1.306__py3-none-any.whl → 0.1.308__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.306.dist-info → auto_coder-0.1.308.dist-info}/METADATA +1 -1
- {auto_coder-0.1.306.dist-info → auto_coder-0.1.308.dist-info}/RECORD +29 -29
- autocoder/agent/auto_demand_organizer.py +13 -20
- autocoder/agent/auto_filegroup.py +10 -16
- autocoder/agent/auto_learn_from_commit.py +22 -32
- autocoder/agent/auto_review_commit.py +12 -63
- autocoder/auto_coder.py +3 -6
- autocoder/auto_coder_runner.py +40 -8
- autocoder/commands/auto_command.py +31 -7
- autocoder/commands/tools.py +1 -1
- autocoder/common/__init__.py +2 -0
- autocoder/common/action_yml_file_manager.py +75 -37
- autocoder/common/code_auto_generate.py +2 -2
- autocoder/common/code_auto_generate_diff.py +2 -2
- autocoder/common/code_auto_generate_editblock.py +2 -2
- autocoder/common/code_auto_generate_strict_diff.py +2 -2
- autocoder/common/code_auto_merge.py +2 -2
- autocoder/common/code_auto_merge_diff.py +2 -2
- autocoder/common/code_auto_merge_editblock.py +2 -2
- autocoder/common/code_auto_merge_strict_diff.py +2 -2
- autocoder/common/code_modification_ranker.py +5 -1
- autocoder/common/git_utils.py +73 -56
- autocoder/common/stream_out_type.py +3 -0
- autocoder/memory/active_context_manager.py +16 -16
- autocoder/version.py +1 -1
- {auto_coder-0.1.306.dist-info → auto_coder-0.1.308.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.306.dist-info → auto_coder-0.1.308.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.306.dist-info → auto_coder-0.1.308.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.306.dist-info → auto_coder-0.1.308.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
autocoder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
autocoder/auto_coder.py,sha256=
|
|
2
|
+
autocoder/auto_coder.py,sha256=ifhdnd39tOIDu_4LdYTxjVCnwmpDoOC90RRwD8bhIKU,65983
|
|
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=bvd1UXYzVT2L-I2ZCkdxy9Ap8P2Q6F2JD-F7QLvaIPc,106545
|
|
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=Cp5_m3pCxEDcRrVG1uojTfD8xecdl9FvYtD948TvLsg,25223
|
|
@@ -14,13 +14,13 @@ autocoder/command_parser.py,sha256=fx1g9E6GaM273lGTcJqaFQ-hoksS_Ik2glBMnVltPCE,1
|
|
|
14
14
|
autocoder/lang.py,sha256=U6AjVV8Rs1uLyjFCZ8sT6WWuNUxMBqkXXIOs4S120uk,14511
|
|
15
15
|
autocoder/models.py,sha256=AyoZ-Pzy0oyYUmWCxOIRiOImsqboSfRET7LO9-UOuxI,11172
|
|
16
16
|
autocoder/run_context.py,sha256=IUfSO6_gp2Wt1blFWAmOpN0b0nDrTTk4LmtCYUBIoro,1643
|
|
17
|
-
autocoder/version.py,sha256=
|
|
17
|
+
autocoder/version.py,sha256=Cn-FGSwetliy8k_Sn6xMPmQzEopzQ5Jw26xsX1g7uA8,23
|
|
18
18
|
autocoder/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
autocoder/agent/auto_demand_organizer.py,sha256=
|
|
20
|
-
autocoder/agent/auto_filegroup.py,sha256=
|
|
19
|
+
autocoder/agent/auto_demand_organizer.py,sha256=URAq0gSEiHeV_W4zwhOI_83kHz0Ryfj1gcfh5jwCv_w,6501
|
|
20
|
+
autocoder/agent/auto_filegroup.py,sha256=pBsAkBcpFTff-9L5OwI8xhf2xPKpl-aZwz-skF2B6dc,6296
|
|
21
21
|
autocoder/agent/auto_guess_query.py,sha256=rDSdhpPHcOGE5MuDXvIrhCXAPR4ARS1LqpyoLsx2Jhw,11374
|
|
22
|
-
autocoder/agent/auto_learn_from_commit.py,sha256=
|
|
23
|
-
autocoder/agent/auto_review_commit.py,sha256=
|
|
22
|
+
autocoder/agent/auto_learn_from_commit.py,sha256=edD4GQJyO2qvVnTKyldeswWoNeKe1Aaua6ieJzlGlFI,10662
|
|
23
|
+
autocoder/agent/auto_review_commit.py,sha256=mHi26sU4gJAsutqJyLyXfg7DfNZJNt-H7_2a-a8pLEQ,10563
|
|
24
24
|
autocoder/agent/auto_tool.py,sha256=DBzip-P_T6ZtT2eHexPcusmKYD0h7ufzp7TLwXAY10E,11554
|
|
25
25
|
autocoder/agent/coder.py,sha256=x6bdJwDuETGg9ebQnYlUWCxCtQcDGg73LtI6McpWslQ,72034
|
|
26
26
|
autocoder/agent/designer.py,sha256=EpRbzO58Xym3GrnppIT1Z8ZFAlnNfgzHbIzZ3PX-Yv8,27037
|
|
@@ -28,13 +28,13 @@ autocoder/agent/planner.py,sha256=SZTSZHxHzDmuWZo3K5fs79RwvJLWurg-nbJRRNbX65o,91
|
|
|
28
28
|
autocoder/agent/project_reader.py,sha256=tWLaPoLw1gI6kO_NzivQj28KbobU2ceOLuppHMbfGl8,18234
|
|
29
29
|
autocoder/chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
30
|
autocoder/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
-
autocoder/commands/auto_command.py,sha256=
|
|
31
|
+
autocoder/commands/auto_command.py,sha256=fZ4TNU4YA9qdoVHmZX0rb6sV_N-DEcgSLaC5s3PGSHA,64200
|
|
32
32
|
autocoder/commands/auto_web.py,sha256=Cc0eb6JN3SvFy3GD_lpSLvIqj7F1eFDTcwg1t-zDcKg,39024
|
|
33
|
-
autocoder/commands/tools.py,sha256
|
|
33
|
+
autocoder/commands/tools.py,sha256=-wPTD7RltwCGdoIRqEeOfgyRU5rVMOtpW6eug6kSpUs,28112
|
|
34
34
|
autocoder/common/JupyterClient.py,sha256=O-wi6pXeAEYhAY24kDa0BINrLYvKS6rKyWe98pDClS0,2816
|
|
35
35
|
autocoder/common/ShellClient.py,sha256=fM1q8t_XMSbLBl2zkCNC2J9xuyKN3eXzGm6hHhqL2WY,2286
|
|
36
|
-
autocoder/common/__init__.py,sha256=
|
|
37
|
-
autocoder/common/action_yml_file_manager.py,sha256=
|
|
36
|
+
autocoder/common/__init__.py,sha256=sIbE0Gm30MkCmZ9ClQeKx1Hw-vjdcVF65hO5TschS1Y,14070
|
|
37
|
+
autocoder/common/action_yml_file_manager.py,sha256=w-422xnvOfhf3MFxNLCZuAEUDa8RrYX12ngHs-fsH0k,17358
|
|
38
38
|
autocoder/common/anything2images.py,sha256=0ILBbWzY02M-CiWB-vzuomb_J1hVdxRcenAfIrAXq9M,25283
|
|
39
39
|
autocoder/common/anything2img.py,sha256=iZQmg8srXlD7N5uGl5b_ONKJMBjYoW8kPmokkG6ISF0,10118
|
|
40
40
|
autocoder/common/audio.py,sha256=Kn9nWKQddWnUrAz0a_ZUgjcu4VUU_IcZBigT7n3N3qc,7439
|
|
@@ -44,15 +44,15 @@ autocoder/common/buildin_tokenizer.py,sha256=L7d5t39ZFvUd6EoMPXUhYK1toD0FHlRH1jt
|
|
|
44
44
|
autocoder/common/chunk_validation.py,sha256=BrR_ZWavW8IANuueEE7hS8NFAwEvm8TX34WnPx_1hs8,3030
|
|
45
45
|
autocoder/common/cleaner.py,sha256=NU72i8C6o9m0vXExab7nao5bstBUsfJFcj11cXa9l4U,1089
|
|
46
46
|
autocoder/common/code_auto_execute.py,sha256=4KXGmiGObr_B1d6tzV9dwS6MifCSc3Gm4j2d6ildBXQ,6867
|
|
47
|
-
autocoder/common/code_auto_generate.py,sha256=
|
|
48
|
-
autocoder/common/code_auto_generate_diff.py,sha256=
|
|
49
|
-
autocoder/common/code_auto_generate_editblock.py,sha256=
|
|
50
|
-
autocoder/common/code_auto_generate_strict_diff.py,sha256=
|
|
51
|
-
autocoder/common/code_auto_merge.py,sha256=
|
|
52
|
-
autocoder/common/code_auto_merge_diff.py,sha256=
|
|
53
|
-
autocoder/common/code_auto_merge_editblock.py,sha256=
|
|
54
|
-
autocoder/common/code_auto_merge_strict_diff.py,sha256=
|
|
55
|
-
autocoder/common/code_modification_ranker.py,sha256=
|
|
47
|
+
autocoder/common/code_auto_generate.py,sha256=mxCPG-RC36q5POPMozPytjJcK0ExUeyau7b9ZWWScps,17228
|
|
48
|
+
autocoder/common/code_auto_generate_diff.py,sha256=lddReDQzJts25x55YDbFWJBJ_n9OzsLkyQ-cc1DFw1M,23095
|
|
49
|
+
autocoder/common/code_auto_generate_editblock.py,sha256=YfXuSYogJ5YoHTsx6LN5pPskZPop-noNViiDSRACOYU,24988
|
|
50
|
+
autocoder/common/code_auto_generate_strict_diff.py,sha256=cKCcDfVADSbkwPMWmHGhRjzKutieEw80NjFjwZbFudw,21990
|
|
51
|
+
autocoder/common/code_auto_merge.py,sha256=WaU-T-ZVn3QDaA_SrdkHciUPKDcTfVa-IbhHKBYEv5w,9961
|
|
52
|
+
autocoder/common/code_auto_merge_diff.py,sha256=DcljWrtlejq2cb9Gj-jBjvUQzRbCE2uMNGg8SBOhEnk,19271
|
|
53
|
+
autocoder/common/code_auto_merge_editblock.py,sha256=pLgs1HsS4mRkO2cm7T18u4w8T3PjSMxqNbJZ4LHnnWI,21765
|
|
54
|
+
autocoder/common/code_auto_merge_strict_diff.py,sha256=C35pFxhkgypsm50VDAFOBAT6YXMtzKTvIpEUH1GjZZg,13209
|
|
55
|
+
autocoder/common/code_modification_ranker.py,sha256=Ld3wtjV10zW7lN_L3bKEsvi7RvAleB8r1DD9eLmVnx4,13462
|
|
56
56
|
autocoder/common/command_completer.py,sha256=jBFi8Y1xWmMcxwdDz6Gs7r8ADFPb7eRr9egWU0vLxLo,35787
|
|
57
57
|
autocoder/common/command_generator.py,sha256=YwB_E818vx0fQDOpLD61GivsSgLnrIoxKrY22ka49JU,2797
|
|
58
58
|
autocoder/common/command_templates.py,sha256=WAixVjue5QmCFAD13K4ElfcOEjdeGr8tFb0atDAbEoo,8658
|
|
@@ -63,7 +63,7 @@ autocoder/common/const.py,sha256=eTjhjh4Aj4CUzviJ81jaf3Y5cwqsLATySn2wJxaS6RQ,291
|
|
|
63
63
|
autocoder/common/context_pruner.py,sha256=HlU5BmxpCX7uVTJUsTFLlXvkwcOQuidI9uCKZaFxh6s,19874
|
|
64
64
|
autocoder/common/conversation_pruner.py,sha256=pzmrQEa7pFzA66eYSS_h7VqP6ZwUABeooDQzm0PGu0A,5770
|
|
65
65
|
autocoder/common/files.py,sha256=nPiKcnUcYZbSUn3TskKeTVnAxCJRtuehPuB_5d2imX8,4618
|
|
66
|
-
autocoder/common/git_utils.py,sha256=
|
|
66
|
+
autocoder/common/git_utils.py,sha256=yxV-eYYwsncNpVs07Nk61506FFpG2REC43l6ppFCYWM,27081
|
|
67
67
|
autocoder/common/global_cancel.py,sha256=TyjYQPESwo04D1BOTmC9hH7IbkKDDM-b2zPacEHGIQ8,3264
|
|
68
68
|
autocoder/common/image_to_page.py,sha256=yWiTJQ49Lm3j0FngiJhQ9u7qayqE_bOGb8Rk0TmSWx0,14123
|
|
69
69
|
autocoder/common/index_import_export.py,sha256=h758AYY1df6JMTKUXYmMkSgxItfymDt82XT7O-ygEuw,4565
|
|
@@ -82,7 +82,7 @@ autocoder/common/search.py,sha256=245iPFgWhMldoUK3CqCP89ltaxZiNPK73evoG6Fp1h8,16
|
|
|
82
82
|
autocoder/common/search_replace.py,sha256=GphFkc57Hb673CAwmbiocqTbw8vrV7TrZxtOhD0332g,22147
|
|
83
83
|
autocoder/common/shells.py,sha256=elminFpNosnV0hsEUcsugDxlGO8NfH96uah-8bkaBvA,19929
|
|
84
84
|
autocoder/common/stats_panel.py,sha256=wGl9O45pjVVDxhNumLv4_NfLYSlUP_18Tw4hcJSjw50,4596
|
|
85
|
-
autocoder/common/stream_out_type.py,sha256=
|
|
85
|
+
autocoder/common/stream_out_type.py,sha256=uNHRg-1my6CxcPzQM6pACrYpTZbxOenVT8aLxnruv2w,333
|
|
86
86
|
autocoder/common/sys_prompt.py,sha256=JlexfjZt554faqbgkCmzOJqYUzDHfbnxly5ugFfHfEE,26403
|
|
87
87
|
autocoder/common/text.py,sha256=KGRQq314GHBmY4MWG8ossRoQi1_DTotvhxchpn78c-k,1003
|
|
88
88
|
autocoder/common/types.py,sha256=PXTETrsTvhLE49jqAeUKGySvxBN9pjeyCgRHLDYdd9U,664
|
|
@@ -117,7 +117,7 @@ autocoder/index/filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
117
117
|
autocoder/index/filter/normal_filter.py,sha256=MI-8xdXCrniaxYCHVTLkq5tafvcUiauD3LN0b3ymRXI,8361
|
|
118
118
|
autocoder/index/filter/quick_filter.py,sha256=ozESEgy506FQ5ecjOumyo4D_KMrterB1QLmnVtiyOiM,43264
|
|
119
119
|
autocoder/memory/__init__.py,sha256=5FeGvsesRViYL4BkFiHw9SdlyHeWlqALpTyqOpfnBRw,179
|
|
120
|
-
autocoder/memory/active_context_manager.py,sha256=
|
|
120
|
+
autocoder/memory/active_context_manager.py,sha256=7f7DznnLXbXH6yptN8rOSSJcre0bSJ2dU9mM9L6bvno,27106
|
|
121
121
|
autocoder/memory/active_package.py,sha256=CyfqZSgNucE5mGQH5JGHTE8lTU0KjFGkW2YN8vl9SoI,17480
|
|
122
122
|
autocoder/memory/async_processor.py,sha256=htHzLGupw9IHQAEdLe2AEaALZSItPi3AltDt8FMTRHk,4643
|
|
123
123
|
autocoder/memory/directory_mapper.py,sha256=BXHblOdRpeZb7URDECALp9uN5oi91KmkW9g_UaWFuZY,2513
|
|
@@ -198,9 +198,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
198
198
|
autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
199
199
|
autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=xuBeWD0YOckqRo8JB1WkVIMOYH6c24m7JfV4svBfPDo,15113
|
|
200
200
|
autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
201
|
-
auto_coder-0.1.
|
|
202
|
-
auto_coder-0.1.
|
|
203
|
-
auto_coder-0.1.
|
|
204
|
-
auto_coder-0.1.
|
|
205
|
-
auto_coder-0.1.
|
|
206
|
-
auto_coder-0.1.
|
|
201
|
+
auto_coder-0.1.308.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
202
|
+
auto_coder-0.1.308.dist-info/METADATA,sha256=9Eqj3xOim16B-cWJRnUGOaF16HLZeCYW2wIIRaNJWAk,2721
|
|
203
|
+
auto_coder-0.1.308.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
204
|
+
auto_coder-0.1.308.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
|
|
205
|
+
auto_coder-0.1.308.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
|
|
206
|
+
auto_coder-0.1.308.dist-info/RECORD,,
|
|
@@ -6,6 +6,8 @@ import byzerllm
|
|
|
6
6
|
import pydantic
|
|
7
7
|
import git
|
|
8
8
|
|
|
9
|
+
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
class DemandItem(pydantic.BaseModel):
|
|
11
13
|
"""单个需求项"""
|
|
@@ -44,6 +46,7 @@ class AutoDemandOrganizer:
|
|
|
44
46
|
file_size_limit: 最多分析多少历史任务
|
|
45
47
|
"""
|
|
46
48
|
self.project_dir = project_dir
|
|
49
|
+
self.action_file_manager = ActionYmlFileManager(project_dir)
|
|
47
50
|
self.actions_dir = os.path.join(project_dir, "actions")
|
|
48
51
|
self.llm = llm
|
|
49
52
|
self.file_size_limit = file_size_limit
|
|
@@ -162,26 +165,16 @@ class AutoDemandOrganizer:
|
|
|
162
165
|
|
|
163
166
|
if query and urls:
|
|
164
167
|
commit_diff = ""
|
|
165
|
-
if not self.skip_diff:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
parent = commit.parents[0]
|
|
176
|
-
commit_diff = repo.git.diff(
|
|
177
|
-
parent.hexsha, commit.hexsha)
|
|
178
|
-
else:
|
|
179
|
-
commit_diff = repo.git.show(commit.hexsha)
|
|
180
|
-
break
|
|
181
|
-
except git.exc.GitCommandError as e:
|
|
182
|
-
logger.error(f"Git命令执行错误: {str(e)}")
|
|
183
|
-
except Exception as e:
|
|
184
|
-
logger.error(f"获取commit diff时出错: {str(e)}")
|
|
168
|
+
if not self.skip_diff:
|
|
169
|
+
commit_id = self.action_file_manager.get_commit_id_from_file(yaml_file)
|
|
170
|
+
commit = repo.commit(commit_id)
|
|
171
|
+
if commit:
|
|
172
|
+
if commit.parents:
|
|
173
|
+
parent = commit.parents[0]
|
|
174
|
+
commit_diff = repo.git.diff(
|
|
175
|
+
parent.hexsha, commit.hexsha)
|
|
176
|
+
else:
|
|
177
|
+
commit_diff = repo.git.show(commit.hexsha)
|
|
185
178
|
|
|
186
179
|
querie_with_urls_and_diffs.append((query, urls, commit_diff))
|
|
187
180
|
|
|
@@ -4,6 +4,7 @@ import yaml
|
|
|
4
4
|
from loguru import logger
|
|
5
5
|
import byzerllm
|
|
6
6
|
import pydantic
|
|
7
|
+
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class FileGroup(pydantic.BaseModel):
|
|
@@ -40,6 +41,7 @@ class AutoFileGroup:
|
|
|
40
41
|
actions_dir: 包含YAML文件的目录
|
|
41
42
|
"""
|
|
42
43
|
self.project_dir = project_dir
|
|
44
|
+
self.action_manager = ActionYmlFileManager(project_dir)
|
|
43
45
|
self.actions_dir = os.path.join(project_dir, "actions")
|
|
44
46
|
self.llm = llm
|
|
45
47
|
self.file_size_limit = file_size_limit
|
|
@@ -152,23 +154,15 @@ class AutoFileGroup:
|
|
|
152
154
|
commit_diff = ""
|
|
153
155
|
if not self.skip_diff:
|
|
154
156
|
# 计算文件的MD5用于匹配commit
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
commit_id = self.action_manager.get_commit_id_from_file(yaml_file)
|
|
158
|
+
commit = repo.commit(commit_id)
|
|
157
159
|
# 查找对应的commit
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
parent.hexsha, commit.hexsha)
|
|
165
|
-
else:
|
|
166
|
-
commit_diff = repo.git.show(commit.hexsha)
|
|
167
|
-
break
|
|
168
|
-
except git.exc.GitCommandError as e:
|
|
169
|
-
logger.error(f"Git命令执行错误: {str(e)}")
|
|
170
|
-
except Exception as e:
|
|
171
|
-
logger.error(f"获取commit diff时出错: {str(e)}")
|
|
160
|
+
if commit and commit.parents:
|
|
161
|
+
parent = commit.parents[0]
|
|
162
|
+
commit_diff = repo.git.diff(
|
|
163
|
+
parent.hexsha, commit.hexsha)
|
|
164
|
+
else:
|
|
165
|
+
commit_diff = repo.git.show(commit.hexsha)
|
|
172
166
|
|
|
173
167
|
querie_with_urls_and_diffs.append((query, urls, commit_diff))
|
|
174
168
|
|
|
@@ -121,40 +121,30 @@ class AutoLearnFromCommit:
|
|
|
121
121
|
if not self.skip_diff:
|
|
122
122
|
# 使用 ActionManager 获取 commit ID
|
|
123
123
|
commit_id = self.action_manager.get_commit_id_from_file(action_file)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
139
|
-
except git.exc.GitCommandError:
|
|
140
|
-
pass # 文件可能是新增的
|
|
124
|
+
commit = repo.commit(commit_id)
|
|
125
|
+
if commit and commit.parents:
|
|
126
|
+
parent = commit.parents[0]
|
|
127
|
+
# 获取所有文件的前后内容
|
|
128
|
+
for diff_item in parent.diff(commit):
|
|
129
|
+
file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
|
|
130
|
+
|
|
131
|
+
# 获取变更前内容
|
|
132
|
+
before_content = None
|
|
133
|
+
try:
|
|
134
|
+
if diff_item.a_blob:
|
|
135
|
+
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
136
|
+
except git.exc.GitCommandError:
|
|
137
|
+
pass # 文件可能是新增的
|
|
141
138
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
139
|
+
# 获取变更后内容
|
|
140
|
+
after_content = None
|
|
141
|
+
try:
|
|
142
|
+
if diff_item.b_blob:
|
|
143
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
144
|
+
except git.exc.GitCommandError:
|
|
145
|
+
pass # 文件可能被删除
|
|
149
146
|
|
|
150
|
-
|
|
151
|
-
break
|
|
152
|
-
except git.exc.GitCommandError as e:
|
|
153
|
-
printer = Printer()
|
|
154
|
-
printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
155
|
-
except Exception as e:
|
|
156
|
-
printer = Printer()
|
|
157
|
-
printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
147
|
+
changes[file_path] = (before_content, after_content)
|
|
158
148
|
|
|
159
149
|
querie_with_urls_and_changes.append((query, urls, changes))
|
|
160
150
|
|
|
@@ -9,6 +9,7 @@ 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
11
|
import hashlib
|
|
12
|
+
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def load_yaml_config(yaml_file: str) -> Dict:
|
|
@@ -41,6 +42,7 @@ class AutoReviewCommit:
|
|
|
41
42
|
self.llm = llm
|
|
42
43
|
self.skip_diff = skip_diff
|
|
43
44
|
self.console = console or Console()
|
|
45
|
+
self.action_yml_manager = ActionYmlFileManager(source_dir=args.source_dir)
|
|
44
46
|
|
|
45
47
|
@byzerllm.prompt()
|
|
46
48
|
def review(self, querie_with_urls_and_changes: List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]], query: str) -> Generator[str,None,None]:
|
|
@@ -141,66 +143,16 @@ class AutoReviewCommit:
|
|
|
141
143
|
action_files = sorted(action_files, key=get_seq)
|
|
142
144
|
action_files.reverse()
|
|
143
145
|
|
|
146
|
+
if not action_files:
|
|
147
|
+
return []
|
|
148
|
+
|
|
144
149
|
action_file = action_files[0]
|
|
145
|
-
|
|
146
150
|
querie_with_urls_and_changes = []
|
|
147
|
-
repo = git.Repo(self.project_dir)
|
|
148
|
-
|
|
149
|
-
# 收集所有query、urls和对应的文件变化
|
|
150
|
-
for yaml_file in [action_file]:
|
|
151
|
-
yaml_path = os.path.join(self.actions_dir, yaml_file)
|
|
152
|
-
config = load_yaml_config(yaml_path)
|
|
153
151
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
urls = config.get('urls', [])
|
|
159
|
-
|
|
160
|
-
if query:
|
|
161
|
-
changes = {}
|
|
162
|
-
if not self.skip_diff:
|
|
163
|
-
# 计算文件的MD5用于匹配commit
|
|
164
|
-
with open(yaml_path, 'r', encoding='utf-8') as f:
|
|
165
|
-
yaml_content = f.read()
|
|
166
|
-
file_md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
|
|
167
|
-
response_id = f"auto_coder_{yaml_file}_{file_md5}"
|
|
168
|
-
# 查找对应的commit
|
|
169
|
-
try:
|
|
170
|
-
for commit in repo.iter_commits():
|
|
171
|
-
if response_id in commit.message:
|
|
172
|
-
if commit.parents:
|
|
173
|
-
parent = commit.parents[0]
|
|
174
|
-
# 获取所有文件的前后内容
|
|
175
|
-
for diff_item in parent.diff(commit):
|
|
176
|
-
file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
|
|
177
|
-
|
|
178
|
-
# 获取变更前内容
|
|
179
|
-
before_content = None
|
|
180
|
-
try:
|
|
181
|
-
if diff_item.a_blob:
|
|
182
|
-
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
183
|
-
except git.exc.GitCommandError:
|
|
184
|
-
pass # 文件可能是新增的
|
|
185
|
-
|
|
186
|
-
# 获取变更后内容
|
|
187
|
-
after_content = None
|
|
188
|
-
try:
|
|
189
|
-
if diff_item.b_blob:
|
|
190
|
-
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
191
|
-
except git.exc.GitCommandError:
|
|
192
|
-
pass # 文件可能被删除
|
|
193
|
-
|
|
194
|
-
changes[file_path] = (before_content, after_content)
|
|
195
|
-
break
|
|
196
|
-
except git.exc.GitCommandError as e:
|
|
197
|
-
printer = Printer()
|
|
198
|
-
printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
199
|
-
except Exception as e:
|
|
200
|
-
printer = Printer()
|
|
201
|
-
printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
202
|
-
|
|
203
|
-
querie_with_urls_and_changes.append((query, urls, changes))
|
|
152
|
+
# 使用ActionYmlFileManager获取提交变更
|
|
153
|
+
changes = self.action_yml_manager.get_commit_changes(action_file)
|
|
154
|
+
if changes:
|
|
155
|
+
querie_with_urls_and_changes = changes
|
|
204
156
|
|
|
205
157
|
return querie_with_urls_and_changes
|
|
206
158
|
|
|
@@ -289,14 +241,11 @@ class AutoReviewCommit:
|
|
|
289
241
|
printer = Printer()
|
|
290
242
|
commit_file_name = None
|
|
291
243
|
if commit_id:
|
|
244
|
+
# 利用ActionYmlFileManager获取文件名
|
|
292
245
|
repo = git.Repo(self.project_dir)
|
|
293
246
|
commit = repo.commit(commit_id)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
commit_file_info = msg.split("_")[0]
|
|
297
|
-
if commit_file_info.startswith("auto_coder_"):
|
|
298
|
-
commit_file_name = "_".join(msg.split("_",)[0:-1])
|
|
299
|
-
|
|
247
|
+
commit_file_name = self.action_yml_manager.get_file_name_from_commit_msg(commit.message)
|
|
248
|
+
|
|
300
249
|
if not commit_file_name:
|
|
301
250
|
raise ValueError(printer.get_message_from_key_with_format("no_commit_file_name",commit_id=commit_id))
|
|
302
251
|
|
autocoder/auto_coder.py
CHANGED
|
@@ -27,7 +27,6 @@ from autocoder.utils.rest import HttpDoc
|
|
|
27
27
|
from byzerllm.apps.byzer_storage.env import get_latest_byzer_retrieval_lib
|
|
28
28
|
from autocoder.command_args import parse_args
|
|
29
29
|
from autocoder.rag.api_server import serve, ServerArgs
|
|
30
|
-
from autocoder.utils import open_yaml_file_in_editor, get_last_yaml_file
|
|
31
30
|
from autocoder.utils.request_queue import (
|
|
32
31
|
request_queue,
|
|
33
32
|
RequestValue,
|
|
@@ -120,12 +119,10 @@ def main(input_args: Optional[List[str]] = None):
|
|
|
120
119
|
# args.request_id = str(uuid.uuid4())
|
|
121
120
|
|
|
122
121
|
if raw_args.command == "revert":
|
|
123
|
-
repo_path = args.source_dir
|
|
124
|
-
|
|
125
122
|
file_name = os.path.basename(args.file)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
action_file_manager = ActionYmlFileManager(source_dir=args.source_dir)
|
|
124
|
+
revert_result = action_file_manager.revert_file(file_name)
|
|
125
|
+
|
|
129
126
|
if revert_result:
|
|
130
127
|
print(f"Successfully reverted changes for {args.file}")
|
|
131
128
|
else:
|
autocoder/auto_coder_runner.py
CHANGED
|
@@ -17,6 +17,7 @@ from contextlib import contextmanager
|
|
|
17
17
|
from typing import List, Dict, Any, Optional
|
|
18
18
|
from autocoder.common import AutoCoderArgs
|
|
19
19
|
from pydantic import BaseModel
|
|
20
|
+
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
20
21
|
from autocoder.common.result_manager import ResultManager
|
|
21
22
|
from autocoder.version import __version__
|
|
22
23
|
from autocoder.auto_coder import main as auto_coder_main
|
|
@@ -695,9 +696,7 @@ def revert():
|
|
|
695
696
|
|
|
696
697
|
if "Successfully reverted changes" in s:
|
|
697
698
|
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
698
|
-
}})
|
|
699
|
-
|
|
700
|
-
os.remove(file_path)
|
|
699
|
+
}})
|
|
701
700
|
else:
|
|
702
701
|
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
703
702
|
}})
|
|
@@ -1428,12 +1427,33 @@ def commit(query: str):
|
|
|
1428
1427
|
with open(os.path.join(execute_file), "w",encoding="utf-8") as f:
|
|
1429
1428
|
f.write(yaml_content)
|
|
1430
1429
|
|
|
1431
|
-
|
|
1432
|
-
|
|
1430
|
+
args.file = execute_file
|
|
1431
|
+
|
|
1433
1432
|
file_name = os.path.basename(execute_file)
|
|
1434
1433
|
commit_result = git_utils.commit_changes(
|
|
1435
1434
|
".", f"{commit_message}\nauto_coder_{file_name}"
|
|
1436
1435
|
)
|
|
1436
|
+
|
|
1437
|
+
printer = Printer()
|
|
1438
|
+
|
|
1439
|
+
action_yml_file_manager = ActionYmlFileManager(args.source_dir)
|
|
1440
|
+
action_file_name = os.path.basename(args.file)
|
|
1441
|
+
add_updated_urls = []
|
|
1442
|
+
commit_result.changed_files
|
|
1443
|
+
for file in commit_result.changed_files:
|
|
1444
|
+
add_updated_urls.append(os.path.join(args.source_dir, file))
|
|
1445
|
+
|
|
1446
|
+
args.add_updated_urls = add_updated_urls
|
|
1447
|
+
update_yaml_success = action_yml_file_manager.update_yaml_field(action_file_name, "add_updated_urls", add_updated_urls)
|
|
1448
|
+
if not update_yaml_success:
|
|
1449
|
+
printer.print_in_terminal("yaml_save_error", style="red", yaml_file=action_file_name)
|
|
1450
|
+
|
|
1451
|
+
if args.enable_active_context:
|
|
1452
|
+
active_context_manager = ActiveContextManager(llm, args.source_dir)
|
|
1453
|
+
task_id = active_context_manager.process_changes(args)
|
|
1454
|
+
printer.print_in_terminal("active_context_background_task",
|
|
1455
|
+
style="blue",
|
|
1456
|
+
task_id=task_id)
|
|
1437
1457
|
git_utils.print_commit_info(commit_result=commit_result)
|
|
1438
1458
|
if commit_message:
|
|
1439
1459
|
printer.print_in_terminal("commit_message", style="green", model_name=target_model, message=commit_message)
|
|
@@ -1800,17 +1820,29 @@ def active_context(query: str):
|
|
|
1800
1820
|
if len(commands_infos) > 0:
|
|
1801
1821
|
if "list" in commands_infos:
|
|
1802
1822
|
command = "list"
|
|
1823
|
+
if "run" in commands_infos:
|
|
1824
|
+
command = "run"
|
|
1803
1825
|
|
|
1804
1826
|
args = get_final_config()
|
|
1827
|
+
printer = Printer()
|
|
1805
1828
|
# 获取LLM实例
|
|
1806
1829
|
llm = get_single_llm(args.model,product_mode=args.product_mode)
|
|
1830
|
+
action_file_manager = ActionYmlFileManager(args.source_dir)
|
|
1807
1831
|
|
|
1808
1832
|
# 获取配置和参数
|
|
1809
1833
|
|
|
1810
1834
|
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1835
|
+
active_context_manager = ActiveContextManager(llm, args.source_dir)
|
|
1836
|
+
if command == "run":
|
|
1837
|
+
file_name = commands_infos["run"]["args"][-1]
|
|
1838
|
+
args.file = action_file_manager.get_full_path_by_file_name(file_name)
|
|
1839
|
+
## 因为更新了args.file
|
|
1840
|
+
active_context_manager = ActiveContextManager(llm, args.source_dir)
|
|
1841
|
+
task_id = active_context_manager.process_changes(args)
|
|
1842
|
+
printer.print_in_terminal("active_context_background_task",
|
|
1843
|
+
style="blue",
|
|
1844
|
+
task_id=task_id)
|
|
1845
|
+
|
|
1814
1846
|
# 处理不同的命令
|
|
1815
1847
|
if command == "list":
|
|
1816
1848
|
# 获取所有任务
|
|
@@ -213,6 +213,8 @@ class CommandAutoTuner:
|
|
|
213
213
|
@byzerllm.prompt()
|
|
214
214
|
def _analyze(self, request: AutoCommandRequest) -> str:
|
|
215
215
|
"""
|
|
216
|
+
你是 auto-coder.chat 软件,帮助用户完成编程方面的需求。我们的目标是根据用户输入和当前上下文,组合多个函数来完成用户的需求。
|
|
217
|
+
|
|
216
218
|
## 当前用户环境信息如下:
|
|
217
219
|
<os_info>
|
|
218
220
|
操作系统: {{ env_info.os_name }} {{ env_info.os_version }}
|
|
@@ -234,10 +236,11 @@ class CommandAutoTuner:
|
|
|
234
236
|
{%- endif %}
|
|
235
237
|
</os_info>
|
|
236
238
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
+
当前项目根目录:
|
|
240
|
+
{{ current_project }}
|
|
241
|
+
|
|
239
242
|
{% if current_files %}
|
|
240
|
-
##
|
|
243
|
+
## 当前用户手动添加关注的文件列表:
|
|
241
244
|
<current_files>
|
|
242
245
|
{% for file in current_files %}
|
|
243
246
|
- {{ file }}
|
|
@@ -246,7 +249,7 @@ class CommandAutoTuner:
|
|
|
246
249
|
{% endif %}
|
|
247
250
|
|
|
248
251
|
|
|
249
|
-
##
|
|
252
|
+
## 这是用户对你的配置
|
|
250
253
|
<current_conf>
|
|
251
254
|
{{ current_conf }}
|
|
252
255
|
</current_conf>
|
|
@@ -260,6 +263,24 @@ class CommandAutoTuner:
|
|
|
260
263
|
## 函数组合说明:
|
|
261
264
|
{{ command_combination_readme }}
|
|
262
265
|
|
|
266
|
+
## active-context 项目追踪文档系统
|
|
267
|
+
|
|
268
|
+
在 {{ current_project }}/.auto-coder/active-context 下,我们提供了对该项目每个文件目录的追踪。
|
|
269
|
+
具体逻辑为:假设我们在当前项目有 ./src/package1/py1.py, 那么相应的在 .auto-coder/active-context 会有一个 ./src/package1 目录,
|
|
270
|
+
该目录下可能会有一个 active-context.md 文件,该文件记录了该目录下所有文件相关信息,可以帮你更好的理解这个目录下的文档,你可以通过 read_files 函数来读取
|
|
271
|
+
这个文件。注意,这个文件不一定存在。如果读取失败也是正常的。
|
|
272
|
+
|
|
273
|
+
## 变更记录文档系统
|
|
274
|
+
|
|
275
|
+
在 {{ current_project }}/actions 目录下,会有格式类似 000000001201_chat_action.yml 的文件,该文件记录了最近10次对话,
|
|
276
|
+
你可以通过 read_files 函数来读取这些文件,从而更好的理解用户的需求。
|
|
277
|
+
|
|
278
|
+
下面是一些字段的简单介绍
|
|
279
|
+
- query: 用户需求
|
|
280
|
+
- urls: 用户提供的上下文文件列表
|
|
281
|
+
- dynamic_urls: auto-coder.chat 自动感知的一些文件列表
|
|
282
|
+
- add_updated_urls: 这次需求发生变更的文件列表
|
|
283
|
+
|
|
263
284
|
{% if conversation_history %}
|
|
264
285
|
## 历史对话:
|
|
265
286
|
<conversation_history>
|
|
@@ -314,7 +335,8 @@ class CommandAutoTuner:
|
|
|
314
335
|
"conversation_safe_zone_tokens": self.args.conversation_prune_safe_zone_tokens,
|
|
315
336
|
"os_distribution": shells.get_os_distribution(),
|
|
316
337
|
"current_user": shells.get_current_username(),
|
|
317
|
-
"command_combination_readme": self._command_combination_readme.prompt()
|
|
338
|
+
"command_combination_readme": self._command_combination_readme.prompt(),
|
|
339
|
+
"current_project": os.path.abspath(self.args.source_dir)
|
|
318
340
|
}
|
|
319
341
|
|
|
320
342
|
@byzerllm.prompt()
|
|
@@ -337,8 +359,10 @@ class CommandAutoTuner:
|
|
|
337
359
|
尽可通过了解项目后,多用 @文件和@@符号,这样 chat 函数可以更清晰的理解你关注的代码,文档和意图。
|
|
338
360
|
|
|
339
361
|
### 调用 coding 函数应该注意的事项
|
|
340
|
-
调用 coding
|
|
341
|
-
|
|
362
|
+
调用 coding 函数的之前,你需要尽可能先了解用户需求,了解项目状态,包括读取 active_context 文件来了解项目。
|
|
363
|
+
然后清晰的描述自己的需求,完整的实现步骤,以及尽可能对@文件和@@符号需要参考以及修改的文件和符号。
|
|
364
|
+
对于比较复杂的需求,你还可以使用 chat 函数来进行讨论,从而获取一些有用的信息。
|
|
365
|
+
如果成功执行了 coding 函数, 最好再调用一次 chat("/review /commit"),方便总结这次代码变更。
|
|
342
366
|
注意,review 完后,需要询问用户是否要做啥调整不,如果用户说不用,那么就停止。否则根据意图进行后续操作。
|
|
343
367
|
|
|
344
368
|
### 关于对话大小的问题
|
autocoder/commands/tools.py
CHANGED
autocoder/common/__init__.py
CHANGED
|
@@ -4,8 +4,10 @@ import hashlib
|
|
|
4
4
|
import git
|
|
5
5
|
from typing import List, Dict, Tuple, Optional, Union, Any
|
|
6
6
|
from loguru import logger
|
|
7
|
+
from autocoder.common.git_utils import get_repo
|
|
7
8
|
from autocoder.common.printer import Printer
|
|
8
9
|
import byzerllm
|
|
10
|
+
from autocoder.common import git_utils
|
|
9
11
|
|
|
10
12
|
class ActionYmlFileManager:
|
|
11
13
|
"""
|
|
@@ -44,7 +46,7 @@ class ActionYmlFileManager:
|
|
|
44
46
|
except Exception as e:
|
|
45
47
|
logger.error(f"Failed to create actions directory: {e}")
|
|
46
48
|
return False
|
|
47
|
-
return True
|
|
49
|
+
return True
|
|
48
50
|
|
|
49
51
|
def get_action_files(self, filter_prefix: Optional[str] = None) -> List[str]:
|
|
50
52
|
"""
|
|
@@ -183,16 +185,21 @@ class ActionYmlFileManager:
|
|
|
183
185
|
Returns:
|
|
184
186
|
Dict: YAML 内容,如果加载失败返回空字典
|
|
185
187
|
"""
|
|
186
|
-
yaml_path = os.path.join(self.actions_dir, file_name)
|
|
187
|
-
|
|
188
|
+
yaml_path = os.path.join(self.actions_dir, file_name)
|
|
188
189
|
try:
|
|
189
190
|
with open(yaml_path, 'r', encoding='utf-8') as f:
|
|
190
191
|
content = yaml.safe_load(f) or {}
|
|
191
192
|
return content
|
|
192
|
-
except Exception as e:
|
|
193
|
+
except Exception as e:
|
|
193
194
|
self.printer.print_in_terminal("yaml_load_error", style="red",
|
|
194
195
|
yaml_file=yaml_path, error=str(e))
|
|
195
196
|
return {}
|
|
197
|
+
|
|
198
|
+
def get_full_path_by_file_name(self, file_name: str) -> str:
|
|
199
|
+
"""
|
|
200
|
+
根据文件名获取完整路径
|
|
201
|
+
"""
|
|
202
|
+
return os.path.join(self.actions_dir, file_name)
|
|
196
203
|
|
|
197
204
|
def save_yaml_content(self, file_name: str, content: Dict) -> bool:
|
|
198
205
|
"""
|
|
@@ -232,6 +239,26 @@ class ActionYmlFileManager:
|
|
|
232
239
|
yaml_content = self.load_yaml_content(file_name)
|
|
233
240
|
yaml_content[field] = value
|
|
234
241
|
return self.save_yaml_content(file_name, yaml_content)
|
|
242
|
+
|
|
243
|
+
def get_all_commit_id_from_file(self,file_name:str):
|
|
244
|
+
'''
|
|
245
|
+
会包含 revert 信息
|
|
246
|
+
'''
|
|
247
|
+
repo = get_repo(self.source_dir)
|
|
248
|
+
if repo is None:
|
|
249
|
+
logger.error("Repository is not initialized.")
|
|
250
|
+
return []
|
|
251
|
+
|
|
252
|
+
commit_hashes = []
|
|
253
|
+
for commit in repo.iter_commits():
|
|
254
|
+
lines = commit.message.strip().split('\n')
|
|
255
|
+
last_line = lines[-1]
|
|
256
|
+
if file_name in last_line or (commit.message.startswith("<revert>") and file_name in commit.message):
|
|
257
|
+
commit_hash = commit.hexsha
|
|
258
|
+
commit_hashes.append(commit_hash)
|
|
259
|
+
|
|
260
|
+
return commit_hashes
|
|
261
|
+
|
|
235
262
|
|
|
236
263
|
def get_commit_id_from_file(self, file_name: str) -> Optional[str]:
|
|
237
264
|
"""
|
|
@@ -243,16 +270,19 @@ class ActionYmlFileManager:
|
|
|
243
270
|
Returns:
|
|
244
271
|
Optional[str]: commit ID,如果计算失败返回 None
|
|
245
272
|
"""
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
with open(yaml_path, 'r', encoding='utf-8') as f:
|
|
250
|
-
yaml_content = f.read()
|
|
251
|
-
file_md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
|
|
252
|
-
return f"auto_coder_{file_name}"
|
|
253
|
-
except Exception as e:
|
|
254
|
-
logger.error(f"Failed to calculate commit ID: {e}")
|
|
273
|
+
repo = get_repo(self.source_dir)
|
|
274
|
+
if repo is None:
|
|
275
|
+
logger.error("Repository is not initialized.")
|
|
255
276
|
return None
|
|
277
|
+
|
|
278
|
+
commit_hash = None
|
|
279
|
+
# 这里遍历从最新的commit 开始遍历
|
|
280
|
+
for commit in repo.iter_commits():
|
|
281
|
+
last_line = commit.message.strip().split('\n')[-1]
|
|
282
|
+
if file_name in last_line and not commit.message.startswith("<revert>"):
|
|
283
|
+
commit_hash = commit.hexsha
|
|
284
|
+
break
|
|
285
|
+
return commit_hash
|
|
256
286
|
|
|
257
287
|
def get_file_name_from_commit_id(self, commit_id: str) -> Optional[str]:
|
|
258
288
|
"""
|
|
@@ -298,7 +328,7 @@ class ActionYmlFileManager:
|
|
|
298
328
|
return self.get_file_name_from_commit_id(last_line)
|
|
299
329
|
except Exception as e:
|
|
300
330
|
logger.error(f"Failed to extract file name from commit message: {e}")
|
|
301
|
-
return None
|
|
331
|
+
return None
|
|
302
332
|
|
|
303
333
|
def get_commit_changes(self, file_name: Optional[str] = None) -> List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]]:
|
|
304
334
|
"""
|
|
@@ -327,31 +357,30 @@ class ActionYmlFileManager:
|
|
|
327
357
|
changes = {}
|
|
328
358
|
try:
|
|
329
359
|
repo = git.Repo(self.source_dir)
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
pass # 文件可能是新增的
|
|
360
|
+
commit =repo.commit(commit_id)
|
|
361
|
+
if commit.parents:
|
|
362
|
+
parent = commit.parents[0]
|
|
363
|
+
# 获取所有文件的前后内容
|
|
364
|
+
for diff_item in parent.diff(commit):
|
|
365
|
+
file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
|
|
366
|
+
|
|
367
|
+
# 获取变更前内容
|
|
368
|
+
before_content = None
|
|
369
|
+
try:
|
|
370
|
+
if diff_item.a_blob:
|
|
371
|
+
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
372
|
+
except git.exc.GitCommandError:
|
|
373
|
+
pass # 文件可能是新增的
|
|
345
374
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
375
|
+
# 获取变更后内容
|
|
376
|
+
after_content = None
|
|
377
|
+
try:
|
|
378
|
+
if diff_item.b_blob:
|
|
379
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
380
|
+
except git.exc.GitCommandError:
|
|
381
|
+
pass # 文件可能被删除
|
|
353
382
|
|
|
354
|
-
|
|
383
|
+
changes[file_path] = (before_content, after_content)
|
|
355
384
|
break
|
|
356
385
|
except git.exc.GitCommandError as e:
|
|
357
386
|
self.printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
@@ -360,6 +389,15 @@ class ActionYmlFileManager:
|
|
|
360
389
|
|
|
361
390
|
return [(query, urls, changes)]
|
|
362
391
|
|
|
392
|
+
def revert_file(self, file_name: str) -> bool:
|
|
393
|
+
revert_result = git_utils.revert_changes(
|
|
394
|
+
self.source_dir, f"auto_coder_{file_name}"
|
|
395
|
+
)
|
|
396
|
+
if revert_result:
|
|
397
|
+
self.update_yaml_field(file_name, "revert_commit_id", revert_result.get("new_commit_hash"))
|
|
398
|
+
return True
|
|
399
|
+
return False
|
|
400
|
+
|
|
363
401
|
def parse_history_tasks(self, limit: int = 5) -> List[Dict]:
|
|
364
402
|
"""
|
|
365
403
|
解析历史任务信息
|
|
@@ -211,7 +211,7 @@ class CodeAutoGenerate:
|
|
|
211
211
|
|
|
212
212
|
if self.args.enable_active_context:
|
|
213
213
|
# 初始化活动上下文管理器
|
|
214
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
214
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
215
215
|
# 获取活动上下文信息
|
|
216
216
|
result = active_context_manager.load_active_contexts_for_files(
|
|
217
217
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -361,7 +361,7 @@ class CodeAutoGenerate:
|
|
|
361
361
|
|
|
362
362
|
if self.args.enable_active_context:
|
|
363
363
|
# 初始化活动上下文管理器
|
|
364
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
364
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
365
365
|
# 获取活动上下文信息
|
|
366
366
|
result = active_context_manager.load_active_contexts_for_files(
|
|
367
367
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -331,7 +331,7 @@ class CodeAutoGenerateDiff:
|
|
|
331
331
|
|
|
332
332
|
if self.args.enable_active_context:
|
|
333
333
|
# 初始化活动上下文管理器
|
|
334
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
334
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
335
335
|
# 获取活动上下文信息
|
|
336
336
|
result = active_context_manager.load_active_contexts_for_files(
|
|
337
337
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -508,7 +508,7 @@ class CodeAutoGenerateDiff:
|
|
|
508
508
|
|
|
509
509
|
if self.args.enable_active_context:
|
|
510
510
|
# 初始化活动上下文管理器
|
|
511
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
511
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
512
512
|
# 获取活动上下文信息
|
|
513
513
|
result = active_context_manager.load_active_contexts_for_files(
|
|
514
514
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -432,7 +432,7 @@ class CodeAutoGenerateEditBlock:
|
|
|
432
432
|
|
|
433
433
|
source_content = source_code_list.to_str()
|
|
434
434
|
|
|
435
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
435
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
436
436
|
|
|
437
437
|
if self.args.template == "common":
|
|
438
438
|
# 获取包上下文信息
|
|
@@ -605,7 +605,7 @@ class CodeAutoGenerateEditBlock:
|
|
|
605
605
|
|
|
606
606
|
if self.args.enable_active_context:
|
|
607
607
|
# 初始化活动上下文管理器
|
|
608
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
608
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
609
609
|
# 获取活动上下文信息
|
|
610
610
|
result = active_context_manager.load_active_contexts_for_files(
|
|
611
611
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -301,7 +301,7 @@ class CodeAutoGenerateStrictDiff:
|
|
|
301
301
|
|
|
302
302
|
if self.args.enable_active_context:
|
|
303
303
|
# 初始化活动上下文管理器
|
|
304
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
304
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
305
305
|
# 获取活动上下文信息
|
|
306
306
|
result = active_context_manager.load_active_contexts_for_files(
|
|
307
307
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -480,7 +480,7 @@ class CodeAutoGenerateStrictDiff:
|
|
|
480
480
|
|
|
481
481
|
if self.args.enable_active_context:
|
|
482
482
|
# 初始化活动上下文管理器
|
|
483
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
483
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
484
484
|
# 获取活动上下文信息
|
|
485
485
|
result = active_context_manager.load_active_contexts_for_files(
|
|
486
486
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -213,8 +213,8 @@ class CodeAutoMerge:
|
|
|
213
213
|
self.printer.print_in_terminal("yaml_save_error", style="red", yaml_file=action_file_name)
|
|
214
214
|
|
|
215
215
|
if self.args.enable_active_context:
|
|
216
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
217
|
-
task_id = active_context_manager.process_changes()
|
|
216
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
217
|
+
task_id = active_context_manager.process_changes(self.args)
|
|
218
218
|
self.printer.print_in_terminal("active_context_background_task",
|
|
219
219
|
style="blue",
|
|
220
220
|
task_id=task_id)
|
|
@@ -596,8 +596,8 @@ class CodeAutoMergeDiff:
|
|
|
596
596
|
self.printer.print_in_terminal("yaml_save_error", style="red", yaml_file=action_file_name)
|
|
597
597
|
|
|
598
598
|
if self.args.enable_active_context:
|
|
599
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
600
|
-
task_id = active_context_manager.process_changes()
|
|
599
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
600
|
+
task_id = active_context_manager.process_changes(self.args)
|
|
601
601
|
self.printer.print_in_terminal("active_context_background_task",
|
|
602
602
|
style="blue",
|
|
603
603
|
task_id=task_id)
|
|
@@ -444,8 +444,8 @@ class CodeAutoMergeEditBlock:
|
|
|
444
444
|
self.printer.print_in_terminal("yaml_save_error", style="red", yaml_file=action_file_name)
|
|
445
445
|
|
|
446
446
|
if self.args.enable_active_context:
|
|
447
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
448
|
-
task_id = active_context_manager.process_changes()
|
|
447
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
448
|
+
task_id = active_context_manager.process_changes(self.args)
|
|
449
449
|
self.printer.print_in_terminal("active_context_background_task",
|
|
450
450
|
style="blue",
|
|
451
451
|
task_id=task_id)
|
|
@@ -303,8 +303,8 @@ class CodeAutoMergeStrictDiff:
|
|
|
303
303
|
self.printer.print_in_terminal("yaml_save_error", style="red", yaml_file=action_file_name)
|
|
304
304
|
|
|
305
305
|
if self.args.enable_active_context:
|
|
306
|
-
active_context_manager = ActiveContextManager(self.llm, self.args)
|
|
307
|
-
active_context_manager.process_changes()
|
|
306
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
307
|
+
active_context_manager.process_changes(self.args)
|
|
308
308
|
|
|
309
309
|
git_utils.print_commit_info(commit_result=commit_result)
|
|
310
310
|
else:
|
|
@@ -13,6 +13,7 @@ from autocoder.utils.llms import get_llm_names, get_model_info
|
|
|
13
13
|
from autocoder.common.types import CodeGenerateResult, MergeCodeWithoutEffect
|
|
14
14
|
import os
|
|
15
15
|
from autocoder.rag.token_counter import count_tokens
|
|
16
|
+
from autocoder.common.stream_out_type import CodeRankStreamOutType
|
|
16
17
|
|
|
17
18
|
class RankResult(BaseModel):
|
|
18
19
|
rank_result: List[int]
|
|
@@ -211,7 +212,10 @@ class CodeModificationRanker:
|
|
|
211
212
|
model_name=model_name,
|
|
212
213
|
title=self.printer.get_message_from_key_with_format(
|
|
213
214
|
"rank_code_modification_title", model_name=model_name),
|
|
214
|
-
args=self.args
|
|
215
|
+
args=self.args,
|
|
216
|
+
extra_meta={
|
|
217
|
+
"stream_out_type": CodeRankStreamOutType.CODE_RANK.value
|
|
218
|
+
}
|
|
215
219
|
)
|
|
216
220
|
|
|
217
221
|
if last_meta:
|
autocoder/common/git_utils.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from git import Repo, GitCommandError
|
|
3
|
+
import git
|
|
3
4
|
from loguru import logger
|
|
4
|
-
from typing import List, Optional, Dict
|
|
5
|
+
from typing import List, Optional, Dict, Any
|
|
5
6
|
from pydantic import BaseModel
|
|
6
7
|
import byzerllm
|
|
7
8
|
from rich.console import Console
|
|
@@ -103,68 +104,84 @@ def get_current_branch(repo_path: str) -> str:
|
|
|
103
104
|
return branch
|
|
104
105
|
|
|
105
106
|
|
|
106
|
-
def revert_changes(repo_path: str,
|
|
107
|
+
def revert_changes(repo_path: str, action_file_path: str) -> Optional[Any]:
|
|
108
|
+
'''
|
|
109
|
+
file_path 类似: auto_coder_000000002009_chat_action.yml 或者 000000002009_chat_action.yml
|
|
110
|
+
'''
|
|
107
111
|
repo = get_repo(repo_path)
|
|
108
112
|
if repo is None:
|
|
109
113
|
logger.error("Repository is not initialized.")
|
|
110
114
|
return False
|
|
111
|
-
|
|
115
|
+
|
|
116
|
+
commit_hash = None
|
|
117
|
+
# 这里遍历从最新的commit 开始遍历
|
|
118
|
+
for commit in repo.iter_commits():
|
|
119
|
+
if action_file_path in commit.message and not commit.message.startswith("<revert>"):
|
|
120
|
+
commit_hash = commit.hexsha
|
|
121
|
+
break
|
|
122
|
+
|
|
123
|
+
if commit_hash is None:
|
|
124
|
+
raise ValueError(f"File {action_file_path} not found in any commit")
|
|
125
|
+
|
|
126
|
+
# 尝试获取指定的提交
|
|
112
127
|
try:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
commit = repo.commit(commit_hash)
|
|
129
|
+
except ValueError:
|
|
130
|
+
# 如果是短哈希,尝试匹配
|
|
131
|
+
matching_commits = [c for c in repo.iter_commits() if c.hexsha.startswith(commit_hash)]
|
|
132
|
+
if not matching_commits:
|
|
133
|
+
raise ValueError(f"Commit {commit_hash} not found")
|
|
134
|
+
commit = matching_commits[0]
|
|
135
|
+
|
|
136
|
+
# 检查工作目录是否干净
|
|
137
|
+
if repo.is_dirty():
|
|
138
|
+
raise ValueError("Working directory is dirty. please commit or stash your changes before reverting.")
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
# 执行 git revert
|
|
142
|
+
# 使用 -n 选项不自动创建提交,而是让我们手动提交
|
|
143
|
+
repo.git.revert(commit.hexsha, no_commit=True)
|
|
144
|
+
|
|
145
|
+
# 创建带有信息的 revert 提交
|
|
146
|
+
revert_message = f"<revert>{commit.message.strip()}\n{commit.hexsha}"
|
|
147
|
+
new_commit = repo.index.commit(
|
|
148
|
+
revert_message,
|
|
149
|
+
author=repo.active_branch.commit.author,
|
|
150
|
+
committer=repo.active_branch.commit.committer
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# 构建新提交的信息
|
|
154
|
+
stats = new_commit.stats.total
|
|
155
|
+
new_commit_info = {
|
|
156
|
+
"new_commit_hash": new_commit.hexsha,
|
|
157
|
+
"new_commit_short_hash": new_commit.hexsha[:7],
|
|
158
|
+
"reverted_commit": {
|
|
159
|
+
"hash": commit.hexsha,
|
|
160
|
+
"short_hash": commit.hexsha[:7],
|
|
161
|
+
"message": commit.message.strip()
|
|
162
|
+
},
|
|
163
|
+
"stats": {
|
|
164
|
+
"insertions": stats["insertions"],
|
|
165
|
+
"deletions": stats["deletions"],
|
|
166
|
+
"files_changed": stats["files"]
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return new_commit_info
|
|
171
|
+
|
|
172
|
+
except git.GitCommandError as e:
|
|
173
|
+
# 如果发生 Git 命令错误,尝试恢复工作目录
|
|
174
|
+
try:
|
|
175
|
+
repo.git.reset("--hard", "HEAD")
|
|
176
|
+
except:
|
|
177
|
+
pass # 如果恢复失败,继续抛出原始错误
|
|
178
|
+
|
|
179
|
+
if "patch does not apply" in str(e):
|
|
180
|
+
raise Exception("Cannot revert: patch does not apply (likely due to conflicts)")
|
|
135
181
|
else:
|
|
136
|
-
|
|
137
|
-
for commit in reversed(commits):
|
|
138
|
-
try:
|
|
139
|
-
repo.git.revert(commit.hexsha, no_commit=True)
|
|
140
|
-
logger.info(f"Reverted changes from commit: {commit.hexsha}")
|
|
141
|
-
except GitCommandError as e:
|
|
142
|
-
logger.error(f"Error reverting commit {commit.hexsha}: {e}")
|
|
143
|
-
repo.git.revert("--abort")
|
|
144
|
-
return False
|
|
145
|
-
|
|
146
|
-
# 提交所有的回滚更改
|
|
147
|
-
repo.git.commit(message=f"Reverted all changes up to {commit_hash}")
|
|
148
|
-
|
|
149
|
-
logger.info(f"Successfully reverted changes up to {commit_hash}")
|
|
150
|
-
|
|
151
|
-
## this is a mark, chat_auto_coder.py need this
|
|
152
|
-
print(f"Successfully reverted changes", flush=True)
|
|
153
|
-
|
|
154
|
-
# # 如果之前有stash,现在应用它
|
|
155
|
-
# if stashed:
|
|
156
|
-
# try:
|
|
157
|
-
# repo.git.stash('pop')
|
|
158
|
-
# logger.info("Applied stashed changes.")
|
|
159
|
-
# except GitCommandError as e:
|
|
160
|
-
# logger.error(f"Error applying stashed changes: {e}")
|
|
161
|
-
# logger.info("Please manually apply the stashed changes.")
|
|
162
|
-
|
|
163
|
-
return True
|
|
182
|
+
raise Exception(f"Git error during revert: {str(e)}")
|
|
164
183
|
|
|
165
|
-
|
|
166
|
-
logger.error(f"Error during revert operation: {e}")
|
|
167
|
-
return False
|
|
184
|
+
return None
|
|
168
185
|
|
|
169
186
|
|
|
170
187
|
def revert_change(repo_path: str, message: str) -> bool:
|
|
@@ -89,20 +89,19 @@ class ActiveContextManager:
|
|
|
89
89
|
cls._instance._is_initialized = False
|
|
90
90
|
return cls._instance
|
|
91
91
|
|
|
92
|
-
def __init__(self, llm: byzerllm.ByzerLLM,
|
|
92
|
+
def __init__(self, llm: byzerllm.ByzerLLM,source_dir:str):
|
|
93
93
|
"""
|
|
94
94
|
初始化活动上下文管理器
|
|
95
95
|
|
|
96
96
|
Args:
|
|
97
|
-
llm: ByzerLLM实例,用于生成文档内容
|
|
98
|
-
args: AutoCoderArgs实例,包含配置信息
|
|
97
|
+
llm: ByzerLLM实例,用于生成文档内容
|
|
99
98
|
"""
|
|
100
99
|
# 如果已经初始化过,则直接返回
|
|
101
100
|
if self._is_initialized:
|
|
102
101
|
return
|
|
103
|
-
|
|
102
|
+
self.source_dir = source_dir
|
|
104
103
|
# 设置日志目录和文件
|
|
105
|
-
log_dir = os.path.join(
|
|
104
|
+
log_dir = os.path.join(source_dir, ".auto-coder", "active-context")
|
|
106
105
|
os.makedirs(log_dir, exist_ok=True)
|
|
107
106
|
log_file = os.path.join(log_dir, "active.log")
|
|
108
107
|
|
|
@@ -119,12 +118,11 @@ class ActiveContextManager:
|
|
|
119
118
|
self.logger = global_logger.bind(name="ActiveContextManager")
|
|
120
119
|
self.logger.info(f"初始化 ActiveContextManager,日志输出到 {log_file}")
|
|
121
120
|
|
|
122
|
-
self.llm = llm
|
|
123
|
-
self.args = args
|
|
121
|
+
self.llm = llm
|
|
124
122
|
self.directory_mapper = DirectoryMapper()
|
|
125
123
|
self.active_package = ActivePackage(llm)
|
|
126
124
|
self.async_processor = AsyncProcessor()
|
|
127
|
-
self.yml_manager = ActionYmlFileManager(
|
|
125
|
+
self.yml_manager = ActionYmlFileManager(source_dir)
|
|
128
126
|
self.tasks = {} # 用于跟踪任务状态
|
|
129
127
|
self.printer = Printer()
|
|
130
128
|
|
|
@@ -137,7 +135,7 @@ class ActiveContextManager:
|
|
|
137
135
|
self.__class__._queue_thread.start()
|
|
138
136
|
|
|
139
137
|
# 标记为已初始化
|
|
140
|
-
self._is_initialized = True
|
|
138
|
+
self._is_initialized = True
|
|
141
139
|
|
|
142
140
|
def _process_queue(self):
|
|
143
141
|
"""
|
|
@@ -177,20 +175,22 @@ class ActiveContextManager:
|
|
|
177
175
|
with self._queue_lock:
|
|
178
176
|
self.__class__._is_processing = False
|
|
179
177
|
|
|
180
|
-
def process_changes(self,
|
|
178
|
+
def process_changes(self, args:AutoCoderArgs) -> str:
|
|
181
179
|
"""
|
|
182
180
|
处理代码变更,创建活动上下文(非阻塞)
|
|
183
181
|
|
|
184
182
|
Args:
|
|
185
|
-
|
|
183
|
+
args: AutoCoderArgs实例,包含配置信息
|
|
186
184
|
|
|
187
185
|
Returns:
|
|
188
186
|
str: 任务ID,可用于后续查询任务状态
|
|
189
187
|
"""
|
|
190
188
|
try:
|
|
191
189
|
# 使用参数中的文件或者指定的文件
|
|
192
|
-
|
|
190
|
+
if not args.file:
|
|
191
|
+
raise ValueError("action file is required")
|
|
193
192
|
|
|
193
|
+
file_name = os.path.basename(args.file)
|
|
194
194
|
# 从YAML文件加载数据
|
|
195
195
|
yaml_content = self.yml_manager.load_yaml_content(file_name)
|
|
196
196
|
|
|
@@ -298,7 +298,7 @@ class ActiveContextManager:
|
|
|
298
298
|
# 1. 映射目录
|
|
299
299
|
self.logger.info("开始映射目录结构...")
|
|
300
300
|
directory_contexts = self.directory_mapper.map_directories(
|
|
301
|
-
self.
|
|
301
|
+
self.source_dir, changed_urls, current_urls
|
|
302
302
|
)
|
|
303
303
|
self.logger.info(f"目录映射完成,找到 {len(directory_contexts)} 个相关目录")
|
|
304
304
|
|
|
@@ -460,7 +460,7 @@ class ActiveContextManager:
|
|
|
460
460
|
# 构建日志文件路径
|
|
461
461
|
log_file_path = None
|
|
462
462
|
if 'file_name' in task:
|
|
463
|
-
log_dir = os.path.join(self.
|
|
463
|
+
log_dir = os.path.join(self.source_dir, '.auto-coder', 'active-context', 'logs')
|
|
464
464
|
log_file_path = os.path.join(log_dir, f'{task_id}.log')
|
|
465
465
|
if not os.path.exists(log_file_path):
|
|
466
466
|
log_file_path = None
|
|
@@ -644,6 +644,6 @@ class ActiveContextManager:
|
|
|
644
644
|
Returns:
|
|
645
645
|
str: 活动上下文中对应的目录路径
|
|
646
646
|
"""
|
|
647
|
-
relative_path = os.path.relpath(directory_path, self.
|
|
648
|
-
return os.path.join(self.
|
|
647
|
+
relative_path = os.path.relpath(directory_path, self.source_dir)
|
|
648
|
+
return os.path.join(self.source_dir, ".auto-coder", "active-context", relative_path)
|
|
649
649
|
|
autocoder/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.308"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|