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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-coder
3
- Version: 0.1.372
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.182
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=iHy8Kt1so1ZLOPpb5GTfi4BurDe3T1hOPqOw-XIBDpQ,26851
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=IJPF7kj0RMIrgRsXbUhTJezs1M_dizS0MuBEVv5ELqM,25
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=DBzip-P_T6ZtT2eHexPcusmKYD0h7ufzp7TLwXAY10E,11554
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=SZTSZHxHzDmuWZo3K5fs79RwvJLWurg-nbJRRNbX65o,9195
32
- autocoder/agent/project_reader.py,sha256=PuZSc5vpfNxSeUzCVljCfSh10IFR97C0zWw_0EnkaWE,17727
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=vINpJfAwHcfj0Bm8lzqrTCiZvqMaTAlGoVPxWTCle4I,116275
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=bwtf4m9N82TCP3piK5UglJk1FVFFm7ZX59XerA2qxko,3131
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=J-GOlaLMwEu83v9VuHIstTpRR_vgPMR9wP_AzoK173s,18009
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=ISJ2jNz0Dfv1W7P2A_mYSM0vPdN0yW1w7Qqt6QjTk98,11170
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=IoPNsM7q-bbO94qbSwj27KPBwFkhuaA0f3sWqv_-ME0,33246
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=rsDzaY0jFnmEsbY8Co_xxpJe9lXgfs07Nnrht8_WWtY,10273
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=5Yavs24XNMOryl0ZDpr1UbVboCZwaIs4x9mFqoC1ZYk,13022
267
- autocoder/linters/python_linter.py,sha256=CurQa4pYeyPv_e4FxgVBHW-pHOzQTOftARLgY97AKBw,22511
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=Ht5GF5yJtrztoliujsZzx_ooWZmHkd5xLZKcGEiicZw,4303
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=6TKtErZ0Us9XSV6HgRKXA6yR3SiZGPHpynOKSaR1wgE,2463
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.372.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
363
- auto_coder-0.1.372.dist-info/METADATA,sha256=l01WcsmQo-Fdr2FvBM4GIWv9PZvBF8X3mc08iePNm8E,2775
364
- auto_coder-0.1.372.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
365
- auto_coder-0.1.372.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
366
- auto_coder-0.1.372.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
367
- auto_coder-0.1.372.dist-info/RECORD,,
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,,
@@ -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),
@@ -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),
@@ -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
- yield CompletionEvent(completion=AttemptCompletionTool(
864
- result=last_message["content"],
865
- command=""
866
- ), completion_xml="")
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
- # yield CompletionEvent(completion=tool_obj, completion_xml=tool_xml)
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 _format_lint_issues(self, lint_result):
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
- def replace_in_file_with_shadow(self, file_path: str, diff_content: str, source_dir: str, abs_project_dir: str, abs_file_path: str) -> ToolResult:
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
- has_lint_issues = True
292
- # 格式化 lint 问题
293
- formatted_issues = self._format_lint_issues(lint_results)
294
- lint_message = f"\n\n代码质量检查发现 {len(lint_results.issues)} 个问题:\n{formatted_issues}"
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
- # Choose the appropriate implementation based on whether shadow_manager is available
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 _format_lint_issues(self, lint_result):
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
- has_lint_issues = True
178
- # 格式化 lint 问题
179
- formatted_issues = self._format_lint_issues(lint_results)
180
- lint_message = f"\n\n代码质量检查发现 {len(lint_results.issues)} 个问题:\n{formatted_issues}"
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
- # Choose the appropriate implementation based on whether shadow_manager is available
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
@@ -665,7 +665,7 @@ class IndexManager:
665
665
  md5=data["md5"],
666
666
  )
667
667
  index_items.append(index_item)
668
- except (KeyError, TypeError) as e:
668
+ except Exception as e:
669
669
  logger.warning(f"处理索引条目 {module_name} 时出错: {str(e)}")
670
670
  logger.exception(e)
671
671
  continue
@@ -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
- if self.verbose:
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 or has_black
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 = "warning"
161
+ severity = "info"
177
162
  if message.get('type') in ['error', 'fatal']:
178
163
  severity = "error"
179
164
  result['error_count'] += 1
180
- else:
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 = "warning"
256
+ severity = "info"
269
257
  # E errors are generally more serious than F warnings
270
- if code.startswith('E'):
258
+ if code.startswith('F'):
271
259
  severity = "error"
272
260
  result['error_count'] += 1
273
- else:
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
- def _run_black(self, target: str, fix: bool) -> Dict[str, Any]:
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:
@@ -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[SimpleRAG, LongContextRAG]):
17
+ def __init__(self, llm: ByzerLLM, rag: Union[LongContextRAG]):
19
18
  self.llm = llm
20
19
  self.rag = rag
21
20
 
@@ -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[SimpleRAG, LongContextRAG]:
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
- if args.rag_type == "simple":
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.372"
2
+ __version__ = "0.1.374"