auto-coder 0.1.346__py3-none-any.whl → 0.1.348__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.346
3
+ Version: 0.1.348
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -4,7 +4,7 @@ autocoder/auto_coder_lang.py,sha256=Rtupq6N3_HT7JRhDKdgCBcwRaiAnyCOR_Gsp4jUomrI,
4
4
  autocoder/auto_coder_rag.py,sha256=NesRm7sIJrRQL1xxm_lbMtM7gi-KrYv9f26RfBuloZE,35386
5
5
  autocoder/auto_coder_rag_client_mcp.py,sha256=QRxUbjc6A8UmDMQ8lXgZkjgqtq3lgKYeatJbDY6rSo0,6270
6
6
  autocoder/auto_coder_rag_mcp.py,sha256=-RrjNwFaS2e5v8XDIrKR-zlUNUE8UBaeOtojffBrvJo,8521
7
- autocoder/auto_coder_runner.py,sha256=2hI2095L5GWP1J04Lr7xBBTDOcNq_l4-HctcJ8bVaFE,111833
7
+ autocoder/auto_coder_runner.py,sha256=LV2QJZC9CEpDYkQEjVh5Ih5Ga5rhHvoW3J4G5cri8Z8,111857
8
8
  autocoder/auto_coder_server.py,sha256=bLORGEclcVdbBVfM140JCI8WtdrU0jbgqdJIVVupiEU,20578
9
9
  autocoder/benchmark.py,sha256=Ypomkdzd1T3GE6dRICY3Hj547dZ6_inqJbBJIp5QMco,4423
10
10
  autocoder/chat_auto_coder.py,sha256=CthuvdjVjTQOVv-zREsl8OCsZHPSP9OQcIgHULrW2Ro,25842
@@ -14,7 +14,7 @@ autocoder/command_parser.py,sha256=fx1g9E6GaM273lGTcJqaFQ-hoksS_Ik2glBMnVltPCE,1
14
14
  autocoder/lang.py,sha256=PFtATuOhHRnfpqHQkXr6p4C893JvpsgwTMif3l-GEi0,14321
15
15
  autocoder/models.py,sha256=_SCar82QIeBFTZZBdM2jPS6atKVhHnvE0gX3V0CsxD4,11590
16
16
  autocoder/run_context.py,sha256=IUfSO6_gp2Wt1blFWAmOpN0b0nDrTTk4LmtCYUBIoro,1643
17
- autocoder/version.py,sha256=FUAij2FADNMtAmQCx7M7pqiOpTP65zxKY6khe4EGQUs,23
17
+ autocoder/version.py,sha256=1h2cvc5WOu9wxtFBJmh-3rclKh09vlAmUylW6SDUges,23
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
@@ -54,7 +54,7 @@ autocoder/common/action_yml_file_manager.py,sha256=DdF5P1R_B_chCnnqoA2IgogakWLZk
54
54
  autocoder/common/anything2images.py,sha256=0ILBbWzY02M-CiWB-vzuomb_J1hVdxRcenAfIrAXq9M,25283
55
55
  autocoder/common/anything2img.py,sha256=iZQmg8srXlD7N5uGl5b_ONKJMBjYoW8kPmokkG6ISF0,10118
56
56
  autocoder/common/audio.py,sha256=Kn9nWKQddWnUrAz0a_ZUgjcu4VUU_IcZBigT7n3N3qc,7439
57
- autocoder/common/auto_coder_lang.py,sha256=ozoGTy4ZFn3YsO5zWhvAGCu54mK4LtnRfC2yCvrMc_8,42462
57
+ autocoder/common/auto_coder_lang.py,sha256=TqyxigNAEg_Ouji-cGMx5alkFjboUDgFPSOwYgYAnNM,42757
58
58
  autocoder/common/auto_configure.py,sha256=D4N-fl9v8bKM5-Ds-uhkC2uGDmHH_ZjLJ759F8KXMKs,13129
59
59
  autocoder/common/buildin_tokenizer.py,sha256=L7d5t39ZFvUd6EoMPXUhYK1toD0FHlRH1jtjKRGokWU,1236
60
60
  autocoder/common/chunk_validation.py,sha256=BrR_ZWavW8IANuueEE7hS8NFAwEvm8TX34WnPx_1hs8,3030
@@ -126,18 +126,19 @@ autocoder/common/v2/code_editblock_manager.py,sha256=G0CIuV9Ki0FqMLnpA8nBT4pnkCN
126
126
  autocoder/common/v2/code_manager.py,sha256=C403bS-f6urixwitlKHcml-J03hci-UyNwHJOqBiY6Q,9182
127
127
  autocoder/common/v2/code_strict_diff_manager.py,sha256=v-J1kDyLg7tLGg_6_lbO9S4fNkx7M_L8Xr2G7fPptiU,9347
128
128
  autocoder/common/v2/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- autocoder/common/v2/agent/agentic_edit.py,sha256=Ghx6HTCdjIYj96zoB5xkL6aGLizftgCmy5ZcUSaFXtQ,92599
129
+ autocoder/common/v2/agent/agentic_edit.py,sha256=qPEvDvK2iF9eyTlWqJMCL6BDzpS1fCbQsTaG4vExyd8,94942
130
130
  autocoder/common/v2/agent/agentic_edit_conversation.py,sha256=qLLhTegH619JQTp3s1bj5FVn2hAcoV-DlhGO3UyIOMc,7338
