auto-coder 0.1.372__py3-none-any.whl → 0.1.374__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.372.dist-info → auto_coder-0.1.374.dist-info}/METADATA +2 -2
- {auto_coder-0.1.372.dist-info → auto_coder-0.1.374.dist-info}/RECORD +21 -21
- autocoder/agent/auto_tool.py +4 -3
- autocoder/agent/planner.py +3 -3
- autocoder/agent/project_reader.py +4 -4
- autocoder/chat_auto_coder.py +10 -19
- autocoder/common/v2/agent/agentic_edit.py +10 -6
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +2 -1
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +47 -141
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +47 -102
- autocoder/index/index.py +1 -1
- autocoder/linters/linter_factory.py +4 -1
- autocoder/linters/normal_linter.py +2 -4
- autocoder/linters/python_linter.py +18 -115
- autocoder/rag/llm_wrapper.py +1 -2
- autocoder/rag/rag_entry.py +2 -6
- autocoder/version.py +1 -1
- {auto_coder-0.1.372.dist-info → auto_coder-0.1.374.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.372.dist-info → auto_coder-0.1.374.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.372.dist-info → auto_coder-0.1.374.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.372.dist-info → auto_coder-0.1.374.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: auto-coder
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.374
|
|
4
4
|
Summary: AutoCoder: AutoCoder
|
|
5
5
|
Author: allwefantasy
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -28,7 +28,7 @@ Requires-Dist: prompt-toolkit
|
|
|
28
28
|
Requires-Dist: tokenizers
|
|
29
29
|
Requires-Dist: aiofiles
|
|
30
30
|
Requires-Dist: readerwriterlock
|
|
31
|
-
Requires-Dist: byzerllm[saas] >=0.1.
|
|
31
|
+
Requires-Dist: byzerllm[saas] >=0.1.184
|
|
32
32
|
Requires-Dist: patch
|
|
33
33
|
Requires-Dist: diff-match-patch
|
|
34
34
|
Requires-Dist: GitPython
|
|
@@ -7,14 +7,14 @@ autocoder/auto_coder_rag_mcp.py,sha256=-RrjNwFaS2e5v8XDIrKR-zlUNUE8UBaeOtojffBrv
|
|
|
7
7
|
autocoder/auto_coder_runner.py,sha256=VktQIEWjVMmraVjD7W73eZmYtdfm9Ma2w_Ib-cWZYhM,112263
|
|
8
8
|
autocoder/auto_coder_server.py,sha256=bLORGEclcVdbBVfM140JCI8WtdrU0jbgqdJIVVupiEU,20578
|
|
9
9
|
autocoder/benchmark.py,sha256=Ypomkdzd1T3GE6dRICY3Hj547dZ6_inqJbBJIp5QMco,4423
|
|
10
|
-
autocoder/chat_auto_coder.py,sha256=
|
|
10
|
+
autocoder/chat_auto_coder.py,sha256=vNQwbYkdqeMl07Vx8z6x-kSPkHKn9AT3sSkYMTJiWtc,26655
|
|
11
11
|
autocoder/chat_auto_coder_lang.py,sha256=ylLr1GskchU6kIUJY2TiznrBg-ckc1o-8fDsKZZ0iQU,29337
|
|
12
12
|
autocoder/command_args.py,sha256=HxflngkYtTrV17Vfgk6lyUyiG68jP2ftSc7FYr9AXwY,30585
|
|
13
13
|
autocoder/command_parser.py,sha256=fx1g9E6GaM273lGTcJqaFQ-hoksS_Ik2glBMnVltPCE,10013
|
|
14
14
|
autocoder/lang.py,sha256=PFtATuOhHRnfpqHQkXr6p4C893JvpsgwTMif3l-GEi0,14321
|
|
15
15
|
autocoder/models.py,sha256=Gu50IATQtZtgEir1PpCfwgH6o4ygw6XqqbQRj3lx5dU,13798
|
|
16
16
|
autocoder/run_context.py,sha256=IUfSO6_gp2Wt1blFWAmOpN0b0nDrTTk4LmtCYUBIoro,1643
|
|
17
|
-
autocoder/version.py,sha256=
|
|
17
|
+
autocoder/version.py,sha256=myTr8pn1VpwBIskg5kgvqwLhCe4h-7rz4I7ovJf4BXM,25
|
|
18
18
|
autocoder/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
autocoder/agent/agentic_edit.py,sha256=XsfePZ-t6M-uBSdG1VLZXk1goqXk2HPeJ_A8IYyBuWQ,58896
|
|
20
20
|
autocoder/agent/agentic_edit_types.py,sha256=oFcDd_cxJ2yH9Ed1uTpD3BipudgoIEWDMPb5pAkq4gI,3288
|
|
@@ -25,11 +25,11 @@ autocoder/agent/auto_guess_query.py,sha256=rDSdhpPHcOGE5MuDXvIrhCXAPR4ARS1LqpyoL
|
|
|
25
25
|
autocoder/agent/auto_learn.py,sha256=EMSbIVo2DK9Lp4sxFtpK4HRxqclGVKHYex51SG7SJpM,13942
|
|
26
26
|
autocoder/agent/auto_learn_from_commit.py,sha256=edD4GQJyO2qvVnTKyldeswWoNeKe1Aaua6ieJzlGlFI,10662
|
|
27
27
|
autocoder/agent/auto_review_commit.py,sha256=1z9FOUDPZTWnrPmJ-TwUlXLOTDPmRcAlYqXbUj1pi08,11015
|
|
28
|
-
autocoder/agent/auto_tool.py,sha256=
|
|
28
|
+
autocoder/agent/auto_tool.py,sha256=EkswqecrV_va6Gh8o6x4t113DNmtUApWdcYRiopLAsw,11583
|
|
29
29
|
autocoder/agent/coder.py,sha256=x6bdJwDuETGg9ebQnYlUWCxCtQcDGg73LtI6McpWslQ,72034
|
|
30
30
|
autocoder/agent/designer.py,sha256=EpRbzO58Xym3GrnppIT1Z8ZFAlnNfgzHbIzZ3PX-Yv8,27037
|
|
31
|
-
autocoder/agent/planner.py,sha256=
|
|
32
|
-
autocoder/agent/project_reader.py,sha256=
|
|
31
|
+
autocoder/agent/planner.py,sha256=2OgJsPVGmp_koEZsdcp2pvtdDzegiMAwxraPc_5GYvo,9215
|
|
32
|
+
autocoder/agent/project_reader.py,sha256=WVl-xvrzseWmv-YBg-bDbdy_OtLdqz0xdadkHc70Lf8,17747
|
|
33
33
|
autocoder/agent/agentic_edit_tools/__init__.py,sha256=wGICCc1dYh07osB21j62zOQ9Ws0PyyOQ12UYRHmHrtI,1229
|
|
34
34
|
autocoder/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py,sha256=8yQq9ypKpq8eU-P-8-p8Pia_9mLRdrqj7s9joRjGDog,1468
|
|
35
35
|
autocoder/agent/agentic_edit_tools/attempt_completion_tool_resolver.py,sha256=Y4E6KTnalEABKmSwWTA_isRITVlBz1LvDHBAOh-rkWM,1297
|
|
@@ -192,13 +192,13 @@ autocoder/common/v2/code_editblock_manager.py,sha256=DMwJw-FAM6VyaBQV3p4xespHpgZ
|
|
|
192
192
|
autocoder/common/v2/code_manager.py,sha256=C403bS-f6urixwitlKHcml-J03hci-UyNwHJOqBiY6Q,9182
|
|
193
193
|
autocoder/common/v2/code_strict_diff_manager.py,sha256=Bys7tFAq4G03R1zUZuxrszBTvP4QB96jIw2y5BDLyRM,9424
|
|
194
194
|
autocoder/common/v2/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
195
|
-
autocoder/common/v2/agent/agentic_edit.py,sha256=
|
|
195
|
+
autocoder/common/v2/agent/agentic_edit.py,sha256=GqzwD-YIuftxz6IGPonE8spxcPBCAiImHPsKuVLQIJE,116459
|
|
196
196
|
autocoder/common/v2/agent/agentic_edit_conversation.py,sha256=pFgWPWHKhZ4J9EcFmIdiGsrSolTZuYcH1qkgKdD8nwk,7726
|
|
197
197
|
autocoder/common/v2/agent/agentic_edit_types.py,sha256=nEcZc2MOZ_fQLaJX-YDha_x9Iim22ao4tykYM2iIy4k,4908
|
|
198
198
|
autocoder/common/v2/agent/agentic_tool_display.py,sha256=-a-JTQLc4q03E_rdIILKMI0B6DHN-5gcGlrqq-mBYK4,7239
|
|
199
199
|
autocoder/common/v2/agent/ignore_utils.py,sha256=gnUchRzKMLbUm_jvnKL-r-K9MWKPtt-6iiuzijY7Es0,1717
|
|
200
200
|
autocoder/common/v2/agent/agentic_edit_tools/__init__.py,sha256=RbPZZcZg_VnGssL577GxSyFrYrxQ_LopJ4G_-mY3z_Q,1337
|
|
201
|
-
autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py,sha256
|
|
201
|
+
autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py,sha256=-HFXo3RR6CH8xXjDaE2mYV4XasTLAmvXe6WutL7qbwA,3208
|
|
202
202
|
autocoder/common/v2/agent/agentic_edit_tools/attempt_completion_tool_resolver.py,sha256=82ZGKeRBSDKeead_XVBW4FxpiE-5dS7tBOk_3RZ6B5s,1511
|
|
203
203
|
autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py,sha256=Zid2m1uZd-2wVFGc_n_KAViXZyNjbdLSpI5n7ut1RUQ,1036
|
|
204
204
|
autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py,sha256=sX00xzczfmyW6yPG3nMm0xO8p-WARQTiD4jcoUiTxsg,3844
|
|
@@ -207,12 +207,12 @@ autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py,sha256=
|
|
|
207
207
|
autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py,sha256=dIdV12VuczHpHuHgx2B1j_3BZYc9PL0jfHCuBk9ryk8,2005
|
|
208
208
|
autocoder/common/v2/agent/agentic_edit_tools/plan_mode_respond_tool_resolver.py,sha256=lGT4_QYJK6Fa9f6HVSGo0cSsGK7qCsDYgJGUowNxPzk,1499
|
|
209
209
|
autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py,sha256=6JhjM3VXV3BGelh1dNcdr-M5FoVPoqLkls1-y8ND8_c,6721
|
|
210
|
-
autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py,sha256=
|
|
210
|
+
autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py,sha256=ZTdImTBK7KTYH98JVUioBNtIz-dqSfhkmNEBhajt7hk,12686
|
|
211
211
|
autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py,sha256=VtDRDFJ2qzACy2jpD1ZNhywgCT3_iYUmGoUhHHmMX3o,9581
|
|
212
212
|
autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py,sha256=9eBo3WLkrr77iNotwIwVmH1ZL3UY0JQgLpdAIc9wTTM,6127
|
|
213
213
|
autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py,sha256=ZWRPsJny_My4UMzovrB8J2_x5N0rEW-xx3DVI-kDRFI,15870
|
|
214
214
|
autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py,sha256=wM2Xy4bcnD0TSLEmcM8rvvyyWenN5_KQnJMO6hJ8lTE,1716
|
|
215
|
-
autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py,sha256=
|
|
215
|
+
autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py,sha256=lPESPLoe9P_bEXXNqqHAkVlqMrIH0XziJ6XeILIejUo,8084
|
|
216
216
|
autocoder/compilers/__init__.py,sha256=C0HOms70QA747XD0uZEMmGtRFcIPenohyqECNStv0Bw,1647
|
|
217
217
|
autocoder/compilers/base_compiler.py,sha256=dsTzMO4H_RoqWfE-SntIk2B52hWuvSlWVLtkdCbHgGs,3244
|
|
218
218
|
autocoder/compilers/compiler_config_api.py,sha256=QRSwWm_EX7jSeZ3dtQqM9HI__x5aZ7U0c3fHIW_2N48,13839
|
|
@@ -252,7 +252,7 @@ autocoder/ignorefiles/test_ignore_file_utils.py,sha256=961_5ilCgzyo09Luj457A4694
|
|
|
252
252
|
autocoder/index/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
253
253
|
autocoder/index/entry.py,sha256=Eb0SmwrgshQte3_IGL4GAB4_HXC2jbatrgrd2uPxQng,15306
|
|
254
254
|
autocoder/index/for_command.py,sha256=BFvljE4t6VaMBGboZAuhUCzVK0EitCy_n5D_7FEnihw,3204
|
|
255
|
-
autocoder/index/index.py,sha256=
|
|
255
|
+
autocoder/index/index.py,sha256=xHm9jrAGy3qErS6GlUli3uFaEzHu_PZLjda8Sp0i0hw,33234
|
|
256
256
|
autocoder/index/symbols_utils.py,sha256=_EP7E_qWXxluAxq3FGZLlLfdrfwx3FmxCdulI8VGuac,2244
|
|
257
257
|
autocoder/index/types.py,sha256=a2s_KV5FJlq7jqA2ELSo9E1sjuLwDB-JJYMhSpzBAhU,596
|
|
258
258
|
autocoder/index/filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -261,10 +261,10 @@ autocoder/index/filter/quick_filter.py,sha256=ozESEgy506FQ5ecjOumyo4D_KMrterB1QL
|
|
|
261
261
|
autocoder/linters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
262
262
|
autocoder/linters/base_linter.py,sha256=1_0DPESnSyF3ZcQhoFkBYJylT5w-B61Rx-3A9uhuPlg,3066
|
|
263
263
|
autocoder/linters/code_linter.py,sha256=JylTj-Mj4jl9-XSH3PVlbQ4l55Y6E1FG-glv860CGSs,22462
|
|
264
|
-
autocoder/linters/linter_factory.py,sha256=
|
|
264
|
+
autocoder/linters/linter_factory.py,sha256=BgGeXPdli7BgiN9BifWoosyn9BGeJnRwSqX0G1R8qvU,10471
|
|
265
265
|
autocoder/linters/models.py,sha256=GBdayu_p50KBxoRms4X68zrDK-OsKDEKKjo926FevwE,9838
|
|
266
|
-
autocoder/linters/normal_linter.py,sha256=
|
|
267
|
-
autocoder/linters/python_linter.py,sha256=
|
|
266
|
+
autocoder/linters/normal_linter.py,sha256=ezToVW33psvBXsGhE7y1ng7ucf7yT_1YuIULns6TXYM,13011
|
|
267
|
+
autocoder/linters/python_linter.py,sha256=vs6cyN77q4HeiBvFbVBzMpL9H75wwskJk5WXjgIPw64,18963
|
|
268
268
|
autocoder/linters/reactjs_linter.py,sha256=LDCXmAI15LUq8nNPyYko3oryzCc2Su05ob63jEeDdIs,20815
|
|
269
269
|
autocoder/linters/shadow_linter.py,sha256=SKgRNVnTavNUviFC9osYMz18nGWCVOPOHx9LavEbnmc,15047
|
|
270
270
|
autocoder/linters/vue_linter.py,sha256=ZyvoxT0kSizFh_UkR7UZYO5DV9edbvDQZaibEF9W95I,20905
|
|
@@ -288,11 +288,11 @@ autocoder/rag/conversation_to_queries.py,sha256=xwmErn4WbdADnhK1me-h_6fV3KYrl_y1
|
|
|
288
288
|
autocoder/rag/doc_filter.py,sha256=UduVO2mlrngwJICrefjDJTYfdmQ4GcRXrfWDQ7xXksk,14206
|
|
289
289
|
autocoder/rag/document_retriever.py,sha256=rFwbAuHTvEFJq16HQNlmRLyJp2ddn2RNFslw_ncU7NI,8847
|
|
290
290
|
autocoder/rag/lang.py,sha256=HvcMeu6jReEJOGxyLMn4rwBoD-myFwmykS3VLceBJLs,3364
|
|
291
|
-
autocoder/rag/llm_wrapper.py,sha256=
|
|
291
|
+
autocoder/rag/llm_wrapper.py,sha256=LsNv8maCnvazyXjjtkO9aN3OT7Br20V1ilHV8Lt45Os,4245
|
|
292
292
|
autocoder/rag/long_context_rag.py,sha256=zLo4SmdZ50Ex8egdXqwVx4Jp5cR1k4UMf49Z-_NbXL0,43550
|
|
293
293
|
autocoder/rag/qa_conversation_strategy.py,sha256=4CiMK88apKbJ2YM4HHq1KGpr5jUkTh0_m_aCyt-JYgc,10568
|
|
294
294
|
autocoder/rag/rag_config.py,sha256=8LwFcTd8OJWWwi1_WY4IzjqgtT6RyE2j4PjxS5cCTDE,802
|
|
295
|
-
autocoder/rag/rag_entry.py,sha256=
|
|
295
|
+
autocoder/rag/rag_entry.py,sha256=QOdUX_nd1Qak2NyOW0CYcLRDB26AZ6MeByHJaMMGgqs,2316
|
|
296
296
|
autocoder/rag/raw_rag.py,sha256=BOr0YGf3umjqXOIDVO1LXQ0bIHx8hzBdiubND2ezyxc,2946
|
|
297
297
|
autocoder/rag/relevant_utils.py,sha256=25wRiX-CrBsratASLGHsZE3ux7VjwaQoDNtl74UlV5U,1749
|
|
298
298
|
autocoder/rag/searchable.py,sha256=miO2U-3J9JDYFOEv85vs9JExDQ0goLIeI20Ob2rNqU4,2067
|
|
@@ -359,9 +359,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
359
359
|
autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
360
360
|
autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=t902pKxQ5xM7zgIHiAOsTPLwxhE6VuvXAqPy751S7fg,14096
|
|
361
361
|
autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
362
|
-
auto_coder-0.1.
|
|
363
|
-
auto_coder-0.1.
|
|
364
|
-
auto_coder-0.1.
|
|
365
|
-
auto_coder-0.1.
|
|
366
|
-
auto_coder-0.1.
|
|
367
|
-
auto_coder-0.1.
|
|
362
|
+
auto_coder-0.1.374.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
363
|
+
auto_coder-0.1.374.dist-info/METADATA,sha256=jnsshouyIn8HqIoTFFx93VtDWl2KrRv_hYJS565hHrw,2775
|
|
364
|
+
auto_coder-0.1.374.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
365
|
+
auto_coder-0.1.374.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
|
|
366
|
+
auto_coder-0.1.374.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
|
|
367
|
+
auto_coder-0.1.374.dist-info/RECORD,,
|
autocoder/agent/auto_tool.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from llama_index.core.agent import ReActAgent
|
|
2
|
-
from llama_index.core.tools import FunctionTool
|
|
3
1
|
from autocoder.pyproject import PyProject
|
|
4
2
|
from autocoder.tsproject import TSProject
|
|
5
3
|
from autocoder.suffixproject import SuffixProject
|
|
@@ -7,7 +5,6 @@ from autocoder.common import AutoCoderArgs
|
|
|
7
5
|
from autocoder.common.interpreter import Interpreter
|
|
8
6
|
from autocoder.common import ExecuteSteps, ExecuteStep, detect_env
|
|
9
7
|
from autocoder.common import code_auto_execute
|
|
10
|
-
from byzerllm.apps.llama_index.byzerai import ByzerAI
|
|
11
8
|
from loguru import logger
|
|
12
9
|
import os
|
|
13
10
|
import io
|
|
@@ -252,6 +249,8 @@ def get_tools(args: AutoCoderArgs, llm: byzerllm.ByzerLLM):
|
|
|
252
249
|
|
|
253
250
|
console.print("[bold red]达到最大尝试次数,任务未能完成。[/bold red]")
|
|
254
251
|
return result
|
|
252
|
+
|
|
253
|
+
from llama_index.core.tools import FunctionTool
|
|
255
254
|
|
|
256
255
|
tools = [
|
|
257
256
|
FunctionTool.from_defaults(run_python_code),
|
|
@@ -284,6 +283,8 @@ class AutoTool:
|
|
|
284
283
|
return self.pp.get_tree_like_directory_structure.prompt()
|
|
285
284
|
|
|
286
285
|
def run(self, query: str, max_iterations: int = 20):
|
|
286
|
+
from byzerllm.apps.llama_index.byzerai import ByzerAI
|
|
287
|
+
from llama_index.core.agent import ReActAgent
|
|
287
288
|
agent = ReActAgent.from_tools(
|
|
288
289
|
tools=self.tools,
|
|
289
290
|
llm=ByzerAI(llm=self.code_model),
|
autocoder/agent/planner.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from llama_index.core.agent import ReActAgent
|
|
2
|
-
from llama_index.core.tools import FunctionTool
|
|
3
1
|
from autocoder.index.index import IndexManager
|
|
4
2
|
from autocoder.pyproject import PyProject
|
|
5
3
|
from autocoder.tsproject import TSProject
|
|
@@ -182,7 +180,8 @@ def get_tools(args: AutoCoderArgs, llm: byzerllm.ByzerLLM):
|
|
|
182
180
|
args.collections = old_collections
|
|
183
181
|
|
|
184
182
|
return "\n".join([sc.source_code for sc in source_codes])
|
|
185
|
-
|
|
183
|
+
|
|
184
|
+
from llama_index.core.tools import FunctionTool
|
|
186
185
|
tools = [
|
|
187
186
|
FunctionTool.from_defaults(get_project_related_files),
|
|
188
187
|
FunctionTool.from_defaults(generate_auto_coder_yaml),
|
|
@@ -202,6 +201,7 @@ class Planner:
|
|
|
202
201
|
|
|
203
202
|
def run(self, query: str, max_iterations: int = 10):
|
|
204
203
|
from byzerllm.apps.llama_index.byzerai import ByzerAI
|
|
204
|
+
from llama_index.core.agent import ReActAgent
|
|
205
205
|
agent = ReActAgent.from_tools(
|
|
206
206
|
tools=self.tools,
|
|
207
207
|
llm=ByzerAI(llm=self.llm),
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from llama_index.core.agent import ReActAgent
|
|
2
|
-
from llama_index.core.tools import FunctionTool
|
|
3
1
|
from autocoder.index.index import IndexManager
|
|
4
2
|
from autocoder.pyproject import PyProject
|
|
5
3
|
from autocoder.tsproject import TSProject
|
|
@@ -176,7 +174,7 @@ def detect_rm_command(command: str) -> Bool:
|
|
|
176
174
|
|
|
177
175
|
|
|
178
176
|
def get_tools(args: AutoCoderArgs, llm: byzerllm.ByzerLLM):
|
|
179
|
-
|
|
177
|
+
|
|
180
178
|
def ask_user(question:str) -> str:
|
|
181
179
|
'''
|
|
182
180
|
如果你对用户的问题有什么疑问,或者你想从用户收集一些额外信息,可以调用
|
|
@@ -404,7 +402,8 @@ def get_tools(args: AutoCoderArgs, llm: byzerllm.ByzerLLM):
|
|
|
404
402
|
pass
|
|
405
403
|
|
|
406
404
|
return ",".join(matched_files)
|
|
407
|
-
|
|
405
|
+
|
|
406
|
+
from llama_index.core.tools import FunctionTool
|
|
408
407
|
tools = [
|
|
409
408
|
# FunctionTool.from_defaults(get_project_related_files),
|
|
410
409
|
FunctionTool.from_defaults(get_related_files_by_symbols),
|
|
@@ -440,6 +439,7 @@ class ProjectReader:
|
|
|
440
439
|
|
|
441
440
|
def run(self, query: str, max_iterations: int = 20):
|
|
442
441
|
from byzerllm.apps.llama_index.byzerai import ByzerAI
|
|
442
|
+
from llama_index.core.agent import ReActAgent
|
|
443
443
|
agent = ReActAgent.from_tools(
|
|
444
444
|
tools=self.tools,
|
|
445
445
|
llm=ByzerAI(llm=self.llm),
|
autocoder/chat_auto_coder.py
CHANGED
|
@@ -19,12 +19,11 @@ from autocoder.events.event_manager_singleton import gengerate_event_file_path
|
|
|
19
19
|
from autocoder.common.global_cancel import global_cancel
|
|
20
20
|
from autocoder.chat.models_command import handle_models_command
|
|
21
21
|
from autocoder.auto_coder_runner import (
|
|
22
|
-
auto_command,
|
|
23
|
-
load_memory,
|
|
24
|
-
save_memory,
|
|
22
|
+
auto_command,
|
|
25
23
|
configure, # Keep configure if it's used elsewhere or by handle_conf_command internally (though we adapted handle_conf_command not to)
|
|
26
24
|
# manage_models, # Removed
|
|
27
25
|
# print_conf, # Removed
|
|
26
|
+
save_memory,
|
|
28
27
|
exclude_dirs,
|
|
29
28
|
exclude_files,
|
|
30
29
|
ask,
|
|
@@ -122,10 +121,7 @@ def show_help():
|
|
|
122
121
|
)
|
|
123
122
|
print(
|
|
124
123
|
f" \033[94m/coding\033[0m \033[93m<query>\033[0m - \033[92m{get_message('coding_desc')}\033[0m"
|
|
125
|
-
)
|
|
126
|
-
print(
|
|
127
|
-
f" \033[94m/ask\033[0m \033[93m<query>\033[0m - \033[92m{get_message('ask_desc')}\033[0m"
|
|
128
|
-
)
|
|
124
|
+
)
|
|
129
125
|
print(
|
|
130
126
|
f" \033[94m/summon\033[0m \033[93m<query>\033[0m - \033[92m{get_message('summon_desc')}\033[0m"
|
|
131
127
|
)
|
|
@@ -302,7 +298,6 @@ def main():
|
|
|
302
298
|
# 加载保存的运行时配置
|
|
303
299
|
plugin_manager.load_runtime_cfg()
|
|
304
300
|
|
|
305
|
-
load_memory()
|
|
306
301
|
memory = get_memory()
|
|
307
302
|
|
|
308
303
|
configure(f"product_mode:{ARGS.product_mode}")
|
|
@@ -345,7 +340,8 @@ def main():
|
|
|
345
340
|
memory["mode"] = "voice_input"
|
|
346
341
|
else: # voice_input
|
|
347
342
|
memory["mode"] = "normal"
|
|
348
|
-
|
|
343
|
+
|
|
344
|
+
save_memory()
|
|
349
345
|
event.app.invalidate()
|
|
350
346
|
|
|
351
347
|
@kb.add("c-n")
|
|
@@ -467,8 +463,8 @@ def main():
|
|
|
467
463
|
else:
|
|
468
464
|
user_input = session.prompt(FormattedText(prompt_message), style=style)
|
|
469
465
|
new_prompt = ""
|
|
470
|
-
|
|
471
|
-
if "mode" not in memory:
|
|
466
|
+
|
|
467
|
+
if "mode" not in memory:
|
|
472
468
|
memory["mode"] = "auto_detect"
|
|
473
469
|
|
|
474
470
|
# 处理 user_input 的空格
|
|
@@ -545,9 +541,11 @@ def main():
|
|
|
545
541
|
print(memory["mode"])
|
|
546
542
|
else:
|
|
547
543
|
memory["mode"] = conf
|
|
544
|
+
save_memory()
|
|
548
545
|
|
|
549
546
|
elif user_input.startswith("/conf/export"):
|
|
550
547
|
from autocoder.common.conf_import_export import export_conf
|
|
548
|
+
export_conf(os.getcwd(), user_input[len("/conf/export") :].strip() or ".")
|
|
551
549
|
|
|
552
550
|
elif user_input.startswith("/plugins"):
|
|
553
551
|
# 提取命令参数并交由 plugin_manager 处理
|
|
@@ -580,14 +578,7 @@ def main():
|
|
|
580
578
|
|
|
581
579
|
elif user_input.startswith("/exclude_files"):
|
|
582
580
|
query = user_input[len("/exclude_files") :].strip()
|
|
583
|
-
exclude_files(query)
|
|
584
|
-
|
|
585
|
-
elif user_input.startswith("/ask"):
|
|
586
|
-
query = user_input[len("/ask") :].strip()
|
|
587
|
-
if not query:
|
|
588
|
-
print("Please enter your question.")
|
|
589
|
-
else:
|
|
590
|
-
ask(query)
|
|
581
|
+
exclude_files(query)
|
|
591
582
|
|
|
592
583
|
elif user_input.startswith("/exit"):
|
|
593
584
|
raise EOFError()
|
|
@@ -850,7 +850,8 @@ class AgenticEdit:
|
|
|
850
850
|
|
|
851
851
|
iteration_count = 0
|
|
852
852
|
tool_executed = False
|
|
853
|
-
should_yield_completion_event = False
|
|
853
|
+
should_yield_completion_event = False
|
|
854
|
+
completion_event = None
|
|
854
855
|
|
|
855
856
|
while True:
|
|
856
857
|
iteration_count += 1
|
|
@@ -860,10 +861,13 @@ class AgenticEdit:
|
|
|
860
861
|
if last_message["role"] == "assistant":
|
|
861
862
|
logger.info(f"Last message is assistant, skipping LLM interaction cycle")
|
|
862
863
|
if should_yield_completion_event:
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
864
|
+
if completion_event is None:
|
|
865
|
+
yield CompletionEvent(completion=AttemptCompletionTool(
|
|
866
|
+
result=last_message["content"],
|
|
867
|
+
command=""
|
|
868
|
+
), completion_xml="")
|
|
869
|
+
else:
|
|
870
|
+
yield completion_event
|
|
867
871
|
break
|
|
868
872
|
logger.info(
|
|
869
873
|
f"Starting LLM interaction cycle. History size: {len(conversations)}")
|
|
@@ -935,7 +939,7 @@ class AgenticEdit:
|
|
|
935
939
|
logger.info(
|
|
936
940
|
"AttemptCompletionTool received. Finalizing session.")
|
|
937
941
|
logger.info(f"Completion result: {tool_obj.result[:50]}...")
|
|
938
|
-
|
|
942
|
+
completion_event = CompletionEvent(completion=tool_obj, completion_xml=tool_xml)
|
|
939
943
|
logger.info(
|
|
940
944
|
"AgenticEdit analyze loop finished due to AttemptCompletion.")
|
|
941
945
|
save_formatted_log(self.args.source_dir, json.dumps(conversations, ensure_ascii=False), "agentic_conversation")
|
|
@@ -13,7 +13,7 @@ from rich.console import Console
|
|
|
13
13
|
from rich.panel import Panel
|
|
14
14
|
from rich.text import Text
|
|
15
15
|
from autocoder.common.result_manager import ResultManager
|
|
16
|
-
|
|
16
|
+
from autocoder.common.printer import Printer
|
|
17
17
|
if typing.TYPE_CHECKING:
|
|
18
18
|
from autocoder.common.v2.agent.agentic_edit import AgenticEdit
|
|
19
19
|
|
|
@@ -22,6 +22,7 @@ class AskFollowupQuestionToolResolver(BaseToolResolver):
|
|
|
22
22
|
super().__init__(agent, tool, args)
|
|
23
23
|
self.tool: AskFollowupQuestionTool = tool # For type hinting
|
|
24
24
|
self.result_manager = ResultManager()
|
|
25
|
+
self.printer = Printer()
|
|
25
26
|
|
|
26
27
|
def resolve(self) -> ToolResult:
|
|
27
28
|
"""
|
|
@@ -7,6 +7,7 @@ from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import Base
|
|
|
7
7
|
from autocoder.common.v2.agent.agentic_edit_types import ReplaceInFileTool, ToolResult
|
|
8
8
|
from autocoder.common.file_checkpoint.models import FileChange as CheckpointFileChange
|
|
9
9
|
from autocoder.common.file_checkpoint.manager import FileChangeManager as CheckpointFileChangeManager
|
|
10
|
+
from autocoder.linters.models import IssueSeverity, FileLintResult
|
|
10
11
|
from loguru import logger
|
|
11
12
|
from autocoder.common.auto_coder_lang import get_message_with_format
|
|
12
13
|
if typing.TYPE_CHECKING:
|
|
@@ -62,7 +63,38 @@ class ReplaceInFileToolResolver(BaseToolResolver):
|
|
|
62
63
|
logger.warning(f"Could not parse any SEARCH/REPLACE blocks from diff: {diff_content}")
|
|
63
64
|
return blocks
|
|
64
65
|
|
|
65
|
-
def
|
|
66
|
+
def _filter_lint_issues(self, lint_result:FileLintResult, levels: List[IssueSeverity] = [IssueSeverity.ERROR, IssueSeverity.WARNING]):
|
|
67
|
+
"""
|
|
68
|
+
过滤 lint 结果,只保留指定级别的问题
|
|
69
|
+
|
|
70
|
+
参数:
|
|
71
|
+
lint_result: 单个文件的 lint 结果对象
|
|
72
|
+
levels: 要保留的问题级别列表,默认保留 ERROR 和 WARNING 级别
|
|
73
|
+
|
|
74
|
+
返回:
|
|
75
|
+
过滤后的 lint 结果对象(原对象的副本)
|
|
76
|
+
"""
|
|
77
|
+
if not lint_result or not lint_result.issues:
|
|
78
|
+
return lint_result
|
|
79
|
+
|
|
80
|
+
# 创建一个新的 issues 列表,只包含指定级别的问题
|
|
81
|
+
filtered_issues = []
|
|
82
|
+
for issue in lint_result.issues:
|
|
83
|
+
if issue.severity in levels:
|
|
84
|
+
filtered_issues.append(issue)
|
|
85
|
+
|
|
86
|
+
# 更新 lint_result 的副本
|
|
87
|
+
filtered_result = lint_result
|
|
88
|
+
filtered_result.issues = filtered_issues
|
|
89
|
+
|
|
90
|
+
# 更新计数
|
|
91
|
+
filtered_result.error_count = sum(1 for issue in filtered_result.issues if issue.severity == IssueSeverity.ERROR)
|
|
92
|
+
filtered_result.warning_count = sum(1 for issue in filtered_result.issues if issue.severity == IssueSeverity.WARNING)
|
|
93
|
+
filtered_result.info_count = sum(1 for issue in filtered_result.issues if issue.severity == IssueSeverity.INFO)
|
|
94
|
+
|
|
95
|
+
return filtered_result
|
|
96
|
+
|
|
97
|
+
def _format_lint_issues(self, lint_result:FileLintResult):
|
|
66
98
|
"""
|
|
67
99
|
将 lint 结果格式化为可读的文本格式
|
|
68
100
|
|
|
@@ -86,130 +118,7 @@ class ReplaceInFileToolResolver(BaseToolResolver):
|
|
|
86
118
|
|
|
87
119
|
return "\n".join(formatted_issues)
|
|
88
120
|
|
|
89
|
-
|
|
90
|
-
"""Replace content in file using shadow manager for path translation"""
|
|
91
|
-
try:
|
|
92
|
-
# Determine target path: shadow file
|
|
93
|
-
target_path = self.shadow_manager.to_shadow_path(abs_file_path)
|
|
94
|
-
|
|
95
|
-
# Read original content
|
|
96
|
-
if os.path.exists(target_path) and os.path.isfile(target_path):
|
|
97
|
-
with open(target_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
98
|
-
original_content = f.read()
|
|
99
|
-
elif os.path.exists(abs_file_path) and os.path.isfile(abs_file_path):
|
|
100
|
-
# If shadow doesn't exist, but original exists, read original content
|
|
101
|
-
with open(abs_file_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
102
|
-
original_content = f.read()
|
|
103
|
-
# create parent dirs of shadow if needed
|
|
104
|
-
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
|
105
|
-
# write original content into shadow file as baseline
|
|
106
|
-
with open(target_path, 'w', encoding='utf-8') as f:
|
|
107
|
-
f.write(original_content)
|
|
108
|
-
logger.info(f"[Shadow] Initialized shadow file from original: {target_path}")
|
|
109
|
-
else:
|
|
110
|
-
return ToolResult(success=False, message=get_message_with_format("replace_in_file.file_not_found", file_path=file_path))
|
|
111
|
-
|
|
112
|
-
parsed_blocks = self.parse_diff(diff_content)
|
|
113
|
-
if not parsed_blocks:
|
|
114
|
-
return ToolResult(success=False, message=get_message_with_format("replace_in_file.no_valid_blocks"))
|
|
115
|
-
|
|
116
|
-
current_content = original_content
|
|
117
|
-
applied_count = 0
|
|
118
|
-
errors = []
|
|
119
|
-
|
|
120
|
-
# Apply blocks sequentially
|
|
121
|
-
for i, (search_block, replace_block) in enumerate(parsed_blocks):
|
|
122
|
-
start_index = current_content.find(search_block)
|
|
123
|
-
|
|
124
|
-
if start_index != -1:
|
|
125
|
-
current_content = current_content[:start_index] + replace_block + current_content[start_index + len(search_block):]
|
|
126
|
-
applied_count += 1
|
|
127
|
-
logger.info(f"Applied SEARCH/REPLACE block {i+1} in file {file_path}")
|
|
128
|
-
else:
|
|
129
|
-
error_message = f"SEARCH block {i+1} not found in the current file content. Content to search:\n---\n{search_block}\n---"
|
|
130
|
-
logger.warning(error_message)
|
|
131
|
-
context_start = max(0, original_content.find(search_block[:20]) - 100)
|
|
132
|
-
context_end = min(len(original_content), context_start + 200 + len(search_block[:20]))
|
|
133
|
-
logger.warning(f"Approximate context in file:\n---\n{original_content[context_start:context_end]}\n---")
|
|
134
|
-
errors.append(error_message)
|
|
135
|
-
|
|
136
|
-
if applied_count == 0 and errors:
|
|
137
|
-
return ToolResult(success=False, message=get_message_with_format("replace_in_file.apply_failed", errors="\n".join(errors)))
|
|
138
|
-
|
|
139
|
-
# Write the modified content back to shadow file
|
|
140
|
-
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
|
141
|
-
with open(target_path, 'w', encoding='utf-8') as f:
|
|
142
|
-
f.write(current_content)
|
|
143
|
-
|
|
144
|
-
logger.info(f"Successfully applied {applied_count}/{len(parsed_blocks)} changes to shadow file: {file_path}")
|
|
145
|
-
|
|
146
|
-
# 新增:执行代码质量检查
|
|
147
|
-
lint_results = None
|
|
148
|
-
lint_message = ""
|
|
149
|
-
formatted_issues = ""
|
|
150
|
-
has_lint_issues = False
|
|
151
|
-
|
|
152
|
-
# 检查是否启用了Lint功能
|
|
153
|
-
enable_lint = self.args.enable_auto_fix_lint
|
|
154
|
-
|
|
155
|
-
if enable_lint:
|
|
156
|
-
try:
|
|
157
|
-
if self.shadow_linter and self.shadow_manager:
|
|
158
|
-
# 对修改后的文件进行 lint 检查
|
|
159
|
-
shadow_path = target_path # 已经是影子路径
|
|
160
|
-
lint_results = self.shadow_linter.lint_shadow_file(shadow_path)
|
|
161
|
-
|
|
162
|
-
if lint_results and lint_results.issues:
|
|
163
|
-
has_lint_issues = True
|
|
164
|
-
# 格式化 lint 问题
|
|
165
|
-
formatted_issues = self._format_lint_issues(lint_results)
|
|
166
|
-
lint_message = f"\n\n代码质量检查发现 {len(lint_results.issues)} 个问题:\n{formatted_issues}"
|
|
167
|
-
else:
|
|
168
|
-
lint_message = "\n\n代码质量检查通过,未发现问题。"
|
|
169
|
-
except Exception as e:
|
|
170
|
-
logger.error(f"Lint 检查失败: {str(e)}")
|
|
171
|
-
lint_message = "\n\n尝试进行代码质量检查时出错。"
|
|
172
|
-
else:
|
|
173
|
-
logger.info("代码质量检查已禁用")
|
|
174
|
-
|
|
175
|
-
# 构建包含 lint 结果的返回消息
|
|
176
|
-
if errors:
|
|
177
|
-
message = get_message_with_format("replace_in_file.apply_success_with_warnings",
|
|
178
|
-
applied=applied_count,
|
|
179
|
-
total=len(parsed_blocks),
|
|
180
|
-
file_path=file_path,
|
|
181
|
-
errors="\n".join(errors))
|
|
182
|
-
else:
|
|
183
|
-
message = get_message_with_format("replace_in_file.apply_success",
|
|
184
|
-
applied=applied_count,
|
|
185
|
-
total=len(parsed_blocks),
|
|
186
|
-
file_path=file_path)
|
|
187
|
-
|
|
188
|
-
# 将 lint 消息添加到结果中,如果启用了Lint
|
|
189
|
-
if enable_lint:
|
|
190
|
-
message += lint_message
|
|
191
|
-
|
|
192
|
-
# 变更跟踪,回调AgenticEdit
|
|
193
|
-
if self.agent:
|
|
194
|
-
rel_path = os.path.relpath(abs_file_path, abs_project_dir)
|
|
195
|
-
self.agent.record_file_change(rel_path, "modified", diff=diff_content, content=current_content)
|
|
196
|
-
|
|
197
|
-
# 附加 lint 结果到返回内容
|
|
198
|
-
result_content = {
|
|
199
|
-
"content": current_content,
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
# 只有在启用Lint时才添加Lint结果
|
|
203
|
-
if enable_lint:
|
|
204
|
-
result_content["lint_results"] = {
|
|
205
|
-
"has_issues": has_lint_issues,
|
|
206
|
-
"issues": formatted_issues if has_lint_issues else None
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return ToolResult(success=True, message=message, content=result_content)
|
|
210
|
-
except Exception as e:
|
|
211
|
-
logger.error(f"Error writing replaced content to shadow file '{file_path}': {str(e)}")
|
|
212
|
-
return ToolResult(success=False, message=get_message_with_format("replace_in_file.write_error", error=str(e)))
|
|
121
|
+
|
|
213
122
|
|
|
214
123
|
def replace_in_file_normal(self, file_path: str, diff_content: str, source_dir: str, abs_project_dir: str, abs_file_path: str) -> ToolResult:
|
|
215
124
|
"""Replace content in file directly without using shadow manager"""
|
|
@@ -282,16 +191,20 @@ class ReplaceInFileToolResolver(BaseToolResolver):
|
|
|
282
191
|
|
|
283
192
|
# 检查是否启用了Lint功能
|
|
284
193
|
enable_lint = self.args.enable_auto_fix_lint
|
|
194
|
+
logger.info(f"检查Lint功能状态: enable_lint={enable_lint}")
|
|
285
195
|
|
|
286
196
|
if enable_lint:
|
|
287
197
|
try:
|
|
288
198
|
if self.agent.linter:
|
|
289
199
|
lint_results = self.agent.linter.lint_file(file_path)
|
|
290
200
|
if lint_results and lint_results.issues:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
201
|
+
# 过滤 lint 结果,只保留 ERROR 和 WARNING 级别的问题
|
|
202
|
+
filtered_results = self._filter_lint_issues(lint_results)
|
|
203
|
+
if filtered_results.issues:
|
|
204
|
+
has_lint_issues = True
|
|
205
|
+
# 格式化 lint 问题
|
|
206
|
+
formatted_issues = self._format_lint_issues(filtered_results)
|
|
207
|
+
lint_message = f"\n\n代码质量检查发现 {len(filtered_results.issues)} 个问题"
|
|
295
208
|
except Exception as e:
|
|
296
209
|
logger.error(f"Lint 检查失败: {str(e)}")
|
|
297
210
|
lint_message = "\n\n尝试进行代码质量检查时出错。"
|
|
@@ -309,17 +222,13 @@ class ReplaceInFileToolResolver(BaseToolResolver):
|
|
|
309
222
|
message = get_message_with_format("replace_in_file.apply_success",
|
|
310
223
|
applied=applied_count,
|
|
311
224
|
total=len(parsed_blocks),
|
|
312
|
-
file_path=file_path)
|
|
313
|
-
|
|
314
|
-
# 将 lint 消息添加到结果中,如果启用了Lint
|
|
315
|
-
if enable_lint:
|
|
316
|
-
message += lint_message
|
|
225
|
+
file_path=file_path)
|
|
317
226
|
|
|
318
227
|
# 变更跟踪,回调AgenticEdit
|
|
319
228
|
if self.agent:
|
|
320
229
|
rel_path = os.path.relpath(abs_file_path, abs_project_dir)
|
|
321
230
|
self.agent.record_file_change(rel_path, "modified", diff=diff_content, content=current_content)
|
|
322
|
-
|
|
231
|
+
|
|
323
232
|
# 附加 lint 结果到返回内容
|
|
324
233
|
result_content = {
|
|
325
234
|
"content": current_content,
|
|
@@ -327,6 +236,7 @@ class ReplaceInFileToolResolver(BaseToolResolver):
|
|
|
327
236
|
|
|
328
237
|
# 只有在启用Lint时才添加Lint结果
|
|
329
238
|
if enable_lint:
|
|
239
|
+
message = message + "\n" + lint_message
|
|
330
240
|
result_content["lint_results"] = {
|
|
331
241
|
"has_issues": has_lint_issues,
|
|
332
242
|
"issues": formatted_issues if has_lint_issues else None
|
|
@@ -348,9 +258,5 @@ class ReplaceInFileToolResolver(BaseToolResolver):
|
|
|
348
258
|
# Security check
|
|
349
259
|
if not abs_file_path.startswith(abs_project_dir):
|
|
350
260
|
return ToolResult(success=False, message=get_message_with_format("replace_in_file.access_denied", file_path=file_path))
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if self.shadow_manager:
|
|
354
|
-
return self.replace_in_file_with_shadow(file_path, diff_content, source_dir, abs_project_dir, abs_file_path)
|
|
355
|
-
else:
|
|
356
|
-
return self.replace_in_file_normal(file_path, diff_content, source_dir, abs_project_dir, abs_file_path)
|
|
261
|
+
|
|
262
|
+
return self.replace_in_file_normal(file_path, diff_content, source_dir, abs_project_dir, abs_file_path)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from typing import Dict, Any, Optional
|
|
2
|
+
from typing import Dict, Any, Optional, List
|
|
3
3
|
from autocoder.common.v2.agent.agentic_edit_types import WriteToFileTool, ToolResult
|
|
4
4
|
from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
|
|
5
5
|
from loguru import logger
|
|
@@ -7,6 +7,7 @@ from autocoder.common import AutoCoderArgs
|
|
|
7
7
|
from autocoder.common.auto_coder_lang import get_message_with_format
|
|
8
8
|
from autocoder.common.file_checkpoint.models import FileChange as CheckpointFileChange
|
|
9
9
|
from autocoder.common.file_checkpoint.manager import FileChangeManager as CheckpointFileChangeManager
|
|
10
|
+
from autocoder.linters.models import IssueSeverity, FileLintResult
|
|
10
11
|
import typing
|
|
11
12
|
|
|
12
13
|
if typing.TYPE_CHECKING:
|
|
@@ -20,7 +21,38 @@ class WriteToFileToolResolver(BaseToolResolver):
|
|
|
20
21
|
self.shadow_manager = self.agent.shadow_manager if self.agent else None
|
|
21
22
|
self.shadow_linter = self.agent.shadow_linter if self.agent else None
|
|
22
23
|
|
|
23
|
-
def
|
|
24
|
+
def _filter_lint_issues(self, lint_result:FileLintResult, levels: List[IssueSeverity] = [IssueSeverity.ERROR, IssueSeverity.WARNING]):
|
|
25
|
+
"""
|
|
26
|
+
过滤 lint 结果,只保留指定级别的问题
|
|
27
|
+
|
|
28
|
+
参数:
|
|
29
|
+
lint_result: 单个文件的 lint 结果对象
|
|
30
|
+
levels: 要保留的问题级别列表,默认保留 ERROR 和 WARNING 级别
|
|
31
|
+
|
|
32
|
+
返回:
|
|
33
|
+
过滤后的 lint 结果对象(原对象的副本)
|
|
34
|
+
"""
|
|
35
|
+
if not lint_result or not lint_result.issues:
|
|
36
|
+
return lint_result
|
|
37
|
+
|
|
38
|
+
# 创建一个新的 issues 列表,只包含指定级别的问题
|
|
39
|
+
filtered_issues = []
|
|
40
|
+
for issue in lint_result.issues:
|
|
41
|
+
if issue.severity in levels:
|
|
42
|
+
filtered_issues.append(issue)
|
|
43
|
+
|
|
44
|
+
# 更新 lint_result 的副本
|
|
45
|
+
filtered_result = lint_result
|
|
46
|
+
filtered_result.issues = filtered_issues
|
|
47
|
+
|
|
48
|
+
# 更新计数
|
|
49
|
+
filtered_result.error_count = sum(1 for issue in filtered_issues if issue.severity == IssueSeverity.ERROR)
|
|
50
|
+
filtered_result.warning_count = sum(1 for issue in filtered_issues if issue.severity == IssueSeverity.WARNING)
|
|
51
|
+
filtered_result.info_count = sum(1 for issue in filtered_issues if issue.severity == IssueSeverity.INFO)
|
|
52
|
+
|
|
53
|
+
return filtered_result
|
|
54
|
+
|
|
55
|
+
def _format_lint_issues(self, lint_result:FileLintResult):
|
|
24
56
|
"""
|
|
25
57
|
将 lint 结果格式化为可读的文本格式
|
|
26
58
|
|
|
@@ -43,74 +75,7 @@ class WriteToFileToolResolver(BaseToolResolver):
|
|
|
43
75
|
)
|
|
44
76
|
|
|
45
77
|
return "\n".join(formatted_issues)
|
|
46
|
-
|
|
47
|
-
def write_file_with_shadow(self, file_path: str, content: str, source_dir: str, abs_project_dir: str, abs_file_path: str) -> ToolResult:
|
|
48
|
-
"""Write file using shadow manager for path translation"""
|
|
49
|
-
try:
|
|
50
|
-
shadow_path = self.shadow_manager.to_shadow_path(abs_file_path)
|
|
51
|
-
# Ensure shadow directory exists
|
|
52
|
-
os.makedirs(os.path.dirname(shadow_path), exist_ok=True)
|
|
53
|
-
with open(shadow_path, 'w', encoding='utf-8') as f:
|
|
54
|
-
f.write(content)
|
|
55
|
-
logger.info(f"[Shadow] Successfully wrote shadow file: {shadow_path}")
|
|
56
|
-
|
|
57
|
-
# 回调AgenticEdit,记录变更
|
|
58
|
-
if self.agent:
|
|
59
|
-
rel_path = os.path.relpath(abs_file_path, abs_project_dir)
|
|
60
|
-
self.agent.record_file_change(rel_path, "added", diff=None, content=content)
|
|
61
|
-
|
|
62
|
-
# 新增:执行代码质量检查
|
|
63
|
-
lint_results = None
|
|
64
|
-
lint_message = ""
|
|
65
|
-
formatted_issues = ""
|
|
66
|
-
has_lint_issues = False
|
|
67
|
-
|
|
68
|
-
# 检查是否启用了Lint功能
|
|
69
|
-
enable_lint = self.args.enable_auto_fix_lint
|
|
70
|
-
|
|
71
|
-
if enable_lint:
|
|
72
|
-
try:
|
|
73
|
-
if self.shadow_linter and self.shadow_manager:
|
|
74
|
-
# 对新创建的文件进行 lint 检查
|
|
75
|
-
shadow_path = self.shadow_manager.to_shadow_path(abs_file_path)
|
|
76
|
-
lint_results = self.shadow_linter.lint_shadow_file(shadow_path)
|
|
77
|
-
|
|
78
|
-
if lint_results and lint_results.issues:
|
|
79
|
-
has_lint_issues = True
|
|
80
|
-
# 格式化 lint 问题
|
|
81
|
-
formatted_issues = self._format_lint_issues(lint_results)
|
|
82
|
-
lint_message = f"\n\n代码质量检查发现 {len(lint_results.issues)} 个问题:\n{formatted_issues}"
|
|
83
|
-
else:
|
|
84
|
-
lint_message = "\n\n代码质量检查通过,未发现问题。"
|
|
85
|
-
except Exception as e:
|
|
86
|
-
logger.error(f"Lint 检查失败: {str(e)}")
|
|
87
|
-
lint_message = "\n\n尝试进行代码质量检查时出错。"
|
|
88
|
-
else:
|
|
89
|
-
logger.info("代码质量检查已禁用")
|
|
90
|
-
|
|
91
|
-
# 构建包含 lint 结果的返回消息
|
|
92
|
-
message = f"Successfully wrote to file (shadow): {file_path}"
|
|
93
|
-
|
|
94
|
-
# 将 lint 消息添加到结果中,如果启用了Lint
|
|
95
|
-
if enable_lint:
|
|
96
|
-
message += lint_message
|
|
97
|
-
|
|
98
|
-
# 附加 lint 结果到返回内容
|
|
99
|
-
result_content = {
|
|
100
|
-
"content": content,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
# 只有在启用Lint时才添加Lint结果
|
|
104
|
-
if enable_lint:
|
|
105
|
-
result_content["lint_results"] = {
|
|
106
|
-
"has_issues": has_lint_issues,
|
|
107
|
-
"issues": formatted_issues if has_lint_issues else None
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return ToolResult(success=True, message=message, content=result_content)
|
|
111
|
-
except Exception as e:
|
|
112
|
-
logger.error(f"Error writing to shadow file '{file_path}': {str(e)}")
|
|
113
|
-
return ToolResult(success=False, message=f"An error occurred while writing to the shadow file: {str(e)}")
|
|
78
|
+
|
|
114
79
|
|
|
115
80
|
def write_file_normal(self, file_path: str, content: str, source_dir: str, abs_project_dir: str, abs_file_path: str) -> ToolResult:
|
|
116
81
|
"""Write file directly without using shadow manager"""
|
|
@@ -153,31 +118,17 @@ class WriteToFileToolResolver(BaseToolResolver):
|
|
|
153
118
|
enable_lint = self.args.enable_auto_fix_lint
|
|
154
119
|
|
|
155
120
|
if enable_lint:
|
|
156
|
-
try:
|
|
157
|
-
if self.shadow_linter and self.shadow_manager:
|
|
158
|
-
# 对新创建的文件进行 lint 检查
|
|
159
|
-
# 由于没有shadow系统,需要先创建shadow文件
|
|
160
|
-
shadow_path = self.shadow_manager.to_shadow_path(abs_file_path)
|
|
161
|
-
os.makedirs(os.path.dirname(shadow_path), exist_ok=True)
|
|
162
|
-
with open(shadow_path, 'w', encoding='utf-8') as f:
|
|
163
|
-
f.write(content)
|
|
164
|
-
|
|
165
|
-
lint_results = self.shadow_linter.lint_shadow_file(shadow_path)
|
|
166
|
-
|
|
167
|
-
if lint_results and lint_results.issues:
|
|
168
|
-
has_lint_issues = True
|
|
169
|
-
# 格式化 lint 问题
|
|
170
|
-
formatted_issues = self._format_lint_issues(lint_results)
|
|
171
|
-
lint_message = f"\n\n代码质量检查发现 {len(lint_results.issues)} 个问题:\n{formatted_issues}"
|
|
172
|
-
else:
|
|
173
|
-
lint_message = "\n\n代码质量检查通过,未发现问题。"
|
|
121
|
+
try:
|
|
174
122
|
if self.agent.linter:
|
|
175
123
|
lint_results = self.agent.linter.lint_file(file_path)
|
|
176
124
|
if lint_results and lint_results.issues:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
125
|
+
# 过滤 lint 结果,只保留 ERROR 和 WARNING 级别的问题
|
|
126
|
+
filtered_results = self._filter_lint_issues(lint_results)
|
|
127
|
+
if filtered_results.issues:
|
|
128
|
+
has_lint_issues = True
|
|
129
|
+
# 格式化 lint 问题
|
|
130
|
+
formatted_issues = self._format_lint_issues(filtered_results)
|
|
131
|
+
lint_message = f"\n\n代码质量检查发现 {len(filtered_results.issues)} 个问题"
|
|
181
132
|
except Exception as e:
|
|
182
133
|
logger.error(f"Lint 检查失败: {str(e)}")
|
|
183
134
|
lint_message = "\n\n尝试进行代码质量检查时出错。"
|
|
@@ -186,10 +137,7 @@ class WriteToFileToolResolver(BaseToolResolver):
|
|
|
186
137
|
|
|
187
138
|
# 构建包含 lint 结果的返回消息
|
|
188
139
|
message = f"{file_path}"
|
|
189
|
-
|
|
190
|
-
# 将 lint 消息添加到结果中,如果启用了Lint
|
|
191
|
-
if enable_lint:
|
|
192
|
-
message += lint_message
|
|
140
|
+
|
|
193
141
|
|
|
194
142
|
# 附加 lint 结果到返回内容
|
|
195
143
|
result_content = {
|
|
@@ -198,6 +146,7 @@ class WriteToFileToolResolver(BaseToolResolver):
|
|
|
198
146
|
|
|
199
147
|
# 只有在启用Lint时才添加Lint结果
|
|
200
148
|
if enable_lint:
|
|
149
|
+
message = message + "\n" + lint_message
|
|
201
150
|
result_content["lint_results"] = {
|
|
202
151
|
"has_issues": has_lint_issues,
|
|
203
152
|
"issues": formatted_issues if has_lint_issues else None
|
|
@@ -219,9 +168,5 @@ class WriteToFileToolResolver(BaseToolResolver):
|
|
|
219
168
|
# Security check: ensure the path is within the source directory
|
|
220
169
|
if not abs_file_path.startswith(abs_project_dir):
|
|
221
170
|
return ToolResult(success=False, message=f"Error: Access denied. Attempted to write file outside the project directory: {file_path}")
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if self.shadow_manager:
|
|
225
|
-
return self.write_file_with_shadow(file_path, content, source_dir, abs_project_dir, abs_file_path)
|
|
226
|
-
else:
|
|
227
|
-
return self.write_file_normal(file_path, content, source_dir, abs_project_dir, abs_file_path)
|
|
171
|
+
|
|
172
|
+
return self.write_file_normal(file_path, content, source_dir, abs_project_dir, abs_file_path)
|
autocoder/index/index.py
CHANGED
|
@@ -9,6 +9,7 @@ from autocoder.linters.base_linter import BaseLinter
|
|
|
9
9
|
from autocoder.linters.reactjs_linter import ReactJSLinter
|
|
10
10
|
from autocoder.linters.vue_linter import VueLinter
|
|
11
11
|
from autocoder.linters.python_linter import PythonLinter
|
|
12
|
+
from loguru import logger
|
|
12
13
|
|
|
13
14
|
class LinterFactory:
|
|
14
15
|
"""
|
|
@@ -115,9 +116,11 @@ class LinterFactory:
|
|
|
115
116
|
Returns:
|
|
116
117
|
Dict[str, Any]: Lint results.
|
|
117
118
|
"""
|
|
119
|
+
logger.info(f"根据文件路径{file_path}自动查找 linter")
|
|
118
120
|
linter = cls.create_linter(file_path=file_path, verbose=verbose)
|
|
121
|
+
logger.info(f"Linting file: {file_path} with linter: {linter.__class__.__name__}")
|
|
119
122
|
if linter is None:
|
|
120
|
-
return None
|
|
123
|
+
return None
|
|
121
124
|
return linter.lint_file(file_path, fix=fix)
|
|
122
125
|
|
|
123
126
|
@classmethod
|
|
@@ -72,10 +72,8 @@ class NormalLinter:
|
|
|
72
72
|
|
|
73
73
|
# 将原始结果转换为Pydantic模型
|
|
74
74
|
return self._convert_raw_lint_result(raw_lint_result, file_path)
|
|
75
|
-
except Exception as e:
|
|
76
|
-
|
|
77
|
-
print(f"检查 {file_path} 时出错: {str(e)}")
|
|
78
|
-
|
|
75
|
+
except Exception as e:
|
|
76
|
+
self.logger.exception(f"检查 {file_path} 时出错: {e}")
|
|
79
77
|
language = self._detect_language(file_path)
|
|
80
78
|
return FileLintResult(
|
|
81
79
|
file_path=file_path,
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Module for linting Python code.
|
|
3
|
-
This module provides functionality to analyze Python code for quality and best practices.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
1
|
import os
|
|
7
2
|
import sys
|
|
8
3
|
import json
|
|
@@ -25,8 +20,7 @@ class PythonLinter(BaseLinter):
|
|
|
25
20
|
Args:
|
|
26
21
|
verbose (bool): Whether to display verbose output.
|
|
27
22
|
"""
|
|
28
|
-
super().__init__(verbose)
|
|
29
|
-
BaseLinter.tt()
|
|
23
|
+
super().__init__(verbose)
|
|
30
24
|
|
|
31
25
|
def get_supported_extensions(self) -> List[str]:
|
|
32
26
|
"""
|
|
@@ -50,8 +44,7 @@ class PythonLinter(BaseLinter):
|
|
|
50
44
|
|
|
51
45
|
# Check for pylint or flake8
|
|
52
46
|
has_pylint = False
|
|
53
|
-
has_flake8 = False
|
|
54
|
-
has_black = False
|
|
47
|
+
has_flake8 = False
|
|
55
48
|
|
|
56
49
|
try:
|
|
57
50
|
subprocess.run([sys.executable, "-m", "pylint", "--version"],
|
|
@@ -67,18 +60,10 @@ class PythonLinter(BaseLinter):
|
|
|
67
60
|
has_flake8 = True
|
|
68
61
|
except (subprocess.SubprocessError, FileNotFoundError):
|
|
69
62
|
if self.verbose:
|
|
70
|
-
print("Flake8 not found.")
|
|
71
|
-
|
|
72
|
-
try:
|
|
73
|
-
subprocess.run([sys.executable, "-m", "black", "--version"],
|
|
74
|
-
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
75
|
-
has_black = True
|
|
76
|
-
except (subprocess.SubprocessError, FileNotFoundError):
|
|
77
|
-
if self.verbose:
|
|
78
|
-
print("Black not found.")
|
|
63
|
+
print("Flake8 not found.")
|
|
79
64
|
|
|
80
65
|
# Need at least one linter
|
|
81
|
-
return has_pylint or has_flake8
|
|
66
|
+
return has_pylint or has_flake8
|
|
82
67
|
|
|
83
68
|
except (subprocess.SubprocessError, FileNotFoundError):
|
|
84
69
|
return False
|
|
@@ -173,12 +158,15 @@ class PythonLinter(BaseLinter):
|
|
|
173
158
|
|
|
174
159
|
# Process pylint issues
|
|
175
160
|
for message in pylint_output:
|
|
176
|
-
severity = "
|
|
161
|
+
severity = "info"
|
|
177
162
|
if message.get('type') in ['error', 'fatal']:
|
|
178
163
|
severity = "error"
|
|
179
164
|
result['error_count'] += 1
|
|
180
|
-
|
|
165
|
+
elif message.get('type') in ['warning']:
|
|
166
|
+
severity = "warning"
|
|
181
167
|
result['warning_count'] += 1
|
|
168
|
+
else:
|
|
169
|
+
result['info_count'] += 1
|
|
182
170
|
|
|
183
171
|
issue = {
|
|
184
172
|
'file': message.get('path', ''),
|
|
@@ -265,13 +253,16 @@ class PythonLinter(BaseLinter):
|
|
|
265
253
|
message = code_message
|
|
266
254
|
|
|
267
255
|
# Determine severity based on error code
|
|
268
|
-
severity = "
|
|
256
|
+
severity = "info"
|
|
269
257
|
# E errors are generally more serious than F warnings
|
|
270
|
-
if code.startswith('
|
|
258
|
+
if code.startswith('F'):
|
|
271
259
|
severity = "error"
|
|
272
260
|
result['error_count'] += 1
|
|
273
|
-
|
|
261
|
+
elif code.startswith('E'):
|
|
262
|
+
severity = "warning"
|
|
274
263
|
result['warning_count'] += 1
|
|
264
|
+
else:
|
|
265
|
+
result['info_count'] += 1
|
|
275
266
|
|
|
276
267
|
issue = {
|
|
277
268
|
'file': file_path,
|
|
@@ -294,76 +285,7 @@ class PythonLinter(BaseLinter):
|
|
|
294
285
|
|
|
295
286
|
return result
|
|
296
287
|
|
|
297
|
-
|
|
298
|
-
"""
|
|
299
|
-
Run black on the target file or directory to check formatting or fix it.
|
|
300
|
-
|
|
301
|
-
Args:
|
|
302
|
-
target (str): Path to the file or directory to format.
|
|
303
|
-
fix (bool): Whether to automatically fix formatting issues.
|
|
304
|
-
|
|
305
|
-
Returns:
|
|
306
|
-
Dict[str, Any]: The black results.
|
|
307
|
-
"""
|
|
308
|
-
result = {
|
|
309
|
-
'error_count': 0,
|
|
310
|
-
'warning_count': 0,
|
|
311
|
-
'issues': []
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
try:
|
|
315
|
-
# Build command
|
|
316
|
-
cmd = [
|
|
317
|
-
sys.executable,
|
|
318
|
-
"-m",
|
|
319
|
-
"black",
|
|
320
|
-
]
|
|
321
|
-
|
|
322
|
-
# Check-only mode if not fixing
|
|
323
|
-
if not fix:
|
|
324
|
-
cmd.append("--check")
|
|
325
|
-
|
|
326
|
-
# Add target
|
|
327
|
-
cmd.append(target)
|
|
328
|
-
|
|
329
|
-
process = subprocess.run(
|
|
330
|
-
cmd,
|
|
331
|
-
stdout=subprocess.PIPE,
|
|
332
|
-
stderr=subprocess.PIPE,
|
|
333
|
-
text=True
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
# Black exit code is 0 if no changes, 1 if changes were needed
|
|
337
|
-
if process.returncode == 1 and not fix:
|
|
338
|
-
# Parse output to find which files would be reformatted
|
|
339
|
-
for line in process.stdout.splitlines():
|
|
340
|
-
if line.startswith("would reformat"):
|
|
341
|
-
file_path = line.replace("would reformat ", "").strip()
|
|
342
|
-
|
|
343
|
-
result['warning_count'] += 1
|
|
344
|
-
|
|
345
|
-
issue = {
|
|
346
|
-
'file': file_path,
|
|
347
|
-
'line': 0, # Black doesn't provide line numbers
|
|
348
|
-
'column': 0,
|
|
349
|
-
'severity': "warning",
|
|
350
|
-
'message': "Code formatting doesn't match Black style",
|
|
351
|
-
'rule': "formatting",
|
|
352
|
-
'tool': 'black'
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
result['issues'].append(issue)
|
|
356
|
-
|
|
357
|
-
# If auto-fixing and Black reports changes
|
|
358
|
-
if fix and process.returncode == 0 and "reformatted" in process.stderr:
|
|
359
|
-
# This is good - it means Black fixed some issues
|
|
360
|
-
pass
|
|
361
|
-
|
|
362
|
-
except Exception as e:
|
|
363
|
-
if self.verbose:
|
|
364
|
-
print(f"Error running black: {str(e)}")
|
|
365
|
-
|
|
366
|
-
return result
|
|
288
|
+
|
|
367
289
|
|
|
368
290
|
def lint_file(self, file_path: str, fix: bool = False) -> Dict[str, Any]:
|
|
369
291
|
"""
|
|
@@ -400,17 +322,7 @@ class PythonLinter(BaseLinter):
|
|
|
400
322
|
# Try to install dependencies
|
|
401
323
|
if not self._install_dependencies_if_needed():
|
|
402
324
|
result['error'] = "Required dependencies are not installed and could not be installed automatically"
|
|
403
|
-
return result
|
|
404
|
-
|
|
405
|
-
# Run black first (to format if fix=True)
|
|
406
|
-
try:
|
|
407
|
-
black_result = self._run_black(file_path, fix)
|
|
408
|
-
result['issues'].extend(black_result['issues'])
|
|
409
|
-
result['error_count'] += black_result['error_count']
|
|
410
|
-
result['warning_count'] += black_result['warning_count']
|
|
411
|
-
except Exception as e:
|
|
412
|
-
if self.verbose:
|
|
413
|
-
print(f"Error running black: {str(e)}")
|
|
325
|
+
return result
|
|
414
326
|
|
|
415
327
|
# Run pylint
|
|
416
328
|
try:
|
|
@@ -477,16 +389,7 @@ class PythonLinter(BaseLinter):
|
|
|
477
389
|
python_files.append(os.path.join(root, file))
|
|
478
390
|
|
|
479
391
|
result['files_analyzed'] = len(python_files)
|
|
480
|
-
|
|
481
|
-
# Run black first (to format if fix=True)
|
|
482
|
-
try:
|
|
483
|
-
black_result = self._run_black(project_path, fix)
|
|
484
|
-
result['issues'].extend(black_result['issues'])
|
|
485
|
-
result['error_count'] += black_result['error_count']
|
|
486
|
-
result['warning_count'] += black_result['warning_count']
|
|
487
|
-
except Exception as e:
|
|
488
|
-
if self.verbose:
|
|
489
|
-
print(f"Error running black: {str(e)}")
|
|
392
|
+
|
|
490
393
|
|
|
491
394
|
# Run pylint
|
|
492
395
|
try:
|
autocoder/rag/llm_wrapper.py
CHANGED
|
@@ -7,7 +7,6 @@ import pydantic
|
|
|
7
7
|
from byzerllm import ByzerLLM
|
|
8
8
|
from byzerllm.utils.client import LLMResponse
|
|
9
9
|
from byzerllm.utils.types import SingleOutputMeta
|
|
10
|
-
from autocoder.rag.simple_rag import SimpleRAG
|
|
11
10
|
from autocoder.rag.long_context_rag import LongContextRAG
|
|
12
11
|
from loguru import logger
|
|
13
12
|
from byzerllm.utils.langutil import asyncfy_with_semaphore
|
|
@@ -15,7 +14,7 @@ from byzerllm.utils.langutil import asyncfy_with_semaphore
|
|
|
15
14
|
|
|
16
15
|
class LLWrapper:
|
|
17
16
|
|
|
18
|
-
def __init__(self, llm: ByzerLLM, rag: Union[
|
|
17
|
+
def __init__(self, llm: ByzerLLM, rag: Union[LongContextRAG]):
|
|
19
18
|
self.llm = llm
|
|
20
19
|
self.rag = rag
|
|
21
20
|
|
autocoder/rag/rag_entry.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
from typing import List, Dict, Any, Optional,Union
|
|
2
2
|
from autocoder.common import AutoCoderArgs, SourceCode
|
|
3
3
|
from byzerllm import ByzerLLM
|
|
4
|
-
from .simple_rag import SimpleRAG
|
|
5
4
|
from .long_context_rag import LongContextRAG
|
|
6
5
|
class RAGFactory:
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
@staticmethod
|
|
10
|
-
def get_rag(llm: ByzerLLM, args: AutoCoderArgs, path: str,**kargs) -> Union[
|
|
9
|
+
def get_rag(llm: ByzerLLM, args: AutoCoderArgs, path: str,**kargs) -> Union[LongContextRAG]:
|
|
11
10
|
"""
|
|
12
11
|
Factory method to get the appropriate RAG implementation based on arguments.
|
|
13
12
|
|
|
@@ -19,10 +18,7 @@ class RAGFactory:
|
|
|
19
18
|
Returns:
|
|
20
19
|
SimpleRAG or LongContextRAG: The appropriate RAG implementation.
|
|
21
20
|
"""
|
|
22
|
-
|
|
23
|
-
return LongContextRAG(llm, args, path,**kargs)
|
|
24
|
-
else:
|
|
25
|
-
return SimpleRAG(llm, args, path)
|
|
21
|
+
return LongContextRAG(llm, args, path,**kargs)
|
|
26
22
|
|
|
27
23
|
class RAGManager:
|
|
28
24
|
def __init__(self, llm: ByzerLLM, args: AutoCoderArgs, path: str):
|
autocoder/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.374"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|