try vscode plugin
This commit is contained in:
@@ -14,7 +14,8 @@ if __name__ == "__main__":
|
||||
host="0.0.0.0",
|
||||
port=5551,
|
||||
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):
|
||||
print(f"Received response: {data}")
|
||||
|
||||
|
||||
|
||||
|
||||
def register_route_with_entry(self, route: str,
|
||||
callback: Optional[Callable] = None,
|
||||
entry: Any = None,
|
||||
@@ -167,10 +164,7 @@ class ASEngineClient:
|
||||
print("Not connected to server")
|
||||
return False
|
||||
|
||||
if route not in self.routes:
|
||||
print(f"Route '{route}' not registered")
|
||||
return False
|
||||
|
||||
|
||||
try:
|
||||
self.sio.emit(route, {'type': 'text', 'data': text}, namespace=self.namespace)
|
||||
print(f"Sent text to route '{route}': {text}")
|
||||
@@ -264,4 +258,14 @@ class ASEngineClient:
|
||||
print("Client stopped by user")
|
||||
self.disconnect()
|
||||
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_uuid2ase_client = {}
|
||||
|
||||
user_uuid2chatmanager = {}
|
||||
from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager
|
||||
agent_manager = AgentManager()
|
||||
def init_extensions(app):
|
||||
@@ -43,7 +43,7 @@ def init_extensions(app):
|
||||
)
|
||||
cors.init_app(
|
||||
app,
|
||||
resources={r"/*": {"origins": app.config["VSCODE_WEB_URL"]}},
|
||||
resources={r"/*": {"origins": "*"}},#app.config["VSCODE_WEB_URL"]}},
|
||||
supports_credentials=True,
|
||||
)
|
||||
|
||||
@@ -59,6 +59,7 @@ def init_extensions(app):
|
||||
app.extensions["agent_manager"] = agent_manager
|
||||
app.extensions["my_function"] = MyFunction()
|
||||
app.extensions["user_uuid2ase_client"] = user_uuid2ase_client
|
||||
app.extensions["user_uuid2chatmanager"] = user_uuid2chatmanager
|
||||
mongo.init_app(app,uri=app.config["MONGO_URI"])
|
||||
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
|
||||
from flask import current_app, request, session
|
||||
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.backboard_service import realtime_response
|
||||
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):
|
||||
def on_login(self,data):
|
||||
@@ -50,32 +53,32 @@ class AgentNamespace(Namespace):
|
||||
user_id = uuid2username[user_uuid]
|
||||
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[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].register_route_with_entry(
|
||||
route='dialog',
|
||||
callback=self.receive_ase_dialog,
|
||||
entry=self, # 传你的 Namespace 对象
|
||||
init_data={'room': user_uuid} # 想传啥都可以
|
||||
entry=self,
|
||||
init_data={'room': user_uuid}
|
||||
)
|
||||
|
||||
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_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)
|
||||
user_uuid2ase_client[user_uuid].loadmarkdown(fmd, fmdp, fsp)
|
||||
|
||||
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}')
|
||||
|
||||
chatmanager.focus_chapter(0)
|
||||
|
||||
def on_language(self, language):
|
||||
ex = current_app.extensions
|
||||
agent_manager = ex["agent_manager"]
|
||||
uuid2username = ex["uuid2username"]
|
||||
uuid = session.get('user_uuid')
|
||||
user_id = uuid2username[uuid]
|
||||
agent_manager.change_language(uuid, language)
|
||||
print(f"Language changed to: {language}")
|
||||
|
||||
def on_message(self, data):
|
||||
print(f"Message from client: {data}")
|
||||
@@ -89,7 +92,6 @@ class AgentNamespace(Namespace):
|
||||
if (type(data)==str):
|
||||
data = json.loads(data)
|
||||
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'])
|
||||
# print('=*='*20)
|
||||
# print(res.content)
|
||||
@@ -102,12 +104,11 @@ class AgentNamespace(Namespace):
|
||||
agent_manager.function_call(uuid, data['data'])
|
||||
|
||||
|
||||
def receive_ase_dialog(client_entry: ASEngineClient, namespace_entry: Namespace, data, init_data):
|
||||
print(f"Received from ASEngine: {data}")
|
||||
# 直接使用 entry(也就是你的 Namespace 对象)
|
||||
def receive_ase_dialog(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data):
|
||||
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):
|
||||
print("User active function call")
|
||||
|
||||
@@ -4,7 +4,7 @@ let system_message_idx=0
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
data = window.appData;
|
||||
console.log(data);
|
||||
socket = io('ws://localhost:5551/agent',{
|
||||
socket = io('wss://localhost:5551/agent',{
|
||||
query:{
|
||||
user_uuid:data.user_uuid,
|
||||
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"])
|
||||
def vscode_data():
|
||||
data = request.get_json(force=True)
|
||||
config = data.get("config") or {}
|
||||
realtime_response(config, data) # 调用服务层逻辑
|
||||
return jsonify({"status": "success", "received": data})
|
||||
# data = request.get_json(force=True)
|
||||
# config = data.get("config") or {}
|
||||
|
||||
# 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