131
- autocoder/common/v2/agent/agentic_edit_types.py,sha256=6qBLLmvdlcsbzrpMHsYQVIHqbOWubMXOnmkqTs1pBWQ,4629
131
+ autocoder/common/v2/agent/agentic_edit_types.py,sha256=VJMrictg6hJ3mC45VgQGRd43DyDUPDUvPV1Rf3z72NI,4776
132
132
  autocoder/common/v2/agent/agentic_tool_display.py,sha256=WKirt-2V346KLnbHgH3NVJiK3xvriD9oaCWj2IdvzLU,7309
133
133
  autocoder/common/v2/agent/ignore_utils.py,sha256=gnUchRzKMLbUm_jvnKL-r-K9MWKPtt-6iiuzijY7Es0,1717
134
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py,sha256=wGICCc1dYh07osB21j62zOQ9Ws0PyyOQ12UYRHmHrtI,1229
134
+ autocoder/common/v2/agent/agentic_edit_tools/__init__.py,sha256=RbPZZcZg_VnGssL577GxSyFrYrxQ_LopJ4G_-mY3z_Q,1337
135
135
  autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py,sha256=bwtf4m9N82TCP3piK5UglJk1FVFFm7ZX59XerA2qxko,3131
136
136
  autocoder/common/v2/agent/agentic_edit_tools/attempt_completion_tool_resolver.py,sha256=82ZGKeRBSDKeead_XVBW4FxpiE-5dS7tBOk_3RZ6B5s,1511
137
137
  autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py,sha256=Zid2m1uZd-2wVFGc_n_KAViXZyNjbdLSpI5n7ut1RUQ,1036
138
138
  autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py,sha256=GueQfIY2hVu2R5j9R5rBtn2znl5MlmEdGtsa6snsMHs,4112
139
139
  autocoder/common/v2/agent/agentic_edit_tools/list_code_definition_names_tool_resolver.py,sha256=8QoMsADUDWliqiDt_dpguz31403syB8eeW0Pcw-qfb8,3842
140
140
  autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py,sha256=d0LzGPA3zsIHK5s1-arPry6ddWFSymRsMY3VbkV6v5A,5795
141
+ autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py,sha256=dIdV12VuczHpHuHgx2B1j_3BZYc9PL0jfHCuBk9ryk8,2005
141
142
  autocoder/common/v2/agent/agentic_edit_tools/plan_mode_respond_tool_resolver.py,sha256=lGT4_QYJK6Fa9f6HVSGo0cSsGK7qCsDYgJGUowNxPzk,1499
142
143
  autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py,sha256=9Bh0KVbL0qiIqwChlb77biiBiETQ3zekxGe5Fj7hXAg,2800
143
144
  autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py,sha256=lpD4fCbVR8GTrynqXON69IjM94nPy3nuUL62Ashm5O4,7988
@@ -198,7 +199,7 @@ autocoder/memory/active_context_manager.py,sha256=nqWD4lBLNcskXDRERhPpqnmn_i1V7_
198
199
  autocoder/memory/active_package.py,sha256=NHLLnncFSfFcOFLWILwJLuEVd4nOoL0mqzFev6QHgzU,25480
199
200
  autocoder/memory/async_processor.py,sha256=htHzLGupw9IHQAEdLe2AEaALZSItPi3AltDt8FMTRHk,4643
200
201
  autocoder/memory/directory_mapper.py,sha256=BXHblOdRpeZb7URDECALp9uN5oi91KmkW9g_UaWFuZY,2513
201
- autocoder/plugins/__init__.py,sha256=uc8UNSAVb9uQvr5zUSS-Xu_RhrdbO2i3w2NhkrVtODM,43023
202
+ autocoder/plugins/__init__.py,sha256=T71wGXBP24NhFyf9BntKDXWPIvKp5hWhq_-xK7C-ptE,43722
202
203
  autocoder/plugins/dynamic_completion_example.py,sha256=dDTeISsGqcWjxY_PzbFSZ4Q7_QwYUcuHUdWJT8x7q-4,4693
203
204
  autocoder/plugins/git_helper_plugin.py,sha256=nKQWkU-nQ39A4WC8nC8KI-x68VjwVARQvtrtQQ1GTMI,8386
204
205
  autocoder/plugins/sample_plugin.py,sha256=0Hn1SdLovSPwMamooXyfcX5JGzsROt238bMbBhE6aIk,5215
@@ -211,11 +212,11 @@ autocoder/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
211
212
  autocoder/rag/api_server.py,sha256=StGyxrM-7-W2vYHJq-i_Fv-MHrl9UgVWY272Hd-6VJ4,13090
212
213
  autocoder/rag/conversation_to_queries.py,sha256=xwmErn4WbdADnhK1me-h_6fV3KYrl_y1qPNQl1aoI6o,4810
213
214
  autocoder/rag/doc_filter.py,sha256=UduVO2mlrngwJICrefjDJTYfdmQ4GcRXrfWDQ7xXksk,14206
214
- autocoder/rag/document_retriever.py,sha256=5BDqKVJqLPScEnua5S5suXhWuCaALIfPf5obXeJoWfs,8461
215
+ autocoder/rag/document_retriever.py,sha256=rFwbAuHTvEFJq16HQNlmRLyJp2ddn2RNFslw_ncU7NI,8847
215
216
  autocoder/rag/lang.py,sha256=HvcMeu6jReEJOGxyLMn4rwBoD-myFwmykS3VLceBJLs,3364
