auto-coder 0.1.336__py3-none-any.whl → 0.1.337__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.336.dist-info → auto_coder-0.1.337.dist-info}/METADATA +1 -1
- {auto_coder-0.1.336.dist-info → auto_coder-0.1.337.dist-info}/RECORD +15 -14
- autocoder/agent/agentic_filter.py +14 -7
- autocoder/auto_coder_runner.py +61 -14
- autocoder/chat_auto_coder.py +1 -2
- autocoder/common/auto_coder_lang.py +8 -0
- autocoder/common/v2/agent/agentic_edit.py +70 -14
- autocoder/common/v2/agent/agentic_edit_conversation.py +113 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +6 -1
- autocoder/common/v2/agent/agentic_tool_display.py +2 -2
- autocoder/version.py +1 -1
- {auto_coder-0.1.336.dist-info → auto_coder-0.1.337.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.336.dist-info → auto_coder-0.1.337.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.336.dist-info → auto_coder-0.1.337.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.336.dist-info → auto_coder-0.1.337.dist-info}/top_level.txt +0 -0
|
@@ -4,21 +4,21 @@ 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=
|
|
7
|
+
autocoder/auto_coder_runner.py,sha256=MMppqdwfT1a-NoIxqbQGNS2z2Wi0CWY6X3AK8morCsE,111424
|
|
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=CthuvdjVjTQOVv-zREsl8OCsZHPSP9OQcIgHULrW2Ro,25842
|
|
11
11
|
autocoder/chat_auto_coder_lang.py,sha256=RxkYAMWUB5ayX0x03yBOcEkjTcWG_EBsLXBC_bh--cc,22265
|
|
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=_SCar82QIeBFTZZBdM2jPS6atKVhHnvE0gX3V0CsxD4,11590
|
|
16
16
|
autocoder/run_context.py,sha256=IUfSO6_gp2Wt1blFWAmOpN0b0nDrTTk4LmtCYUBIoro,1643
|
|
17
|
-
autocoder/version.py,sha256=
|
|
17
|
+
autocoder/version.py,sha256=_LNwUtBnPaBerh9KZiByo60wMmCJ6961eqCjdcRR4Zk,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
|
|
21
|
-
autocoder/agent/agentic_filter.py,sha256=
|
|
21
|
+
autocoder/agent/agentic_filter.py,sha256=9Miqj9lVOkKrKRXK9MZDouhkp2n1s_RakpRwdmLfFtY,39516
|
|
22
22
|
autocoder/agent/auto_demand_organizer.py,sha256=URAq0gSEiHeV_W4zwhOI_83kHz0Ryfj1gcfh5jwCv_w,6501
|
|
23
23
|
autocoder/agent/auto_filegroup.py,sha256=pBsAkBcpFTff-9L5OwI8xhf2xPKpl-aZwz-skF2B6dc,6296
|
|
24
24
|
autocoder/agent/auto_guess_query.py,sha256=rDSdhpPHcOGE5MuDXvIrhCXAPR4ARS1LqpyoLsx2Jhw,11374
|
|
@@ -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=
|
|
57
|
+
autocoder/common/auto_coder_lang.py,sha256=cNwzXknWDDFUoG68D0xhp1KgTC25bS8pbObeL-1pRpA,40656
|
|
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,9 +126,10 @@ 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=
|
|
129
|
+
autocoder/common/v2/agent/agentic_edit.py,sha256=iFr2Umr1qXYGH0enzn2KJS8H2nqfuKkyBidbUKq38Bc,87031
|
|
130
|
+
autocoder/common/v2/agent/agentic_edit_conversation.py,sha256=XtN0D1stP80gKnGiVxFMZL1DbIU56AISyDkS52RMaac,4434
|
|
130
131
|
autocoder/common/v2/agent/agentic_edit_types.py,sha256=ZCgIu0Dj4xPP9s-lWtzh1-wBvoXrSkgu3pan_Oo_Ng0,4433
|
|
131
|
-
autocoder/common/v2/agent/agentic_tool_display.py,sha256=
|
|
132
|
+
autocoder/common/v2/agent/agentic_tool_display.py,sha256=5KshKQX0YFcGobfbJIwylwkalAEuZVUO68hSrIlPM64,7341
|
|
132
133
|
autocoder/common/v2/agent/agentic_edit_tools/__init__.py,sha256=wGICCc1dYh07osB21j62zOQ9Ws0PyyOQ12UYRHmHrtI,1229
|
|
133
134
|
autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py,sha256=pjrukXjWXMIfUAUzoHzr7j2Onf1L7bxmjsUR1gGaFoA,2809
|
|
134
135
|
autocoder/common/v2/agent/agentic_edit_tools/attempt_completion_tool_resolver.py,sha256=82ZGKeRBSDKeead_XVBW4FxpiE-5dS7tBOk_3RZ6B5s,1511
|
|
@@ -139,7 +140,7 @@ autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py,sha256=
|
|
|
139
140
|
autocoder/common/v2/agent/agentic_edit_tools/plan_mode_respond_tool_resolver.py,sha256=SZwFUxK6d2BaKWqQXi_c3IVe2iffviF6VUXJA9T9sx0,1492
|
|
140
141
|
autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py,sha256=9Bh0KVbL0qiIqwChlb77biiBiETQ3zekxGe5Fj7hXAg,2800
|
|
141
142
|
autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py,sha256=tTQpCIGIzh1XO_MZm6wefMvUm_h6cKoa--oPIm-VwXM,7342
|
|
142
|
-
autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py,sha256=
|
|
143
|
+
autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py,sha256=K-TcqY0z7nDupMkTRDAJdqW3z2Y_RUM_wUb-pOEVQRI,6044
|
|
143
144
|
autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py,sha256=wM2Xy4bcnD0TSLEmcM8rvvyyWenN5_KQnJMO6hJ8lTE,1716
|
|
144
145
|
autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py,sha256=UO4SrkDek3WDlRdlHH022W1roSNMdMcipJqDxRBlheM,3044
|
|
145
146
|
autocoder/compilers/__init__.py,sha256=C0HOms70QA747XD0uZEMmGtRFcIPenohyqECNStv0Bw,1647
|
|
@@ -275,9 +276,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
275
276
|
autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
276
277
|
autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=KW0mlmcHlStXi8-_6fXZ2-ifeJ5mgP0OV7DQFzCtIsw,14008
|
|
277
278
|
autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
278
|
-
auto_coder-0.1.
|
|
279
|
-
auto_coder-0.1.
|
|
280
|
-
auto_coder-0.1.
|
|
281
|
-
auto_coder-0.1.
|
|
282
|
-
auto_coder-0.1.
|
|
283
|
-
auto_coder-0.1.
|
|
279
|
+
auto_coder-0.1.337.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
280
|
+
auto_coder-0.1.337.dist-info/METADATA,sha256=GH7LgmlLQFdtYtvXWvRcDzUoY5toRt_Bmf0XX8Mcghg,2747
|
|
281
|
+
auto_coder-0.1.337.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
282
|
+
auto_coder-0.1.337.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
|
|
283
|
+
auto_coder-0.1.337.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
|
|
284
|
+
auto_coder-0.1.337.dist-info/RECORD,,
|
|
@@ -259,8 +259,8 @@ class AgenticFilter:
|
|
|
259
259
|
3. **深入分析**:
|
|
260
260
|
* 使用 `read_files` 读取关键文件的内容进行确认。如果文件过大,使用 `line_ranges` 参数分段读取。
|
|
261
261
|
* 如有必要,使用 `run_python` 或 `execute_shell_command` 执行代码或命令进行更复杂的分析。
|
|
262
|
-
4. **迭代决策**: 根据工具的返回结果,你可能需要多次调用不同的工具来逐步缩小范围或获取更多信息。
|
|
263
|
-
|
|
262
|
+
4. **迭代决策**: 根据工具的返回结果,你可能需要多次调用不同的工具来逐步缩小范围或获取更多信息。
|
|
263
|
+
6. **最终响应**: 当你确定了所有需要参考和修改的文件后,**必须**调用 `output_result` 工具,并提供符合其要求格式的JSON字符串作为其 `response` 参数。
|
|
264
264
|
该json格式要求为:
|
|
265
265
|
```json
|
|
266
266
|
{
|
|
@@ -273,9 +273,17 @@ class AgenticFilter:
|
|
|
273
273
|
"reasoning": "详细说明你是如何通过分析和使用工具得出这个文件列表的。"
|
|
274
274
|
}
|
|
275
275
|
```
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
276
|
+
|
|
277
|
+
{% if enable_active_context %}
|
|
278
|
+
** 非常非常重要的提示 **
|
|
279
|
+
每一个目录都有一个描述信息,比如 {{ project_path }}/src/abc/bbc 的目录描述信息会放在 {{ project_path }}/.auto-coder/active-context/src/abc/bbc/active.md 文件中。
|
|
280
|
+
你可以使用 read_files 函数读取,从而帮助你更好的挑选要详细阅读哪个文件。值得注意的是,active.md 并不会包含该目录下所有的文件信息,只保存最近发生变更的文件的信息。
|
|
281
|
+
{% endif %}
|
|
282
|
+
"""
|
|
283
|
+
return {
|
|
284
|
+
"project_path": os.path.abspath(self.args.source_dir),
|
|
285
|
+
"enable_active_context": self.args.enable_active_context,
|
|
286
|
+
}
|
|
279
287
|
|
|
280
288
|
@byzerllm.prompt()
|
|
281
289
|
def _execute_command_result(self, result: str) -> str:
|
|
@@ -590,8 +598,7 @@ class AgenticFilter:
|
|
|
590
598
|
- 如果未找到匹配项,会返回提示信息
|
|
591
599
|
|
|
592
600
|
</usage>
|
|
593
|
-
</command>
|
|
594
|
-
|
|
601
|
+
</command>
|
|
595
602
|
<command>
|
|
596
603
|
<n>execute_mcp_server</n>
|
|
597
604
|
<description>执行MCP服务器</description>
|
autocoder/auto_coder_runner.py
CHANGED
|
@@ -22,6 +22,8 @@ from autocoder.common.result_manager import ResultManager
|
|
|
22
22
|
from autocoder.version import __version__
|
|
23
23
|
from autocoder.auto_coder import main as auto_coder_main
|
|
24
24
|
from autocoder.utils import get_last_yaml_file
|
|
25
|
+
from autocoder.commands.auto_command import CommandAutoTuner, AutoCommandRequest, CommandConfig, MemoryConfig
|
|
26
|
+
from autocoder.common.v2.agent.agentic_edit import AgenticEdit,AgenticEditRequest
|
|
25
27
|
from autocoder.index.symbols_utils import (
|
|
26
28
|
extract_symbols,
|
|
27
29
|
SymbolType,
|
|
@@ -60,7 +62,7 @@ from autocoder.common.conf_validator import ConfigValidator
|
|
|
60
62
|
from autocoder import command_parser as CommandParser
|
|
61
63
|
from loguru import logger as global_logger
|
|
62
64
|
from autocoder.utils.project_structure import EnhancedFileAnalyzer
|
|
63
|
-
from autocoder.common import SourceCodeList
|
|
65
|
+
from autocoder.common import SourceCodeList,SourceCode
|
|
64
66
|
|
|
65
67
|
|
|
66
68
|
## 对外API,用于第三方集成 auto-coder 使用。
|
|
@@ -2777,22 +2779,67 @@ def conf_import(path: str):
|
|
|
2777
2779
|
from autocoder.common.conf_import_export import import_conf
|
|
2778
2780
|
import_conf(os.getcwd(), path)
|
|
2779
2781
|
|
|
2782
|
+
def generate_new_yaml(query: str):
|
|
2783
|
+
memory = get_memory()
|
|
2784
|
+
conf = memory.get("conf",{})
|
|
2785
|
+
current_files = memory.get("current_files",{}).get("files",[])
|
|
2786
|
+
auto_coder_main(["next", "chat_action"])
|
|
2787
|
+
latest_yaml_file = get_last_yaml_file("actions")
|
|
2788
|
+
if latest_yaml_file:
|
|
2789
|
+
yaml_config = {
|
|
2790
|
+
"include_file": ["./base/base.yml"],
|
|
2791
|
+
"auto_merge": conf.get("auto_merge", "editblock"),
|
|
2792
|
+
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
2793
|
+
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
2794
|
+
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
2795
|
+
"silence": conf.get("silence", "true") == "true",
|
|
2796
|
+
"include_project_structure": conf.get("include_project_structure", "true")
|
|
2797
|
+
== "true",
|
|
2798
|
+
"exclude_files": memory.get("exclude_files", []),
|
|
2799
|
+
}
|
|
2800
|
+
yaml_config["context"] = ""
|
|
2801
|
+
for key, value in conf.items():
|
|
2802
|
+
converted_value = convert_config_value(key, value)
|
|
2803
|
+
if converted_value is not None:
|
|
2804
|
+
yaml_config[key] = converted_value
|
|
2805
|
+
|
|
2806
|
+
yaml_config["urls"] = current_files + get_llm_friendly_package_docs(
|
|
2807
|
+
return_paths=True
|
|
2808
|
+
)
|
|
2809
|
+
# handle image
|
|
2810
|
+
v = Image.convert_image_paths_from(query)
|
|
2811
|
+
yaml_config["query"] = v
|
|
2812
|
+
|
|
2813
|
+
yaml_content = convert_yaml_config_to_str(yaml_config=yaml_config)
|
|
2814
|
+
|
|
2815
|
+
execute_file = os.path.join("actions", latest_yaml_file)
|
|
2816
|
+
with open(os.path.join(execute_file), "w",encoding="utf-8") as f:
|
|
2817
|
+
f.write(yaml_content)
|
|
2818
|
+
return execute_file,convert_yaml_to_config(execute_file)
|
|
2819
|
+
|
|
2780
2820
|
@run_in_raw_thread()
|
|
2781
2821
|
def auto_command(query: str,extra_args: Dict[str,Any]={}):
|
|
2782
|
-
"""处理/auto指令"""
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2822
|
+
"""处理/auto指令"""
|
|
2823
|
+
args = get_final_config()
|
|
2824
|
+
memory = get_memory()
|
|
2786
2825
|
if args.enable_agentic_edit:
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2826
|
+
execute_file,args = generate_new_yaml(query)
|
|
2827
|
+
args.file = execute_file
|
|
2828
|
+
current_files = memory.get("current_files",{}).get("files",[])
|
|
2829
|
+
sources = []
|
|
2830
|
+
for file in current_files:
|
|
2831
|
+
with open(file,"r",encoding="utf-8") as f:
|
|
2832
|
+
sources.append(SourceCode(module_name=file,source_code=f.read()))
|
|
2833
|
+
|
|
2834
|
+
llm = get_single_llm(args.code_model or args.model,product_mode=args.product_mode)
|
|
2835
|
+
agent = AgenticEdit(llm=llm,args=args,files=SourceCodeList(sources=sources),
|
|
2836
|
+
conversation_history=[],
|
|
2837
|
+
memory_config=MemoryConfig(memory=memory,
|
|
2838
|
+
save_memory_func=save_memory), command_config=CommandConfig)
|
|
2839
|
+
agent.run_in_terminal(AgenticEditRequest(user_input=query))
|
|
2840
|
+
return
|
|
2841
|
+
|
|
2842
|
+
args = get_final_config()
|
|
2796
2843
|
# 准备请求参数
|
|
2797
2844
|
request = AutoCommandRequest(
|
|
2798
2845
|
user_input=query
|
autocoder/chat_auto_coder.py
CHANGED
|
@@ -825,6 +825,14 @@ MESSAGES = {
|
|
|
825
825
|
"/compile/check/end": {
|
|
826
826
|
"en": "Finished compile error checking process.",
|
|
827
827
|
"zh": "结束编译错误检查过程."
|
|
828
|
+
},
|
|
829
|
+
"/agent/edit/objective":{
|
|
830
|
+
"en":"Objective",
|
|
831
|
+
"zh":"目标"
|
|
832
|
+
},
|
|
833
|
+
"/agent/edit/user_query":{
|
|
834
|
+
"en":"User Query",
|
|
835
|
+
"zh":"用户查询"
|
|
828
836
|
}
|
|
829
837
|
}
|
|
830
838
|
|
|
@@ -12,7 +12,8 @@ from rich.panel import Panel
|
|
|
12
12
|
from pydantic import SkipValidation
|
|
13
13
|
|
|
14
14
|
# Removed ResultManager, stream_out, git_utils, AutoCommandTools, count_tokens, global_cancel, ActionYmlFileManager, get_event_manager, EventContentCreator, get_run_context, AgenticFilterStreamOutType
|
|
15
|
-
from autocoder.
|
|
15
|
+
from autocoder.common import AutoCoderArgs, git_utils, SourceCodeList, SourceCode
|
|
16
|
+
from autocoder.common.global_cancel import global_cancel
|
|
16
17
|
from autocoder.common import detect_env
|
|
17
18
|
from autocoder.common import shells
|
|
18
19
|
from loguru import logger
|
|
@@ -34,10 +35,13 @@ from rich.syntax import Syntax # Added
|
|
|
34
35
|
from rich.markdown import Markdown # Added
|
|
35
36
|
from autocoder.events.event_manager_singleton import get_event_manager
|
|
36
37
|
from autocoder.events.event_types import Event, EventType, EventMetadata
|
|
38
|
+
from autocoder.memory.active_context_manager import ActiveContextManager
|
|
37
39
|
from autocoder.events import event_content as EventContentCreator
|
|
38
40
|
from autocoder.shadows.shadow_manager import ShadowManager
|
|
39
41
|
from autocoder.linters.shadow_linter import ShadowLinter
|
|
40
42
|
from autocoder.compilers.shadow_compiler import ShadowCompiler
|
|
43
|
+
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
44
|
+
from autocoder.common.auto_coder_lang import get_message
|
|
41
45
|
# Import the new display function
|
|
42
46
|
from autocoder.common.v2.agent.agentic_tool_display import get_tool_display_message
|
|
43
47
|
from autocoder.common.v2.agent.agentic_edit_types import FileChangeEntry
|
|
@@ -655,6 +659,13 @@ class AgenticEdit:
|
|
|
655
659
|
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within <thinking></thinking> tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
|
|
656
660
|
4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built.
|
|
657
661
|
5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.
|
|
662
|
+
|
|
663
|
+
{{ enable_active_context }}
|
|
664
|
+
**Very Important Notice**
|
|
665
|
+
Each directory has a description file stored separately. For example, the description for the directory `{{ current_project }}/src/abc/bbc` can be found in the file `{{ current_project }}/.auto-coder/active-context/src/abc/bbc/active.md`.
|
|
666
|
+
You can use the tool `read_file` to read these description files, which helps you decide exactly which files need detailed attention. Note that the `active.md` file does not contain information about all files within the directory—it only includes information
|
|
667
|
+
about the files that were recently changed.
|
|
668
|
+
{{ enable_active_context }}
|
|
658
669
|
"""
|
|
659
670
|
env_info = detect_env()
|
|
660
671
|
shell_type = "bash"
|
|
@@ -674,6 +685,7 @@ class AgenticEdit:
|
|
|
674
685
|
"home_dir": os.path.expanduser("~"),
|
|
675
686
|
"files": self.files.to_str(),
|
|
676
687
|
"mcp_server_info": self.mcp_server_info,
|
|
688
|
+
"enable_active_context": self.args.enable_active_context,
|
|
677
689
|
}
|
|
678
690
|
|
|
679
691
|
# Removed _execute_command_result and execute_auto_command methods
|
|
@@ -732,11 +744,12 @@ class AgenticEdit:
|
|
|
732
744
|
f"Initial conversation history size: {len(conversations)}")
|
|
733
745
|
|
|
734
746
|
while True:
|
|
747
|
+
global_cancel.check_and_raise()
|
|
735
748
|
logger.info(
|
|
736
749
|
f"Starting LLM interaction cycle. History size: {len(conversations)}")
|
|
737
750
|
tool_executed = False
|
|
738
751
|
assistant_buffer = ""
|
|
739
|
-
|
|
752
|
+
|
|
740
753
|
llm_response_gen = stream_chat_with_continue(
|
|
741
754
|
llm=self.llm,
|
|
742
755
|
conversations=conversations,
|
|
@@ -749,6 +762,7 @@ class AgenticEdit:
|
|
|
749
762
|
llm_response_gen,meta_holder)
|
|
750
763
|
|
|
751
764
|
for event in parsed_events:
|
|
765
|
+
global_cancel.check_and_raise()
|
|
752
766
|
if isinstance(event, (LLMOutputEvent, LLMThinkingEvent)):
|
|
753
767
|
assistant_buffer += event.text
|
|
754
768
|
yield event # Yield text/thinking immediately for display
|
|
@@ -929,6 +943,8 @@ class AgenticEdit:
|
|
|
929
943
|
return None
|
|
930
944
|
|
|
931
945
|
for content_chunk, metadata in generator:
|
|
946
|
+
global_cancel.check_and_raise()
|
|
947
|
+
|
|
932
948
|
meta_holder.meta = metadata
|
|
933
949
|
if not content_chunk:
|
|
934
950
|
continue
|
|
@@ -1160,17 +1176,51 @@ class AgenticEdit:
|
|
|
1160
1176
|
)
|
|
1161
1177
|
event_manager.write_error(content=error_content.to_dict(), metadata=metadata.to_dict())
|
|
1162
1178
|
# Re-raise the exception if needed, or handle appropriately
|
|
1163
|
-
|
|
1179
|
+
raise e
|
|
1164
1180
|
|
|
1165
1181
|
def apply_changes(self):
|
|
1166
1182
|
"""
|
|
1167
1183
|
Apply all tracked file changes to the original project directory.
|
|
1168
|
-
"""
|
|
1169
|
-
for change in self.get_all_file_changes():
|
|
1170
|
-
file_path = change['file_path']
|
|
1171
|
-
content = change['content']
|
|
1184
|
+
"""
|
|
1185
|
+
for (file_path,change) in self.get_all_file_changes().items():
|
|
1172
1186
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
1173
|
-
f.write(content)
|
|
1187
|
+
f.write(change.content)
|
|
1188
|
+
|
|
1189
|
+
if len(self.get_all_file_changes()) > 0:
|
|
1190
|
+
if not self.args.skip_commit:
|
|
1191
|
+
try:
|
|
1192
|
+
file_name = os.path.basename(self.args.file)
|
|
1193
|
+
commit_result = git_utils.commit_changes(
|
|
1194
|
+
self.args.source_dir,
|
|
1195
|
+
f"{self.args.query}\nauto_coder_{file_name}",
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1198
|
+
action_yml_file_manager = ActionYmlFileManager(self.args.source_dir)
|
|
1199
|
+
action_file_name = os.path.basename(self.args.file)
|
|
1200
|
+
add_updated_urls = []
|
|
1201
|
+
commit_result.changed_files
|
|
1202
|
+
for file in commit_result.changed_files:
|
|
1203
|
+
add_updated_urls.append(os.path.join(self.args.source_dir, file))
|
|
1204
|
+
|
|
1205
|
+
self.args.add_updated_urls = add_updated_urls
|
|
1206
|
+
update_yaml_success = action_yml_file_manager.update_yaml_field(action_file_name, "add_updated_urls", add_updated_urls)
|
|
1207
|
+
if not update_yaml_success:
|
|
1208
|
+
self.printer.print_in_terminal("yaml_save_error", style="red", yaml_file=action_file_name)
|
|
1209
|
+
|
|
1210
|
+
if self.args.enable_active_context:
|
|
1211
|
+
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
1212
|
+
task_id = active_context_manager.process_changes(self.args)
|
|
1213
|
+
self.printer.print_in_terminal("active_context_background_task",
|
|
1214
|
+
style="blue",
|
|
1215
|
+
task_id=task_id)
|
|
1216
|
+
git_utils.print_commit_info(commit_result=commit_result)
|
|
1217
|
+
except Exception as e:
|
|
1218
|
+
self.printer.print_str_in_terminal(
|
|
1219
|
+
self.git_require_msg(source_dir=self.args.source_dir, error=str(e)),
|
|
1220
|
+
style="red"
|
|
1221
|
+
)
|
|
1222
|
+
else:
|
|
1223
|
+
self.printer.print_in_terminal("no_changes_made")
|
|
1174
1224
|
|
|
1175
1225
|
def run_in_terminal(self, request: AgenticEditRequest):
|
|
1176
1226
|
"""
|
|
@@ -1181,7 +1231,7 @@ class AgenticEdit:
|
|
|
1181
1231
|
project_name = os.path.basename(os.path.abspath(self.args.source_dir))
|
|
1182
1232
|
console.rule(f"[bold cyan]Starting Agentic Edit: {project_name}[/]")
|
|
1183
1233
|
console.print(Panel(
|
|
1184
|
-
f"[bold]
|
|
1234
|
+
f"[bold]{get_message('/agent/edit/user_query')}:[/bold]\n{request.user_input}", title=get_message("/agent/edit/objective"), border_style="blue"))
|
|
1185
1235
|
|
|
1186
1236
|
try:
|
|
1187
1237
|
event_stream = self.analyze(request)
|
|
@@ -1214,12 +1264,17 @@ class AgenticEdit:
|
|
|
1214
1264
|
base_content = f"[bold]Status:[/bold] {'Success' if result.success else 'Failure'}\n"
|
|
1215
1265
|
base_content += f"[bold]Message:[/bold] {result.message}\n"
|
|
1216
1266
|
|
|
1267
|
+
def _format_content(content):
|
|
1268
|
+
if len(content) > 200:
|
|
1269
|
+
return f"{content[:100]}\n...\n{content[-100:]}"
|
|
1270
|
+
else:
|
|
1271
|
+
return content
|
|
1272
|
+
|
|
1217
1273
|
# Prepare panel for base info first
|
|
1218
1274
|
panel_content = [base_content]
|
|
1219
1275
|
syntax_content = None
|
|
1220
1276
|
|
|
1221
|
-
if result.content is not None:
|
|
1222
|
-
panel_content.append("[bold]Content:[/bold]\n")
|
|
1277
|
+
if result.content is not None:
|
|
1223
1278
|
content_str = ""
|
|
1224
1279
|
try:
|
|
1225
1280
|
if isinstance(result.content, (dict, list)):
|
|
@@ -1257,16 +1312,16 @@ class AgenticEdit:
|
|
|
1257
1312
|
lexer = "text"
|
|
1258
1313
|
|
|
1259
1314
|
syntax_content = Syntax(
|
|
1260
|
-
result.content
|
|
1315
|
+
_format_content(result.content), lexer, theme="default", line_numbers=True)
|
|
1261
1316
|
else:
|
|
1262
1317
|
content_str = str(result.content)
|
|
1263
1318
|
# Append simple string content directly
|
|
1264
|
-
panel_content.append(content_str
|
|
1319
|
+
panel_content.append(_format_content(content_str))
|
|
1265
1320
|
except Exception as e:
|
|
1266
1321
|
logger.warning(
|
|
1267
1322
|
f"Error formatting tool result content: {e}")
|
|
1268
1323
|
panel_content.append(
|
|
1269
|
-
str(result.content)) # Fallback
|
|
1324
|
+
_format_content(str(result.content))) # Fallback
|
|
1270
1325
|
|
|
1271
1326
|
# Print the base info panel
|
|
1272
1327
|
console.print(Panel("\n".join(
|
|
@@ -1298,5 +1353,6 @@ class AgenticEdit:
|
|
|
1298
1353
|
"An unexpected error occurred during agent execution:")
|
|
1299
1354
|
console.print(Panel(
|
|
1300
1355
|
f"[bold red]FATAL ERROR:[/bold red]\n{str(e)}", title="🔥 System Error", border_style="red"))
|
|
1356
|
+
raise e
|
|
1301
1357
|
finally:
|
|
1302
1358
|
console.rule("[bold cyan]Agentic Edit Finished[/]")
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# src/autocoder/common/v2/agent/agentic_edit_conversation.py
|
|
2
|
+
import os
|
|
3
|
+
import json
|
|
4
|
+
from typing import List, Dict, Any, Optional
|
|
5
|
+
from autocoder.common import AutoCoderArgs
|
|
6
|
+
|
|
7
|
+
# Define a type alias for a message dictionary
|
|
8
|
+
MessageType = Dict[str, Any]
|
|
9
|
+
|
|
10
|
+
class AgenticConversation:
|
|
11
|
+
"""
|
|
12
|
+
Manages the conversation history for an agentic editing process.
|
|
13
|
+
|
|
14
|
+
Handles adding messages (user, assistant, tool calls, tool results)
|
|
15
|
+
and retrieving the history.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, args: AutoCoderArgs, initial_history: Optional[List[MessageType]] = None):
|
|
19
|
+
"""
|
|
20
|
+
Initializes the conversation history.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
initial_history: An optional list of messages to start with.
|
|
24
|
+
"""
|
|
25
|
+
self.project_path = args.source_dir
|
|
26
|
+
self._history: List[MessageType] = initial_history if initial_history is not None else []
|
|
27
|
+
self.memory_file_path = os.path.join(self.project_path, ".auto-coder", "memory", "agentic_edit_memory.json")
|
|
28
|
+
self._load_memory()
|
|
29
|
+
|
|
30
|
+
def add_message(self, role: str, content: Any, **kwargs):
|
|
31
|
+
"""
|
|
32
|
+
Adds a message to the conversation history.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
role: The role of the message sender (e.g., "user", "assistant", "tool").
|
|
36
|
+
content: The content of the message. Can be None for messages like tool calls.
|
|
37
|
+
**kwargs: Additional key-value pairs to include in the message dictionary (e.g., tool_calls, tool_call_id).
|
|
38
|
+
"""
|
|
39
|
+
message: MessageType = {"role": role}
|
|
40
|
+
if content is not None:
|
|
41
|
+
message["content"] = content
|
|
42
|
+
message.update(kwargs)
|
|
43
|
+
self._history.append(message)
|
|
44
|
+
self._save_memory()
|
|
45
|
+
|
|
46
|
+
def add_user_message(self, content: str):
|
|
47
|
+
"""Adds a user message."""
|
|
48
|
+
self.add_message(role="user", content=content)
|
|
49
|
+
|
|
50
|
+
def add_assistant_message(self, content: str):
|
|
51
|
+
"""Adds an assistant message (potentially containing text response)."""
|
|
52
|
+
self.add_message(role="assistant", content=content)
|
|
53
|
+
|
|
54
|
+
def add_assistant_tool_call_message(self, tool_calls: List[Dict[str, Any]], content: Optional[str] = None):
|
|
55
|
+
"""
|
|
56
|
+
Adds a message representing one or more tool calls from the assistant.
|
|
57
|
+
Optionally includes assistant's textual reasoning/content alongside the calls.
|
|
58
|
+
"""
|
|
59
|
+
self.add_message(role="assistant", content=content, tool_calls=tool_calls)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def add_tool_result_message(self, tool_call_id: str, content: Any):
|
|
63
|
+
"""Adds a message representing the result of a specific tool call."""
|
|
64
|
+
# The content here is typically the output/result from the tool execution.
|
|
65
|
+
self.add_message(role="tool", content=content, tool_call_id=tool_call_id)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_history(self) -> List[MessageType]:
|
|
69
|
+
"""
|
|
70
|
+
Returns the current conversation history.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
A list of message dictionaries.
|
|
74
|
+
"""
|
|
75
|
+
# Return a deep copy might be safer if messages contain mutable objects,
|
|
76
|
+
# but a shallow copy is usually sufficient for typical message structures.
|
|
77
|
+
return self._history.copy()
|
|
78
|
+
|
|
79
|
+
def clear_history(self):
|
|
80
|
+
"""Clears the conversation history."""
|
|
81
|
+
self._history = []
|
|
82
|
+
|
|
83
|
+
def __len__(self) -> int:
|
|
84
|
+
"""Returns the number of messages in the history."""
|
|
85
|
+
return len(self._history)
|
|
86
|
+
|
|
87
|
+
def __str__(self) -> str:
|
|
88
|
+
"""Returns a string representation of the conversation history."""
|
|
89
|
+
# Consider a more readable format if needed for debugging
|
|
90
|
+
return str(self._history)
|
|
91
|
+
|
|
92
|
+
# Potential future enhancements:
|
|
93
|
+
# - Method to limit history size (by tokens or message count)
|
|
94
|
+
# - Method to format history specifically for different LLM APIs
|
|
95
|
+
# - Serialization/deserialization methods
|
|
96
|
+
|
|
97
|
+
def _save_memory(self):
|
|
98
|
+
try:
|
|
99
|
+
os.makedirs(os.path.dirname(self.memory_file_path), exist_ok=True)
|
|
100
|
+
with open(self.memory_file_path, "w", encoding="utf-8") as f:
|
|
101
|
+
json.dump(self._history, f, ensure_ascii=False, indent=2)
|
|
102
|
+
except Exception as e:
|
|
103
|
+
# Optionally log or ignore
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
def _load_memory(self):
|
|
107
|
+
try:
|
|
108
|
+
if os.path.exists(self.memory_file_path):
|
|
109
|
+
with open(self.memory_file_path, "r", encoding="utf-8") as f:
|
|
110
|
+
self._history = json.load(f)
|
|
111
|
+
except Exception as e:
|
|
112
|
+
# Ignore loading errors, start fresh
|
|
113
|
+
pass
|
|
@@ -54,9 +54,14 @@ class SearchFilesToolResolver(BaseToolResolver):
|
|
|
54
54
|
compiled_regex = re.compile(regex_pattern)
|
|
55
55
|
search_glob_pattern = os.path.join(search_base_path, "**", file_pattern)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
ignored_dirs = ['.git', 'node_modules', '.mvn', '.idea', '__pycache__', '.venv', 'venv', 'dist', 'build', '.gradle']
|
|
58
|
+
logger.info(f"Searching for regex '{regex_pattern}' in files matching '{file_pattern}' under '{search_base_path}' (shadow: {shadow_exists}), ignoring directories: {ignored_dirs}")
|
|
58
59
|
|
|
59
60
|
for filepath in glob.glob(search_glob_pattern, recursive=True):
|
|
61
|
+
normalized_path = filepath.replace("\\", "/") # Normalize for Windows paths
|
|
62
|
+
if any(f"/{ignored_dir}/" in normalized_path or normalized_path.endswith(f"/{ignored_dir}") or f"/{ignored_dir}/" in normalized_path for ignored_dir in ignored_dirs):
|
|
63
|
+
continue
|
|
64
|
+
|
|
60
65
|
if os.path.isfile(filepath):
|
|
61
66
|
try:
|
|
62
67
|
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
|
|
@@ -129,11 +129,11 @@ def get_tool_display_message(tool: BaseTool) -> str:
|
|
|
129
129
|
"ellipsis": '...' if len(tool.content) > 150 else ''
|
|
130
130
|
}
|
|
131
131
|
elif isinstance(tool, ReplaceInFileTool):
|
|
132
|
-
snippet = tool.diff
|
|
132
|
+
snippet = tool.diff
|
|
133
133
|
context = {
|
|
134
134
|
"path": tool.path,
|
|
135
135
|
"diff_snippet": snippet,
|
|
136
|
-
"ellipsis": '
|
|
136
|
+
"ellipsis": ''
|
|
137
137
|
}
|
|
138
138
|
elif isinstance(tool, ExecuteCommandTool):
|
|
139
139
|
context = {"command": tool.command, "requires_approval": tool.requires_approval}
|
autocoder/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.337"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|