pycoze 0.1.239__py3-none-any.whl → 0.1.241__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/bot/agent/agent.py +3 -2
- pycoze/bot/agent/agent_types/openai_func_call_agent.py +50 -2
- pycoze/bot/agent/assistant.py +2 -1
- pycoze/bot/agent_chat.py +22 -6
- pycoze/bot/bot.py +1 -0
- {pycoze-0.1.239.dist-info → pycoze-0.1.241.dist-info}/METADATA +1 -1
- {pycoze-0.1.239.dist-info → pycoze-0.1.241.dist-info}/RECORD +10 -13
- pycoze/automation/__init__.py +0 -0
- pycoze/automation/browser/__init__.py +0 -0
- pycoze/automation/browser/edge_driver_manager.py +0 -77
- {pycoze-0.1.239.dist-info → pycoze-0.1.241.dist-info}/LICENSE +0 -0
- {pycoze-0.1.239.dist-info → pycoze-0.1.241.dist-info}/WHEEL +0 -0
- {pycoze-0.1.239.dist-info → pycoze-0.1.241.dist-info}/top_level.txt +0 -0
pycoze/bot/agent/agent.py
CHANGED
@@ -13,7 +13,7 @@ from langchain_core.agents import AgentFinish
|
|
13
13
|
from .agent_types.const import HumanToolString
|
14
14
|
|
15
15
|
|
16
|
-
async def run_agent(agent, inputs: list):
|
16
|
+
async def run_agent(agent, inputs: list, tool_compatibility_mode: bool):
|
17
17
|
exist_ids = set()
|
18
18
|
content_list = []
|
19
19
|
async for event in agent.astream_events(inputs, version="v2"):
|
@@ -29,7 +29,7 @@ async def run_agent(agent, inputs: list):
|
|
29
29
|
input_list = event["data"]["input"]
|
30
30
|
for msg in input_list:
|
31
31
|
if isinstance(msg, HumanMessage) or isinstance(msg, SystemMessage):
|
32
|
-
if not msg.content.startswith(HumanToolString):
|
32
|
+
if not tool_compatibility_mode or not msg.content.startswith(HumanToolString):
|
33
33
|
content_list = [] # 防止内容重复
|
34
34
|
if isinstance(msg, AIMessage) and not isinstance(
|
35
35
|
msg, AIMessageChunk
|
@@ -84,6 +84,7 @@ if __name__ == "__main__":
|
|
84
84
|
tools=[python_tool],
|
85
85
|
llm=chat,
|
86
86
|
assistant_message="请以女友的口吻回答,输出不小于100字,可以随便说点其他的",
|
87
|
+
tool_compatibility_mode=False,
|
87
88
|
)
|
88
89
|
|
89
90
|
inputs = [HumanMessage(content="计算根号7+根号88")]
|
@@ -34,13 +34,48 @@ def get_tools(last_message):
|
|
34
34
|
if "tool_calls" in last_message.additional_kwargs:
|
35
35
|
return last_message.additional_kwargs["tool_calls"]
|
36
36
|
else:
|
37
|
-
|
37
|
+
tool_calls = None
|
38
|
+
if '"name"' in last_message.content and '"parameters":' in last_message.content:
|
39
|
+
print("name 和 paremeters 模式")
|
40
|
+
all_json = get_all_markdown_json(last_message.content)
|
41
|
+
tool_calls = []
|
42
|
+
for tool_call in all_json:
|
43
|
+
if "name" not in tool_call or "parameters" not in tool_call:
|
44
|
+
return "end"
|
45
|
+
tool_call["arguments"] = json.dumps(tool_call["parameters"])
|
46
|
+
tool_call.pop("parameters")
|
47
|
+
tool_calls.append(
|
48
|
+
{
|
49
|
+
"function": tool_call,
|
50
|
+
"id": random.randint(0, 1000000),
|
51
|
+
}
|
52
|
+
)
|
53
|
+
if "<|tool▁sep|>" in last_message.content:
|
54
|
+
print("deepseek的bug: <|tool▁sep|> 模式")
|
55
|
+
name = (
|
56
|
+
last_message.content.split("<|tool▁sep|>")[1].split("```")[0].strip()
|
57
|
+
)
|
58
|
+
all_json = get_all_markdown_json(last_message.content)
|
59
|
+
tool_calls = []
|
60
|
+
for argument in all_json:
|
61
|
+
tool_calls.append(
|
62
|
+
{
|
63
|
+
"function": {
|
64
|
+
"name": name,
|
65
|
+
"arguments": json.dumps(argument),
|
66
|
+
},
|
67
|
+
"id": random.randint(0, 1000000),
|
68
|
+
}
|
69
|
+
)
|
70
|
+
|
71
|
+
return tool_calls
|
38
72
|
|
39
73
|
|
40
74
|
def create_openai_func_call_agent_executor(
|
41
75
|
tools: list[BaseTool],
|
42
76
|
llm: LanguageModelLike,
|
43
77
|
system_message: str,
|
78
|
+
tool_compatibility_mode: str,
|
44
79
|
**kwargs
|
45
80
|
):
|
46
81
|
|
@@ -86,6 +121,14 @@ def create_openai_func_call_agent_executor(
|
|
86
121
|
for tool_call in get_tools(last_message):
|
87
122
|
function = tool_call["function"]
|
88
123
|
function_name = function["name"]
|
124
|
+
if function_name == "a_delay_function":
|
125
|
+
return [
|
126
|
+
ToolMessage(
|
127
|
+
tool_call_id=tool_call["id"],
|
128
|
+
content="a_delay_function只是一个占位符,请忽略重新调用工具",
|
129
|
+
additional_kwargs={"name": tool_call["function"]["name"]},
|
130
|
+
)
|
131
|
+
]
|
89
132
|
|
90
133
|
_tool_input = json.loads(function["arguments"] or "{}")
|
91
134
|
# We construct an ToolInvocation from the function_call
|
@@ -113,7 +156,12 @@ def create_openai_func_call_agent_executor(
|
|
113
156
|
additional_kwargs={"name": tool_call["function"]["name"]},
|
114
157
|
)
|
115
158
|
tool_messages.append(message)
|
116
|
-
|
159
|
+
if tool_compatibility_mode:
|
160
|
+
# HumanMessage
|
161
|
+
tool_msgs_str = repr(tool_messages)
|
162
|
+
tool_messages = [
|
163
|
+
HumanMessage(content=HumanToolString + tool_msgs_str)
|
164
|
+
]
|
117
165
|
return tool_messages
|
118
166
|
|
119
167
|
workflow = MessageGraph()
|
pycoze/bot/agent/assistant.py
CHANGED
@@ -18,10 +18,11 @@ class Runnable(RunnableBinding):
|
|
18
18
|
tools: Sequence[BaseTool],
|
19
19
|
llm: LanguageModelLike,
|
20
20
|
assistant_message: str,
|
21
|
+
tool_compatibility_mode: bool
|
21
22
|
) -> None:
|
22
23
|
|
23
24
|
agent_executor = create_openai_func_call_agent_executor(
|
24
|
-
tools, llm, assistant_message
|
25
|
+
tools, llm, assistant_message, tool_compatibility_mode
|
25
26
|
)
|
26
27
|
agent_executor = agent_executor.with_config({"recursion_limit": 50})
|
27
28
|
super().__init__(
|
pycoze/bot/agent_chat.py
CHANGED
@@ -11,7 +11,6 @@ import os
|
|
11
11
|
|
12
12
|
cfg = utils.read_json_file("llm.json")
|
13
13
|
|
14
|
-
|
15
14
|
def load_role_setting(bot_setting_file: str):
|
16
15
|
with open(bot_setting_file, "r", encoding="utf-8") as f:
|
17
16
|
return json.load(f)
|
@@ -43,10 +42,10 @@ async def check_interrupt_file(interval, interrupt_file,agent_task):
|
|
43
42
|
agent_task.cancel()
|
44
43
|
break
|
45
44
|
|
46
|
-
async def run_with_interrupt_check(agent, history, interrupt_file, check_interval=1):
|
45
|
+
async def run_with_interrupt_check(agent, history, tool_compatibility_mode, interrupt_file, check_interval=1):
|
47
46
|
clear_chat_data()
|
48
47
|
try:
|
49
|
-
agent_task = asyncio.create_task(run_agent(agent, history))
|
48
|
+
agent_task = asyncio.create_task(run_agent(agent, history, tool_compatibility_mode))
|
50
49
|
check_task = asyncio.create_task(check_interrupt_file(check_interval, interrupt_file, agent_task))
|
51
50
|
result = await agent_task
|
52
51
|
return result
|
@@ -86,18 +85,35 @@ async def agent_chat(bot_setting_file, history):
|
|
86
85
|
], # 停用deepseek的工具调用标记,不然会虚构工具调用过程和结果
|
87
86
|
)
|
88
87
|
prompt = role_setting["prompt"]
|
89
|
-
|
88
|
+
if (
|
89
|
+
(cfg["model"].startswith("deepseek")
|
90
|
+
or cfg["toolCompatibilityMode"])
|
91
|
+
and len(abilities) > 0
|
92
|
+
):
|
93
|
+
prompt += """
|
94
|
+
作为一个AI,你如果不确定结果,请务必使用工具查询。
|
95
|
+
你可以通过下面的方式使用工具,并耐心等待工具返回结果。
|
96
|
+
如果你需要调用工具,请使用以正确markdown中的json代码格式进行结尾(务必保证json格式正确,不要出现反斜杠未转义等问题):
|
97
|
+
```json
|
98
|
+
{"name": 函数名, "parameters": 参数词典}
|
99
|
+
```
|
100
|
+
"""
|
101
|
+
if cfg["model"].startswith("yi-"):
|
102
|
+
prompt += "\nAvailable functions:\n"
|
103
|
+
for t in abilities:
|
104
|
+
prompt += f"\n```json\n{json.dumps(convert_to_openai_tool(t))}\n```"
|
90
105
|
agent = Runnable(
|
91
106
|
agent_execution_mode="FuncCall",
|
92
107
|
tools=abilities,
|
93
108
|
llm=chat,
|
94
109
|
assistant_message=prompt,
|
110
|
+
tool_compatibility_mode=cfg["toolCompatibilityMode"],
|
95
111
|
)
|
96
112
|
params = utils.read_params_file()
|
97
113
|
if "interruptFile" in params:
|
98
114
|
interrupt_file_path = params["interruptFile"]
|
99
|
-
result = await run_with_interrupt_check(agent, history,interrupt_file_path)
|
115
|
+
result = await run_with_interrupt_check(agent, history, cfg["toolCompatibilityMode"], interrupt_file_path)
|
100
116
|
else:
|
101
|
-
result = await run_agent(agent, history)
|
117
|
+
result = await run_agent(agent, history, cfg["toolCompatibilityMode"])
|
102
118
|
return result
|
103
119
|
|
pycoze/bot/bot.py
CHANGED
@@ -5,19 +5,16 @@ pycoze/ai/llm/__init__.py,sha256=kAXcQ7SefJYysgKeVInlwYZoDk0BPuEnUuixy-quD_A,127
|
|
5
5
|
pycoze/ai/llm/chat.py,sha256=izriC7nCp5qeJRqcUVQBVqTHiH6MJS77ROzGBJufdNI,5133
|
6
6
|
pycoze/ai/llm/text_to_image_prompt.py,sha256=0bx2C_YRvjAo7iphHGp1-pmGKsKqwur7dM0t3SiA8kA,3398
|
7
7
|
pycoze/ai/llm/think.py,sha256=sUgTBdGzcZtL3r-Wx8M3lDuVUmDVz8g3qC0VU8uiKAI,5143
|
8
|
-
pycoze/automation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
pycoze/automation/browser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
pycoze/automation/browser/edge_driver_manager.py,sha256=gpgseunph5owZH6EskSYthuhey2SU3UP204gY0yIcuI,3022
|
11
8
|
pycoze/bot/__init__.py,sha256=6HHMxDQVOyZM9dtSjQm9tjGnhj4h7CixD0JOvEwTi48,41
|
12
|
-
pycoze/bot/agent_chat.py,sha256=
|
13
|
-
pycoze/bot/bot.py,sha256=
|
9
|
+
pycoze/bot/agent_chat.py,sha256=jRtPko2OfCkfzSTkJaI62oaBojmkHu-ZUwlZrxCIl8I,4498
|
10
|
+
pycoze/bot/bot.py,sha256=fmcgnWcYTFeOxDuAwqWhFhOJzv4mAyJGLqbod-nkhJE,862
|
14
11
|
pycoze/bot/agent/__init__.py,sha256=3wE8_FFQS8j2BY-g9Cr-onV0POEvDRZaw_NCzpqrNus,265
|
15
|
-
pycoze/bot/agent/agent.py,sha256=
|
16
|
-
pycoze/bot/agent/assistant.py,sha256=
|
12
|
+
pycoze/bot/agent/agent.py,sha256=chUgNZh6v6375L_Y2dBEAaLJyfmw4SygYjVVrDN8VIk,3548
|
13
|
+
pycoze/bot/agent/assistant.py,sha256=3iLxnRvf_ia0cP-FHK5Fv4ylltlnzPq1KscRCFYqjkc,1147
|
17
14
|
pycoze/bot/agent/chat.py,sha256=mubOCAHvA6VtyE6N40elI6KrP6A69uB_G6ihE3G_Vi4,860
|
18
15
|
pycoze/bot/agent/agent_types/__init__.py,sha256=zmU2Kmrv5mCdfg-QlPn2H6pWxbGeq8s7YTqLhpzJC6k,179
|
19
16
|
pycoze/bot/agent/agent_types/const.py,sha256=BfUKPrhAHREoMLHuFNG2bCIEkC1-f7K0LEqNg4RwiRE,70
|
20
|
-
pycoze/bot/agent/agent_types/openai_func_call_agent.py,sha256=
|
17
|
+
pycoze/bot/agent/agent_types/openai_func_call_agent.py,sha256=SnEm5MODHn2uMsaMNqgzULM_91vqLHC0TU6ovwCOqLU,6675
|
21
18
|
pycoze/reference/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
19
|
pycoze/reference/bot.py,sha256=BDflTV3zYoZqWnJpD5lMM_1vU_5b20M3XiFt1p-RHWM,2427
|
23
20
|
pycoze/reference/lib.py,sha256=0xQJTLTHedGzQBsjuTFNBVqYc4-8Yl65gGCrAhWyOX8,2155
|
@@ -32,8 +29,8 @@ pycoze/utils/__init__.py,sha256=Gi5EnrWZGMD2JRejgV4c_VLCXyvA2wwBFI_niDF5MUE,110
|
|
32
29
|
pycoze/utils/arg.py,sha256=GtfGbMTMdaK75Fwh6MpUe1pCA5X6Ep4LFG7a72YrzjI,525
|
33
30
|
pycoze/utils/env.py,sha256=W04lhvTHhAAC6EldP6kk2xrctqtu8K6kl1vDLZDNeh8,561
|
34
31
|
pycoze/utils/text_or_file.py,sha256=gpxZVWt2DW6YiEg_MnMuwg36VNf3TX383QD_1oZNB0Y,551
|
35
|
-
pycoze-0.1.
|
36
|
-
pycoze-0.1.
|
37
|
-
pycoze-0.1.
|
38
|
-
pycoze-0.1.
|
39
|
-
pycoze-0.1.
|
32
|
+
pycoze-0.1.241.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
|
33
|
+
pycoze-0.1.241.dist-info/METADATA,sha256=eBnfm6cgiBHsRSIf7Il-Lj4oK4R9xAD4b6eu8DyHx8c,699
|
34
|
+
pycoze-0.1.241.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
35
|
+
pycoze-0.1.241.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
|
36
|
+
pycoze-0.1.241.dist-info/RECORD,,
|
pycoze/automation/__init__.py
DELETED
File without changes
|
File without changes
|
@@ -1,77 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import requests
|
3
|
-
from selenium.webdriver.edge.service import Service
|
4
|
-
from webdriver_manager.microsoft import EdgeChromiumDriverManager
|
5
|
-
from selenium import webdriver
|
6
|
-
|
7
|
-
|
8
|
-
# Function to check network availability
|
9
|
-
def is_network_available():
|
10
|
-
try:
|
11
|
-
# Attempt to access the download URL for Edge Chromium driver to check network connection
|
12
|
-
response = requests.get("https://msedgedriver.azureedge.net/", timeout=3)
|
13
|
-
return response.status_code == 200
|
14
|
-
except requests.ConnectionError:
|
15
|
-
return False
|
16
|
-
|
17
|
-
|
18
|
-
# Function to get the default download path for Edge Chromium driver
|
19
|
-
def get_default_driver_path():
|
20
|
-
manager = EdgeChromiumDriverManager()
|
21
|
-
return manager.install()
|
22
|
-
|
23
|
-
|
24
|
-
# Function to get the driver version from cache
|
25
|
-
def get_cached_driver_version(manager):
|
26
|
-
cache_dir = manager._cache_manager._root_dir # Get the root path of the cache directory
|
27
|
-
os_type = manager._os_system_manager.get_os_type() # Get the OS type
|
28
|
-
driver_name = manager.driver.get_name()
|
29
|
-
|
30
|
-
# List all versions in the cache directory
|
31
|
-
versions_dir = os.path.join(cache_dir, "drivers", driver_name, os_type)
|
32
|
-
if os.path.exists(versions_dir):
|
33
|
-
versions = os.listdir(versions_dir)
|
34
|
-
if versions:
|
35
|
-
# Return the latest version found in the cache
|
36
|
-
return max(versions)
|
37
|
-
return None
|
38
|
-
|
39
|
-
|
40
|
-
# Function to check if the driver has already been downloaded
|
41
|
-
def get_driver_path():
|
42
|
-
network_available = is_network_available()
|
43
|
-
print("Network status:", "Available" if network_available else "Unavailable")
|
44
|
-
manager = EdgeChromiumDriverManager()
|
45
|
-
if network_available:
|
46
|
-
return get_default_driver_path()
|
47
|
-
else:
|
48
|
-
# If no network, check the cache directory
|
49
|
-
driver_version = get_cached_driver_version(manager)
|
50
|
-
if driver_version:
|
51
|
-
driver_name = manager.driver.get_name()
|
52
|
-
os_type = manager._os_system_manager.get_os_type()
|
53
|
-
cache_dir = manager._cache_manager._root_dir
|
54
|
-
|
55
|
-
# Determine the correct driver filename based on the OS
|
56
|
-
if os.name == 'nt': # Windows
|
57
|
-
driver_filename = "msedgedriver.exe"
|
58
|
-
else: # macOS and Linux
|
59
|
-
driver_filename = "msedgedriver"
|
60
|
-
|
61
|
-
# Construct the driver path
|
62
|
-
driver_path = os.path.join(cache_dir, "drivers", driver_name, os_type, driver_version, driver_filename)
|
63
|
-
# Check if the driver path exists
|
64
|
-
if os.path.exists(driver_path):
|
65
|
-
return driver_path
|
66
|
-
raise Exception("Network unavailable and no downloaded driver found")
|
67
|
-
|
68
|
-
|
69
|
-
# Function to get the Edge driver service
|
70
|
-
def get_edge_driver_service():
|
71
|
-
driver_path = get_driver_path()
|
72
|
-
print("driver_path", driver_path)
|
73
|
-
# Check if the driver path exists
|
74
|
-
if os.path.exists(driver_path):
|
75
|
-
return Service(driver_path)
|
76
|
-
else:
|
77
|
-
raise Exception("Network unavailable and no downloaded driver found")
|
File without changes
|
File without changes
|
File without changes
|