216
217
  autocoder/rag/llm_wrapper.py,sha256=Ht5GF5yJtrztoliujsZzx_ooWZmHkd5xLZKcGEiicZw,4303
217
- autocoder/rag/long_context_rag.py,sha256=84haMjfbPd2Rw_8Zdj-Azf_v9tbYST_OUPW0NZlmeJY,42189
218
- autocoder/rag/qa_conversation_strategy.py,sha256=vv62JhmdZvLJ3U1gG4ZZ3m9thIlGvU1H0RXHtrRTJ6s,11788
218
+ autocoder/rag/long_context_rag.py,sha256=syPIxO_TQJpBgjZ0taF-G7xVGvkNjKWL65KTI-sy4io,42234
219
+ autocoder/rag/qa_conversation_strategy.py,sha256=N4zcLstmTEZH4iGTnmNhzlRSRPfdZnTlKOXPqnqSEUQ,11727
219
220
  autocoder/rag/rag_config.py,sha256=8LwFcTd8OJWWwi1_WY4IzjqgtT6RyE2j4PjxS5cCTDE,802
220
221
  autocoder/rag/rag_entry.py,sha256=6TKtErZ0Us9XSV6HgRKXA6yR3SiZGPHpynOKSaR1wgE,2463
221
222
  autocoder/rag/raw_rag.py,sha256=BOr0YGf3umjqXOIDVO1LXQ0bIHx8hzBdiubND2ezyxc,2946
@@ -232,16 +233,18 @@ autocoder/rag/utils.py,sha256=f21ybCAlYVgr3tJP9MkVoM9d82-uG5NHu2gsv2oaVBQ,4961
232
233
  autocoder/rag/variable_holder.py,sha256=PFvBjFcR7-fNDD4Vcsc8CpH2Te057vcpwJMxtrfUgKI,75
233
234
  autocoder/rag/cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
234
235
  autocoder/rag/cache/base_cache.py,sha256=EaYYYbclMBvnlOUoM7qonnluwZX5oSvUjdvGvFun8_8,742
235
- autocoder/rag/cache/byzer_storage_cache.py,sha256=S_afj4_fFt88A0KJ23N-Gc3mMwPTDjzv9E3J9O_IiT4,29319
236
+ autocoder/rag/cache/byzer_storage_cache.py,sha256=buUrsY7-gWf6BXtzhFVKRJ-ME4LGrr9EEzjoSVu9G6g,27937
236
237
  autocoder/rag/cache/cache_result_merge.py,sha256=VnTdbT2OMBmWl_83bqds97d9_M33IhPNX8tF7KH2GMM,10556
237
- autocoder/rag/cache/file_monitor_cache.py,sha256=OdSXTH3vo6inAzkN5d55I0RN03GUlSlnUEKmXpjFl78,9443
238
- autocoder/rag/cache/local_byzer_storage_cache.py,sha256=1xskK7X_hFEAsHHoT_F9lFYhQOTrpQtsFyFCIeI2Mvk,31964
239
- autocoder/rag/cache/local_duckdb_storage_cache.py,sha256=37WH2mlOgykBUrp6ow43kcaaKFZc1CRTkNLSFdELPcE,32714
238
+ autocoder/rag/cache/failed_files_utils.py,sha256=kITguXANLC3EEJy5JoKzNXrtwvTkmZT-ANPwcno42Ck,1183
239
+ autocoder/rag/cache/file_monitor_cache.py,sha256=TelBRzw2uD9QLUIvyrdD6XWmgvb3MyTgx63ZrpptaXI,9512
240
+ autocoder/rag/cache/local_byzer_storage_cache.py,sha256=X7EVGa4xcmUWC7WLnyGPx17I1l9NvW3OHfkErO4Ww0M,30784
241
+ autocoder/rag/cache/local_duckdb_storage_cache.py,sha256=6NsNlqA8-nGSD8ILXQgO-6QbgE8eUy4uT3eM1t69nic,34447
240
242
  autocoder/rag/cache/rag_file_meta.py,sha256=RQ3n4wfkHlB-1ljS3sFSi8ijbsUPeIqBSgjmmbRuwRI,20521
241
- autocoder/rag/cache/simple_cache.py,sha256=yGmt8iXY2ZVif4_2-_DqWGl_zG0fzgSI3tUOxvdqHZU,14230
243
+ autocoder/rag/cache/simple_cache.py,sha256=yrGgRXGcMNrWSQOviPshm3Qlo2QDNVFoRZPLNTV_nQs,15997
242
244
  autocoder/rag/loaders/__init__.py,sha256=EQHEZ5Cmz-mGP2SllUTvcIbYCnF7W149dNpNItfs0yE,304
243
245
  autocoder/rag/loaders/docx_loader.py,sha256=ZswPqiiLngUEpzLhNNm1nmwEYV7ZHFEfIoXoG7c5GDU,614
244
246
  autocoder/rag/loaders/excel_loader.py,sha256=Ue8YB1z_kBs8SjIPuBskyM08Q1JiONs_BJZPrzi59oo,896
247
+ autocoder/rag/loaders/image_loader.py,sha256=UMzVDG4wmqpXYlWclNvFWCC0UHr_sWBj36RVBnjaIoA,20218
245
248
  autocoder/rag/loaders/pdf_loader.py,sha256=9cLPdhfSiedvEUFFM7I-PkZ-9klJmj8AtuihETfzO_o,706
