pycoze 0.1.239__tar.gz → 0.1.241__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pycoze-0.1.239 → pycoze-0.1.241}/PKG-INFO +1 -1
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/agent.py +3 -2
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/agent_types/openai_func_call_agent.py +50 -2
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/assistant.py +2 -1
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent_chat.py +22 -6
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/bot.py +1 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze.egg-info/PKG-INFO +1 -1
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze.egg-info/SOURCES.txt +0 -3
- {pycoze-0.1.239 → pycoze-0.1.241}/setup.py +1 -1
- pycoze-0.1.239/pycoze/automation/browser/__init__.py +0 -0
- pycoze-0.1.239/pycoze/automation/browser/edge_driver_manager.py +0 -77
- pycoze-0.1.239/pycoze/reference/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/LICENSE +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/README.md +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ai/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ai/llm/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ai/llm/chat.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ai/llm/text_to_image_prompt.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ai/llm/think.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ai/vram_reserve.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/agent_types/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/agent_types/const.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/bot/agent/chat.py +0 -0
- {pycoze-0.1.239/pycoze/automation → pycoze-0.1.241/pycoze/reference}/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/reference/bot.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/reference/lib.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/reference/tool.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/reference/workflow.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ui/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ui/base.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ui/color.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ui/typ.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/ui/ui_def.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/utils/__init__.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/utils/arg.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/utils/env.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze/utils/text_or_file.py +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze.egg-info/dependency_links.txt +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/pycoze.egg-info/top_level.txt +0 -0
- {pycoze-0.1.239 → pycoze-0.1.241}/setup.cfg +0 -0
@@ -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()
|
@@ -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__(
|
@@ -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
|
|
@@ -12,9 +12,6 @@ pycoze/ai/llm/__init__.py
|
|
12
12
|
pycoze/ai/llm/chat.py
|
13
13
|
pycoze/ai/llm/text_to_image_prompt.py
|
14
14
|
pycoze/ai/llm/think.py
|
15
|
-
pycoze/automation/__init__.py
|
16
|
-
pycoze/automation/browser/__init__.py
|
17
|
-
pycoze/automation/browser/edge_driver_manager.py
|
18
15
|
pycoze/bot/__init__.py
|
19
16
|
pycoze/bot/agent_chat.py
|
20
17
|
pycoze/bot/bot.py
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|