try vscode plugin
This commit is contained in:
@@ -14,7 +14,8 @@ if __name__ == "__main__":
|
|||||||
host="0.0.0.0",
|
host="0.0.0.0",
|
||||||
port=5551,
|
port=5551,
|
||||||
debug=True, # 开发期打开
|
debug=True, # 开发期打开
|
||||||
allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示
|
allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示
|
||||||
|
ssl_context=('server.crt', 'server.key')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
from .client import ASEngineClient
|
from .client import ASEngineClient, HSAEngineClient
|
||||||
|
from .manager import ChatManager
|
||||||
@@ -56,9 +56,6 @@ class ASEngineClient:
|
|||||||
def on_response(data):
|
def on_response(data):
|
||||||
print(f"Received response: {data}")
|
print(f"Received response: {data}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def register_route_with_entry(self, route: str,
|
def register_route_with_entry(self, route: str,
|
||||||
callback: Optional[Callable] = None,
|
callback: Optional[Callable] = None,
|
||||||
entry: Any = None,
|
entry: Any = None,
|
||||||
@@ -167,9 +164,6 @@ class ASEngineClient:
|
|||||||
print("Not connected to server")
|
print("Not connected to server")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if route not in self.routes:
|
|
||||||
print(f"Route '{route}' not registered")
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.sio.emit(route, {'type': 'text', 'data': text}, namespace=self.namespace)
|
self.sio.emit(route, {'type': 'text', 'data': text}, namespace=self.namespace)
|
||||||
@@ -265,3 +259,13 @@ class ASEngineClient:
|
|||||||
self.disconnect()
|
self.disconnect()
|
||||||
else:
|
else:
|
||||||
print("Not connected to server")
|
print("Not connected to server")
|
||||||
|
|
||||||
|
|
||||||
|
class HSAEngineClient(ASEngineClient):
|
||||||
|
def __init__(self, server_url: str, namespace: str):
|
||||||
|
super().__init__(server_url, namespace)
|
||||||
|
def loadmarkdown(self, fmd, fmdp, fsp):
|
||||||
|
self.send_text('markdown-in', fmd)
|
||||||
|
self.send_text('markdown-prompt-in', fmdp)
|
||||||
|
self.send_text('score-prompt-in', fsp)
|
||||||
|
|
||||||
|
|||||||
120
Html/apps/extension_ase/ase_client/manager.py
Normal file
120
Html/apps/extension_ase/ase_client/manager.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
import configparser
|
||||||
|
from ...function_tools.function_manager import FunctionManager
|
||||||
|
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from ...utils import *
|
||||||
|
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ChatManager:
|
||||||
|
def __init__(self,user_uuid,ase_client,raw_markdown,raw_markdown_prompts,raw_score_prompts,max_iter = 5, app=None, socketio=None):
|
||||||
|
self.chapter_chain_now = -1
|
||||||
|
self.ase_client = ase_client
|
||||||
|
self.app = app
|
||||||
|
self.socketio = socketio
|
||||||
|
self.user_uuid = user_uuid
|
||||||
|
self.raw_markdown = raw_markdown
|
||||||
|
self.raw_markdown_prompts = raw_markdown_prompts
|
||||||
|
self.raw_score_prompts = raw_score_prompts
|
||||||
|
self.chapter_chain = load_chapters(raw_markdown, raw_markdown_prompts, raw_score_prompts)
|
||||||
|
self.function_manager = FunctionManager()
|
||||||
|
|
||||||
|
|
||||||
|
def next_chapter(self):
|
||||||
|
assert self.chapter_chain_now + 1 < len(self.chapter_chain), "chapter_chain_now out of range"
|
||||||
|
self.chapter_chain_now += 1
|
||||||
|
self.focus_chapter(self.chapter_chain_now)
|
||||||
|
|
||||||
|
def focus_chapter(self, chapter_index):
|
||||||
|
assert chapter_index < len(self.chapter_chain), "chapter_index out of range"
|
||||||
|
self.chapter_chain_now = chapter_index
|
||||||
|
self.chapter_chain[chapter_index].Focus()
|
||||||
|
self.ase_client.loadmarkdown(self.chapter_chain[chapter_index].chapter, self.chapter_chain[chapter_index].chapter_prompt, self.chapter_chain[chapter_index].score_prompt)
|
||||||
|
|
||||||
|
|
||||||
|
def message_pass(self, messagetype, message):
|
||||||
|
print("message_pass", self.user_uuid, messagetype, message)
|
||||||
|
with self.app.app_context():
|
||||||
|
try:
|
||||||
|
self.socketio.emit(messagetype, message, room=self.user_uuid, 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=self.user_uuid, 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):
|
||||||
|
|
||||||
|
self.app.my_function.save_chapter_memory(self.user_uuid, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def function_call(self, function_name, arg_function):
|
||||||
|
return self.function_manager.call_function(function_name, arg_function)
|
||||||
|
|
||||||
|
def change_language(self, id, language):
|
||||||
|
self.ase_client.send_text('language', language)
|
||||||
|
|
||||||
|
def sample_judge(self, id, bb):
|
||||||
|
self.function_manager.call_function('sample_judge', {'bb': bb})
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ course_list = CourseList()
|
|||||||
user_uuid2UserClass = {}
|
user_uuid2UserClass = {}
|
||||||
|
|
||||||
user_uuid2ase_client = {}
|
user_uuid2ase_client = {}
|
||||||
|
user_uuid2chatmanager = {}
|
||||||
from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager
|
from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager
|
||||||
agent_manager = AgentManager()
|
agent_manager = AgentManager()
|
||||||
def init_extensions(app):
|
def init_extensions(app):
|
||||||
@@ -43,7 +43,7 @@ def init_extensions(app):
|
|||||||
)
|
)
|
||||||
cors.init_app(
|
cors.init_app(
|
||||||
app,
|
app,
|
||||||
resources={r"/*": {"origins": app.config["VSCODE_WEB_URL"]}},
|
resources={r"/*": {"origins": "*"}},#app.config["VSCODE_WEB_URL"]}},
|
||||||
supports_credentials=True,
|
supports_credentials=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -59,6 +59,7 @@ def init_extensions(app):
|
|||||||
app.extensions["agent_manager"] = agent_manager
|
app.extensions["agent_manager"] = agent_manager
|
||||||
app.extensions["my_function"] = MyFunction()
|
app.extensions["my_function"] = MyFunction()
|
||||||
app.extensions["user_uuid2ase_client"] = user_uuid2ase_client
|
app.extensions["user_uuid2ase_client"] = user_uuid2ase_client
|
||||||
|
app.extensions["user_uuid2chatmanager"] = user_uuid2chatmanager
|
||||||
mongo.init_app(app,uri=app.config["MONGO_URI"])
|
mongo.init_app(app,uri=app.config["MONGO_URI"])
|
||||||
app.extensions["mongo"] = mongo
|
app.extensions["mongo"] = mongo
|
||||||
|
|
||||||
|
|||||||
2
Html/apps/function_tools/__init__.py
Normal file
2
Html/apps/function_tools/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from . import judge
|
||||||
|
from .function_manager import FunctionManager
|
||||||
18
Html/apps/function_tools/function_manager.py
Normal file
18
Html/apps/function_tools/function_manager.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from typing import Callable
|
||||||
|
class FunctionManager:
|
||||||
|
def __init__(self):
|
||||||
|
self.function_caller = {}
|
||||||
|
self.function_predifine_args = {}
|
||||||
|
|
||||||
|
def add_function(self, function:Callable, predifine_args:dict):
|
||||||
|
self.function_caller[function.__name__] = function
|
||||||
|
self.function_predifine_args[function.__name__] = predifine_args
|
||||||
|
|
||||||
|
def get_function(self, function_name:str):
|
||||||
|
return self.function_caller[function_name]
|
||||||
|
|
||||||
|
def get_function_predifine_args(self, function_name:str):
|
||||||
|
return self.function_predifine_args[function_name]
|
||||||
|
|
||||||
|
def call_function(self, function_name:str, args:dict):
|
||||||
|
return self.function_caller[function_name]( **args, **self.function_predifine_args[function_name])
|
||||||
74
Html/apps/function_tools/judge.py
Normal file
74
Html/apps/function_tools/judge.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
from ..models.function import FunctionResponse, FunctionStatus
|
||||||
|
def judge(filepath:str, name: str, course_id: str, lesson_id: str, root_path:str):
|
||||||
|
"""Call this method to judge the student's solution after they have completed the problem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath (`str`): The path to the file containing the student's solution.
|
||||||
|
name (`str`): The name of the problem.
|
||||||
|
course_id (`str`): The id of the course.
|
||||||
|
lesson_id (`str`): The id of the lesson.
|
||||||
|
root_path (`str`): The root path of the user's workspace project.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Report `tuple(int,str)`: The report of the student's solution.
|
||||||
|
"""
|
||||||
|
# 从books/code_tests/name/中获取所有.in文件
|
||||||
|
|
||||||
|
directory = 'books/code_tests/'+course_id+'/'+name
|
||||||
|
# 如果目录不存在,报错
|
||||||
|
if not os.path.exists(directory):
|
||||||
|
status = FunctionStatus.FAILED
|
||||||
|
return FunctionResponse("judge", status, f"The name {name} is not found.")
|
||||||
|
files = os.listdir(directory)
|
||||||
|
in_files = [file for file in files if file.endswith('.in')]
|
||||||
|
save_dir = root_path
|
||||||
|
Report = ""
|
||||||
|
passed_num=0
|
||||||
|
failed_num=0
|
||||||
|
erroroutput = ""
|
||||||
|
exceptoutput=""
|
||||||
|
for file in in_files:
|
||||||
|
file_path = os.path.join(save_dir, f"_{name}.out")
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
os.remove(file_path)
|
||||||
|
with open(file_path, 'w') as ff:
|
||||||
|
ff.write("")
|
||||||
|
|
||||||
|
cmd = "cat " + os.path.join(directory, file) + " | " + "python " + os.path.join(root_path, filepath) +" > " + os.path.join(save_dir, f"_{name}.out")
|
||||||
|
os.system(cmd)
|
||||||
|
# 比较结果
|
||||||
|
re = ""
|
||||||
|
if compare_file(os.path.join(save_dir, f"_{name}.out"), os.path.join(directory, file.replace(".in", ".out"))):
|
||||||
|
re = f"Passed {file}"
|
||||||
|
passed_num += 1
|
||||||
|
else:
|
||||||
|
re = f"Failed {file}"
|
||||||
|
failed_num += 1
|
||||||
|
with open(os.path.join(directory, file.replace(".in", ".out")),'r') as f: exceptoutput = f.read()
|
||||||
|
with open(os.path.join(save_dir, f"_{name}.out"),'r') as f: erroroutput = f.read()
|
||||||
|
Report = Report + re + "\n"
|
||||||
|
os.remove(os.path.join(save_dir, f"_{name}.out"))
|
||||||
|
score = int (100 * passed_num / (passed_num + failed_num))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
status = FunctionStatus.SUCCESS
|
||||||
|
return FunctionResponse("judge", status, f"评测得分为 {score}, 在 {passed_num + failed_num} 个测试用例中通过了 {passed_num}个。最后一个错误样例期望输出:'{exceptoutput}',但你的输出:'{erroroutput}")
|
||||||
|
|
||||||
|
|
||||||
|
def compare_file(path1:str, path2:str):
|
||||||
|
"""
|
||||||
|
Compare two files and return true if they are the same.
|
||||||
|
"""
|
||||||
|
with open(path1, 'r') as f1, open(path2, 'r') as f2:
|
||||||
|
# 逐行比较
|
||||||
|
print('-------------------COMPARE-------------------------')
|
||||||
|
for line1, line2 in zip(f1, f2):
|
||||||
|
print(line1.strip(), "||",line2.strip())
|
||||||
|
if line1.strip() != line2.strip():
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
judge_tools = [judge]
|
||||||
11
Html/apps/models/function.py
Normal file
11
Html/apps/models/function.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
FunctionStatus = Enum("FunctionStatus", ["SUCCESS", "ERROR"])
|
||||||
|
|
||||||
|
class FunctionResponse(BaseModel):
|
||||||
|
name: str
|
||||||
|
status: FunctionStatus
|
||||||
|
message: str = ""
|
||||||
|
args: Optional[dict] = None
|
||||||
@@ -2,10 +2,13 @@
|
|||||||
import json
|
import json
|
||||||
from flask import current_app, request, session
|
from flask import current_app, request, session
|
||||||
from flask_socketio import Namespace, join_room, leave_room, emit
|
from flask_socketio import Namespace, join_room, leave_room, emit
|
||||||
|
|
||||||
|
from ..function_tools import judge
|
||||||
from ..services.memory_service import save_chapter_memory_by_uuid
|
from ..services.memory_service import save_chapter_memory_by_uuid
|
||||||
from ..services.backboard_service import realtime_response
|
from ..services.backboard_service import realtime_response
|
||||||
from ..services.markdown_service import load_full_markdown_file
|
from ..services.markdown_service import load_full_markdown_file
|
||||||
from ..extension_ase.ase_client import ASEngineClient
|
from ..extension_ase.ase_client import HSAEngineClient, ChatManager
|
||||||
|
|
||||||
|
|
||||||
class VSCodeNamespace(Namespace):
|
class VSCodeNamespace(Namespace):
|
||||||
def on_login(self,data):
|
def on_login(self,data):
|
||||||
@@ -50,32 +53,32 @@ class AgentNamespace(Namespace):
|
|||||||
user_id = uuid2username[user_uuid]
|
user_id = uuid2username[user_uuid]
|
||||||
session['user_uuid'] = user_uuid
|
session['user_uuid'] = user_uuid
|
||||||
print(f'User connected with session user_uuid: {user_uuid}')
|
print(f'User connected with session user_uuid: {user_uuid}')
|
||||||
|
user_uuid2chatmanager = ex["user_uuid2chatmanager"]
|
||||||
user_uuid2ase_client = ex["user_uuid2ase_client"]
|
user_uuid2ase_client = ex["user_uuid2ase_client"]
|
||||||
user_uuid2ase_client[user_uuid] = ASEngineClient(current_app.config["ASE_ENGINE_URL"], current_app.config["ASE_ENGINE_NAMESPACE"])
|
user_uuid2ase_client[user_uuid] = HSAEngineClient(current_app.config["ASE_ENGINE_URL"], current_app.config["ASE_ENGINE_NAMESPACE"])
|
||||||
user_uuid2ase_client[user_uuid].connect()
|
user_uuid2ase_client[user_uuid].connect()
|
||||||
user_uuid2ase_client[user_uuid].register_route_with_entry(
|
user_uuid2ase_client[user_uuid].register_route_with_entry(
|
||||||
route='dialog',
|
route='dialog',
|
||||||
callback=self.receive_ase_dialog,
|
callback=self.receive_ase_dialog,
|
||||||
entry=self, # 传你的 Namespace 对象
|
entry=self,
|
||||||
init_data={'room': user_uuid} # 想传啥都可以
|
init_data={'room': user_uuid}
|
||||||
)
|
)
|
||||||
|
|
||||||
fmd,fmdp,fsp = load_full_markdown_file(course_id, chapter_name, lesson_name)
|
fmd,fmdp,fsp = load_full_markdown_file(course_id, chapter_name, lesson_name)
|
||||||
# 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent
|
user_uuid2chatmanager[user_uuid] = ChatManager(user_uuid, user_uuid2ase_client[user_uuid], fmd, fmdp, fsp, max_iter=5, app=current_app, socketio=self)
|
||||||
|
chatmanager = user_uuid2chatmanager[user_uuid]
|
||||||
|
chatmanager.function_manager.add_function(judge, {'course_id': course_id, 'lesson_name': lesson_name, 'root_path': f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}'})
|
||||||
|
|
||||||
|
user_uuid2ase_client[user_uuid].loadmarkdown(fmd, fmdp, fsp)
|
||||||
|
|
||||||
user_uuid, agent = agent_manager.new_agent(course_id, lesson_name, fmd, fmdp, fsp, id=user_uuid,
|
|
||||||
root_path=f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}')
|
|
||||||
print(user_uuid)
|
|
||||||
join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room
|
join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room
|
||||||
backboard_manager.add_backboard(user_uuid, user_id, course_id, lesson_name, root_path=f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}')
|
backboard_manager.add_backboard(user_uuid, user_id, course_id, lesson_name, root_path=f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}')
|
||||||
|
|
||||||
|
chatmanager.focus_chapter(0)
|
||||||
|
|
||||||
def on_language(self, language):
|
def on_language(self, language):
|
||||||
ex = current_app.extensions
|
ex = current_app.extensions
|
||||||
agent_manager = ex["agent_manager"]
|
print(f"Language changed to: {language}")
|
||||||
uuid2username = ex["uuid2username"]
|
|
||||||
uuid = session.get('user_uuid')
|
|
||||||
user_id = uuid2username[uuid]
|
|
||||||
agent_manager.change_language(uuid, language)
|
|
||||||
|
|
||||||
def on_message(self, data):
|
def on_message(self, data):
|
||||||
print(f"Message from client: {data}")
|
print(f"Message from client: {data}")
|
||||||
@@ -89,7 +92,6 @@ class AgentNamespace(Namespace):
|
|||||||
if (type(data)==str):
|
if (type(data)==str):
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
if data['type'] == 'text':
|
if data['type'] == 'text':
|
||||||
# res = agent_manager.invoke(uuid, data['data'], backboard_manager.get_backboard(uuid).get_info_prompt())
|
|
||||||
user_uuid2ase_client[uuid].send_text('dialog', data['data'])
|
user_uuid2ase_client[uuid].send_text('dialog', data['data'])
|
||||||
# print('=*='*20)
|
# print('=*='*20)
|
||||||
# print(res.content)
|
# print(res.content)
|
||||||
@@ -102,12 +104,11 @@ class AgentNamespace(Namespace):
|
|||||||
agent_manager.function_call(uuid, data['data'])
|
agent_manager.function_call(uuid, data['data'])
|
||||||
|
|
||||||
|
|
||||||
def receive_ase_dialog(client_entry: ASEngineClient, namespace_entry: Namespace, data, init_data):
|
def receive_ase_dialog(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data):
|
||||||
print(f"Received from ASEngine: {data}")
|
|
||||||
# 直接使用 entry(也就是你的 Namespace 对象)
|
|
||||||
namespace_entry.emit('message', data['data'], room=init_data['room'], namespace='/agent')
|
namespace_entry.emit('message', data['data'], room=init_data['room'], namespace='/agent')
|
||||||
|
|
||||||
|
def receive_ase_function(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data):
|
||||||
|
namespace_entry.emit('request_function', data['data'], room=init_data['room'], namespace='/agent')
|
||||||
|
|
||||||
def on_initiative(self,data):
|
def on_initiative(self,data):
|
||||||
print("User active function call")
|
print("User active function call")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ let system_message_idx=0
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
data = window.appData;
|
data = window.appData;
|
||||||
console.log(data);
|
console.log(data);
|
||||||
socket = io('ws://localhost:5551/agent',{
|
socket = io('wss://localhost:5551/agent',{
|
||||||
query:{
|
query:{
|
||||||
user_uuid:data.user_uuid,
|
user_uuid:data.user_uuid,
|
||||||
folder:data.folder
|
folder:data.folder
|
||||||
|
|||||||
1
Html/apps/utils/__init__.py
Normal file
1
Html/apps/utils/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .chapterUtil import *
|
||||||
159
Html/apps/utils/chapterUtil.py
Normal file
159
Html/apps/utils/chapterUtil.py
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
from typing import Callable, Any
|
||||||
|
from AlgoriAgent.projects.algoriAgent.tools.judge_tools import judge
|
||||||
|
|
||||||
|
CHAPTER_FINISH = 0
|
||||||
|
CHAPTER_FOCUS = 1
|
||||||
|
CHAPTER_LATTER = 2
|
||||||
|
CHAPTER_FAILED = 3
|
||||||
|
|
||||||
|
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, {"name": tool_args[0]}))
|
||||||
|
return tools
|
||||||
|
|
||||||
|
class Chapter():
|
||||||
|
def __init__(self, No = 1, focus = 2,title="", chapter = "", chapter_prompt = "",
|
||||||
|
score_prompt = "", append_tools : list[Callable[..., Any], dict] = None) -> None:
|
||||||
|
'''
|
||||||
|
No : 序号
|
||||||
|
focus : 0: Finished, 1: Focus, 2: Latter, 3: Failed
|
||||||
|
title : 子章节标题
|
||||||
|
chapter : 教案子章节内容
|
||||||
|
chapter_prompt : 教案的提示
|
||||||
|
score_prompt : 评测标准
|
||||||
|
append_tools : 追加工具函数
|
||||||
|
'''
|
||||||
|
self.No = No
|
||||||
|
self.focus = focus
|
||||||
|
self.chapter = chapter
|
||||||
|
self.chapter_prompt = chapter_prompt
|
||||||
|
self.score_prompt = score_prompt
|
||||||
|
self.append_tools = append_tools
|
||||||
|
self.memory = None
|
||||||
|
self.title =title
|
||||||
|
|
||||||
|
|
||||||
|
def GetChapter(self):
|
||||||
|
if self.focus == CHAPTER_FINISH: f = "(Finished Chapter)"
|
||||||
|
elif self.focus == CHAPTER_FOCUS: f = "(Your Now Chapter)"
|
||||||
|
elif self.focus == CHAPTER_LATTER: f = "(Ignore for Latter Chapter)"
|
||||||
|
elif self.focus == CHAPTER_FAILED: f = "(Failed Chapter)"
|
||||||
|
# des = f"{f} Chapter {self.No}: {self.chapter if self.focus else 'Hidden for further study.'}"
|
||||||
|
des = f"{f} Chapter {self.No}: "
|
||||||
|
if self.focus == CHAPTER_FINISH or self.focus == CHAPTER_FAILED: des += 'Hidden due to finished.'
|
||||||
|
if self.focus == CHAPTER_LATTER: des += 'Hidden for further study.'
|
||||||
|
if self.focus == CHAPTER_FOCUS:
|
||||||
|
des+=self.chapter
|
||||||
|
des+='\n'
|
||||||
|
des+='Here are some concrete instructions:\n'
|
||||||
|
des+=self.chapter_prompt+'\n'
|
||||||
|
|
||||||
|
return des
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def Finished(self, successful: bool = True):
|
||||||
|
if successful: self.focus = 0
|
||||||
|
else: self.focus = 3
|
||||||
|
|
||||||
|
def Focus(self):
|
||||||
|
self.focus = 1
|
||||||
|
def load_chapters(markdown, markdown_prompt, score_prompt):
|
||||||
|
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( 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
|
||||||
|
return chapter_chain
|
||||||
@@ -62,7 +62,10 @@ def desktop_nouser(course_id, chapter_name, lesson_name):
|
|||||||
|
|
||||||
@bp.route("/vscode_data", methods=["POST"])
|
@bp.route("/vscode_data", methods=["POST"])
|
||||||
def vscode_data():
|
def vscode_data():
|
||||||
data = request.get_json(force=True)
|
# data = request.get_json(force=True)
|
||||||
config = data.get("config") or {}
|
# config = data.get("config") or {}
|
||||||
realtime_response(config, data) # 调用服务层逻辑
|
|
||||||
return jsonify({"status": "success", "received": data})
|
# realtime_response(config, data) # 调用服务层逻辑
|
||||||
|
# return jsonify({"status": "success", "received": data})
|
||||||
|
|
||||||
|
return jsonify({"status": "success", "received": "success"})
|
||||||
|
|||||||
22
Html/server.crt
Normal file
22
Html/server.crt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDoTCCAokCFF/OMLJof3ypmpQCK3zGNpJ15pDBMA0GCSqGSIb3DQEBCwUAMIGM
|
||||||
|
MQswCQYDVQQGEwJVUzESMBAGA1UECAwJU29tZVN0YXRlMREwDwYDVQQHDAhTb21l
|
||||||
|
Q2l0eTEQMA4GA1UECgwHU29tZU9yZzERMA8GA1UECwwIU29tZVVuaXQxEjAQBgNV
|
||||||
|
BAMMCWxvY2FsaG9zdDEdMBsGCSqGSIb3DQEJARYOeW91ckBlbWFpbC5jb20wHhcN
|
||||||
|
MjUwOTEwMTYzMTU4WhcNMjYwOTEwMTYzMTU4WjCBjDELMAkGA1UEBhMCVVMxEjAQ
|
||||||
|
BgNVBAgMCVNvbWVTdGF0ZTERMA8GA1UEBwwIU29tZUNpdHkxEDAOBgNVBAoMB1Nv
|
||||||
|
bWVPcmcxETAPBgNVBAsMCFNvbWVVbml0MRIwEAYDVQQDDAlsb2NhbGhvc3QxHTAb
|
||||||
|
BgkqhkiG9w0BCQEWDnlvdXJAZW1haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||||
|
AQ8AMIIBCgKCAQEA0BFtyncXSrEEXn0iCSumufiJMwIf+qmes3tv8db05yHPjReD
|
||||||
|
gDvwzSmm4+5lDo/EkMK64gOXAoqy7nO/40OyEnIOBbWrUg6M9gPM6F9DEJZsM9Ae
|
||||||
|
M/1lkwnsJ3IgbKSf2uw+riwBAfnnClDWvEkIqH96d4352yQba694k7Zn936NnzWd
|
||||||
|
ROYaLXqy4HoR2UYOM4nzaPq9EoANLsPNgftQjWMDVhsAnt7FtDnvT+86wB4KWKXA
|
||||||
|
QVIw2QmjrhaeajpL2N4xG5SQxb6mlFaZKw/sCHAo5JqmRhQ9p7CAE47DYHIDC+Sp
|
||||||
|
GHaJJKrbA81RLU1iTLtmsYrpRHNp+S2f1nJODQIDAQABMA0GCSqGSIb3DQEBCwUA
|
||||||
|
A4IBAQAhagxrnwPkVpdM6tqaaEE4xGdWxrIuipBNXTbtYd/8WOhVDDaLWjMo0vG4
|
||||||
|
70Pgq+HJ166XdL00ZTj4UfcC1Ls5qRLkfimb/Rz59BfK0iE8QVEKt6yfJWUD6HuI
|
||||||
|
y2tl9hqUJrW1OTcMgEOV6Dg+RX3VpDcDML5SJ17r9IqaaB0HAV9IVGt+jK1ZzUBp
|
||||||
|
h0iQUrH3+x9xR5x41Vz2TKgeFuxYnwqGPhCdRdDX2prYWDMV4awAkUvx/5oyCw3q
|
||||||
|
juisnWoyzFw1WMiA9Hl+29XL1k5X1QE9gLrW3qvhB/OnrRaYK3sfHZMSYSrr+CDJ
|
||||||
|
+bT/JOuQBdTSsc4VCLphezh8C1Sy
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
Html/server.key
Normal file
28
Html/server.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQEW3KdxdKsQRe
|
||||||
|
fSIJK6a5+IkzAh/6qZ6ze2/x1vTnIc+NF4OAO/DNKabj7mUOj8SQwrriA5cCirLu
|
||||||
|
c7/jQ7IScg4FtatSDoz2A8zoX0MQlmwz0B4z/WWTCewnciBspJ/a7D6uLAEB+ecK
|
||||||
|
UNa8SQiof3p3jfnbJBtrr3iTtmf3fo2fNZ1E5hoterLgehHZRg4zifNo+r0SgA0u
|
||||||
|
w82B+1CNYwNWGwCe3sW0Oe9P7zrAHgpYpcBBUjDZCaOuFp5qOkvY3jEblJDFvqaU
|
||||||
|
VpkrD+wIcCjkmqZGFD2nsIATjsNgcgML5KkYdokkqtsDzVEtTWJMu2axiulEc2n5
|
||||||
|
LZ/Wck4NAgMBAAECggEAE3JAOyc0mj//eF9PR4vOCjKUNsa7kL9lUZa3UziJF3MT
|
||||||
|
BWJNtuCjSbbbXhE2s7eJzRJ4yffrl2AO3MzHrJNz+K0H6iOyY+Rv60GsAd8paEr5
|
||||||
|
c5bqGRIqpKVNmNrd9Jl8RpyZjR4YEq8LF206bKA80Ba+A5+AMH7oQIEcDrOCdbXc
|
||||||
|
m9JYo0yiehyZyVtPZJjw70uAstJ+n/gFhIh1B7kSaIbKCPLmHHph19jnWAEXKVLX
|
||||||
|
Hzb7Q5BhcCqiON7RJ3kDlomGiMmS/xuqjdbsruNcdg2ze/iAA2Gvw7Y52Q4/q69e
|
||||||
|
y/yxupS5FeFz9YjrmSJavws8ttZTVb1Y2W3ZoUFFZwKBgQDq5ZZXsWieslAq6x6S
|
||||||
|
MAwIz4NGAlui721QBG8aFipMr3B/wi9PJHqNkkCywYnm26xjkkpRsiPlWkbnfbeB
|
||||||
|
7mw6t1Yo58qZPNCxVKpl8cFX76mzhNyPEjI7b2N7fmiwJZQx6QXEQ98XEWeWrPVg
|
||||||
|
7E5SN4/aw6EScxC/Qlwf9CgjLwKBgQDiws4R14/+K4lv9omdobs+AX2TqZ/XugQR
|
||||||
|
zClLWgHziPhj+lzJlbuFqM6h+aFKETTCPRlJGjDy42R+FrU4rtfhEmILaEyuox02
|
||||||
|
0xHfNdJ7bziQSiRrOqNmpKIhZvt71ozh0XuRBwFMQOwFI5nnCvbyGWRep9ChMw8m
|
||||||
|
czFqhb1DgwKBgQCLu6vl2smLrjN2dIupFx/xldBXs0tj794tPZYCBLGBENRxi8is
|
||||||
|
4dxtn1URgYRRathwGzROyRQFeeC4ENc7WePUQf/lMY4Z/k1/UAhVwKztbMqc2iqC
|
||||||
|
iaaMKMUbT6VjM9emoSInEOEDTf07awRFdg1ZZ2gSEVIeMYkC3a0D7TB7TQKBgQCD
|
||||||
|
KPBuq4OTHXWSeERjE9As7knHZj6ZVfPSo4djGT21so0RrxeKVfwwNFLIp44ePFOK
|
||||||
|
4jJE8UxMwTA4KkRJ8//UJIDnXj20aY6VToKw2/3R/aP2+ZuVFka7MRDCR0HBAHle
|
||||||
|
iH9zhFzA0XBzDIOReusZX4yJn4FyLAlgURLNLWwqpwKBgB/hh4aM0oUcl3KNnvMY
|
||||||
|
Vd/PFTiGgwfTebOpIAMBiyquAjDyto659M6N2ZE5kMipvfX+mqaV0ZLTw1rKzVhp
|
||||||
|
qvUVtFXlZipkb6yCFnkLvvoC+FJrobKK0cqZ3KlIcfx3hkt07ykmcqd8Q2rV7qMT
|
||||||
|
8/exXLRwkWtd0Tfq52ZLH+Yw
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
Reference in New Issue
Block a user