pycoze 0.1.439__py3-none-any.whl → 0.1.441__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.
- pycoze/api/lib/web.py +53 -4
- pycoze/bot/chat.py +5 -1
- pycoze/bot/chat_base.py +1 -2
- pycoze/bot/lib.py +2 -4
- pycoze/bot/tools.py +23 -2
- {pycoze-0.1.439.dist-info → pycoze-0.1.441.dist-info}/METADATA +1 -1
- {pycoze-0.1.439.dist-info → pycoze-0.1.441.dist-info}/RECORD +10 -10
- {pycoze-0.1.439.dist-info → pycoze-0.1.441.dist-info}/LICENSE +0 -0
- {pycoze-0.1.439.dist-info → pycoze-0.1.441.dist-info}/WHEEL +0 -0
- {pycoze-0.1.439.dist-info → pycoze-0.1.441.dist-info}/top_level.txt +0 -0
pycoze/api/lib/web.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from pycoze import utils
|
2
|
+
from bs4 import BeautifulSoup, Comment
|
2
3
|
|
3
4
|
|
4
5
|
socket = utils.socket
|
@@ -10,7 +11,55 @@ class WebCls:
|
|
10
11
|
"getSimplifiedWebpage", {"url": url}
|
11
12
|
)
|
12
13
|
|
13
|
-
def get_simplified_html(self, html: str) -> str:
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def get_simplified_html(self, html: str, selector=None) -> str:
|
15
|
+
soup = BeautifulSoup(html, 'html.parser')
|
16
|
+
|
17
|
+
# 如果指定了selector,则只提取该元素的内容
|
18
|
+
if selector:
|
19
|
+
element = soup.select_one(selector)
|
20
|
+
if element:
|
21
|
+
soup = BeautifulSoup(str(element), 'html.parser')
|
22
|
+
|
23
|
+
# 定义需要移除的标签
|
24
|
+
tags_to_remove = ['script', 'style', 'noscript', 'meta', 'link']
|
25
|
+
for tag in tags_to_remove:
|
26
|
+
for element in soup(tag):
|
27
|
+
element.decompose()
|
28
|
+
|
29
|
+
# 移除注释
|
30
|
+
for element in soup.find_all(string=lambda text: isinstance(text, Comment)):
|
31
|
+
element.extract()
|
32
|
+
|
33
|
+
# 定义需要保留的交互属性
|
34
|
+
INTERACTIVE_ATTRIBUTES = {
|
35
|
+
'a': ['href', 'onclick'],
|
36
|
+
'button': ['onclick'],
|
37
|
+
'img': ['src', 'onload'],
|
38
|
+
'form': ['action', 'onsubmit'],
|
39
|
+
'input': ['type', 'onclick', 'onchange'],
|
40
|
+
'*': ['onclick', 'onload', 'onchange', 'onsubmit', 'onmouseover']
|
41
|
+
}
|
42
|
+
|
43
|
+
# 遍历所有标签,保留交互属性并移除其他属性
|
44
|
+
for element in soup.find_all(True):
|
45
|
+
tag_name = element.name
|
46
|
+
allowed_attrs = INTERACTIVE_ATTRIBUTES.get(tag_name, []) + INTERACTIVE_ATTRIBUTES['*']
|
47
|
+
attrs = list(element.attrs.keys())
|
48
|
+
for attr in attrs:
|
49
|
+
if attr not in allowed_attrs:
|
50
|
+
del element[attr]
|
51
|
+
|
52
|
+
# 如果是<img>标签,检查src是否为Base64
|
53
|
+
if tag_name == 'img' and 'src' in element.attrs and element['src'].startswith('data:'):
|
54
|
+
del element['src']
|
55
|
+
|
56
|
+
# 处理文本内容,超过1000字符则截取
|
57
|
+
if element.string and len(element.string) > 1000:
|
58
|
+
element.string = element.string[:1000] + '...'
|
59
|
+
|
60
|
+
# 移除标签之间的多余空白
|
61
|
+
for element in soup.find_all(True):
|
62
|
+
if not element.get_text(strip=True):
|
63
|
+
element.string = ''
|
64
|
+
|
65
|
+
return str(soup)
|
pycoze/bot/chat.py
CHANGED
@@ -8,7 +8,7 @@ from pycoze import utils
|
|
8
8
|
import tempfile
|
9
9
|
import re
|
10
10
|
import datetime
|
11
|
-
|
11
|
+
import atexit
|
12
12
|
|
13
13
|
|
14
14
|
def eclipse_tool_result(text, threshold=100):
|
@@ -78,6 +78,10 @@ async def run_with_interrupt_check(
|
|
78
78
|
check_task = asyncio.create_task(
|
79
79
|
check_interrupt_file(0.5, interrupt_file, chat_task)
|
80
80
|
)
|
81
|
+
def cleanup():
|
82
|
+
chat_task.cancel()
|
83
|
+
check_task.cancel()
|
84
|
+
atexit.register(cleanup)
|
81
85
|
result = await chat_task
|
82
86
|
return result
|
83
87
|
except asyncio.CancelledError:
|
pycoze/bot/chat_base.py
CHANGED
pycoze/bot/lib.py
CHANGED
@@ -66,10 +66,8 @@ def get_system_prompt(abilities, bot_setting):
|
|
66
66
|
cd_prompt = "When executing outside the working directory, include the CD command, such as cd /path/to/directory && ls."
|
67
67
|
system = platform.system()
|
68
68
|
|
69
|
-
|
70
|
-
print("abilities", abilities)
|
69
|
+
|
71
70
|
abilities_str = "\n".join([function_to_string(a) for a in abilities])
|
72
|
-
print("abilities_str", abilities_str)
|
73
71
|
|
74
72
|
context = {
|
75
73
|
"prompt": bot_setting["prompt"],
|
@@ -96,7 +94,7 @@ def get_system_prompt(abilities, bot_setting):
|
|
96
94
|
if key != "folder_context" and bot_setting["systemAbility"][key] == True:
|
97
95
|
has_any_tool = True
|
98
96
|
break
|
99
|
-
|
97
|
+
|
100
98
|
context["has_any_tool"] = has_any_tool
|
101
99
|
system_prompt = template.render(context)
|
102
100
|
|
pycoze/bot/tools.py
CHANGED
@@ -132,17 +132,38 @@ class ReplaceInFileTool(Tool):
|
|
132
132
|
with open(path, "r", encoding="utf-8") as f:
|
133
133
|
content = f.read()
|
134
134
|
|
135
|
+
# 初始化成功和失败的计数器
|
136
|
+
success_count = 0
|
137
|
+
failure_count = 0
|
138
|
+
failure_details = [] # 用于记录匹配失败的详细信息
|
139
|
+
|
135
140
|
# 处理差异内容
|
136
141
|
diff_content = self.params["diff"]
|
137
142
|
for diff_block in diff_content.split("<<<<<<< SEARCH")[1:]:
|
138
143
|
search, replace = diff_block.split("=======")
|
139
144
|
search = search.strip()
|
140
145
|
replace = replace.split(">>>>>>> REPLACE")[0].strip()
|
141
|
-
|
146
|
+
if search in content:
|
147
|
+
content = content.replace(search, replace, 1)
|
148
|
+
success_count += 1
|
149
|
+
else:
|
150
|
+
failure_count += 1
|
151
|
+
# 记录匹配失败的前20个字符
|
152
|
+
failure_details.append(f"Failed to match: '{search[:20]}...'")
|
142
153
|
|
143
154
|
with open(path, "w", encoding="utf-8") as f:
|
144
155
|
f.write(content)
|
145
|
-
|
156
|
+
|
157
|
+
# 构建返回结果
|
158
|
+
result = (
|
159
|
+
f"The content of the file {path} has been replaced successfully. "
|
160
|
+
f"Successfully replaced {success_count} occurrences. "
|
161
|
+
f"Failed to replace {failure_count} occurrences."
|
162
|
+
)
|
163
|
+
if failure_details:
|
164
|
+
result += "\nFailure details:\n" + "\n".join(failure_details)
|
165
|
+
|
166
|
+
return result
|
146
167
|
|
147
168
|
|
148
169
|
class SearchFilesTool(Tool):
|
@@ -7,15 +7,15 @@ pycoze/api/__init__.py,sha256=TLKvaZlRzTTt0KiXijLjj9b_iCr7fU1siwsXqyd74b8,375
|
|
7
7
|
pycoze/api/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
pycoze/api/lib/tab.py,sha256=DWO8ElI-VOODtIxqUFWaDB8VRrrFYAZRWivuIeD1wG0,2619
|
9
9
|
pycoze/api/lib/view.py,sha256=_PIpTfeuTPPlMDKshMGsqFQYMq7ZiO4Hg5XwHwDoU60,7357
|
10
|
-
pycoze/api/lib/web.py,sha256=
|
10
|
+
pycoze/api/lib/web.py,sha256=l56koyd7RUzK-4mQE_5W-POyqSD79mvwusIN0rxND-Q,2347
|
11
11
|
pycoze/api/lib/window.py,sha256=dkzWfLwn5pE_L0DfQ38K8nx9tQyT5KO-GYyXi0rytFc,2073
|
12
12
|
pycoze/bot/__init__.py,sha256=rL3Q-ycczRpSFfKn84fg3QBl5k22WpyeIU5qOEjEby8,79
|
13
|
-
pycoze/bot/chat.py,sha256=
|
14
|
-
pycoze/bot/chat_base.py,sha256=
|
15
|
-
pycoze/bot/lib.py,sha256
|
13
|
+
pycoze/bot/chat.py,sha256=bScsMc0hGh2NlvhQxzWEbnA_WXU9JdAJv-rx27SpEB8,6554
|
14
|
+
pycoze/bot/chat_base.py,sha256=I_QOB22Ud1HpBDg8kip9AW4stGbbLOrKpZPSMCHEMAE,12567
|
15
|
+
pycoze/bot/lib.py,sha256=_bQ52mKsWgFGAogFHnmRBJbvK_tPOwsAJ8NqJNMR5K4,7210
|
16
16
|
pycoze/bot/message.py,sha256=udnIi-h4QgGzkbr_5VcAsVGjoLp9wXJSfBCeuOz7_Bk,802
|
17
17
|
pycoze/bot/prompt.md,sha256=t7NQdiiNe-jCDVfeVbvTPfq5WK5nF8CxFUQUFMyXJlo,13880
|
18
|
-
pycoze/bot/tools.py,sha256=
|
18
|
+
pycoze/bot/tools.py,sha256=BWMdwvqLzvcyaW38lzxUWtc0K1V-C_qPSEZ3OKlAQvU,11108
|
19
19
|
pycoze/reference/__init__.py,sha256=zgqGqvmA9HaqytEM33B6vi0kQVk8IiCwJaXa22xsFz8,114
|
20
20
|
pycoze/reference/bot.py,sha256=UZK24Qm8kpqpwXJy_zNZeTEEDee05luXdSBeUm0NCt0,2029
|
21
21
|
pycoze/reference/lib.py,sha256=T-oBOKxkus5dTouc0oDgfRzUyi6aTyY-FF4yX7SzF5M,3755
|
@@ -31,8 +31,8 @@ pycoze/utils/arg.py,sha256=jop1tBfe5hYkHW1NSpCeaZBEznkgguBscj_7M2dWfrs,503
|
|
31
31
|
pycoze/utils/env.py,sha256=5pWlXfM1F5ZU9hhv1rHlDEanjEW5wf0nbyez9bNRqqA,559
|
32
32
|
pycoze/utils/socket.py,sha256=bZbFFRH4mfThzRqt55BAAGQ6eICx_ja4x8UGGrUdAm8,2428
|
33
33
|
pycoze/utils/text_or_file.py,sha256=gpxZVWt2DW6YiEg_MnMuwg36VNf3TX383QD_1oZNB0Y,551
|
34
|
-
pycoze-0.1.
|
35
|
-
pycoze-0.1.
|
36
|
-
pycoze-0.1.
|
37
|
-
pycoze-0.1.
|
38
|
-
pycoze-0.1.
|
34
|
+
pycoze-0.1.441.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
|
35
|
+
pycoze-0.1.441.dist-info/METADATA,sha256=hcD7MM_qfiSIrfLURPH8qxnJqJnK6DtcbG0jnAhanfE,854
|
36
|
+
pycoze-0.1.441.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
37
|
+
pycoze-0.1.441.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
|
38
|
+
pycoze-0.1.441.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|