auto-coder 0.1.382__py3-none-any.whl → 0.1.384__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.382.dist-info → auto_coder-0.1.384.dist-info}/METADATA +1 -1
- {auto_coder-0.1.382.dist-info → auto_coder-0.1.384.dist-info}/RECORD +13 -10
- autocoder/auto_coder_runner.py +71 -1
- autocoder/common/llm_friendly_package.py +410 -0
- autocoder/common/llm_friendly_package_example.py +138 -0
- autocoder/common/llm_friendly_package_test.py +63 -0
- autocoder/common/v2/agent/agentic_edit.py +69 -2
- autocoder/utils/operate_config_api.py +14 -38
- autocoder/version.py +1 -1
- {auto_coder-0.1.382.dist-info → auto_coder-0.1.384.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.382.dist-info → auto_coder-0.1.384.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.382.dist-info → auto_coder-0.1.384.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.382.dist-info → auto_coder-0.1.384.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
autocoder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
autocoder/auto_coder.py,sha256=7602L3tG0JErNxh8vkLAmGUgv2c-DGPzPCkmWIQt9bs,69757
|
|
3
3
|
autocoder/auto_coder_rag.py,sha256=tRAKfo3jIhcaQKN_3g7DZRKtDJSZXJxMRdT6Zz8W9nw,41173
|
|
4
|
-
autocoder/auto_coder_runner.py,sha256=
|
|
4
|
+
autocoder/auto_coder_runner.py,sha256=NhT1fVdV4NnV2SwpXl7G-tTKgduA0D-0lK_p2R6DWew,115569
|
|
5
5
|
autocoder/auto_coder_server.py,sha256=bLORGEclcVdbBVfM140JCI8WtdrU0jbgqdJIVVupiEU,20578
|
|
6
6
|
autocoder/benchmark.py,sha256=Ypomkdzd1T3GE6dRICY3Hj547dZ6_inqJbBJIp5QMco,4423
|
|
7
7
|
autocoder/chat_auto_coder.py,sha256=vNQwbYkdqeMl07Vx8z6x-kSPkHKn9AT3sSkYMTJiWtc,26655
|
|
@@ -11,7 +11,7 @@ autocoder/command_parser.py,sha256=fx1g9E6GaM273lGTcJqaFQ-hoksS_Ik2glBMnVltPCE,1
|
|
|
11
11
|
autocoder/lang.py,sha256=PFtATuOhHRnfpqHQkXr6p4C893JvpsgwTMif3l-GEi0,14321
|
|
12
12
|
autocoder/models.py,sha256=pD5u6gcMKRwWaLxeVin18g25k-ERyeHOFsRpOgO_Ae0,13788
|
|
13
13
|
autocoder/run_context.py,sha256=IUfSO6_gp2Wt1blFWAmOpN0b0nDrTTk4LmtCYUBIoro,1643
|
|
14
|
-
autocoder/version.py,sha256=
|
|
14
|
+
autocoder/version.py,sha256=GKXrGNop64hmj7p85hlLkViSFSxh9tQvQZ4yEDTAuu4,25
|
|
15
15
|
autocoder/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
autocoder/agent/agentic_filter.py,sha256=zlInIRhawKIYTJjCiJBWqPCOV5UtMbh5VnvszfTy2vo,39824
|
|
17
17
|
autocoder/agent/auto_demand_organizer.py,sha256=URAq0gSEiHeV_W4zwhOI_83kHz0Ryfj1gcfh5jwCv_w,6501
|
|
@@ -97,6 +97,9 @@ autocoder/common/global_cancel.py,sha256=EYMIzdIJHQjoYP4grxhBxSIT3tCJOy3ESULNd-c
|
|
|
97
97
|
autocoder/common/image_to_page.py,sha256=yWiTJQ49Lm3j0FngiJhQ9u7qayqE_bOGb8Rk0TmSWx0,14123
|
|
98
98
|
autocoder/common/index_import_export.py,sha256=h758AYY1df6JMTKUXYmMkSgxItfymDt82XT7O-ygEuw,4565
|
|
99
99
|
autocoder/common/interpreter.py,sha256=62-dIakOunYB4yjmX8SHC0Gdy2h8NtxdgbpdqRZJ5vk,2833
|
|
100
|
+
autocoder/common/llm_friendly_package.py,sha256=j44Wqco8-5sA2Yz05ZEidA1HwTbVGnbevbALCoasTtM,14760
|
|
101
|
+
autocoder/common/llm_friendly_package_example.py,sha256=NXUiz6j7gpfzExC-2jmppnZaZaTuu4oGMCDneV7FC_k,4647
|
|
102
|
+
autocoder/common/llm_friendly_package_test.py,sha256=FhbzdNPEceuEBIxNvek2OYDFVlJlYJpkskZ7_PB4YSg,1930
|
|
100
103
|
autocoder/common/mcp_hub.py,sha256=grf51bZbZDXQIqlruIxXZjfat8MoVwK7NvHTHMaxKrg,23614
|
|
101
104
|
autocoder/common/mcp_server.py,sha256=Aj6snmB4XXEcLpcm7SC-KBbNLOlEmiNW6hFtMLltpt8,17624
|
|
102
105
|
autocoder/common/mcp_server_install.py,sha256=vQOWWZsl6MZ2qz3b7Y2zctKOEGO69Ph2Nrof4p_1SOg,11599
|
|
@@ -172,7 +175,7 @@ autocoder/common/v2/code_editblock_manager.py,sha256=DMwJw-FAM6VyaBQV3p4xespHpgZ
|
|
|
172
175
|
autocoder/common/v2/code_manager.py,sha256=C403bS-f6urixwitlKHcml-J03hci-UyNwHJOqBiY6Q,9182
|
|
173
176
|
autocoder/common/v2/code_strict_diff_manager.py,sha256=Bys7tFAq4G03R1zUZuxrszBTvP4QB96jIw2y5BDLyRM,9424
|
|
174
177
|
autocoder/common/v2/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
175
|
-
autocoder/common/v2/agent/agentic_edit.py,sha256=
|
|
178
|
+
autocoder/common/v2/agent/agentic_edit.py,sha256=f9GxvaOvgirxyPCEiGxFi7u8X4ZB3do72PGldxCzpAI,115291
|
|
176
179
|
autocoder/common/v2/agent/agentic_edit_types.py,sha256=nEcZc2MOZ_fQLaJX-YDha_x9Iim22ao4tykYM2iIy4k,4908
|
|
177
180
|
autocoder/common/v2/agent/agentic_tool_display.py,sha256=-a-JTQLc4q03E_rdIILKMI0B6DHN-5gcGlrqq-mBYK4,7239
|
|
178
181
|
autocoder/common/v2/agent/agentic_edit_tools/__init__.py,sha256=RbPZZcZg_VnGssL577GxSyFrYrxQ_LopJ4G_-mY3z_Q,1337
|
|
@@ -320,7 +323,7 @@ autocoder/utils/llms.py,sha256=CQRNsX8SJBpeHl_zJ1N-Nj-MYyqkFCi3zETYSurCMkU,4021
|
|
|
320
323
|
autocoder/utils/log_capture.py,sha256=I-bsJFLWoGUiX-GKoZsH9kWJCKSV7ZlUnRt7jh-fOL0,1548
|
|
321
324
|
autocoder/utils/model_provider_selector.py,sha256=JTYy6GLaqnGoqsumjRNXmQuwy9nDqiTSZlGQ9zkfdK0,8102
|
|
322
325
|
autocoder/utils/multi_turn.py,sha256=unK9OpqVRbK6uIcTKXgggX2wNmyj7s5eyEAQ2xUwHoM,88
|
|
323
|
-
autocoder/utils/operate_config_api.py,sha256=
|
|
326
|
+
autocoder/utils/operate_config_api.py,sha256=j9Ika5bbAGSQbFziREwISmp8BQ54m_eigEa5jwdG64Q,4530
|
|
324
327
|
autocoder/utils/print_table.py,sha256=ZMRhCA9DD0FUfKyJBWd5bDdj1RrtPtgOMWSJwtvZcLs,403
|
|
325
328
|
autocoder/utils/project_structure.py,sha256=KnRWtGsJSmZrEV5aOOjv120vvBkZ1UZtDTnWkzpMmKI,11426
|
|
326
329
|
autocoder/utils/queue_communicate.py,sha256=buyEzdvab1QA4i2QKbq35rG5v_9x9PWVLWWMTznWcYM,6832
|
|
@@ -333,9 +336,9 @@ autocoder/utils/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
333
336
|
autocoder/utils/auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
334
337
|
autocoder/utils/auto_coder_utils/chat_stream_out.py,sha256=t902pKxQ5xM7zgIHiAOsTPLwxhE6VuvXAqPy751S7fg,14096
|
|
335
338
|
autocoder/utils/chat_auto_coder_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
336
|
-
auto_coder-0.1.
|
|
337
|
-
auto_coder-0.1.
|
|
338
|
-
auto_coder-0.1.
|
|
339
|
-
auto_coder-0.1.
|
|
340
|
-
auto_coder-0.1.
|
|
341
|
-
auto_coder-0.1.
|
|
339
|
+
auto_coder-0.1.384.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
340
|
+
auto_coder-0.1.384.dist-info/METADATA,sha256=rPHocW41diQxO73kihXrTOfC8r9HBwK07EUF5X_F960,2796
|
|
341
|
+
auto_coder-0.1.384.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
342
|
+
auto_coder-0.1.384.dist-info/entry_points.txt,sha256=0nzHtHH4pNcM7xq4EBA2toS28Qelrvcbrr59GqD_0Ak,350
|
|
343
|
+
auto_coder-0.1.384.dist-info/top_level.txt,sha256=Jqc0_uJSw2GwoFQAa9iJxYns-2mWla-9ok_Y3Gcznjk,10
|
|
344
|
+
auto_coder-0.1.384.dist-info/RECORD,,
|
autocoder/auto_coder_runner.py
CHANGED
|
@@ -657,6 +657,16 @@ def save_memory():
|
|
|
657
657
|
load_memory()
|
|
658
658
|
|
|
659
659
|
|
|
660
|
+
def save_memory_with_new_memory(new_memory):
|
|
661
|
+
memory_path = os.path.join(base_persist_dir, "memory.json")
|
|
662
|
+
lock_path = memory_path + ".lock"
|
|
663
|
+
|
|
664
|
+
with FileLock(lock_path, timeout=30):
|
|
665
|
+
with open(memory_path, "w", encoding="utf-8") as f:
|
|
666
|
+
json.dump(new_memory, f, indent=2, ensure_ascii=False)
|
|
667
|
+
load_memory()
|
|
668
|
+
|
|
669
|
+
|
|
660
670
|
def load_memory():
|
|
661
671
|
global memory
|
|
662
672
|
memory_path = os.path.join(base_persist_dir, "memory.json")
|
|
@@ -2653,7 +2663,7 @@ def lib_command(args: List[str]):
|
|
|
2653
2663
|
|
|
2654
2664
|
if not args:
|
|
2655
2665
|
console.print(
|
|
2656
|
-
"Please specify a subcommand: /add, /remove, /list, /set-proxy, /refresh, or /get"
|
|
2666
|
+
"Please specify a subcommand: /add, /remove, /list, /list_all, /set-proxy, /refresh, or /get"
|
|
2657
2667
|
)
|
|
2658
2668
|
return
|
|
2659
2669
|
|
|
@@ -2710,6 +2720,66 @@ def lib_command(args: List[str]):
|
|
|
2710
2720
|
console.print(table)
|
|
2711
2721
|
else:
|
|
2712
2722
|
console.print("No libraries added yet")
|
|
2723
|
+
|
|
2724
|
+
elif subcommand == "/list_all":
|
|
2725
|
+
if not os.path.exists(llm_friendly_packages_dir):
|
|
2726
|
+
console.print("llm_friendly_packages repository does not exist. Please run /lib /add <library_name> command first to clone it.")
|
|
2727
|
+
return
|
|
2728
|
+
|
|
2729
|
+
available_libs = []
|
|
2730
|
+
|
|
2731
|
+
# 遍历所有domain目录
|
|
2732
|
+
for domain in os.listdir(llm_friendly_packages_dir):
|
|
2733
|
+
domain_path = os.path.join(llm_friendly_packages_dir, domain)
|
|
2734
|
+
if os.path.isdir(domain_path):
|
|
2735
|
+
# 遍历所有username目录
|
|
2736
|
+
for username in os.listdir(domain_path):
|
|
2737
|
+
username_path = os.path.join(domain_path, username)
|
|
2738
|
+
if os.path.isdir(username_path):
|
|
2739
|
+
# 遍历所有lib_name目录
|
|
2740
|
+
for lib_name in os.listdir(username_path):
|
|
2741
|
+
lib_path = os.path.join(username_path, lib_name)
|
|
2742
|
+
if os.path.isdir(lib_path):
|
|
2743
|
+
# 检查是否有Markdown文件
|
|
2744
|
+
has_md_files = False
|
|
2745
|
+
for root, _, files in os.walk(lib_path):
|
|
2746
|
+
if any(file.endswith('.md') for file in files):
|
|
2747
|
+
has_md_files = True
|
|
2748
|
+
break
|
|
2749
|
+
|
|
2750
|
+
if has_md_files:
|
|
2751
|
+
available_libs.append({
|
|
2752
|
+
"domain": domain,
|
|
2753
|
+
"username": username,
|
|
2754
|
+
"lib_name": lib_name,
|
|
2755
|
+
"full_path": f"{username}/{lib_name}",
|
|
2756
|
+
"is_added": lib_name in memory["libs"]
|
|
2757
|
+
})
|
|
2758
|
+
|
|
2759
|
+
if available_libs:
|
|
2760
|
+
table = Table(title="Available Libraries")
|
|
2761
|
+
table.add_column("Domain", style="blue")
|
|
2762
|
+
table.add_column("Username", style="green")
|
|
2763
|
+
table.add_column("Library Name", style="cyan")
|
|
2764
|
+
table.add_column("Full Path", style="magenta")
|
|
2765
|
+
table.add_column("Status", style="yellow")
|
|
2766
|
+
|
|
2767
|
+
# 按domain和username分组排序
|
|
2768
|
+
available_libs.sort(key=lambda x: (x["domain"], x["username"], x["lib_name"]))
|
|
2769
|
+
|
|
2770
|
+
for lib in available_libs:
|
|
2771
|
+
status = "[green]Added[/green]" if lib["is_added"] else "[white]Not Added[/white]"
|
|
2772
|
+
table.add_row(
|
|
2773
|
+
lib["domain"],
|
|
2774
|
+
lib["username"],
|
|
2775
|
+
lib["lib_name"],
|
|
2776
|
+
lib["full_path"],
|
|
2777
|
+
status
|
|
2778
|
+
)
|
|
2779
|
+
|
|
2780
|
+
console.print(table)
|
|
2781
|
+
else:
|
|
2782
|
+
console.print("No available libraries found in the repository.")
|
|
2713
2783
|
|
|
2714
2784
|
elif subcommand == "/set-proxy":
|
|
2715
2785
|
if len(args) == 1:
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLM Friendly Package Manager
|
|
3
|
+
|
|
4
|
+
This module provides a class-based interface for managing LLM friendly packages,
|
|
5
|
+
including operations like get, list, list_all, add, remove, refresh, etc.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import json
|
|
10
|
+
from typing import List, Dict, Any, Optional, Tuple
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.table import Table
|
|
14
|
+
import git
|
|
15
|
+
from filelock import FileLock
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class LibraryInfo:
|
|
20
|
+
"""Information about a library"""
|
|
21
|
+
domain: str
|
|
22
|
+
username: str
|
|
23
|
+
lib_name: str
|
|
24
|
+
full_path: str
|
|
25
|
+
is_added: bool
|
|
26
|
+
has_md_files: bool = True
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class PackageDoc:
|
|
31
|
+
"""Package documentation information"""
|
|
32
|
+
file_path: str
|
|
33
|
+
content: Optional[str] = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LLMFriendlyPackageManager:
|
|
37
|
+
"""Manager for LLM friendly packages"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, project_root: str = None, base_persist_dir: str = None):
|
|
40
|
+
"""
|
|
41
|
+
Initialize the package manager
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
project_root: Project root directory, defaults to current working directory
|
|
45
|
+
base_persist_dir: Base directory for persistence, defaults to .auto-coder/plugins/chat-auto-coder
|
|
46
|
+
"""
|
|
47
|
+
self.project_root = project_root or os.getcwd()
|
|
48
|
+
self.base_persist_dir = base_persist_dir or os.path.join(
|
|
49
|
+
self.project_root, ".auto-coder", "plugins", "chat-auto-coder"
|
|
50
|
+
)
|
|
51
|
+
self.lib_dir = os.path.join(self.project_root, ".auto-coder", "libs")
|
|
52
|
+
self.llm_friendly_packages_dir = os.path.join(self.lib_dir, "llm_friendly_packages")
|
|
53
|
+
self.console = Console()
|
|
54
|
+
|
|
55
|
+
# Ensure directories exist
|
|
56
|
+
os.makedirs(self.lib_dir, exist_ok=True)
|
|
57
|
+
os.makedirs(self.base_persist_dir, exist_ok=True)
|
|
58
|
+
|
|
59
|
+
def _get_memory_path(self) -> str:
|
|
60
|
+
"""Get memory file path"""
|
|
61
|
+
return os.path.join(self.base_persist_dir, "memory.json")
|
|
62
|
+
|
|
63
|
+
def _load_memory(self) -> Dict[str, Any]:
|
|
64
|
+
"""Load memory from file"""
|
|
65
|
+
memory_path = self._get_memory_path()
|
|
66
|
+
lock_path = memory_path + ".lock"
|
|
67
|
+
|
|
68
|
+
default_memory = {
|
|
69
|
+
"conversation": [],
|
|
70
|
+
"current_files": {"files": [], "groups": {}},
|
|
71
|
+
"conf": {},
|
|
72
|
+
"exclude_dirs": [],
|
|
73
|
+
"mode": "auto_detect",
|
|
74
|
+
"libs": {}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if not os.path.exists(memory_path):
|
|
78
|
+
return default_memory
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
with FileLock(lock_path, timeout=30):
|
|
82
|
+
with open(memory_path, "r", encoding="utf-8") as f:
|
|
83
|
+
memory = json.load(f)
|
|
84
|
+
# Ensure libs key exists
|
|
85
|
+
if "libs" not in memory:
|
|
86
|
+
memory["libs"] = {}
|
|
87
|
+
return memory
|
|
88
|
+
except Exception:
|
|
89
|
+
return default_memory
|
|
90
|
+
|
|
91
|
+
def _save_memory(self, memory: Dict[str, Any]) -> None:
|
|
92
|
+
"""Save memory to file"""
|
|
93
|
+
memory_path = self._get_memory_path()
|
|
94
|
+
lock_path = memory_path + ".lock"
|
|
95
|
+
|
|
96
|
+
with FileLock(lock_path, timeout=30):
|
|
97
|
+
with open(memory_path, "w", encoding="utf-8") as f:
|
|
98
|
+
json.dump(memory, f, indent=2, ensure_ascii=False)
|
|
99
|
+
|
|
100
|
+
def _get_current_proxy(self) -> str:
|
|
101
|
+
"""Get current proxy URL"""
|
|
102
|
+
memory = self._load_memory()
|
|
103
|
+
return memory.get("lib-proxy", "https://github.com/allwefantasy/llm_friendly_packages")
|
|
104
|
+
|
|
105
|
+
def _clone_repository(self) -> bool:
|
|
106
|
+
"""Clone the llm_friendly_packages repository"""
|
|
107
|
+
if os.path.exists(self.llm_friendly_packages_dir):
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
self.console.print("Cloning llm_friendly_packages repository...")
|
|
111
|
+
try:
|
|
112
|
+
proxy_url = self._get_current_proxy()
|
|
113
|
+
git.Repo.clone_from(proxy_url, self.llm_friendly_packages_dir)
|
|
114
|
+
self.console.print("Successfully cloned llm_friendly_packages repository")
|
|
115
|
+
return True
|
|
116
|
+
except git.exc.GitCommandError as e:
|
|
117
|
+
self.console.print(f"Error cloning repository: {e}")
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
def get_docs(self, package_name: Optional[str] = None, return_paths: bool = False) -> List[str]:
|
|
121
|
+
"""
|
|
122
|
+
Get documentation for packages
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
package_name: Specific package name to get docs for, None for all packages
|
|
126
|
+
return_paths: If True, return file paths; if False, return file contents
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
List of documentation content or file paths
|
|
130
|
+
"""
|
|
131
|
+
docs = []
|
|
132
|
+
|
|
133
|
+
if not os.path.exists(self.llm_friendly_packages_dir):
|
|
134
|
+
return docs
|
|
135
|
+
|
|
136
|
+
memory = self._load_memory()
|
|
137
|
+
libs = list(memory.get("libs", {}).keys())
|
|
138
|
+
|
|
139
|
+
for domain in os.listdir(self.llm_friendly_packages_dir):
|
|
140
|
+
domain_path = os.path.join(self.llm_friendly_packages_dir, domain)
|
|
141
|
+
if not os.path.isdir(domain_path):
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
for username in os.listdir(domain_path):
|
|
145
|
+
username_path = os.path.join(domain_path, username)
|
|
146
|
+
if not os.path.isdir(username_path):
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
for lib_name in os.listdir(username_path):
|
|
150
|
+
lib_path = os.path.join(username_path, lib_name)
|
|
151
|
+
|
|
152
|
+
# Check if this is the requested package
|
|
153
|
+
if not os.path.isdir(lib_path):
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
if package_name is not None:
|
|
157
|
+
if not (lib_name == package_name or
|
|
158
|
+
package_name == os.path.join(username, lib_name)):
|
|
159
|
+
continue
|
|
160
|
+
|
|
161
|
+
# Check if library is added
|
|
162
|
+
if lib_name not in libs:
|
|
163
|
+
continue
|
|
164
|
+
|
|
165
|
+
# Collect markdown files
|
|
166
|
+
for root, _, files in os.walk(lib_path):
|
|
167
|
+
for file in files:
|
|
168
|
+
if file.endswith(".md"):
|
|
169
|
+
file_path = os.path.join(root, file)
|
|
170
|
+
if return_paths:
|
|
171
|
+
docs.append(file_path)
|
|
172
|
+
else:
|
|
173
|
+
try:
|
|
174
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
175
|
+
docs.append(f.read())
|
|
176
|
+
except Exception as e:
|
|
177
|
+
self.console.print(f"Error reading {file_path}: {e}")
|
|
178
|
+
|
|
179
|
+
return docs
|
|
180
|
+
|
|
181
|
+
def list_added_libraries(self) -> List[str]:
|
|
182
|
+
"""List all added libraries"""
|
|
183
|
+
memory = self._load_memory()
|
|
184
|
+
return list(memory.get("libs", {}).keys())
|
|
185
|
+
|
|
186
|
+
def list_all_available_libraries(self) -> List[LibraryInfo]:
|
|
187
|
+
"""List all available libraries in the repository"""
|
|
188
|
+
if not os.path.exists(self.llm_friendly_packages_dir):
|
|
189
|
+
return []
|
|
190
|
+
|
|
191
|
+
available_libs = []
|
|
192
|
+
memory = self._load_memory()
|
|
193
|
+
added_libs = set(memory.get("libs", {}).keys())
|
|
194
|
+
|
|
195
|
+
for domain in os.listdir(self.llm_friendly_packages_dir):
|
|
196
|
+
domain_path = os.path.join(self.llm_friendly_packages_dir, domain)
|
|
197
|
+
if not os.path.isdir(domain_path):
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
for username in os.listdir(domain_path):
|
|
201
|
+
username_path = os.path.join(domain_path, username)
|
|
202
|
+
if not os.path.isdir(username_path):
|
|
203
|
+
continue
|
|
204
|
+
|
|
205
|
+
for lib_name in os.listdir(username_path):
|
|
206
|
+
lib_path = os.path.join(username_path, lib_name)
|
|
207
|
+
if not os.path.isdir(lib_path):
|
|
208
|
+
continue
|
|
209
|
+
|
|
210
|
+
# Check if has markdown files
|
|
211
|
+
has_md_files = False
|
|
212
|
+
for root, _, files in os.walk(lib_path):
|
|
213
|
+
if any(file.endswith('.md') for file in files):
|
|
214
|
+
has_md_files = True
|
|
215
|
+
break
|
|
216
|
+
|
|
217
|
+
if has_md_files:
|
|
218
|
+
available_libs.append(LibraryInfo(
|
|
219
|
+
domain=domain,
|
|
220
|
+
username=username,
|
|
221
|
+
lib_name=lib_name,
|
|
222
|
+
full_path=f"{username}/{lib_name}",
|
|
223
|
+
is_added=lib_name in added_libs,
|
|
224
|
+
has_md_files=has_md_files
|
|
225
|
+
))
|
|
226
|
+
|
|
227
|
+
# Sort by domain, username, lib_name
|
|
228
|
+
available_libs.sort(key=lambda x: (x.domain, x.username, x.lib_name))
|
|
229
|
+
return available_libs
|
|
230
|
+
|
|
231
|
+
def add_library(self, lib_name: str) -> bool:
|
|
232
|
+
"""
|
|
233
|
+
Add a library to the list
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
lib_name: Library name to add
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
True if successful, False otherwise
|
|
240
|
+
"""
|
|
241
|
+
# Clone repository if needed
|
|
242
|
+
if not self._clone_repository():
|
|
243
|
+
return False
|
|
244
|
+
|
|
245
|
+
memory = self._load_memory()
|
|
246
|
+
|
|
247
|
+
if lib_name in memory["libs"]:
|
|
248
|
+
self.console.print(f"Library {lib_name} is already added")
|
|
249
|
+
return False
|
|
250
|
+
|
|
251
|
+
memory["libs"][lib_name] = {}
|
|
252
|
+
self._save_memory(memory)
|
|
253
|
+
self.console.print(f"Added library: {lib_name}")
|
|
254
|
+
return True
|
|
255
|
+
|
|
256
|
+
def remove_library(self, lib_name: str) -> bool:
|
|
257
|
+
"""
|
|
258
|
+
Remove a library from the list
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
lib_name: Library name to remove
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
True if successful, False otherwise
|
|
265
|
+
"""
|
|
266
|
+
memory = self._load_memory()
|
|
267
|
+
|
|
268
|
+
if lib_name not in memory["libs"]:
|
|
269
|
+
self.console.print(f"Library {lib_name} is not in the list")
|
|
270
|
+
return False
|
|
271
|
+
|
|
272
|
+
del memory["libs"][lib_name]
|
|
273
|
+
self._save_memory(memory)
|
|
274
|
+
self.console.print(f"Removed library: {lib_name}")
|
|
275
|
+
return True
|
|
276
|
+
|
|
277
|
+
def set_proxy(self, proxy_url: Optional[str] = None) -> str:
|
|
278
|
+
"""
|
|
279
|
+
Set or get proxy URL
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
proxy_url: New proxy URL, None to get current proxy
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
Current proxy URL
|
|
286
|
+
"""
|
|
287
|
+
memory = self._load_memory()
|
|
288
|
+
|
|
289
|
+
if proxy_url is None:
|
|
290
|
+
current_proxy = memory.get("lib-proxy", "No proxy set")
|
|
291
|
+
self.console.print(f"Current proxy: {current_proxy}")
|
|
292
|
+
return current_proxy
|
|
293
|
+
|
|
294
|
+
memory["lib-proxy"] = proxy_url
|
|
295
|
+
self._save_memory(memory)
|
|
296
|
+
self.console.print(f"Set proxy to: {proxy_url}")
|
|
297
|
+
return proxy_url
|
|
298
|
+
|
|
299
|
+
def refresh_repository(self) -> bool:
|
|
300
|
+
"""
|
|
301
|
+
Refresh the repository by pulling latest changes
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
True if successful, False otherwise
|
|
305
|
+
"""
|
|
306
|
+
if not os.path.exists(self.llm_friendly_packages_dir):
|
|
307
|
+
self.console.print(
|
|
308
|
+
"llm_friendly_packages repository does not exist. "
|
|
309
|
+
"Please run add_library() first to clone it."
|
|
310
|
+
)
|
|
311
|
+
return False
|
|
312
|
+
|
|
313
|
+
try:
|
|
314
|
+
repo = git.Repo(self.llm_friendly_packages_dir)
|
|
315
|
+
origin = repo.remotes.origin
|
|
316
|
+
|
|
317
|
+
# Update remote URL if proxy is set
|
|
318
|
+
memory = self._load_memory()
|
|
319
|
+
proxy_url = memory.get("lib-proxy")
|
|
320
|
+
current_url = origin.url
|
|
321
|
+
|
|
322
|
+
if proxy_url and proxy_url != current_url:
|
|
323
|
+
origin.set_url(proxy_url)
|
|
324
|
+
self.console.print(f"Updated remote URL to: {proxy_url}")
|
|
325
|
+
|
|
326
|
+
origin.pull()
|
|
327
|
+
self.console.print("Successfully updated llm_friendly_packages repository")
|
|
328
|
+
return True
|
|
329
|
+
|
|
330
|
+
except git.exc.GitCommandError as e:
|
|
331
|
+
self.console.print(f"Error updating repository: {e}")
|
|
332
|
+
return False
|
|
333
|
+
|
|
334
|
+
def get_library_docs_paths(self, package_name: str) -> List[str]:
|
|
335
|
+
"""
|
|
336
|
+
Get documentation file paths for a specific package
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
package_name: Package name
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
List of markdown file paths
|
|
343
|
+
"""
|
|
344
|
+
return self.get_docs(package_name, return_paths=True)
|
|
345
|
+
|
|
346
|
+
def display_added_libraries(self) -> None:
|
|
347
|
+
"""Display added libraries in a table"""
|
|
348
|
+
libs = self.list_added_libraries()
|
|
349
|
+
|
|
350
|
+
if not libs:
|
|
351
|
+
self.console.print("No libraries added yet")
|
|
352
|
+
return
|
|
353
|
+
|
|
354
|
+
table = Table(title="Added Libraries")
|
|
355
|
+
table.add_column("Library Name", style="cyan")
|
|
356
|
+
|
|
357
|
+
for lib_name in libs:
|
|
358
|
+
table.add_row(lib_name)
|
|
359
|
+
|
|
360
|
+
self.console.print(table)
|
|
361
|
+
|
|
362
|
+
def display_all_libraries(self) -> None:
|
|
363
|
+
"""Display all available libraries in a table"""
|
|
364
|
+
if not os.path.exists(self.llm_friendly_packages_dir):
|
|
365
|
+
self.console.print(
|
|
366
|
+
"llm_friendly_packages repository does not exist. "
|
|
367
|
+
"Please call add_library() first to clone it."
|
|
368
|
+
)
|
|
369
|
+
return
|
|
370
|
+
|
|
371
|
+
available_libs = self.list_all_available_libraries()
|
|
372
|
+
|
|
373
|
+
if not available_libs:
|
|
374
|
+
self.console.print("No available libraries found in the repository.")
|
|
375
|
+
return
|
|
376
|
+
|
|
377
|
+
table = Table(title="Available Libraries")
|
|
378
|
+
table.add_column("Domain", style="blue")
|
|
379
|
+
table.add_column("Username", style="green")
|
|
380
|
+
table.add_column("Library Name", style="cyan")
|
|
381
|
+
table.add_column("Full Path", style="magenta")
|
|
382
|
+
table.add_column("Status", style="yellow")
|
|
383
|
+
|
|
384
|
+
for lib in available_libs:
|
|
385
|
+
status = "[green]Added[/green]" if lib.is_added else "[white]Not Added[/white]"
|
|
386
|
+
table.add_row(
|
|
387
|
+
lib.domain,
|
|
388
|
+
lib.username,
|
|
389
|
+
lib.lib_name,
|
|
390
|
+
lib.full_path,
|
|
391
|
+
status
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
self.console.print(table)
|
|
395
|
+
|
|
396
|
+
def display_library_docs(self, package_name: str) -> None:
|
|
397
|
+
"""Display documentation paths for a package in a table"""
|
|
398
|
+
docs = self.get_library_docs_paths(package_name)
|
|
399
|
+
|
|
400
|
+
if not docs:
|
|
401
|
+
self.console.print(f"No markdown files found for package: {package_name}")
|
|
402
|
+
return
|
|
403
|
+
|
|
404
|
+
table = Table(title=f"Markdown Files for {package_name}")
|
|
405
|
+
table.add_column("File Path", style="cyan")
|
|
406
|
+
|
|
407
|
+
for doc in docs:
|
|
408
|
+
table.add_row(doc)
|
|
409
|
+
|
|
410
|
+
self.console.print(table)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLMFriendlyPackageManager Usage Examples
|
|
3
|
+
|
|
4
|
+
This file demonstrates various ways to use the LLMFriendlyPackageManager class
|
|
5
|
+
for managing LLM friendly packages.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from autocoder.common.llm_friendly_package import LLMFriendlyPackageManager
|
|
9
|
+
|
|
10
|
+
def example_basic_usage():
|
|
11
|
+
"""Basic usage example"""
|
|
12
|
+
print("=== Basic Usage Example ===")
|
|
13
|
+
|
|
14
|
+
# Initialize the manager
|
|
15
|
+
manager = LLMFriendlyPackageManager()
|
|
16
|
+
|
|
17
|
+
# List current added libraries
|
|
18
|
+
added_libs = manager.list_added_libraries()
|
|
19
|
+
print(f"Currently added libraries: {added_libs}")
|
|
20
|
+
|
|
21
|
+
# Display added libraries in a nice table
|
|
22
|
+
manager.display_added_libraries()
|
|
23
|
+
|
|
24
|
+
def example_library_management():
|
|
25
|
+
"""Library management example"""
|
|
26
|
+
print("\n=== Library Management Example ===")
|
|
27
|
+
|
|
28
|
+
manager = LLMFriendlyPackageManager()
|
|
29
|
+
|
|
30
|
+
# Add a library (this will clone the repository if needed)
|
|
31
|
+
print("Adding a library...")
|
|
32
|
+
success = manager.add_library("example-lib")
|
|
33
|
+
if success:
|
|
34
|
+
print("Library added successfully!")
|
|
35
|
+
|
|
36
|
+
# List all available libraries
|
|
37
|
+
print("\nAll available libraries:")
|
|
38
|
+
manager.display_all_libraries()
|
|
39
|
+
|
|
40
|
+
# Remove a library
|
|
41
|
+
print("\nRemoving the library...")
|
|
42
|
+
removed = manager.remove_library("example-lib")
|
|
43
|
+
if removed:
|
|
44
|
+
print("Library removed successfully!")
|
|
45
|
+
|
|
46
|
+
def example_documentation_access():
|
|
47
|
+
"""Documentation access example"""
|
|
48
|
+
print("\n=== Documentation Access Example ===")
|
|
49
|
+
|
|
50
|
+
manager = LLMFriendlyPackageManager()
|
|
51
|
+
|
|
52
|
+
# Get documentation content for all packages
|
|
53
|
+
docs_content = manager.get_docs()
|
|
54
|
+
print(f"Total documentation content items: {len(docs_content)}")
|
|
55
|
+
|
|
56
|
+
# Get documentation file paths for all packages
|
|
57
|
+
docs_paths = manager.get_docs(return_paths=True)
|
|
58
|
+
print(f"Total documentation files: {len(docs_paths)}")
|
|
59
|
+
|
|
60
|
+
# Get documentation for a specific package
|
|
61
|
+
specific_docs = manager.get_docs(package_name="some-package", return_paths=True)
|
|
62
|
+
print(f"Documentation files for 'some-package': {len(specific_docs)}")
|
|
63
|
+
|
|
64
|
+
# Display documentation paths for a specific package
|
|
65
|
+
manager.display_library_docs("some-package")
|
|
66
|
+
|
|
67
|
+
def example_repository_management():
|
|
68
|
+
"""Repository management example"""
|
|
69
|
+
print("\n=== Repository Management Example ===")
|
|
70
|
+
|
|
71
|
+
manager = LLMFriendlyPackageManager()
|
|
72
|
+
|
|
73
|
+
# Get current proxy setting
|
|
74
|
+
current_proxy = manager.set_proxy()
|
|
75
|
+
print(f"Current proxy: {current_proxy}")
|
|
76
|
+
|
|
77
|
+
# Set a new proxy (optional)
|
|
78
|
+
# manager.set_proxy("https://gitee.com/your-mirror/llm_friendly_packages")
|
|
79
|
+
|
|
80
|
+
# Refresh the repository to get latest changes
|
|
81
|
+
print("Refreshing repository...")
|
|
82
|
+
success = manager.refresh_repository()
|
|
83
|
+
if success:
|
|
84
|
+
print("Repository refreshed successfully!")
|
|
85
|
+
|
|
86
|
+
def example_data_access():
|
|
87
|
+
"""Data access example"""
|
|
88
|
+
print("\n=== Data Access Example ===")
|
|
89
|
+
|
|
90
|
+
manager = LLMFriendlyPackageManager()
|
|
91
|
+
|
|
92
|
+
# Get all available libraries as structured data
|
|
93
|
+
available_libs = manager.list_all_available_libraries()
|
|
94
|
+
print(f"Total available libraries: {len(available_libs)}")
|
|
95
|
+
|
|
96
|
+
# Process the library information
|
|
97
|
+
for lib in available_libs[:3]: # Show first 3
|
|
98
|
+
print(f"Domain: {lib.domain}, "
|
|
99
|
+
f"Username: {lib.username}, "
|
|
100
|
+
f"Library: {lib.lib_name}, "
|
|
101
|
+
f"Added: {lib.is_added}")
|
|
102
|
+
|
|
103
|
+
def example_custom_configuration():
|
|
104
|
+
"""Custom configuration example"""
|
|
105
|
+
print("\n=== Custom Configuration Example ===")
|
|
106
|
+
|
|
107
|
+
# Initialize with custom directories (using existing project directory)
|
|
108
|
+
import tempfile
|
|
109
|
+
import os
|
|
110
|
+
|
|
111
|
+
# Create a temporary directory for demonstration
|
|
112
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
113
|
+
custom_project_root = temp_dir
|
|
114
|
+
custom_persist_dir = os.path.join(temp_dir, "custom_persist")
|
|
115
|
+
|
|
116
|
+
manager = LLMFriendlyPackageManager(
|
|
117
|
+
project_root=custom_project_root,
|
|
118
|
+
base_persist_dir=custom_persist_dir
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
print("Manager initialized with custom configuration")
|
|
122
|
+
print(f"Project root: {custom_project_root}")
|
|
123
|
+
print(f"Persistence directory: {custom_persist_dir}")
|
|
124
|
+
|
|
125
|
+
# Use the manager with custom configuration
|
|
126
|
+
added_libs = manager.list_added_libraries()
|
|
127
|
+
print(f"Added libraries with custom config: {added_libs}")
|
|
128
|
+
|
|
129
|
+
if __name__ == "__main__":
|
|
130
|
+
# Run all examples
|
|
131
|
+
example_basic_usage()
|
|
132
|
+
example_library_management()
|
|
133
|
+
example_documentation_access()
|
|
134
|
+
example_repository_management()
|
|
135
|
+
example_data_access()
|
|
136
|
+
example_custom_configuration()
|
|
137
|
+
|
|
138
|
+
print("\n=== All examples completed ===")
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test script for LLMFriendlyPackageManager
|
|
3
|
+
|
|
4
|
+
This script demonstrates the usage of the new LLMFriendlyPackageManager class.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Add the project root to the Python path
|
|
12
|
+
project_root = Path(__file__).parent.parent.parent
|
|
13
|
+
sys.path.insert(0, str(project_root))
|
|
14
|
+
|
|
15
|
+
from autocoder.common.llm_friendly_package import LLMFriendlyPackageManager
|
|
16
|
+
|
|
17
|
+
def test_llm_friendly_package_manager():
|
|
18
|
+
"""Test the LLMFriendlyPackageManager functionality"""
|
|
19
|
+
|
|
20
|
+
# Initialize the manager
|
|
21
|
+
manager = LLMFriendlyPackageManager()
|
|
22
|
+
|
|
23
|
+
print("=== Testing LLMFriendlyPackageManager ===\n")
|
|
24
|
+
|
|
25
|
+
# Test 1: Display added libraries (should be empty initially)
|
|
26
|
+
print("1. Testing display_added_libraries():")
|
|
27
|
+
manager.display_added_libraries()
|
|
28
|
+
print()
|
|
29
|
+
|
|
30
|
+
# Test 2: List added libraries programmatically
|
|
31
|
+
print("2. Testing list_added_libraries():")
|
|
32
|
+
added_libs = manager.list_added_libraries()
|
|
33
|
+
print(f"Added libraries: {added_libs}")
|
|
34
|
+
print()
|
|
35
|
+
|
|
36
|
+
# Test 3: Show current proxy
|
|
37
|
+
print("3. Testing set_proxy() to get current proxy:")
|
|
38
|
+
current_proxy = manager.set_proxy()
|
|
39
|
+
print(f"Current proxy: {current_proxy}")
|
|
40
|
+
print()
|
|
41
|
+
|
|
42
|
+
# Test 4: Try to get docs (should be empty if no libraries added)
|
|
43
|
+
print("4. Testing get_docs():")
|
|
44
|
+
docs = manager.get_docs(return_paths=True)
|
|
45
|
+
print(f"Number of documentation files found: {len(docs)}")
|
|
46
|
+
if docs:
|
|
47
|
+
print("First few docs:")
|
|
48
|
+
for i, doc in enumerate(docs[:3]):
|
|
49
|
+
print(f" - {doc}")
|
|
50
|
+
print()
|
|
51
|
+
|
|
52
|
+
# Test 5: Display all available libraries (may require repository)
|
|
53
|
+
print("5. Testing display_all_libraries():")
|
|
54
|
+
try:
|
|
55
|
+
manager.display_all_libraries()
|
|
56
|
+
except Exception as e:
|
|
57
|
+
print(f"Could not display all libraries: {e}")
|
|
58
|
+
print()
|
|
59
|
+
|
|
60
|
+
print("=== Test completed ===")
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
test_llm_friendly_package_manager()
|
|
@@ -58,6 +58,7 @@ from autocoder.common.v2.agent.agentic_edit_tools import ( # Import specific re
|
|
|
58
58
|
AttemptCompletionToolResolver, PlanModeRespondToolResolver, UseMcpToolResolver,
|
|
59
59
|
ListPackageInfoToolResolver
|
|
60
60
|
)
|
|
61
|
+
from autocoder.common.llm_friendly_package import LLMFriendlyPackageManager
|
|
61
62
|
from autocoder.common.rulefiles.autocoderrules_utils import get_rules,auto_select_rules,get_required_and_index_rules
|
|
62
63
|
from autocoder.common.v2.agent.agentic_edit_types import (AgenticEditRequest, ToolResult,
|
|
63
64
|
MemoryConfig, CommandConfig, BaseTool,
|
|
@@ -127,7 +128,8 @@ class AgenticEdit:
|
|
|
127
128
|
self.memory_config = memory_config
|
|
128
129
|
self.command_config = command_config # Note: command_config might be unused now
|
|
129
130
|
self.project_type_analyzer = ProjectTypeAnalyzer(
|
|
130
|
-
args=args, llm=self.llm)
|
|
131
|
+
args=args, llm=self.llm)
|
|
132
|
+
self.base_persist_dir = os.path.join(args.source_dir, ".auto-coder", "plugins", "chat-auto-coder")
|
|
131
133
|
|
|
132
134
|
# self.shadow_manager = ShadowManager(
|
|
133
135
|
# args.source_dir, args.event_file, args.ignore_clean_shadows)
|
|
@@ -163,6 +165,33 @@ class AgenticEdit:
|
|
|
163
165
|
# 格式: { file_path: FileChangeEntry(...) }
|
|
164
166
|
self.file_changes: Dict[str, FileChangeEntry] = {}
|
|
165
167
|
|
|
168
|
+
@byzerllm.prompt()
|
|
169
|
+
def generate_library_docs_prompt(self, libraries: List[str], docs_content: str) -> Dict[str, Any]:
|
|
170
|
+
"""
|
|
171
|
+
====
|
|
172
|
+
|
|
173
|
+
THIRD-PARTY LIBRARY DOCUMENTATION
|
|
174
|
+
|
|
175
|
+
The following documentation is for third-party libraries that are available in this project. Use this information to understand the capabilities and APIs of these libraries when they are relevant to the user's task.
|
|
176
|
+
|
|
177
|
+
Libraries included: {{ libraries_list }}
|
|
178
|
+
|
|
179
|
+
<library_documentation>
|
|
180
|
+
{{ combined_docs }}
|
|
181
|
+
</library_documentation>
|
|
182
|
+
|
|
183
|
+
You should reference this documentation when:
|
|
184
|
+
1. The user asks about functionality that might be provided by these libraries
|
|
185
|
+
2. You need to implement features that could leverage these library capabilities
|
|
186
|
+
3. You want to suggest using library functions instead of implementing from scratch
|
|
187
|
+
4. You need to understand the API or usage patterns of these libraries
|
|
188
|
+
====
|
|
189
|
+
"""
|
|
190
|
+
return {
|
|
191
|
+
"libraries_list": ", ".join(libraries),
|
|
192
|
+
"combined_docs": docs_content
|
|
193
|
+
}
|
|
194
|
+
|
|
166
195
|
def record_file_change(self, file_path: str, change_type: str, diff: Optional[str] = None, content: Optional[str] = None):
|
|
167
196
|
"""
|
|
168
197
|
记录单个文件的变更信息。
|
|
@@ -801,6 +830,43 @@ class AgenticEdit:
|
|
|
801
830
|
conversations = [
|
|
802
831
|
{"role": "system", "content": system_prompt},
|
|
803
832
|
]
|
|
833
|
+
|
|
834
|
+
# Add third-party library documentation information
|
|
835
|
+
try:
|
|
836
|
+
package_manager = LLMFriendlyPackageManager(
|
|
837
|
+
project_root=self.args.source_dir,
|
|
838
|
+
base_persist_dir=self.base_persist_dir
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
# Get list of added libraries
|
|
842
|
+
added_libraries = package_manager.list_added_libraries()
|
|
843
|
+
|
|
844
|
+
if added_libraries:
|
|
845
|
+
# Get documentation content for all added libraries
|
|
846
|
+
docs_content = package_manager.get_docs(return_paths=False)
|
|
847
|
+
|
|
848
|
+
if docs_content:
|
|
849
|
+
# Combine all documentation content
|
|
850
|
+
combined_docs = "\n\n".join(docs_content)
|
|
851
|
+
|
|
852
|
+
# Generate library documentation prompt using decorator
|
|
853
|
+
library_docs_prompt = self.generate_library_docs_prompt.prompt(
|
|
854
|
+
libraries=added_libraries,
|
|
855
|
+
docs_content=combined_docs
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
conversations.append({
|
|
859
|
+
"role": "user",
|
|
860
|
+
"content": library_docs_prompt
|
|
861
|
+
})
|
|
862
|
+
|
|
863
|
+
conversations.append({
|
|
864
|
+
"role": "assistant",
|
|
865
|
+
"content": "我已经阅读并理解了项目中可用的第三方库文档信息。在处理您的请求时,我会适当地参考这些库的功能和API,帮助您更好地利用这些库的能力。"
|
|
866
|
+
})
|
|
867
|
+
|
|
868
|
+
except Exception as e:
|
|
869
|
+
logger.warning(f"Failed to load library documentation: {str(e)}")
|
|
804
870
|
|
|
805
871
|
conversations.append({
|
|
806
872
|
"role": "user", "content": request.user_input
|
|
@@ -824,7 +890,8 @@ class AgenticEdit:
|
|
|
824
890
|
|
|
825
891
|
while True:
|
|
826
892
|
iteration_count += 1
|
|
827
|
-
logger.info(f"Starting LLM interaction cycle #{iteration_count}")
|
|
893
|
+
logger.info(f"Starting LLM interaction cycle #{iteration_count}, reset tool_executed to False")
|
|
894
|
+
tool_executed = False
|
|
828
895
|
global_cancel.check_and_raise(token=self.args.event_file)
|
|
829
896
|
last_message = conversations[-1]
|
|
830
897
|
if last_message["role"] == "assistant":
|
|
@@ -41,44 +41,20 @@ def convert_yaml_config_to_str(yaml_config):
|
|
|
41
41
|
def get_llm_friendly_package_docs(memory,
|
|
42
42
|
package_name: Optional[str] = None, return_paths: bool = False
|
|
43
43
|
) -> List[str]:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
username_path = os.path.join(domain_path, username)
|
|
59
|
-
if os.path.isdir(username_path):
|
|
60
|
-
for lib_name in os.listdir(username_path):
|
|
61
|
-
lib_path = os.path.join(username_path, lib_name)
|
|
62
|
-
if (
|
|
63
|
-
os.path.isdir(lib_path)
|
|
64
|
-
and (
|
|
65
|
-
package_name is None
|
|
66
|
-
or lib_name == package_name
|
|
67
|
-
or package_name == os.path.join(username, lib_name)
|
|
68
|
-
)
|
|
69
|
-
and lib_name in libs
|
|
70
|
-
):
|
|
71
|
-
for root, _, files in os.walk(lib_path):
|
|
72
|
-
for file in files:
|
|
73
|
-
if file.endswith(".md"):
|
|
74
|
-
file_path = os.path.join(root, file)
|
|
75
|
-
if return_paths:
|
|
76
|
-
docs.append(file_path)
|
|
77
|
-
else:
|
|
78
|
-
with open(file_path, "r",encoding="utf-8") as f:
|
|
79
|
-
docs.append(f.read())
|
|
80
|
-
|
|
81
|
-
return docs
|
|
44
|
+
"""
|
|
45
|
+
Legacy function for backward compatibility.
|
|
46
|
+
Use LLMFriendlyPackageManager class for new code.
|
|
47
|
+
"""
|
|
48
|
+
from autocoder.common.llm_friendly_package import LLMFriendlyPackageManager
|
|
49
|
+
|
|
50
|
+
project_root = os.getcwd()
|
|
51
|
+
base_persist_dir = os.path.join(project_root, ".auto-coder", "plugins", "chat-auto-coder")
|
|
52
|
+
|
|
53
|
+
manager = LLMFriendlyPackageManager(
|
|
54
|
+
project_root=project_root,
|
|
55
|
+
base_persist_dir=base_persist_dir
|
|
56
|
+
)
|
|
57
|
+
return manager.get_docs(package_name, return_paths)
|
|
82
58
|
|
|
83
59
|
|
|
84
60
|
def convert_config_value(key, value):
|
autocoder/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.384"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|