246
249
  autocoder/rag/loaders/ppt_loader.py,sha256=7VEYc-bqgK8VHCoGC3DIUcqbpda-E5jQF9lYLqP256I,1681
247
250
  autocoder/rag/stream_event/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -277,9 +280,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
277
280
  autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
278
281
  autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=KW0mlmcHlStXi8-_6fXZ2-ifeJ5mgP0OV7DQFzCtIsw,14008
279
282
  autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
280
- auto_coder-0.1.346.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
281
- auto_coder-0.1.346.dist-info/METADATA,sha256=pXxlRR0gvLNboAcWQtU9VzpKpiaCTj4evVC9Ztas7R4,2728
282
- auto_coder-0.1.346.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
283
- auto_coder-0.1.346.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
284
- auto_coder-0.1.346.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
285
- auto_coder-0.1.346.dist-info/RECORD,,
283
+ auto_coder-0.1.348.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
284
+ auto_coder-0.1.348.dist-info/METADATA,sha256=RSE1DWgb1J9bSnwhqwMngmydulCNkWiEETsz7nB6rwQ,2728
285
+ auto_coder-0.1.348.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
286
+ auto_coder-0.1.348.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
287
+ auto_coder-0.1.348.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
288
+ auto_coder-0.1.348.dist-info/RECORD,,
@@ -2838,11 +2838,12 @@ def auto_command(query: str,extra_args: Dict[str,Any]={}):
2838
2838
  memory_config=MemoryConfig(memory=memory,
2839
2839
  save_memory_func=save_memory), command_config=CommandConfig,
2840
2840
  conversation_name="current"
2841
- )
2842
- if get_run_context() == RunMode.TERMINAL:
2843
- agent.run_in_terminal(AgenticEditRequest(user_input=query))
2844
- else:
2841
+ )
2842
+ if get_run_context().mode == RunMode.WEB:
2845
2843
  agent.run_with_events(AgenticEditRequest(user_input=query))
2844
+ else:
2845
+ agent.run_in_terminal(AgenticEditRequest(user_input=query))
2846
+
2846
2847
  return
2847
2848
 
2848
2849
  args = get_final_config()
@@ -833,6 +833,14 @@ MESSAGES = {
833
833
  "/agent/edit/user_query":{
834
834
  "en":"User Query",
835
835
  "zh":"用户查询"
836
+ },
837
+ "/agent/edit/apply_pre_changes":{
838
+ "en":"Commit user changes",
839
+ "zh":"检查用户是否有手动修改(如有,会自动提交)..."
840
+ },
841
+ "/agent/edit/apply_changes":{
842
+ "en":"Commit the changes in preview steps",
843
+ "zh":"提交前面步骤的修改"
836
844
  }
837
845
  }
838
846
 
@@ -52,8 +52,10 @@ from autocoder.common.v2.agent.agentic_edit_tools import ( # Import specific re
52
52
  ExecuteCommandToolResolver, ReadFileToolResolver, WriteToFileToolResolver,
53
53
  ReplaceInFileToolResolver, SearchFilesToolResolver, ListFilesToolResolver,
54
54
  ListCodeDefinitionNamesToolResolver, AskFollowupQuestionToolResolver,
55
- AttemptCompletionToolResolver, PlanModeRespondToolResolver, UseMcpToolResolver
55
+ AttemptCompletionToolResolver, PlanModeRespondToolResolver, UseMcpToolResolver,
56
+ ListPackageInfoToolResolver
56
57
  )
