提交版本

This commit is contained in:
CakeCN
2025-01-02 09:29:49 +08:00
parent eb67bcfb70
commit a1904afbc8
137 changed files with 1906 additions and 885 deletions

View File

@@ -1,235 +1,329 @@
import sys
import os
current_directory = os.path.dirname(os.path.abspath(__file__))
sys.path.append(current_directory)
import agentscope
from agentscope.message import Msg
import os
import asyncio
import threading
import json
from agent.flex_service_toolkit import *
from AlgoriAgent.projects.algoriAgent.agent.algori_agent import *
from agentscope.service import (
ServiceToolkit,
ServiceResponse,
ServiceExecStatus,
)
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
openai_api_key = config['Global']['api_key']
OPENAI_CFG_DICT = {
"config_name": "openai_cfg", # 此配置的名称,必须保证唯一
"model_type": "openai_chat", # 模型类型
"model_name": "gpt-4o-mini", # 模型名称
#"model_name": "gpt-4", # 模型名称
#"model_name": "llama3",
"api_key": openai_api_key, # OpenAI API key. 如果没有设置,将使用环境变量中的 OPENAI_API_KEY
"client_args": {
"base_url": config['Global']['base_chat_url']
},
}
import uuid
from AlgoriAgent.projects.algoriAgent.tools.judge_tools import judge
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
def tool_name_to_tool(tool_name_list):
tools = []
for tool_name in tool_name_list:
if tool_name == "":
continue
if tool_name == "judge":
tools.append(judge)
return tools
class AgentManager:
def __init__(self):
agentscope.init(model_configs=[OPENAI_CFG_DICT])#, studio_url="http://0.0.0.0:5000")
self.agents = {}
def new_agent(self, markdown:str, markdown_prompt:str, score_prompt:str, id = None):
'''
markdown: 教案的markdown文件内容
markdown_prompt: 教案的prompt的markdown文件内容
score_prompt: 评分的prompt的markdown文件内容
根据3个教案的prompt生成一个agent返回agent的id与agent
'''
markdown_list = markdown.split("\n")
markdown_prompt_list = markdown_prompt.split("\n")
score_prompt_list = score_prompt.split("\n")
# 获取 H1 标题
title = ""
for line in markdown_list:
if line.startswith("# "):
title = line[2:]
break
# 对于 H3 标题 构造每一个 Chapter
# 首先找到所有的 H3 标题
chapter_dict = {}
chapter_sequence = []
for line in markdown_list:
if line.startswith("### "):
chapter_name = line[4:]
chapter_dict[chapter_name] = {}
chapter_sequence.append(chapter_name)
# 将 H3 标题 和 其对应的内容 构造成一个 Chapter
h3_name = ""
content = ""
for i in range(len(markdown_list)):
if markdown_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["markdown"] = content
h3_name = markdown_list[i][4:]
content = ""
continue
if h3_name != "":
content += markdown_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["markdown"] = content
h3_name = ""
content = ""
require_tools = []
for i in range(len(markdown_prompt_list)):
if markdown_prompt_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["markdown_prompt"] = content
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool(require_tools)
h3_name = markdown_prompt_list[i][4:]
content = ""
continue
if h3_name != "":
if markdown_prompt_list[i].startswith("_require_tools"):
require_tools.append(markdown_prompt_list[i].split("=")[1].strip())
continue
content += markdown_prompt_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["markdown_prompt"] = content
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool(require_tools)
h3_name = ""
content = ""
for i in range(len(score_prompt_list)):
if score_prompt_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["score_prompt"] = content
h3_name = score_prompt_list[i][4:]
content = ""
continue
if h3_name != "":
content += score_prompt_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["score_prompt"] = content
chapter_chain = []
No = 1
print (chapter_dict)
for chapter_name in chapter_sequence:
chapter_chain.append(Chapter(No, CHAPTER_LATTER, title, chapter_dict[chapter_name]["markdown"], chapter_dict[chapter_name]["markdown_prompt"], chapter_dict[chapter_name]["score_prompt"],chapter_dict[chapter_name]["require_tools"]))
No+=1
chapter_chain[0].Focus()
# Prepare the tools for the agent
service_toolkit = FlexServiceToolkit()
# for tool_function in unity_function_list:
# service_toolkit.add(tool_function)
agent = ChapterChainAgent(
name="assistant",
model_config_name="openai_cfg",
verbose=True,
service_toolkit=service_toolkit,
max_iters=5,
chapter_chain=chapter_chain
)
self.agents[id] = agent
return id, agent
def new_agent_with_chain(self, chapter_chain = None, id = None):
'''
'''
if chapter_chain is None:
chapter_chain = EMPTY_CHAPTER_CHAIN
# Prepare the tools for the agent
service_toolkit = FlexServiceToolkit()
# for tool_function in unity_function_list:
# service_toolkit.add(tool_function)
agent = ChapterChainAgent(
name="assistant",
model_config_name="openai_cfg",
verbose=True,
service_toolkit=service_toolkit,
max_iters=5,
chapter_chain=EMPTY_CHAPTER_CHAIN
)
if id is None: id = uuid.uuid4()
self.agents[id] = agent
return id, agent
def get_agent(self, id=None):
'''
如果在get agent之前没有new agent并用id进行访问就返回一个章节链为空的agent
'''
if id:
if id in self.agents:
return self.agents[id]
self.agents[id] = self.new_agent(id)[1]
else:
id = str(uuid.uuid4())
self.agents[id] = self.new_agent()[1]
return id, self.agents[id]
def invoke(self,id, query, user_backboard):
msg = Msg("user", query, role="user")
return self.agents[id](msg, user_backboard = user_backboard)
import time
if __name__ == '__main__':
# tool_demo = ToolDemo("Lava")
# response = tool_demo.invoke("I want such a Gurouce, when use it, it will be thrown and fly towards the mouse position for a short time, and stop. And will damage Enemy who step on it. I call it Lava Gurouce.")
# print(response)
# Start the WebSocket server in a separate thread
manager = AgentManager()
id, agent = manager.new_agent()
# Main thread logic
try:
# Your code that might be interrupted
while True:
input_data = input("用户:")
print(manager.invoke(id, input_data))
except KeyboardInterrupt:
print("Process interrupted by user.")
# You can add any cleanup code here if needed
finally:
print("Exiting program.")
# Code to run before the program exits
import sys
import os
current_directory = os.path.dirname(os.path.abspath(__file__))
sys.path.append(current_directory)
from flask_socketio import SocketIO, join_room, emit, Namespace
import agentscope
from agentscope.message import Msg
import os
import asyncio
import threading
import json
from agent.flex_service_toolkit import *
from AlgoriAgent.projects.algoriAgent.agent.algori_agent import *
from agentscope.service import (
ServiceToolkit,
ServiceResponse,
ServiceExecStatus,
)
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
openai_api_key = config['Global']['api_key']
OPENAI_CFG_DICT = {
"config_name": "openai_cfg", # 此配置的名称,必须保证唯一
"model_type": "openai_chat", # 模型类型
"model_name": "gpt-4o-mini", # 模型名称
#"model_name": "gpt-4", # 模型名称
#"model_name": "llama3",
"api_key": openai_api_key, # OpenAI API key. 如果没有设置,将使用环境变量中的 OPENAI_API_KEY
"client_args": {
"base_url": config['Global']['base_chat_url']
},
}
import uuid
from AlgoriAgent.projects.algoriAgent.tools.judge_tools import judge
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
def tool_name_to_tool(tool_name_list):
tools = []
for tool_name in tool_name_list:
if tool_name == "":
continue
if tool_name == "judge":
tools.append(judge)
return tools
def tool_name_to_tool_with_args(tool_name_list, tool_args_list) -> list[tuple[Callable, dict]]:
tools = []
for tool_name, tool_args in zip(tool_name_list, tool_args_list):
if tool_name == "":
continue
if tool_name == "judge":
tools.append((judge, {"course_id": tool_args[0], "lesson_id": tool_args[1], "name": tool_args[2]}))
return tools
class AgentManager:
def __init__(self,max_iter = 5, app=None, socketio=None):
agentscope.init(model_configs=[OPENAI_CFG_DICT])#, studio_url="http://0.0.0.0:5000")
self.agents = {}
self.max_iter = max_iter
self.agent_to_id = {}
self.app = app
self.socketio = socketio
def new_agent(self, course_id, lesson_id, markdown:str, markdown_prompt:str, score_prompt:str, id = "Defult Assistant", root_path="."):
'''
markdown: 教案的markdown文件内容
markdown_prompt: 教案的prompt的markdown文件内容
score_prompt: 评分的prompt的markdown文件内容
根据3个教案的prompt生成一个agent返回agent的id与agent
'''
markdown_list = markdown.split("\n")
markdown_prompt_list = markdown_prompt.split("\n")
score_prompt_list = score_prompt.split("\n")
# 获取 H1 标题
title = ""
for line in markdown_list:
if line.startswith("# "):
title = line[2:]
break
# 对于 H3 标题 构造每一个 Chapter
# 首先找到所有的 H3 标题
chapter_dict = {}
chapter_sequence = []
for line in markdown_list:
if line.startswith("### "):
chapter_name = line[4:]
chapter_dict[chapter_name] = {}
chapter_sequence.append(chapter_name)
# 将 H3 标题 和 其对应的内容 构造成一个 Chapter
h3_name = ""
content = ""
for i in range(len(markdown_list)):
if markdown_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["markdown"] = content
h3_name = markdown_list[i][4:]
content = ""
continue
if h3_name != "":
content += markdown_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["markdown"] = content
h3_name = ""
content = ""
require_tools = []
require_tools_args = []
for i in range(len(markdown_prompt_list)):
if markdown_prompt_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["markdown_prompt"] = content
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool_with_args(require_tools, require_tools_args)
h3_name = markdown_prompt_list[i][4:]
content = ""
require_tools=[]
require_tools_args = []
continue
if h3_name != "":
if markdown_prompt_list[i].startswith("_require_tools"):
require_tools.append(markdown_prompt_list[i].split("=")[1].strip().split(",")[0])
require_tools_args.append((markdown_prompt_list[i].split("=")[1].strip().split(",")[1:]))
continue
content += markdown_prompt_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["markdown_prompt"] = content
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool_with_args(require_tools, require_tools_args)
h3_name = ""
content = ""
for i in range(len(score_prompt_list)):
if score_prompt_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["score_prompt"] = content
h3_name = score_prompt_list[i][4:]
content = ""
continue
if h3_name != "":
content += score_prompt_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["score_prompt"] = content
chapter_chain = []
No = 1
print (chapter_dict)
for chapter_name in chapter_sequence:
chapter_chain.append(Chapter(course_id, lesson_id, No, CHAPTER_LATTER, chapter_name, chapter_dict[chapter_name]["markdown"], chapter_dict[chapter_name]["markdown_prompt"], chapter_dict[chapter_name]["score_prompt"],chapter_dict[chapter_name]["require_tools"]))
No+=1
chapter_chain[0].Focus()
# Prepare the tools for the agent
service_toolkit = FlexServiceToolkit()
# for tool_function in unity_function_list:
# service_toolkit.add(tool_function)
agent = ChapterChainAgent(
name=id,
model_config_name="openai_cfg",
verbose=True,
service_toolkit=service_toolkit,
max_iters=5,
chapter_chain=chapter_chain,
root_path = root_path,
)
self.agents[id] = agent
self.agent_to_id[agent] = id
agent.agent_manager = self
return id, agent
def message_pass(self, agent, messagetype, message):
id = self.agent_to_id[agent]
print("message_pass", id, messagetype, message)
with self.app.app_context():
try:
self.socketio.emit(messagetype, message, room=id, namespace='/agent')
except Exception as e:
print("message_pass",e)
def system_message(self, message):
with self.app.app_context():
try:
self.socketio.emit('system_message', message, room=id, namespace='/agent')
except Exception as e:
print("ERROR: system_message",e)
def save_chapter_memory(self, agent,course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal):
id = self.agent_to_id[agent]
self.app.my_function.save_chapter_memory(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal)
def new_agent_with_chain(self, chapter_chain = None, id = None):
if chapter_chain is None:
chapter_chain = EMPTY_CHAPTER_CHAIN
# Prepare the tools for the agent
service_toolkit = FlexServiceToolkit()
# for tool_function in unity_function_list:
# service_toolkit.add(tool_function)
agent = ChapterChainAgent(
name="assistant",
model_config_name="openai_cfg",
verbose=True,
service_toolkit=service_toolkit,
max_iters=5,
chapter_chain=EMPTY_CHAPTER_CHAIN
)
if id is None: id = uuid.uuid4()
self.agents[id] = agent
return id, agent
def get_agent(self, id=None):
'''
如果在get agent之前没有new agent并用id进行访问就返回一个章节链为空的agent
'''
if id:
if id in self.agents:
return self.agents[id]
self.agents[id] = self.new_agent(id)[1]
else:
id = str(uuid.uuid4())
self.agents[id] = self.new_agent()[1]
return id, self.agents[id]
def invoke(self,id, query, user_backboard, reset=False):
msg = Msg("user", query, role="user")
agent = self.agents[id]
res = agent(msg, user_backboard=user_backboard)
return res
# 暂时取消生成器的写法
# 假设 agent 是一个生成器
# if reset or not hasattr(agent, '_generator'):
# agent._generator = agent(msg, user_backboard=user_backboard)
# try:
# response = next(agent._generator)
# yield response
# except StopIteration:
# return
def function_call(self, id, arg_function):
agent = self.agents[id]
return agent.function_call(arg_function)
def change_language(self, id, language):
agent = self.agents[id]
agent.change_language(language)
def sample_judge(self, id, bb):
agent = self.agents[id]
with self.app.app_context():
try:
print(bb.get_active_file_reletive_path())
assert bb is not None and bb.active_file_path != "" , "no path specified"
if bb.get_active_file_reletive_path().endswith(".py"):
self.socketio.emit('terminal', {'data': f"python {bb.get_active_file_reletive_path()}"}, room=id, namespace='/vscode')
self.socketio.emit('system_message', "代码试运行尚在建设,推荐直接通过命令行执行!", room=id, namespace='/agent')
else:
self.socketio.emit('system_message', "代码试运行尚仅支持python文件", room=id, namespace='/agent')
except Exception as e:
print(e)
if (str(e) == "no path specified"):
self.socketio.emit("system_message", "未加载IDE文件同步请尝试重新打开IDE文件或刷新页面并确保插件已连接", room=id, namespace='/agent')
def judge(self, id, bb):
agent = self.agents[id]
with self.app.app_context():
try:
if (agent.chapter_chain[agent.chapter_chain_now].append_tools is not None and len(agent.chapter_chain[agent.chapter_chain_now].append_tools)):
for tool, tool_kwargs in agent.chapter_chain[agent.chapter_chain_now].append_tools:
if tool.__name__ == "judge":
print(bb.get_active_file_reletive_path())
assert bb is not None and bb.active_file_path != "" , "no path specified"
if bb.get_active_file_reletive_path().endswith(".py"):
# self.socketio.emit('terminal', {'data': f"python {bb.get_active_file_reletive_path()}"}, room=id, namespace='/vscode')
self.socketio.emit('system_message', "代码评测中,请稍后", room=id, namespace='/agent')
agent.function_call({'name':'judge','arguments':{'filepath': bb.get_active_file_reletive_path()}})
else:
self.socketio.emit('system_message', "代码评测尚仅支持python文件", room=id, namespace='/agent')
else:
with self.app.app_context():
self.socketio.emit("system_message", "本章学习无需评测", room=id, namespace='/agent')
else:
with self.app.app_context():
self.socketio.emit("system_message", "本章学习无需评测", room=id, namespace='/agent')
except Exception as e:
if (str(e) == "no path specified"):
self.socketio.emit("system_message", "未加载IDE文件同步请尝试重新打开IDE文件或刷新页面并确保插件已连接", room=id, namespace='/agent')
import time
if __name__ == '__main__':
manager = AgentManager()
id, agent = manager.new_agent()
# Main thread logic
try:
# Your code that might be interrupted
while True:
input_data = input("用户:")
print(manager.invoke(id, input_data))
except KeyboardInterrupt:
print("Process interrupted by user.")
# You can add any cleanup code here if needed
finally:
print("Exiting program.")
# Code to run before the program exits