pycoze 0.1.10__tar.gz → 0.1.19__tar.gz
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-0.1.10 → pycoze-0.1.19}/PKG-INFO +1 -1
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/__init__.py +4 -3
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/agent.py +72 -67
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/agent_types/react_agent.py +3 -3
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/base.py +81 -79
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/bot.py +54 -50
- pycoze-0.1.19/pycoze/gpu/__init__.py +1 -0
- pycoze-0.1.19/pycoze/gpu/gpu_reserve.py +167 -0
- pycoze-0.1.19/pycoze/ui/ui_def.py +167 -0
- pycoze-0.1.19/pycoze/utils/__init__.py +1 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze.egg-info/PKG-INFO +1 -1
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze.egg-info/SOURCES.txt +2 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/setup.py +19 -19
- pycoze-0.1.10/pycoze/ui/ui_def.py +0 -110
- pycoze-0.1.10/pycoze/utils/__init__.py +0 -1
- {pycoze-0.1.10 → pycoze-0.1.19}/LICENSE +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/README.md +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/__init__.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/__init__.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/agent_types/__init__.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/agent_types/openai_func_call_agent.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/agent_types/react_prompt.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/assistant.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/bot/agent/chat.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/module.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/ui/__init__.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/ui/base.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/ui/color.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/ui/typ.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze/utils/arg.py +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze.egg-info/dependency_links.txt +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/pycoze.egg-info/top_level.txt +0 -0
- {pycoze-0.1.10 → pycoze-0.1.19}/setup.cfg +0 -0
@@ -1,3 +1,4 @@
|
|
1
|
-
from . import bot
|
2
|
-
from . import
|
3
|
-
from . import ui
|
1
|
+
from . import bot
|
2
|
+
from . import gpu
|
3
|
+
from . import ui
|
4
|
+
from . import utils
|
@@ -1,67 +1,72 @@
|
|
1
|
-
import asyncio
|
2
|
-
import json
|
3
|
-
from langchain_openai import ChatOpenAI
|
4
|
-
from .chat import info
|
5
|
-
from .assistant import Runnable
|
6
|
-
from langchain_core.messages import HumanMessage, AIMessage,AIMessageChunk
|
7
|
-
from langchain_core.agents import AgentFinish
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
async def run_agent(agent, inputs: list):
|
12
|
-
if agent.agent_execution_mode == 'FuncCall':
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
1
|
+
import asyncio
|
2
|
+
import json
|
3
|
+
from langchain_openai import ChatOpenAI
|
4
|
+
from .chat import info
|
5
|
+
from .assistant import Runnable
|
6
|
+
from langchain_core.messages import HumanMessage, AIMessage,AIMessageChunk
|
7
|
+
from langchain_core.agents import AgentFinish
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
async def run_agent(agent, inputs: list):
|
12
|
+
if agent.agent_execution_mode == 'FuncCall':
|
13
|
+
exist_ids = set()
|
14
|
+
content_list = []
|
15
|
+
async for event in agent.astream_events(inputs, version="v2"):
|
16
|
+
kind = event["event"]
|
17
|
+
if kind == "on_chat_model_stream":
|
18
|
+
content = event["data"]["chunk"].content
|
19
|
+
if content:
|
20
|
+
content_list.append(content)
|
21
|
+
info("assistant", content)
|
22
|
+
elif kind == "on_chain_start":
|
23
|
+
data = event["data"]
|
24
|
+
if "input" in data:
|
25
|
+
input_list = data["input"] if isinstance(data["input"], list) else [data["input"]]
|
26
|
+
msg = input_list[-1]
|
27
|
+
if isinstance(msg, AIMessage) and not isinstance(msg, AIMessageChunk):
|
28
|
+
if "tool_calls" in msg.additional_kwargs:
|
29
|
+
tool_calls = msg.additional_kwargs["tool_calls"]
|
30
|
+
for t in tool_calls:
|
31
|
+
if t["id"] in exist_ids:
|
32
|
+
continue
|
33
|
+
exist_ids.add(t["id"])
|
34
|
+
tool = t["function"]["name"]
|
35
|
+
info("assistant", f"[调用工具:{tool}]")
|
36
|
+
|
37
|
+
return "".join(content_list)
|
38
|
+
else:
|
39
|
+
assert agent.agent_execution_mode == 'ReAct'
|
40
|
+
inputs_msg = {'input': inputs[-1].content,'chat_history': inputs[:-1]}
|
41
|
+
use_tools = []
|
42
|
+
async for event in agent.astream_events(inputs_msg, version="v2"):
|
43
|
+
kind = event["event"]
|
44
|
+
result = None
|
45
|
+
if kind == "on_chain_end":
|
46
|
+
if 'data' in event:
|
47
|
+
if 'output' in event['data']:
|
48
|
+
output = event['data']['output']
|
49
|
+
if 'agent_outcome' in output and "input" in output:
|
50
|
+
outcome = output['agent_outcome']
|
51
|
+
if isinstance(outcome, AgentFinish):
|
52
|
+
result = outcome.return_values['output']
|
53
|
+
elif kind == "on_tool_start":
|
54
|
+
use_tools.append(event['name'])
|
55
|
+
info("assistant", f"[调用工具:{use_tools}]")
|
56
|
+
return result
|
57
|
+
|
58
|
+
|
59
|
+
if __name__ == "__main__":
|
60
|
+
from langchain_experimental.tools import PythonREPLTool
|
61
|
+
llm_file = r"C:\Users\aiqqq\AppData\Roaming\pycoze\JsonStorage\llm.json"
|
62
|
+
with open(llm_file, "r", encoding="utf-8") as f:
|
63
|
+
cfg = json.load(f)
|
64
|
+
chat = ChatOpenAI(api_key=cfg["apiKey"], base_url=cfg['baseURL'], model=cfg["model"], temperature=0)
|
65
|
+
python_tool = PythonREPLTool()
|
66
|
+
agent = Runnable(agent_execution_mode='FuncCall', # 'FuncCall' or 'ReAct',大模型支持FuncCall的话就用FuncCall
|
67
|
+
tools=[python_tool],
|
68
|
+
llm=chat,
|
69
|
+
assistant_message="请以女友的口吻回答,输出不小于100字,可以随便说点其他的",)
|
70
|
+
|
71
|
+
inputs = [HumanMessage(content="计算根号7+根号88")]
|
72
|
+
print(asyncio.run(run_agent(agent, inputs)))
|
@@ -8,15 +8,15 @@ from langchain_core.language_models import LanguageModelLike
|
|
8
8
|
from langgraph.graph import END, StateGraph
|
9
9
|
from langgraph.graph.state import CompiledStateGraph
|
10
10
|
from langgraph.prebuilt.tool_executor import ToolExecutor
|
11
|
-
from langgraph.utils import RunnableCallable
|
11
|
+
from langgraph.utils.runnable import RunnableCallable
|
12
12
|
from langchain.agents import create_structured_chat_agent
|
13
13
|
from .react_prompt import react_agent_prompt
|
14
14
|
|
15
15
|
|
16
16
|
def create_react_agent_executor(
|
17
|
-
tools: list[BaseTool],
|
17
|
+
tools: list[BaseTool],
|
18
18
|
llm: LanguageModelLike,
|
19
|
-
system_message: str,
|
19
|
+
system_message: str,
|
20
20
|
**kwargs # ignore
|
21
21
|
):
|
22
22
|
prompt = react_agent_prompt.partial(assistant_message=system_message)
|
@@ -1,79 +1,81 @@
|
|
1
|
-
import sys
|
2
|
-
import os
|
3
|
-
import argparse
|
4
|
-
import importlib
|
5
|
-
from langchain.agents import tool as _tool
|
6
|
-
import types
|
7
|
-
import langchain_core
|
8
|
-
|
9
|
-
def wrapped_tool(tool, module_path):
|
10
|
-
old_tool_fun = tool.func
|
11
|
-
def _wrapped_tool(*args, **kwargs):
|
12
|
-
print(f"调用了{tool.name}")
|
13
|
-
old_path = os.getcwd()
|
14
|
-
try:
|
15
|
-
sys.path.insert(0, module_path) # 插入到第一个位置
|
16
|
-
os.chdir(module_path)
|
17
|
-
result = old_tool_fun(*args, **kwargs)
|
18
|
-
finally:
|
19
|
-
sys.path.remove(module_path)
|
20
|
-
os.chdir(old_path)
|
21
|
-
print(f"{tool.name}调用完毕,结果为:", result)
|
22
|
-
return result
|
23
|
-
return _wrapped_tool
|
24
|
-
|
25
|
-
|
26
|
-
def import_tools(tool_id):
|
27
|
-
tool_path = "../../tool"
|
28
|
-
old_path = os.getcwd()
|
29
|
-
module_path = os.path.join(tool_path, tool_id)
|
30
|
-
module_path = os.path.normpath(os.path.abspath(module_path))
|
31
|
-
|
32
|
-
if not os.path.exists(module_path):
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
1
|
+
import sys
|
2
|
+
import os
|
3
|
+
import argparse
|
4
|
+
import importlib
|
5
|
+
from langchain.agents import tool as _tool
|
6
|
+
import types
|
7
|
+
import langchain_core
|
8
|
+
|
9
|
+
def wrapped_tool(tool, module_path):
|
10
|
+
old_tool_fun = tool.func
|
11
|
+
def _wrapped_tool(*args, **kwargs):
|
12
|
+
print(f"调用了{tool.name}")
|
13
|
+
old_path = os.getcwd()
|
14
|
+
try:
|
15
|
+
sys.path.insert(0, module_path) # 插入到第一个位置
|
16
|
+
os.chdir(module_path)
|
17
|
+
result = old_tool_fun(*args, **kwargs)
|
18
|
+
finally:
|
19
|
+
sys.path.remove(module_path)
|
20
|
+
os.chdir(old_path)
|
21
|
+
print(f"{tool.name}调用完毕,结果为:", result)
|
22
|
+
return result
|
23
|
+
return _wrapped_tool
|
24
|
+
|
25
|
+
|
26
|
+
def import_tools(tool_id):
|
27
|
+
tool_path = "../../tool"
|
28
|
+
old_path = os.getcwd()
|
29
|
+
module_path = os.path.join(tool_path, tool_id)
|
30
|
+
module_path = os.path.normpath(os.path.abspath(module_path))
|
31
|
+
|
32
|
+
if not os.path.exists(module_path):
|
33
|
+
print(f"Tool {tool_id} not found")
|
34
|
+
return []
|
35
|
+
|
36
|
+
# 保存当前的 sys.modules 状态
|
37
|
+
original_modules = sys.modules.copy()
|
38
|
+
|
39
|
+
try:
|
40
|
+
sys.path.insert(0, module_path) # 插入到第一个位置
|
41
|
+
os.chdir(module_path)
|
42
|
+
module = importlib.import_module("tool")
|
43
|
+
export_tools = getattr(module, "export_tools")
|
44
|
+
temp_list = []
|
45
|
+
for tool in export_tools:
|
46
|
+
assert isinstance(tool, langchain_core.tools.StructuredTool) or isinstance(tool, types.FunctionType), f"Tool is not a StructuredTool or function: {tool}"
|
47
|
+
if isinstance(tool, types.FunctionType) and not isinstance(tool, langchain_core.tools.StructuredTool):
|
48
|
+
temp_list.append(_tool(tool))
|
49
|
+
export_tools = temp_list
|
50
|
+
|
51
|
+
except Exception as e:
|
52
|
+
print(f"Error loading tool {tool_id}: {e}")
|
53
|
+
sys.path.remove(module_path)
|
54
|
+
os.chdir(old_path)
|
55
|
+
return []
|
56
|
+
|
57
|
+
# 卸载模块并恢复 sys.modules 状态
|
58
|
+
importlib.invalidate_caches()
|
59
|
+
for key in list(sys.modules.keys()):
|
60
|
+
if key not in original_modules:
|
61
|
+
del sys.modules[key]
|
62
|
+
|
63
|
+
sys.path.remove(module_path)
|
64
|
+
os.chdir(old_path)
|
65
|
+
|
66
|
+
for tool in export_tools:
|
67
|
+
tool.func = wrapped_tool(tool, module_path)
|
68
|
+
|
69
|
+
return export_tools
|
70
|
+
|
71
|
+
|
72
|
+
def read_arg(param: str, is_path=False):
|
73
|
+
parser = argparse.ArgumentParser()
|
74
|
+
parser.add_argument(param, nargs='?', help=f'Parameter {param}')
|
75
|
+
args = parser.parse_args()
|
76
|
+
value = getattr(args, param.lstrip('-'))
|
77
|
+
# 如果是路径并且有引号,去掉引号
|
78
|
+
if is_path and value and value.startswith('"') and value.endswith('"'):
|
79
|
+
value = value[1:-1]
|
80
|
+
|
81
|
+
return value
|
@@ -1,50 +1,54 @@
|
|
1
|
-
import json
|
2
|
-
from langchain_openai import ChatOpenAI
|
3
|
-
from .base import import_tools
|
4
|
-
from .agent import run_agent, Runnable, INPUT_MESSAGE, output
|
5
|
-
import asyncio
|
6
|
-
from langchain_core.messages import HumanMessage
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def
|
14
|
-
with open(bot_setting_file, "r", encoding="utf-8") as f:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
1
|
+
import json
|
2
|
+
from langchain_openai import ChatOpenAI
|
3
|
+
from .base import import_tools
|
4
|
+
from .agent import run_agent, Runnable, INPUT_MESSAGE, output
|
5
|
+
import asyncio
|
6
|
+
from langchain_core.messages import HumanMessage
|
7
|
+
from pycoze import utils
|
8
|
+
|
9
|
+
|
10
|
+
params = utils.arg.read_params()
|
11
|
+
llm_file = params["appPath"] + "/JsonStorage/llm.json"
|
12
|
+
|
13
|
+
def load_role_setting(bot_setting_file:str):
|
14
|
+
with open(bot_setting_file, "r", encoding="utf-8") as f:
|
15
|
+
return json.load(f)
|
16
|
+
|
17
|
+
def load_tools(bot_setting_file:str):
|
18
|
+
with open(bot_setting_file, "r", encoding="utf-8") as f:
|
19
|
+
role_setting = json.load(f)
|
20
|
+
|
21
|
+
tools = []
|
22
|
+
for tool_id in role_setting["tools"]:
|
23
|
+
tools.extend(import_tools(tool_id))
|
24
|
+
return tools
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
def chat(bot_setting_file:str):
|
30
|
+
history = []
|
31
|
+
|
32
|
+
while True:
|
33
|
+
message = input()
|
34
|
+
role_setting = load_role_setting(bot_setting_file)
|
35
|
+
tools = load_tools(bot_setting_file)
|
36
|
+
if not message.startswith(INPUT_MESSAGE):
|
37
|
+
raise ValueError("Invalid message")
|
38
|
+
message = json.loads(message[len(INPUT_MESSAGE):])["content"]
|
39
|
+
print("user:", message)
|
40
|
+
|
41
|
+
with open(llm_file, "r", encoding="utf-8") as f:
|
42
|
+
cfg = json.load(f)
|
43
|
+
chat = ChatOpenAI(api_key=cfg["apiKey"], base_url=cfg['baseURL'], model=cfg["model"], temperature=role_setting["temperature"])
|
44
|
+
|
45
|
+
|
46
|
+
agent = Runnable(agent_execution_mode='FuncCall', # 'FuncCall' or 'ReAct',大模型支持FuncCall的话就用FuncCall
|
47
|
+
tools=tools,
|
48
|
+
llm=chat,
|
49
|
+
assistant_message=role_setting["prompt"],)
|
50
|
+
|
51
|
+
history += [HumanMessage(content=message)]
|
52
|
+
result = asyncio.run(run_agent(agent, history))
|
53
|
+
output("assistant", result, history)
|
54
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
from .gpu_reserve import reserve_gpu_retry, release_gpu, reserve_gpu_retry
|
@@ -0,0 +1,167 @@
|
|
1
|
+
import subprocess
|
2
|
+
import sqlite3
|
3
|
+
import atexit
|
4
|
+
import time
|
5
|
+
import os
|
6
|
+
import psutil
|
7
|
+
|
8
|
+
try:
|
9
|
+
from pycoze.utils import utils
|
10
|
+
|
11
|
+
# 定义数据库连接和初始化
|
12
|
+
params = utils.arg.read_params()
|
13
|
+
if params:
|
14
|
+
DATABASE_PATH = params["appPath"] + "/gpu_usage.db"
|
15
|
+
else:
|
16
|
+
raise Exception("No params")
|
17
|
+
except:
|
18
|
+
DATABASE_DIR = os.path.expanduser("~/pycoze")
|
19
|
+
os.makedirs(DATABASE_DIR, exist_ok=True)
|
20
|
+
DATABASE_PATH = os.path.join(DATABASE_DIR, "gpu_usage.db")
|
21
|
+
TABLE_NAME = "gpu_usage"
|
22
|
+
|
23
|
+
|
24
|
+
def initialize_db():
|
25
|
+
conn = sqlite3.connect(DATABASE_PATH)
|
26
|
+
cursor = conn.cursor()
|
27
|
+
cursor.execute(
|
28
|
+
f"""
|
29
|
+
CREATE TABLE IF NOT EXISTS {TABLE_NAME} (
|
30
|
+
id INTEGER PRIMARY KEY,
|
31
|
+
process_id TEXT NOT NULL,
|
32
|
+
reserved_gb REAL NOT NULL
|
33
|
+
)
|
34
|
+
"""
|
35
|
+
)
|
36
|
+
conn.commit()
|
37
|
+
conn.close()
|
38
|
+
|
39
|
+
|
40
|
+
# 检测GPU资源
|
41
|
+
def get_gpu_resources():
|
42
|
+
try:
|
43
|
+
# 使用nvidia-smi命令获取GPU信息
|
44
|
+
result = subprocess.run(
|
45
|
+
["nvidia-smi", "--query-gpu=memory.free", "--format=csv,noheader,nounits"],
|
46
|
+
stdout=subprocess.PIPE,
|
47
|
+
text=True,
|
48
|
+
)
|
49
|
+
free_memory = result.stdout.strip().split("\n")
|
50
|
+
total_free_memory = sum(float(mem) for mem in free_memory)
|
51
|
+
|
52
|
+
# 获取正在使用GPU的进程信息
|
53
|
+
process_result = subprocess.run(
|
54
|
+
[
|
55
|
+
"nvidia-smi",
|
56
|
+
"--query-compute-apps=pid,process_name,used_memory",
|
57
|
+
"--format=csv,noheader,nounits",
|
58
|
+
],
|
59
|
+
stdout=subprocess.PIPE,
|
60
|
+
text=True,
|
61
|
+
)
|
62
|
+
process_info = process_result.stdout.strip().split("\n")
|
63
|
+
|
64
|
+
# 过滤掉进程名中包含"python"的进程
|
65
|
+
python_memory_usage = 0.0
|
66
|
+
for process in process_info:
|
67
|
+
pid, process_name, used_memory = process.split(", ")
|
68
|
+
if "python" in process_name.lower():
|
69
|
+
python_memory_usage += float(used_memory)
|
70
|
+
|
71
|
+
# 计算排除python进程后的总空闲内存
|
72
|
+
total_free_memory -= python_memory_usage
|
73
|
+
return round(total_free_memory / 1024, 2)
|
74
|
+
except Exception as e:
|
75
|
+
print(f"Error getting GPU resources: {e}")
|
76
|
+
return 0.0
|
77
|
+
|
78
|
+
|
79
|
+
# 预留GPU资源
|
80
|
+
def reserve_gpu(gb):
|
81
|
+
process_id = str(os.getpid())
|
82
|
+
with sqlite3.connect(DATABASE_PATH) as conn:
|
83
|
+
cursor = conn.cursor()
|
84
|
+
cursor.execute(f"SELECT SUM(reserved_gb) FROM {TABLE_NAME}")
|
85
|
+
total_reserved = cursor.fetchone()[0]
|
86
|
+
if total_reserved is None:
|
87
|
+
total_reserved = 0.0
|
88
|
+
available_gb = get_gpu_resources() - total_reserved
|
89
|
+
if available_gb >= gb:
|
90
|
+
cursor.execute(
|
91
|
+
f"INSERT INTO {TABLE_NAME} (process_id, reserved_gb) VALUES (?, ?)",
|
92
|
+
(process_id, gb),
|
93
|
+
)
|
94
|
+
conn.commit()
|
95
|
+
print(f"预留成功,剩余GPU大小: {available_gb - gb} GB")
|
96
|
+
return True
|
97
|
+
else:
|
98
|
+
print(f"预留失败,剩余GPU大小: {available_gb} GB")
|
99
|
+
return False
|
100
|
+
|
101
|
+
|
102
|
+
def reserve_gpu_retry(gb, retry=10000):
|
103
|
+
for i in range(retry):
|
104
|
+
time.sleep(1)
|
105
|
+
if reserve_gpu(gb):
|
106
|
+
if i % 10 == 0 or i < 10:
|
107
|
+
print(f"重试第{i}次")
|
108
|
+
return True
|
109
|
+
return False
|
110
|
+
|
111
|
+
|
112
|
+
# 释放GPU资源
|
113
|
+
def release_gpu():
|
114
|
+
process_id = str(os.getpid())
|
115
|
+
with sqlite3.connect(DATABASE_PATH) as conn:
|
116
|
+
cursor = conn.cursor()
|
117
|
+
cursor.execute(f"DELETE FROM {TABLE_NAME} WHERE process_id = ?", (process_id,))
|
118
|
+
conn.commit()
|
119
|
+
# 计算释放后的剩余GPU大小
|
120
|
+
cursor.execute(f"SELECT SUM(reserved_gb) FROM {TABLE_NAME}")
|
121
|
+
total_reserved = cursor.fetchone()[0]
|
122
|
+
if total_reserved is None:
|
123
|
+
total_reserved = 0.0
|
124
|
+
available_gb = get_gpu_resources() - total_reserved
|
125
|
+
print(f"释放成功,剩余GPU大小: {available_gb} GB")
|
126
|
+
|
127
|
+
|
128
|
+
# 注册退出时的清理函数
|
129
|
+
def cleanup():
|
130
|
+
release_gpu()
|
131
|
+
print("程序退出,GPU资源已释放")
|
132
|
+
|
133
|
+
|
134
|
+
def initialize_and_check():
|
135
|
+
initialize_db()
|
136
|
+
with sqlite3.connect(DATABASE_PATH) as conn:
|
137
|
+
cursor = conn.cursor()
|
138
|
+
cursor.execute(f"SELECT process_id, reserved_gb FROM {TABLE_NAME}")
|
139
|
+
rows = cursor.fetchall()
|
140
|
+
for row in rows:
|
141
|
+
process_id, reserved_gb = row
|
142
|
+
try:
|
143
|
+
# 检查进程是否存在
|
144
|
+
psutil.Process(int(process_id))
|
145
|
+
except psutil.NoSuchProcess:
|
146
|
+
# 进程不存在,删除对应的记录
|
147
|
+
cursor.execute(
|
148
|
+
f"DELETE FROM {TABLE_NAME} WHERE process_id = ?", (process_id,)
|
149
|
+
)
|
150
|
+
print(f"进程 {process_id} 不存在,已删除对应的预留记录")
|
151
|
+
conn.commit()
|
152
|
+
|
153
|
+
|
154
|
+
# 在模块加载时执行初始化检查
|
155
|
+
initialize_and_check()
|
156
|
+
|
157
|
+
# 注册清理函数
|
158
|
+
atexit.register(cleanup)
|
159
|
+
|
160
|
+
if __name__ == "__main__":
|
161
|
+
if reserve_gpu_retry(10):
|
162
|
+
print("GPU资源预留成功")
|
163
|
+
time.sleep(100)
|
164
|
+
release_gpu()
|
165
|
+
print("GPU资源释放成功")
|
166
|
+
else:
|
167
|
+
print("GPU资源不足,无法预留")
|
@@ -0,0 +1,167 @@
|
|
1
|
+
from .base import get_ui
|
2
|
+
from .typ import useDefaultType
|
3
|
+
from typing import Union, List
|
4
|
+
from .color import hex_to_rgb, rgb_to_hsl, ColorFormat
|
5
|
+
import sys
|
6
|
+
|
7
|
+
|
8
|
+
def useDefault(name, default):
|
9
|
+
ui_data = get_ui()
|
10
|
+
if name not in ui_data:
|
11
|
+
return default
|
12
|
+
return useDefaultType(ui_data[name], default)
|
13
|
+
|
14
|
+
|
15
|
+
def get_ui_text():
|
16
|
+
ui = get_ui()
|
17
|
+
output = ""
|
18
|
+
for key, value in ui.items():
|
19
|
+
output += f"{key}: {value}\n"
|
20
|
+
return output
|
21
|
+
|
22
|
+
|
23
|
+
def label(name, tip="", hide_if="", style="", cls=""):
|
24
|
+
pass
|
25
|
+
|
26
|
+
|
27
|
+
def number(
|
28
|
+
name,
|
29
|
+
default,
|
30
|
+
min=-sys.maxsize - 1,
|
31
|
+
max=sys.maxsize,
|
32
|
+
step=1,
|
33
|
+
tip="",
|
34
|
+
hide_if="",
|
35
|
+
style="",
|
36
|
+
cls="",
|
37
|
+
) -> Union[int, float]: # 注意Python3.9不兼容int|float
|
38
|
+
return useDefault(name, default)
|
39
|
+
|
40
|
+
|
41
|
+
def text(name, default, tip="", hide_if="", style="", cls="") -> str:
|
42
|
+
return useDefault(name, default)
|
43
|
+
|
44
|
+
|
45
|
+
def textarea(name, default, tip="", hide_if="", style="", cls="") -> str:
|
46
|
+
return useDefault(name, default)
|
47
|
+
|
48
|
+
|
49
|
+
def password(name, default, tip="", hide_if="", style="", cls="") -> str:
|
50
|
+
return useDefault(name, default)
|
51
|
+
|
52
|
+
|
53
|
+
def color(
|
54
|
+
name,
|
55
|
+
default,
|
56
|
+
color_format: ColorFormat = "hex",
|
57
|
+
tip="",
|
58
|
+
hide_if="",
|
59
|
+
style="",
|
60
|
+
cls="",
|
61
|
+
) -> str:
|
62
|
+
rgbhex = useDefault(name, default)
|
63
|
+
if color_format == "hex":
|
64
|
+
return rgbhex
|
65
|
+
elif color_format == "rgb":
|
66
|
+
return hex_to_rgb(rgbhex)
|
67
|
+
elif color_format == "hsl":
|
68
|
+
return rgb_to_hsl(hex_to_rgb(rgbhex))
|
69
|
+
return rgbhex
|
70
|
+
|
71
|
+
|
72
|
+
def checkbox(name, default, tip="", hide_if="", style="", cls="") -> bool:
|
73
|
+
return useDefault(name, default)
|
74
|
+
|
75
|
+
|
76
|
+
def single_select(
|
77
|
+
name,
|
78
|
+
default: Union[str, int, float, bool],
|
79
|
+
options,
|
80
|
+
tip="",
|
81
|
+
hide_if="",
|
82
|
+
style="",
|
83
|
+
cls="",
|
84
|
+
):
|
85
|
+
return useDefault(name, default)
|
86
|
+
|
87
|
+
|
88
|
+
def multi_select(
|
89
|
+
name,
|
90
|
+
default: Union[List[str], List[int], List[float], List[bool]],
|
91
|
+
options,
|
92
|
+
tip="",
|
93
|
+
hide_if="",
|
94
|
+
style="",
|
95
|
+
cls="",
|
96
|
+
):
|
97
|
+
return useDefault(name, default)
|
98
|
+
|
99
|
+
|
100
|
+
def single_file_select(name, default: str, tip="", hide_if="", style="", cls="") -> str:
|
101
|
+
return useDefault(name, default)
|
102
|
+
|
103
|
+
|
104
|
+
def multi_file_select(
|
105
|
+
name, default: List[str], tip="", hide_if="", style="", cls=""
|
106
|
+
) -> List[str]:
|
107
|
+
return useDefault(name, default)
|
108
|
+
|
109
|
+
|
110
|
+
def single_folder_select(
|
111
|
+
name, default: str, tip="", hide_if="", style="", cls=""
|
112
|
+
) -> str:
|
113
|
+
return useDefault(name, default)
|
114
|
+
|
115
|
+
|
116
|
+
def multi_folder_select(
|
117
|
+
name, default: List[str], tip="", hide_if="", style="", cls=""
|
118
|
+
) -> List[str]:
|
119
|
+
return useDefault(name, default)
|
120
|
+
|
121
|
+
|
122
|
+
def folder_tree(
|
123
|
+
name, root="", default: List[str] = None, tip="", hide_if="", style="", cls=""
|
124
|
+
) -> dict:
|
125
|
+
if default is None:
|
126
|
+
default = []
|
127
|
+
return useDefault(name, default)
|
128
|
+
|
129
|
+
|
130
|
+
def single_image_select(
|
131
|
+
name, default: str, tip="", hide_if="", style="", cls=""
|
132
|
+
) -> str:
|
133
|
+
return useDefault(name, default)
|
134
|
+
|
135
|
+
|
136
|
+
def multi_image_select(
|
137
|
+
name, default: List[str], tip="", hide_if="", style="", cls=""
|
138
|
+
) -> List[str]:
|
139
|
+
return useDefault(name, default)
|
140
|
+
|
141
|
+
|
142
|
+
def single_audio_select(
|
143
|
+
name, default: str, tip="", hide_if="", style="", cls=""
|
144
|
+
) -> str:
|
145
|
+
return useDefault(name, default)
|
146
|
+
|
147
|
+
|
148
|
+
def multi_audio_select(
|
149
|
+
name, default: List[str], tip="", hide_if="", style="", cls=""
|
150
|
+
) -> List[str]:
|
151
|
+
return useDefault(name, default)
|
152
|
+
|
153
|
+
|
154
|
+
def single_video_select(
|
155
|
+
name, default: str, tip="", hide_if="", style="", cls=""
|
156
|
+
) -> str:
|
157
|
+
return useDefault(name, default)
|
158
|
+
|
159
|
+
|
160
|
+
def multi_video_select(
|
161
|
+
name, default: List[str], tip="", hide_if="", style="", cls=""
|
162
|
+
) -> List[str]:
|
163
|
+
return useDefault(name, default)
|
164
|
+
|
165
|
+
|
166
|
+
def seed(name, default=0, tip="", hide_if="", style="", cls="") -> int:
|
167
|
+
return useDefault(name, default)
|
@@ -0,0 +1 @@
|
|
1
|
+
from .arg import read_arg, read_params
|
@@ -18,6 +18,8 @@ pycoze/bot/agent/agent_types/__init__.py
|
|
18
18
|
pycoze/bot/agent/agent_types/openai_func_call_agent.py
|
19
19
|
pycoze/bot/agent/agent_types/react_agent.py
|
20
20
|
pycoze/bot/agent/agent_types/react_prompt.py
|
21
|
+
pycoze/gpu/__init__.py
|
22
|
+
pycoze/gpu/gpu_reserve.py
|
21
23
|
pycoze/ui/__init__.py
|
22
24
|
pycoze/ui/base.py
|
23
25
|
pycoze/ui/color.py
|
@@ -1,19 +1,19 @@
|
|
1
|
-
from setuptools import setup, find_packages
|
2
|
-
|
3
|
-
setup(
|
4
|
-
name="pycoze",
|
5
|
-
version="0.1.
|
6
|
-
packages=find_packages(),
|
7
|
-
install_requires=[],
|
8
|
-
author="Yuan Jie Xiong",
|
9
|
-
author_email="aiqqqqqqq@qq.com",
|
10
|
-
description="Package for pycoze only!",
|
11
|
-
long_description=open('README.md', encoding="utf-8").read(),
|
12
|
-
long_description_content_type='text/markdown',
|
13
|
-
classifiers=[
|
14
|
-
"Programming Language :: Python :: 3",
|
15
|
-
"License :: OSI Approved :: MIT License",
|
16
|
-
"Operating System :: OS Independent",
|
17
|
-
],
|
18
|
-
python_requires='>=3.6',
|
19
|
-
)
|
1
|
+
from setuptools import setup, find_packages
|
2
|
+
|
3
|
+
setup(
|
4
|
+
name="pycoze",
|
5
|
+
version="0.1.19",
|
6
|
+
packages=find_packages(),
|
7
|
+
install_requires=[],
|
8
|
+
author="Yuan Jie Xiong",
|
9
|
+
author_email="aiqqqqqqq@qq.com",
|
10
|
+
description="Package for pycoze only!",
|
11
|
+
long_description=open('README.md', encoding="utf-8").read(),
|
12
|
+
long_description_content_type='text/markdown',
|
13
|
+
classifiers=[
|
14
|
+
"Programming Language :: Python :: 3",
|
15
|
+
"License :: OSI Approved :: MIT License",
|
16
|
+
"Operating System :: OS Independent",
|
17
|
+
],
|
18
|
+
python_requires='>=3.6',
|
19
|
+
)
|
@@ -1,110 +0,0 @@
|
|
1
|
-
from .base import get_ui
|
2
|
-
from .typ import useDefaultType
|
3
|
-
from typing import Union, List
|
4
|
-
from .color import hex_to_rgb, rgb_to_hsl, ColorFormat
|
5
|
-
import sys
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def useDefault(name, default):
|
10
|
-
ui_data = get_ui()
|
11
|
-
if name not in ui_data:
|
12
|
-
return default
|
13
|
-
return useDefaultType(ui_data[name], default)
|
14
|
-
|
15
|
-
|
16
|
-
def get_ui_text():
|
17
|
-
ui = get_ui()
|
18
|
-
output = ''
|
19
|
-
for key, value in ui.items():
|
20
|
-
output += f'{key}: {value}\n'
|
21
|
-
return output
|
22
|
-
|
23
|
-
|
24
|
-
def label(name, tip="", hide_if="", style="", cls=""):
|
25
|
-
pass
|
26
|
-
|
27
|
-
|
28
|
-
def number(name,
|
29
|
-
default,
|
30
|
-
min=-sys.maxsize - 1,
|
31
|
-
max=sys.maxsize,
|
32
|
-
step=1,
|
33
|
-
tip="",
|
34
|
-
hide_if="",
|
35
|
-
style="",
|
36
|
-
cls="") -> Union[int, float]: # 注意Python3.9不兼容int|float
|
37
|
-
return useDefault(name, default)
|
38
|
-
|
39
|
-
|
40
|
-
def text(name, default, tip="", hide_if="", style="", cls="") -> str:
|
41
|
-
return useDefault(name, default)
|
42
|
-
|
43
|
-
|
44
|
-
def textarea(name, default, tip="", hide_if="", style="", cls="") -> str:
|
45
|
-
return useDefault(name, default)
|
46
|
-
|
47
|
-
|
48
|
-
def password(name, default, tip="", hide_if="", style="", cls="") -> str:
|
49
|
-
return useDefault(name, default)
|
50
|
-
|
51
|
-
|
52
|
-
def color(name, default, color_format: ColorFormat = "hex", tip="", hide_if="", style="", cls="") -> str:
|
53
|
-
rgbhex = useDefault(name, default)
|
54
|
-
if color_format == "hex":
|
55
|
-
return rgbhex
|
56
|
-
elif color_format == "rgb":
|
57
|
-
return hex_to_rgb(rgbhex)
|
58
|
-
elif color_format == "hsl":
|
59
|
-
return rgb_to_hsl(hex_to_rgb(rgbhex))
|
60
|
-
return rgbhex
|
61
|
-
|
62
|
-
|
63
|
-
def checkbox(name, default, tip="", hide_if="", style="", cls="") -> bool:
|
64
|
-
return useDefault(name, default)
|
65
|
-
|
66
|
-
|
67
|
-
def single_select(name, default: Union[str, int, float, bool], options, tip="", hide_if="", style="", cls=""):
|
68
|
-
return useDefault(name, default)
|
69
|
-
|
70
|
-
|
71
|
-
def multi_select(name,
|
72
|
-
default: Union[List[str], List[int], List[float], List[bool]],
|
73
|
-
options,
|
74
|
-
tip="",
|
75
|
-
hide_if="",
|
76
|
-
style="",
|
77
|
-
cls=""):
|
78
|
-
return useDefault(name, default)
|
79
|
-
|
80
|
-
|
81
|
-
def file(name, default: Union[str, List[str]], is_multiple: bool, tip="", hide_if="", style="", cls="") -> str:
|
82
|
-
return useDefault(name, default)
|
83
|
-
|
84
|
-
|
85
|
-
def folder(name, default: Union[str, List[str]], is_multiple: bool, tip="", hide_if="", style="", cls="") -> str:
|
86
|
-
return useDefault(name, default)
|
87
|
-
|
88
|
-
|
89
|
-
def folder_tree(name, root="", default: List[str] = None, tip="", hide_if="", style="", cls="") -> dict:
|
90
|
-
if default is None:
|
91
|
-
default = []
|
92
|
-
return useDefault(name, default)
|
93
|
-
|
94
|
-
|
95
|
-
def image(name, default: Union[str, List[str]], is_multiple: bool=False, tip="", hide_if="", style="", cls="") -> str:
|
96
|
-
return useDefault(name, default)
|
97
|
-
|
98
|
-
|
99
|
-
def audio(name, default: Union[str, List[str]], is_multiple: bool=False, tip="", hide_if="", style="", cls="") -> str:
|
100
|
-
return useDefault(name, default)
|
101
|
-
|
102
|
-
|
103
|
-
def video(name, default: Union[str, List[str]], is_multiple: bool=False, tip="", hide_if="", style="", cls="") -> str:
|
104
|
-
return useDefault(name, default)
|
105
|
-
|
106
|
-
|
107
|
-
def seed(name, default=0, tip="", hide_if="", style="", cls="") -> int:
|
108
|
-
return useDefault(name, default)
|
109
|
-
|
110
|
-
|
@@ -1 +0,0 @@
|
|
1
|
-
from .arg import read_arg
|
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
|