58
+
57
59
  from autocoder.common.v2.agent.agentic_edit_types import (AgenticEditRequest, ToolResult,
58
60
  MemoryConfig, CommandConfig, BaseTool,
59
61
  ExecuteCommandTool, ReadFileTool,
@@ -63,6 +65,7 @@ from autocoder.common.v2.agent.agentic_edit_types import (AgenticEditRequest, To
63
65
  ListFilesTool,
64
66
  ListCodeDefinitionNamesTool, AskFollowupQuestionTool,
65
67
  AttemptCompletionTool, PlanModeRespondTool, UseMcpTool,
68
+ ListPackageInfoTool,
66
69
  TOOL_MODEL_MAP,
67
70
  # Event Types
68
71
  LLMOutputEvent, LLMThinkingEvent, ToolCallEvent,
@@ -83,6 +86,7 @@ TOOL_RESOLVER_MAP: Dict[Type[BaseTool], Type[BaseToolResolver]] = {
83
86
  SearchFilesTool: SearchFilesToolResolver,
84
87
  ListFilesTool: ListFilesToolResolver,
85
88
  ListCodeDefinitionNamesTool: ListCodeDefinitionNamesToolResolver,
89
+ ListPackageInfoTool: ListPackageInfoToolResolver,
86
90
  AskFollowupQuestionTool: AskFollowupQuestionToolResolver,
87
91
  AttemptCompletionTool: AttemptCompletionToolResolver, # Will stop the loop anyway
88
92
  PlanModeRespondTool: PlanModeRespondToolResolver,
@@ -208,18 +212,7 @@ class AgenticEdit:
208
212
  @byzerllm.prompt()
209
213
  def _analyze(self, request: AgenticEditRequest) -> str:
210
214
  """
211
- You are a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
212
-
213
- ====
214
-
215
- FILES CONTEXT
216
-
217
- The following files are provided to you as context for the user's task. You can use these files to understand the project structure and codebase, and to make informed decisions about which files to modify.
218
- If you need to read more files, you can use the tools to find and read more files.
219
-
220
- <files>
221
- {{files}}
222
- </files>
215
+ You are a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
223
216
 
224
217
  ====
225
218
 
@@ -245,6 +238,7 @@ class AgenticEdit:
245
238
 
246
239
  Always adhere to this format for the tool use to ensure proper parsing and execution.
247
240
 
241
+
248
242
  # Tools
249
243
 
250
244
  ## execute_command
@@ -258,6 +252,15 @@ class AgenticEdit:
258
252
  <requires_approval>true or false</requires_approval>
259
253
  </execute_command>
260
254
 
255
+ ## list_package_info
256
+ Description: Request to retrieve information about a source code package, such as recent changes or documentation summary, to better understand the code context. It accepts a directory path (absolute or relative to the current project).
257
+ Parameters:
258
+ - path: (required) The source code package directory path.
259
+ Usage:
260
+ <list_package_info>
261
+ <path>relative/or/absolute/package/path</path>
262
+ </list_package_info>
263
+
261
264
  ## read_file
262
265
  Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
263
266
  Parameters:
@@ -670,20 +673,23 @@ class AgenticEdit:
670
673
 
671
674
  {% if extra_docs %}
672
675
  ====
673
-
676
+
674
677
  RULES PROVIDED BY USER
675
678
 
676
679
  The following rules are provided by the user, and you must follow them strictly.
677
680
 
678
681
  {% for key, value in extra_docs.items() %}
679
- ### {{ key }}
682
+ <user_rule>
683
+ ##File: {{ key }}
680
684
  {{ value }}
685
+ </user_rule>
681
686
  {% endfor %}
682
687
  {% endif %}
683
688
  """
684
689
  import os
685
690
  extra_docs = {}
686
- rules_dir = os.path.join(self.args.source_dir,".auto-coder", "autocoderrules")
691
+ rules_dir = os.path.join(self.args.source_dir,
692
+ ".auto-coder", "autocoderrules")
687
693
  if os.path.isdir(rules_dir):
688
694
  for fname in os.listdir(rules_dir):
689
695
  if fname.endswith(".md"):
@@ -691,7 +697,7 @@ class AgenticEdit:
691
697
  try:
692
698
  with open(fpath, "r", encoding="utf-8") as f:
693
699
  content = f.read()
694
- key = os.path.splitext(fname)[0]
700
+ key = fpath
695
701
  extra_docs[key] = content
696
702
  except Exception:
697
703
  continue
@@ -769,11 +775,25 @@ class AgenticEdit:
769
775
  # print(system_prompt)
770
776
  conversations = [
771
777
  {"role": "system", "content": system_prompt},
772
- ] + self.conversation_manager.get_history()
778
+ ]
779
+
780
+ conversations.append({
781
+ "role":"user","content":f'''
782
+ Below are some files the user is focused on, and the content is up to date. These entries show the file paths along with their full text content, which can help you better understand the user's needs. If the information is insufficient, you can use tools such as read_file to retrieve more details.
783
+ <files>
784
+ {self.files.to_str()}
785
+ </files>'''
786
+ })
787
+
788
+ conversations.append({
789
+ "role":"assistant","content":"Ok"
790
+ })
791
+ conversations.extend(self.conversation_manager.get_history())
773
792
  conversations.append({
774
793
  "role": "user", "content": request.user_input
775
794
  })
776
795
  self.conversation_manager.add_user_message(request.user_input)
796
+
777
797
  logger.debug(
778
798
  f"Initial conversation history size: {len(conversations)}")
779
799
 
@@ -998,9 +1018,7 @@ class AgenticEdit:
998
1018
 
999
1019
  for content_chunk, metadata in generator:
1000
1020
  global_cancel.check_and_raise()
1001
-
1002
- meta_holder.meta = metadata
1003
- logger.info(f"metadata: {metadata.input_tokens_count}")
1021
+ meta_holder.meta = metadata
1004
1022
  if not content_chunk:
1005
1023
  continue
1006
1024
  buffer += content_chunk
@@ -1137,6 +1155,7 @@ class AgenticEdit:
1137
1155
  standard event system format and writing them using the event manager.
1138
1156
  """
1139
1157
  event_manager = get_event_manager(self.args.event_file)
1158
+ self.apply_pre_changes()
1140
1159
 
1141
1160
  try:
1142
1161
  event_stream = self.analyze(request)
@@ -1280,6 +1299,25 @@ class AgenticEdit:
1280
1299
  # Re-raise the exception if needed, or handle appropriately
1281
1300
  raise e
1282
1301
 
1302
+ def apply_pre_changes(self):
1303
+ # get the file name
1304
+ file_name = os.path.basename(self.args.file)
1305
+ if not self.args.skip_commit:
1306
+ try:
1307
+ get_event_manager(self.args.event_file).write_result(
1308
+ EventContentCreator.create_result(
1309
+ content=self.printer.get_message_from_key("/agent/edit/apply_pre_changes")), metadata=EventMetadata(
1310
+ action_file=self.args.file,
1311
+ is_streaming=False,
1312
+ path="/agent/edit/apply_pre_changes",
1313
+ stream_out_type="/agent/edit").to_dict())
1314
+ git_utils.commit_changes(
1315
+ self.args.source_dir, f"auto_coder_pre_{file_name}")
1316
+ except Exception as e:
1317
+ self.printer.print_in_terminal("git_init_required",
1318
+ source_dir=self.args.source_dir, error=str(e))
1319
+ return
1320
+
1283
1321
  def apply_changes(self):
1284
1322
  """
1285
1323
  Apply all tracked file changes to the original project directory.
@@ -1297,6 +1335,12 @@ class AgenticEdit:
1297
1335
  f"{self.args.query}\nauto_coder_{file_name}",
1298
1336
  )
1299
1337
 
1338
+ get_event_manager(self.args.event_file).write_result(
1339
+ EventContentCreator.create_result(
1340
+ content=self.printer.get_message_from_key("/agent/edit/apply_changes")), metadata=EventMetadata(
1341
+ action_file=self.args.file,
1342
+ is_streaming=False,
1343
+ stream_out_type="/agent/edit").to_dict())
1300
1344
  action_yml_file_manager = ActionYmlFileManager(
1301
1345
  self.args.source_dir)
1302
1346
  action_file_name = os.path.basename(self.args.file)
@@ -1343,6 +1387,7 @@ class AgenticEdit:
1343
1387
  f"[bold]{get_message('/agent/edit/user_query')}:[/bold]\n{request.user_input}", title=get_message("/agent/edit/objective"), border_style="blue"))
