gomyck-tools 1.3.5__py3-none-any.whl → 1.3.7__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.
- ctools/ai/llm_chat.py +3 -7
- ctools/ai/llm_client.py +17 -4
- ctools/ai/tools/json_extract.py +155 -0
- ctools/ai/tools/think_process.py +11 -0
- ctools/ai/tools/tool_use_xml_parse.py +14 -7
- ctools/aio_web_server.py +16 -4
- {gomyck_tools-1.3.5.dist-info → gomyck_tools-1.3.7.dist-info}/METADATA +4 -2
- {gomyck_tools-1.3.5.dist-info → gomyck_tools-1.3.7.dist-info}/RECORD +11 -10
- {gomyck_tools-1.3.5.dist-info → gomyck_tools-1.3.7.dist-info}/WHEEL +0 -0
- {gomyck_tools-1.3.5.dist-info → gomyck_tools-1.3.7.dist-info}/licenses/LICENSE +0 -0
- {gomyck_tools-1.3.5.dist-info → gomyck_tools-1.3.7.dist-info}/top_level.txt +0 -0
ctools/ai/llm_chat.py
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
import enum
|
2
|
-
import re
|
3
|
-
|
4
1
|
from ctools import sys_log
|
5
2
|
from ctools.ai.llm_client import LLMClient
|
6
3
|
from ctools.ai.mcp.mcp_client import MCPClient, res_has_img, is_image_content, get_tools_prompt, mcp_tool_call
|
7
4
|
from ctools.ai.tools.xml_extract import extract_all_xml_blocks
|
5
|
+
from ctools.ai.tools.think_process import remove_think_blocks
|
8
6
|
|
9
7
|
log = sys_log.flog
|
10
8
|
|
@@ -22,10 +20,6 @@ class ROLE:
|
|
22
20
|
def get_message_json(role_type: ROLE, content):
|
23
21
|
return {"role": role_type, "content": content}
|
24
22
|
|
25
|
-
def remove_think_blocks(text: str) -> str:
|
26
|
-
cleaned_text = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL)
|
27
|
-
return cleaned_text.strip()
|
28
|
-
|
29
23
|
class ChatSession:
|
30
24
|
|
31
25
|
def __init__(self, prompts: str, llm_client: LLMClient, max_tools_call: int = 10, mcp_clients: list[MCPClient] = None,
|
@@ -50,6 +44,7 @@ class ChatSession:
|
|
50
44
|
|
51
45
|
self.current_message = {}
|
52
46
|
self.full_messages = []
|
47
|
+
self.is_success = True
|
53
48
|
|
54
49
|
async def init_prompts(self, user_system_prompt):
|
55
50
|
if self.mcp_clients:
|
@@ -134,6 +129,7 @@ class ChatSession:
|
|
134
129
|
|
135
130
|
async def process_error_message(self, error_msg, get_call_id, get_event_msg_func, get_full_msg_func):
|
136
131
|
# 最终结果通知前端+实时通知都要有
|
132
|
+
self.is_success = False
|
137
133
|
self.current_message = error_msg
|
138
134
|
if get_event_msg_func: await get_event_msg_func(get_call_id(), ROLE.ASSISTANT, self.current_message)
|
139
135
|
if get_full_msg_func: await get_full_msg_func(get_call_id(), True, self.full_messages)
|
ctools/ai/llm_client.py
CHANGED
@@ -23,7 +23,17 @@ def process_SSE(line):
|
|
23
23
|
class LLMClient:
|
24
24
|
"""Manages communication with the LLM provider."""
|
25
25
|
|
26
|
-
def __init__(self, api_key: str=os.getenv("LLM_API_KEY"),
|
26
|
+
def __init__(self, api_key: str=os.getenv("LLM_API_KEY"),
|
27
|
+
llm_url: str="https://api.siliconflow.cn/v1/",
|
28
|
+
model_name: str="Qwen/Qwen3-235B-A22B",
|
29
|
+
temperature: float=1, stream: bool=True,
|
30
|
+
thinking: bool=True,
|
31
|
+
thinking_budget: int=4096,
|
32
|
+
max_tokens: int=8192,
|
33
|
+
top_p: float=0.5,
|
34
|
+
top_k: int=50,
|
35
|
+
frequency_penalty: float=0.5
|
36
|
+
) -> None:
|
27
37
|
self.api_key = api_key
|
28
38
|
self.llm_url = llm_url
|
29
39
|
self.model_name = model_name
|
@@ -32,6 +42,9 @@ class LLMClient:
|
|
32
42
|
self.thinking = thinking
|
33
43
|
self.thinking_budget = thinking_budget
|
34
44
|
self.max_tokens = max_tokens
|
45
|
+
self.top_p = top_p
|
46
|
+
self.top_k = top_k
|
47
|
+
self.frequency_penalty = frequency_penalty
|
35
48
|
|
36
49
|
async def model_completion(self, messages: list[dict[str, str]]):
|
37
50
|
self.no_think_compatible(messages)
|
@@ -45,9 +58,9 @@ class LLMClient:
|
|
45
58
|
"model": self.model_name,
|
46
59
|
"temperature": self.temperature,
|
47
60
|
"max_tokens": self.max_tokens,
|
48
|
-
"top_p":
|
49
|
-
"top_k":
|
50
|
-
"frequency_penalty":
|
61
|
+
"top_p": self.top_p,
|
62
|
+
"top_k": self.top_k,
|
63
|
+
"frequency_penalty": self.frequency_penalty,
|
51
64
|
"stream": self.stream,
|
52
65
|
"enable_thinking": self.thinking,
|
53
66
|
"thinking_budget": self.thinking_budget
|
ctools/ai/tools/json_extract.py
CHANGED
@@ -5,6 +5,9 @@ __date__ = '2025/5/19 16:45'
|
|
5
5
|
|
6
6
|
import re
|
7
7
|
|
8
|
+
from ctools import cjson
|
9
|
+
|
10
|
+
|
8
11
|
def extract_json_from_text(text):
|
9
12
|
"""
|
10
13
|
从混杂文本中提取第一个完整的 JSON 对象
|
@@ -44,3 +47,155 @@ def extract_json_from_text(text):
|
|
44
47
|
|
45
48
|
return None
|
46
49
|
|
50
|
+
if __name__ == '__main__':
|
51
|
+
xx = """
|
52
|
+
<think>
|
53
|
+
|
54
|
+
</think>
|
55
|
+
|
56
|
+
{
|
57
|
+
"sjbs": {
|
58
|
+
"xsbt": "东都公园业主集体信访事件",
|
59
|
+
"sjbh": "202406031234",
|
60
|
+
"jjcd": ["黄"]
|
61
|
+
},
|
62
|
+
"skys": {
|
63
|
+
"zxsj": [
|
64
|
+
{
|
65
|
+
"jqsj": "2024-06-03 09:00",
|
66
|
+
"sjms": "6月3日",
|
67
|
+
"sjlx": ["计划时间"]
|
68
|
+
}
|
69
|
+
],
|
70
|
+
"zxdd": [
|
71
|
+
{
|
72
|
+
"bzdz": "黑龙江省哈尔滨市信访局",
|
73
|
+
"cslx": ["政府机关"]
|
74
|
+
}
|
75
|
+
]
|
76
|
+
},
|
77
|
+
"ssqt": {
|
78
|
+
"qtms": ["哈尔滨市道外区东都公园业主"],
|
79
|
+
"qtgm": ["约5人以上,可能发展至群体性事件"],
|
80
|
+
"qtbq": ["房地产纠纷", "历史遗留问题"],
|
81
|
+
"zztz": ["有核心组织"]
|
82
|
+
},
|
83
|
+
"ryqd": [
|
84
|
+
{
|
85
|
+
"xm": ["杨开亮"],
|
86
|
+
"sfzh": ["2301251968101335**"],
|
87
|
+
"js": ["组织者"],
|
88
|
+
"hjd": ["哈尔滨市宾县满井镇永宁村崔海屯"],
|
89
|
+
"jzd": ["团结镇东都公元一区五栋二单元603"],
|
90
|
+
"lxdh": ["139366789**"],
|
91
|
+
"rybq": ["重点人"],
|
92
|
+
"wlzh": {
|
93
|
+
"wx": [],
|
94
|
+
"qq": []
|
95
|
+
},
|
96
|
+
"gjxx": [
|
97
|
+
{
|
98
|
+
"sj": ["2024-05-28 20:26"],
|
99
|
+
"dd": ["网络群聊"],
|
100
|
+
"xw": ["组织动员"]
|
101
|
+
}
|
102
|
+
]
|
103
|
+
},
|
104
|
+
{
|
105
|
+
"xm": ["孙凤玲"],
|
106
|
+
"sfzh": ["2301041955121712**"],
|
107
|
+
"js": ["积极参与者"],
|
108
|
+
"hjd": ["哈尔滨市道外区迎新街好民居滨港水岸D15栋1单元14层4号"],
|
109
|
+
"jzd": ["道外区陶瓷小区D15-1-1404"],
|
110
|
+
"lxdh": ["17758887348"],
|
111
|
+
"rybq": [],
|
112
|
+
"wlzh": {
|
113
|
+
"wx": [],
|
114
|
+
"qq": []
|
115
|
+
},
|
116
|
+
"gjxx": [
|
117
|
+
{
|
118
|
+
"sj": ["2024-05-28 19:00"],
|
119
|
+
"dd": ["网络群聊"],
|
120
|
+
"xw": ["响应组织"]
|
121
|
+
}
|
122
|
+
]
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"xm": ["高秀艳"],
|
126
|
+
"sfzh": ["2323261982060762**"],
|
127
|
+
"js": ["积极参与者"],
|
128
|
+
"hjd": ["绥化市青冈县劳动乡北斗村丛喜云屯"],
|
129
|
+
"jzd": ["哈尔滨市道外区团结镇森桐木业"],
|
130
|
+
"lxdh": ["15846349146"],
|
131
|
+
"rybq": [],
|
132
|
+
"wlzh": {
|
133
|
+
"wx": [],
|
134
|
+
"qq": []
|
135
|
+
},
|
136
|
+
"gjxx": [
|
137
|
+
{
|
138
|
+
"sj": ["2024-05-28 20:00"],
|
139
|
+
"dd": ["网络群聊"],
|
140
|
+
"xw": ["响应组织"]
|
141
|
+
}
|
142
|
+
]
|
143
|
+
},
|
144
|
+
{
|
145
|
+
"xm": ["高振凤"],
|
146
|
+
"sfzh": ["2323031974103046**"],
|
147
|
+
"js": ["一般参与者"],
|
148
|
+
"hjd": ["绥化市肇东市东发乡夕阳村郭家屯"],
|
149
|
+
"jzd": ["团结镇团结镇东都公园一区七栋一单元101"],
|
150
|
+
"lxdh": ["18004659805"],
|
151
|
+
"rybq": [],
|
152
|
+
"wlzh": {
|
153
|
+
"wx": [],
|
154
|
+
"qq": []
|
155
|
+
},
|
156
|
+
"gjxx": [
|
157
|
+
{
|
158
|
+
"sj": ["2024-05-28 19:30"],
|
159
|
+
"dd": ["网络群聊"],
|
160
|
+
"xw": ["响应组织"]
|
161
|
+
}
|
162
|
+
]
|
163
|
+
},
|
164
|
+
{
|
165
|
+
"xm": ["陈立军"],
|
166
|
+
"sfzh": ["2301251980031907**"],
|
167
|
+
"js": ["组织者", "群主"],
|
168
|
+
"hjd": ["哈尔滨市宾县宾西镇一委六组"],
|
169
|
+
"jzd": [],
|
170
|
+
"lxdh": ["15776806667"],
|
171
|
+
"rybq": ["重点人"],
|
172
|
+
"wlzh": {
|
173
|
+
"wx": [],
|
174
|
+
"qq": []
|
175
|
+
},
|
176
|
+
"gjxx": [
|
177
|
+
{
|
178
|
+
"sj": ["2024-05-28 19:00"],
|
179
|
+
"dd": ["网络群聊"],
|
180
|
+
"xw": ["组织动员"]
|
181
|
+
}
|
182
|
+
]
|
183
|
+
}
|
184
|
+
],
|
185
|
+
"sjtz": {
|
186
|
+
"xwlx": ["集体信访", "网络串联"],
|
187
|
+
"sqnr": ["要求政府解决房产证办理问题,明确责任主体并推动政策落实"],
|
188
|
+
"dktz": [],
|
189
|
+
"zjly": ["自筹"]
|
190
|
+
},
|
191
|
+
"czjy": {
|
192
|
+
"zrdw": ["哈尔滨市公安局道外分局", "信访维稳专班"],
|
193
|
+
"yjcs": ["提前约谈重点人员", "加强网络群组监控", "部署现场警力"]
|
194
|
+
}
|
195
|
+
}
|
196
|
+
20250603142141-INFO-8399134464-web_log(log:214) 127.0.0.1 [03/Jun/2025:14:18:39 +0800] "POST /chat/completion HTTP/1.1" 200 3670 "-" "python-requests/2.32.3"
|
197
|
+
|
198
|
+
|
199
|
+
"""
|
200
|
+
|
201
|
+
print((cjson.dumps(extract_json_from_text(xx))))
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
__author__ = 'haoyang'
|
4
|
+
__date__ = '2025/6/3 14:30'
|
5
|
+
|
6
|
+
import re
|
7
|
+
|
8
|
+
|
9
|
+
def remove_think_blocks(text: str) -> str:
|
10
|
+
cleaned_text = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL)
|
11
|
+
return cleaned_text.strip()
|
@@ -9,13 +9,20 @@ def parse_tool_use(xml_string):
|
|
9
9
|
root = ET.fromstring(xml_string.strip())
|
10
10
|
if root.tag != "tool_use": raise ValueError("根标签必须是 <tool_use>")
|
11
11
|
tool_name = root.find("name").text.strip()
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
args = root.find("arguments").text
|
13
|
+
if args:
|
14
|
+
arguments_text = args.strip()
|
15
|
+
arguments_text = html.unescape(arguments_text)
|
16
|
+
arguments = json.loads(arguments_text)
|
17
|
+
return {
|
18
|
+
"tool": tool_name,
|
19
|
+
"arguments": arguments
|
20
|
+
}
|
21
|
+
else:
|
22
|
+
return {
|
23
|
+
"tool": tool_name,
|
24
|
+
"arguments": {}
|
25
|
+
}
|
19
26
|
except Exception as e:
|
20
27
|
raise ValueError(f"tool_use_{tool_name} 解析失败: {e}")
|
21
28
|
|
ctools/aio_web_server.py
CHANGED
@@ -5,17 +5,30 @@
|
|
5
5
|
__author__ = 'haoyang'
|
6
6
|
__date__ = '2025/5/30 09:54'
|
7
7
|
|
8
|
-
import asyncio
|
9
8
|
import sys
|
10
9
|
from pathlib import Path
|
11
10
|
from typing import Optional, Dict, Any
|
12
11
|
|
13
12
|
from aiohttp import web
|
14
13
|
|
15
|
-
from ctools import sys_info
|
14
|
+
from ctools import sys_info, cjson
|
15
|
+
from ctools.api_result import R
|
16
16
|
|
17
17
|
DEFAULT_PORT = 8888
|
18
18
|
|
19
|
+
@web.middleware
|
20
|
+
async def response_wrapper_middleware(request, handler):
|
21
|
+
try:
|
22
|
+
result = await handler(request)
|
23
|
+
if isinstance(result, web.Response):
|
24
|
+
return result
|
25
|
+
elif isinstance(result, str):
|
26
|
+
return web.Response(text=result)
|
27
|
+
else:
|
28
|
+
return web.Response(text=cjson.dumps(result))
|
29
|
+
except Exception as e:
|
30
|
+
return web.json_response(text=R.error(str(e)), status=200)
|
31
|
+
|
19
32
|
class AioHttpServer:
|
20
33
|
def __init__(self, port: int = DEFAULT_PORT, app: Optional[web.Application] = None, routes: Optional[web.RouteTableDef] = None, async_func = None):
|
21
34
|
"""
|
@@ -25,7 +38,7 @@ class AioHttpServer:
|
|
25
38
|
port: Port number to listen on
|
26
39
|
app: Optional existing aiohttp Application instance
|
27
40
|
"""
|
28
|
-
self.app = app or web.Application()
|
41
|
+
self.app = app or web.Application(middlewares=[response_wrapper_middleware])
|
29
42
|
self.port = port
|
30
43
|
self.index_root = Path('./')
|
31
44
|
self.index_filename = 'index.html'
|
@@ -58,7 +71,6 @@ class AioHttpServer:
|
|
58
71
|
return web.HTTPNotFound()
|
59
72
|
|
60
73
|
if self.is_tpl:
|
61
|
-
# If using templates, you might want to use a template engine here
|
62
74
|
return web.FileResponse(
|
63
75
|
index_path,
|
64
76
|
headers={'Content-Type': 'text/html'}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: gomyck-tools
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.7
|
4
4
|
Summary: A tools collection for python development by hao474798383
|
5
5
|
Author-email: gomyck <hao474798383@163.com>
|
6
6
|
License-Expression: Apache-2.0
|
@@ -33,7 +33,9 @@ Provides-Extra: db
|
|
33
33
|
Requires-Dist: sqlalchemy>=2.0; extra == "db"
|
34
34
|
Requires-Dist: asyncpg>=0.28; extra == "db"
|
35
35
|
Provides-Extra: office
|
36
|
-
Requires-Dist:
|
36
|
+
Requires-Dist: pandas>=2.2.3; extra == "office"
|
37
|
+
Requires-Dist: xlrd>=2.0.1; extra == "office"
|
38
|
+
Requires-Dist: python-docx>=1.1.2; extra == "office"
|
37
39
|
Provides-Extra: auto-ui
|
38
40
|
Requires-Dist: pynput==1.7.7; extra == "auto-ui"
|
39
41
|
Dynamic: license-file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
ctools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
ctools/aes_tools.py,sha256=L5Jg4QtVTdIxHe9zEpR8oMQx0IrYK68vjEYb_RmkhPA,699
|
3
|
-
ctools/aio_web_server.py,sha256=
|
3
|
+
ctools/aio_web_server.py,sha256=W4vqHBr4VxaKppRmotyRamOf59f0WU6iYQHGqKFvPJs,4746
|
4
4
|
ctools/api_result.py,sha256=UeQXI_zuZB-uY5qECTpz1fC7EGy82yGQqWMx20tyRTw,1572
|
5
5
|
ctools/application.py,sha256=DcuSt2m8cDuSftx6eKfJ5gA6_F9dDlzkj0K86EG4F7s,15884
|
6
6
|
ctools/b64.py,sha256=_BdhX3p3-MaSSlU2wivN5qPxQfacR3VRBr1WC456tU0,194
|
@@ -60,16 +60,17 @@ ctools/word_fill_entity.py,sha256=eX3G0Gy16hfGpavQSEkCIoKDdTnNgRRJrFvKliETZK8,98
|
|
60
60
|
ctools/work_path.py,sha256=OmfYu-Jjg2huRY6Su8zJ_2EGFFhtBZFbobYTwbjJtG4,1817
|
61
61
|
ctools/ai/__init__.py,sha256=gTYAICILq48icnFbg0HCbsQO8PbU02EDOQ0JeMvfqTY,98
|
62
62
|
ctools/ai/env_config.py,sha256=hOuDVjyK00Ioq1G2z9Plf20TQha0tMV-VHWKAeCv16s,990
|
63
|
-
ctools/ai/llm_chat.py,sha256=
|
64
|
-
ctools/ai/llm_client.py,sha256=
|
63
|
+
ctools/ai/llm_chat.py,sha256=xcjk9ALp9GfTlcHGCMOTYi7MuWoBFB73bmKAL9NedfY,8433
|
64
|
+
ctools/ai/llm_client.py,sha256=Zqizex4Umozqtfh__-wdgNu8p66Bl9iv6cLbNUGyRF8,5098
|
65
65
|
ctools/ai/mcp/__init__.py,sha256=gTYAICILq48icnFbg0HCbsQO8PbU02EDOQ0JeMvfqTY,98
|
66
66
|
ctools/ai/mcp/mcp_client.py,sha256=HLoGN-yCL5vMxwxcZMmXQyWof-nmp1KjrPrXQ46KGQs,11525
|
67
67
|
ctools/ai/tools/__init__.py,sha256=gPc-ViRgtFlfX7JUbk5wQZ3wkJ5Ylh14CIqPwa83VPs,98
|
68
|
-
ctools/ai/tools/json_extract.py,sha256=
|
69
|
-
ctools/ai/tools/
|
68
|
+
ctools/ai/tools/json_extract.py,sha256=bgubZ2RwTo_R1X0CzMnvBWu61hglB1l6oO553645RXc,4842
|
69
|
+
ctools/ai/tools/think_process.py,sha256=RGU9j3_O328Byw05ILek-aMfFBczbly2RA-QRouqUjM,257
|
70
|
+
ctools/ai/tools/tool_use_xml_parse.py,sha256=zpHKMhU5LFSpuznU_Z5w_HHp-Bney-Te8DxoU1BNHZ0,1429
|
70
71
|
ctools/ai/tools/xml_extract.py,sha256=KTzsrJZDKmpJ-92yTO6z5nJ9a183ngF6ikTb4oiIjW4,246
|
71
|
-
gomyck_tools-1.3.
|
72
|
-
gomyck_tools-1.3.
|
73
|
-
gomyck_tools-1.3.
|
74
|
-
gomyck_tools-1.3.
|
75
|
-
gomyck_tools-1.3.
|
72
|
+
gomyck_tools-1.3.7.dist-info/licenses/LICENSE,sha256=X25ypfH9E6VTht2hcO8k7LCSdHUcoG_ALQt80jdYZfY,547
|
73
|
+
gomyck_tools-1.3.7.dist-info/METADATA,sha256=VFfjvXYkg1-Pfwksb08fqdFftCuNd4sjJTWwpAVcaOo,1595
|
74
|
+
gomyck_tools-1.3.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
75
|
+
gomyck_tools-1.3.7.dist-info/top_level.txt,sha256=-MiIH9FYRVKp1i5_SVRkaI-71WmF1sZSRrNWFU9ls3s,7
|
76
|
+
gomyck_tools-1.3.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|