1344
1388
 
1345
1389
  try:
1390
+ self.apply_pre_changes()
1346
1391
  event_stream = self.analyze(request)
1347
1392
  for event in event_stream:
1348
1393
  if isinstance(event, LLMThinkingEvent):
@@ -1434,7 +1479,8 @@ class AgenticEdit:
1434
1479
  logger.warning(
1435
1480
  f"Error formatting tool result content: {e}")
1436
1481
  panel_content.append(
1437
- _format_content(str(result.content))) # Fallback
1482
+ # Fallback
1483
+ _format_content(str(result.content)))
1438
1484
 
1439
1485
  # Print the base info panel
1440
1486
  console.print(Panel("\n".join(
@@ -11,6 +11,7 @@ from .ask_followup_question_tool_resolver import AskFollowupQuestionToolResolver
11
11
  from .attempt_completion_tool_resolver import AttemptCompletionToolResolver
12
12
  from .plan_mode_respond_tool_resolver import PlanModeRespondToolResolver
13
13
  from .use_mcp_tool_resolver import UseMcpToolResolver
14
+ from .list_package_info_tool_resolver import ListPackageInfoToolResolver
14
15
 
15
16
  __all__ = [
16
17
  "BaseToolResolver",
@@ -25,4 +26,5 @@ __all__ = [
25
26
  "AttemptCompletionToolResolver",
26
27
  "PlanModeRespondToolResolver",
27
28
  "UseMcpToolResolver",
29
+ "ListPackageInfoToolResolver",
28
30
  ]
@@ -0,0 +1,42 @@
1
+
2
+ import os
3
+ from typing import Optional
4
+ from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
5
+ from autocoder.common.v2.agent.agentic_edit_types import ListPackageInfoTool, ToolResult
6
+ from loguru import logger
7
+ import typing
8
+
9
+ if typing.TYPE_CHECKING:
10
+ from autocoder.common.v2.agent.agentic_edit import AgenticEdit
11
+
12
+ class ListPackageInfoToolResolver(BaseToolResolver):
13
+ def __init__(self, agent: Optional['AgenticEdit'], tool: ListPackageInfoTool, args):
14
+ super().__init__(agent, tool, args)
15
+ self.tool: ListPackageInfoTool = tool
16
+
17
+ def resolve(self) -> ToolResult:
18
+ source_dir = self.args.source_dir or "."
19
+ abs_source_dir = os.path.abspath(source_dir)
20
+
21
+ input_path = self.tool.path.strip()
22
+ abs_input_path = os.path.abspath(os.path.join(source_dir, input_path)) if not os.path.isabs(input_path) else input_path
23
+
24
+ # 校验输入目录是否在项目目录内
25
+ if not abs_input_path.startswith(abs_source_dir):
26
+ return ToolResult(success=False, message=f"Error: Access denied. Path outside project: {self.tool.path}")
27
+
28
+ rel_package_path = os.path.relpath(abs_input_path, abs_source_dir)
29
+ active_md_path = os.path.join(abs_source_dir, ".auto-coder", "active-context", rel_package_path, "active.md")
30
+
31
+ logger.info(f"Looking for package info at: {active_md_path}")
32
+
33
+ if not os.path.exists(active_md_path):
34
+ return ToolResult(success=True, message="No package info found for this path.", content="没有相关包信息。")
35
+
36
+ try:
37
+ with open(active_md_path, 'r', encoding='utf-8', errors='replace') as f:
38
+ content = f.read()
39
+ return ToolResult(success=True, message="Successfully retrieved package info.", content=content)
40
+ except Exception as e:
41
+ logger.error(f"Error reading package info file: {e}")
42
+ return ToolResult(success=False, message=f"Error reading package info file: {e}")
@@ -57,6 +57,9 @@ class UseMcpTool(BaseTool):
57
57
  tool_name: str
58
58
  query:str
59
59
 
60
+ class ListPackageInfoTool(BaseTool):
61
+ path: str # 源码包目录,相对路径或绝对路径
62
+
60
63
  # Event Types for Rich Output Streaming
61
64
  class LLMOutputEvent(BaseModel):
62
65
  """Represents plain text output from the LLM."""
@@ -112,6 +115,7 @@ TOOL_MODEL_MAP: Dict[str, Type[BaseTool]] = {
112
115
  "attempt_completion": AttemptCompletionTool,
113
116
  "plan_mode_respond": PlanModeRespondTool,
114
117
  "use_mcp_tool": UseMcpTool,
118
+ "list_package_info": ListPackageInfoTool,
115
119
  }
116
120
 
117
121
  class FileChangeEntry(BaseModel):
@@ -256,6 +256,7 @@ class PluginManager:
256
256
  "/plugins/dirs /remove",
257
257
  "/plugins/dirs /clear",
258
258
  ]
259
+ self._wrapped_functions: Dict[str, Callable] = {}
259
260
 
260
261
  @property
261
262
  def cached_discover_plugins(self) -> List[Type[Plugin]]:
@@ -561,6 +562,7 @@ class PluginManager:
561
562
  return result
562
563
  return None
563
564
 
565
+ self._wrapped_functions[func_name] = wrapped
564
566
  return wrapped
565
567
 
566
568
  def register_function_interception(self, plugin_name: str, func_name: str) -> None:
@@ -1107,6 +1109,24 @@ class PluginManager:
1107
1109
 
1108
1110
  return processed_completions
1109
1111
 
1112
+ def get_wrapped_functions(self) -> Dict[str, Callable]:
1113
+ """获取所有已包装的函数。
1114
+
1115
+ Returns:
1116
+ Dict[str, Callable]: 包含所有已包装函数的字典,键为函数名,值为包装后的函数
1117
+ """
1118
+ return self._wrapped_functions
1119
+
1120
+ def get_wrapped_function(self, func_name: str) -> Callable:
1121
+ """获取已包装的函数。
1122
+
1123
+ Args:
1124
+ func_name: 函数名
1125
+
1126
+ Returns:
1127
+ 已包装的函数,如果未找到则返回 None
1128
+ """
1129
+ return self._wrapped_functions.get(func_name)
1110
1130
 
1111
1131
  def register_global_plugin_dir(plugin_dir: str) -> None:
1112
1132
  """注册一个全局插件目录。
@@ -29,6 +29,7 @@ import hashlib
29
29
  from typing import Union
30
30
  from pydantic import BaseModel
31
31
  from autocoder.rag.cache.cache_result_merge import CacheResultMerger, MergeStrategy
32
+ from .failed_files_utils import save_failed_files, load_failed_files
32
33
  import time
33
34
 
34
35
  if platform.system() != "Windows":
@@ -65,74 +66,18 @@ class ByzerStorageCache(BaseCacheManager):
65
66
  ignore_spec,
66
67
  required_exts,
67
68
  extra_params: Optional[AutoCoderArgs] = None,
69
+ args=None,
70
+ llm=None,
68
71
  ):
69
72
  """
70
73
  初始化基于云端 Byzer Storage 的 RAG 缓存管理器。
71
-
72
- 参数:
73
- path: 需要索引的代码库根目录
74
- ignore_spec: 指定哪些文件/目录应被忽略的规则
75
- required_exts: 需要处理的文件扩展名列表
76
- extra_params: 额外的配置参数,包含向量索引相关设置
77
-
78
- 缓存结构 (self.cache):
79
- self.cache 是一个字典,键为文件路径,值为 CacheItem 对象:
80
- {
81
- "file_path1": CacheItem(
82
- file_path: str, # 文件的绝对路径
83
- relative_path: str, # 相对于项目根目录的路径
84
- content: List[Dict], # 文件内容的结构化表示,每个元素是 SourceCode 对象的序列化
85
- modify_time: float, # 文件最后修改时间的时间戳
86
- md5: str # 文件内容的 MD5 哈希值,用于检测变更
87
- ),
88
- "file_path2": CacheItem(...),
89
- ...
90
- }
91
-
92
- 这个缓存有两层存储:
93
- 1. 本地文件缓存: 保存在项目根目录的 .cache/byzer_storage_speedup.jsonl 文件中
94
- - 用于跟踪文件变更和快速加载
95
- - 使用 JSONL 格式存储,每行是一个 CacheItem 的 JSON 表示
96
-
97
- 2. 云端 Byzer Storage 向量数据库:
98
- - 存储文件内容的分块和向量嵌入
99
- - 每个文件被分割成大小为 chunk_size 的文本块
100
- - 每个块都会生成向量嵌入,用于语义搜索
101
- - 存储结构包含: 文件路径、内容块、原始内容、向量嵌入、修改时间
102
-
103
- 源代码处理流程:
104
- 在缓存更新过程中使用了两个关键函数:
105
-
106
- 1. process_file_in_multi_process: 在多进程环境中处理文件
107
- - 参数: file_info (文件信息元组)
108
- - 返回值: List[SourceCode] 或 None
109
- - 用途: 在初始构建缓存时并行处理多个文件
110
-
111
- 2. process_file_local: 在当前进程中处理单个文件
112
- - 参数: file_path (文件路径)
113
- - 返回值: List[SourceCode] 或 None
114
- - 用途: 在检测到文件更新时处理单个文件
115
-
116
- 文件处理后,会:
117
- 1. 更新内存中的缓存 (self.cache)
118
- 2. 将缓存持久化到本地文件
119
- 3. 将内容分块并更新到 Byzer Storage 向量数据库
120
-
121
- 更新机制:
122
- - 通过单独的线程异步处理文件变更
123
- - 使用 MD5 哈希值检测文件是否发生变化
124
- - 支持文件添加、更新和删除事件
125
- - 使用向量数据库进行语义检索,支持相似度搜索
126
-
127
- 与 LocalByzerStorageCache 的区别:
128
- - 使用云端 ByzerStorage 而非本地存储
129
- - 适用于需要远程访问和共享索引的场景
130
- - 支持大规模分布式检索和更高级的查询功能
131
74
  """
132
75
  self.path = path
133
76
  self.ignore_spec = ignore_spec
134
77
  self.required_exts = required_exts
135
78
  self.extra_params = extra_params
79
+ self.args = args
80
+ self.llm = llm
136
81
  self.rag_build_name = extra_params.rag_build_name
137
82
  self.storage = ByzerStorage("byzerai_store", "rag", self.rag_build_name)
138
83
  self.queue = []
@@ -150,16 +95,20 @@ class ByzerStorageCache(BaseCacheManager):
150
95
  self.cache_file = os.path.join(self.cache_dir, "byzer_storage_speedup.jsonl")
151
96
  self.cache: Dict[str, CacheItem] = {}
152
97
 
98
+ # 创建缓存目录
99
+ if not os.path.exists(self.cache_dir):
100
+ os.makedirs(self.cache_dir)
101
+
102
+ # failed files support
103
+ self.failed_files_path = os.path.join(self.cache_dir, "failed_files.json")
104
+ self.failed_files = load_failed_files(self.failed_files_path)
105
+
153
106
  self.lock = threading.Lock()
154
107
  self.stop_event = threading.Event()
155
108
  self.thread = threading.Thread(target=self.process_queue)
156
109
  self.thread.daemon = True
157
110
  self.thread.start()
158
111
 
159
- # 创建缓存目录
160
- if not os.path.exists(self.cache_dir):
161
- os.makedirs(self.cache_dir)
162
-
163
112
  # 加载缓存
164
113
  self.cache = self._load_cache()
165
114
 
@@ -455,6 +404,10 @@ class ByzerStorageCache(BaseCacheManager):
455
404
  for item in file_list.file_paths:
456
405
  logger.info(f"[QUEUE PROCESSING] Processing file deletion: {item}")
457
406
  del self.cache[item]
407
+ # remove from failed files if present
408
+ if item in self.failed_files:
409
+ self.failed_files.remove(item)
410
+ save_failed_files(self.failed_files_path, self.failed_files)
458
411
  # Create a temporary FileInfo object
459
412
  file_info = FileInfo(file_path=item, relative_path="", modify_time=0, file_md5="")
460
413
  self.update_storage(file_info, is_delete=True)
@@ -463,16 +416,29 @@ class ByzerStorageCache(BaseCacheManager):
463
416
  logger.info(f"[QUEUE PROCESSING] Processing add/update event, total files: {len(file_list.file_infos)}")
464
417
  for file_info in file_list.file_infos:
465
418
  logger.info(f"[QUEUE PROCESSING] Processing file update: {file_info.file_path}")
466
- # Process file and create CacheItem
467
- content = process_file_local(self.fileinfo_to_tuple(file_info))
468
- self.cache[file_info.file_path] = CacheItem(
469
- file_path=file_info.file_path,
470
- relative_path=file_info.relative_path,
471
- content=[c.model_dump() for c in content],
472
- modify_time=file_info.modify_time,
473
- md5=file_info.file_md5,
474
- )
475
- self.update_storage(file_info, is_delete=False)
419
+ try:
420
+ content = process_file_local(self.fileinfo_to_tuple(file_info))
421
+ if content:
422
+ self.cache[file_info.file_path] = CacheItem(
423
+ file_path=file_info.file_path,
424
+ relative_path=file_info.relative_path,
425
+ content=[c.model_dump() for c in content],
426
+ modify_time=file_info.modify_time,
427
+ md5=file_info.file_md5,
428
+ )
429
+ self.update_storage(file_info, is_delete=False)
430
+ # remove from failed files if present
431
+ if file_info.file_path in self.failed_files:
432
+ self.failed_files.remove(file_info.file_path)
433
+ save_failed_files(self.failed_files_path, self.failed_files)
434
+ else:
435
+ logger.warning(f"Empty result for file: {file_info.file_path}, treat as parse failed, skipping cache update")
436
+ self.failed_files.add(file_info.file_path)
437
+ save_failed_files(self.failed_files_path, self.failed_files)
438
+ except Exception as e:
439
+ logger.error(f"Error in process_queue: {e}")
440
+ self.failed_files.add(file_info.file_path)
441
+ save_failed_files(self.failed_files_path, self.failed_files)
476
442
  self.write_cache()
477
443
 
478
444
  elapsed = time.time() - start_time
@@ -486,6 +452,10 @@ class ByzerStorageCache(BaseCacheManager):
486
452
  current_files = set()
487
453
  for file_info in self.get_all_files():
488
454
  current_files.add(file_info.file_path)
455
+ # skip failed files
456
+ if file_info.file_path in self.failed_files:
457
+ logger.info(f"文件 {file_info.file_path} 之前解析失败,跳过此次更新")
458
+ continue
489
459
  if (
490
460
  file_info.file_path not in self.cache
491
461
  or self.cache[file_info.file_path].md5 != file_info.file_md5