# myapp/sockets/namespaces.py import json import time from flask import current_app, request, session from flask_socketio import Namespace, join_room, leave_room, emit from ..function_tools import judge from ..function_tools import next_chapter from ..services.backboard_service import realtime_response from ..services.markdown_service import load_full_markdown_file from ..extension_ase.ase_client import HSAEngineClient from ..services.user_service import get_or_load_current_user class VSCodeNamespace(Namespace): def on_login(self,data): ex = current_app.extensions print("VSCode client connected") dataconfig = data['config'] user_uuid = dataconfig.get('user_uuid') path = dataconfig.get('path') course_id = dataconfig.get('course_id') lesson_id = dataconfig.get('chapter_id') print(f"User {user_uuid} connected with path: {path}") join_room(user_uuid, namespace='/vscode') chatmanager = ex['user_uuid2chatmanager'][user_uuid] chatmanager.set_vscode_ws(self) def on_load_chapter(self, data): dataconfig = data['config'] user_uuid = dataconfig.get('user_uuid') ex = current_app.extensions chatmanager = ex['user_uuid2chatmanager'][user_uuid] chatmanager.load_code_in_markdown() def on_message(self, data): # print(f"Received from VSCode client: {data}") dataconfig = data['config'] realtime_response(dataconfig, data) # emit('response', {'message': 'Config data received and connection established'}) def on_disconnect(self, data): print("VSCode client disconnected") print("Disconnect reason:"+str(data)) class AgentNamespace(Namespace): def on_login(self, data): self.current_app = current_app ex = current_app.extensions uuid2username = ex["uuid2username"] backboard_manager = ex["backboard_manager"] data = json.loads(data) user_uuid = data['user_uuid'] course_id = data['course_id'] lesson_name = data['lesson_name'] chapter_name = data['chapter_name'] user_id = uuid2username[user_uuid] session['user_uuid'] = user_uuid join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room print(f'User connected with session user_uuid: {user_uuid}') user_uuid2chatmanager = ex["user_uuid2chatmanager"] user_uuid2ase_client = ex["user_uuid2ase_client"] if (user_uuid2ase_client.get(user_uuid,None) is not None and user_uuid2ase_client[user_uuid].connected): user_uuid2ase_client[user_uuid].disconnect() chatmanager = user_uuid2chatmanager[user_uuid] chatmanager.function_manager.add_function(judge, {'course_id': course_id, 'root_path': f'/home/{user_id}/{course_id}/{chapter_name}/{lesson_name}'}) chatmanager.function_manager.add_function(next_chapter, {'user_uuid': user_uuid}) chatmanager.chat_historys = [] chatmanager.scores = [] fmd,fmdp,fsp = load_full_markdown_file(course_id, chapter_name, lesson_name) user_uuid2ase_client[user_uuid] = HSAEngineClient(current_app.config["ASE_ENGINE_URL"], current_app.config["ASE_ENGINE_NAMESPACE"],id=user_id, chatmanager = chatmanager) chatmanager.init(user_uuid, user_uuid2ase_client[user_uuid], fmd, fmdp, fsp, course_id, chapter_name, lesson_name, max_iter=5, app=current_app, socketio=self) backboard_manager.add_backboard(user_uuid, user_id, course_id, lesson_name, root_path=f'/home/{user_id}/{course_id}/{chapter_name}/{lesson_name}') chatmanager.bb = backboard_manager.get_backboard(user_uuid) chatmanager.next_chapter() self.chatmanager = chatmanager self.ase_client = user_uuid2ase_client[user_uuid] user_uuid2ase_client[user_uuid].register_on_connect_entry( callback=self.on_connect_to_ase, entry=(self, user_uuid2ase_client[user_uuid]), init_data={'room':user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='dialog', callback=self.receive_ase_dialog, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='dialog-hint', callback=self.receive_ase_message_hint, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='voice_out', callback=self.receive_ase_voice_out, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='judge', callback=self.receive_ase_judge, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='next_chapter', callback=self.receive_ase_next_chapter, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='chapter_score', callback=self.receive_ase_chapter_score, entry=(get_or_load_current_user(),chatmanager), init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='process', callback=self.receive_ase_process, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].register_route_with_entry( route='paste_detected', callback=self.receive_ase_paste_detected, entry=self, init_data={'room': user_uuid} ) user_uuid2ase_client[user_uuid].connect() def on_language(self, language): ex = current_app.extensions print(f"Language changed to: {language}") def on_message(self, data): print(f"Message from client: {data}") ex = current_app.extensions chatmanager = ex["user_uuid2chatmanager"] uuid = session.get('user_uuid') user_uuid2ase_client = ex["user_uuid2ase_client"] if (type(data)==str): data = json.loads(data) if data['type'] == 'text': res = user_uuid2ase_client[uuid].send_text('dialog', data['data']) chatmanager[uuid].chat_historys.append({'role': 'user', 'content': data['data']}) print(f"Send text to route 'dialog' success: {res}") if data['type'] == 'function': # 在这里 前端会发送允许执行的function与参数 print("function_call", data['data']) d = data['data'] res = chatmanager[uuid].function_call(d['data']['name'], d['data'].get('args', {})) d['data'] = res.to_dict() print("function_call_res", d['data']) emit(d['route'], d, room=uuid, namespace='/agent') chatmanager[uuid].chat_historys.append({'role': 'user', 'content': data['data']}) user_uuid2ase_client[uuid].send_text(d['route'], data['data']) def on_voice(self, voice_data): ex = current_app.extensions chatmanager = ex["user_uuid2chatmanager"] uuid = session.get('user_uuid') user_uuid2ase_client = ex["user_uuid2ase_client"] res = user_uuid2ase_client[uuid].send_voice('voice_in', voice_data['data']) print(f"Send voicce to route 'voice_in' success: {res}") def on_connect_to_ase(client_entry: HSAEngineClient, namespace_entry, init_data): ''' 此时刚刚建立好aseclient连接,并向前端发送打开code-server-like指令。 ''' print(f"on_connect_to_ase {client_entry}, {namespace_entry}, {init_data}") namespace_entry, ase_client = namespace_entry namespace_entry.emit('open-iframe',"", room=init_data['room'], namespace='/agent') ase_client.chatmanager.load_next_chapter() ase_client.send_text("chapter-start", "") ase_client.send_text("clear","") namespace_entry.emit('message', "Multi-Agents服务已连接", room=init_data['room'], namespace='/agent') #接受消息回来直接让message监听发送 def receive_ase_paste_detected(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): print("receive_ase_paste_detected", data) client_entry.chatmanager.chat_historys.append({'role': 'assistant', 'content': data['data']}) namespace_entry.emit('message', data['data'], room=init_data['room'], namespace='/agent') def receive_ase_dialog(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): print("receive_ase_dialog", data) client_entry.chatmanager.chat_historys.append({'role': 'assistant', 'content': data['data']}) namespace_entry.emit('message', data['data'], room=init_data['room'], namespace='/agent') def receive_ase_message_hint(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): print("receive_ase_message_hint", data) namespace_entry.emit('message-hint', data['data'], room=init_data['room'], namespace='/agent') #接受语音信息 def receive_ase_voice_out(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): namespace_entry.emit('voiceMessage', data['data'], room=init_data['room'], namespace='/agent') def receive_ase_process(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): namespace_entry.emit('process', data['data'], room=init_data['room'], namespace='/agent') def receive_ase_judge(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): print("receive_ase_judge", data) namespace_entry.emit('request_function', data, room=init_data['room'], namespace='/agent') # data 是一个列表 /dict也支持 def receive_ase_next_chapter(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data): print("receive_ase_next_chapter", data) namespace_entry.emit('request_function',data, room=init_data['room'], namespace='/agent') # data 是一个列表 /dict也支持 def receive_ase_chapter_score(client_entry: HSAEngineClient, user_and_manager, data, init_data): print("load_next_chapter") user, chatmanager = user_and_manager if len(chatmanager.scores) >= chatmanager.chapter_chain_now: chatmanager.scores[chatmanager.chapter_chain_now - 1] = data.get('data', None) else: chatmanager.scores.append(data.get('data', None)) user.set_course_progress(chatmanager.chat_historys, chatmanager.scores, chatmanager.material_id, chatmanager.chapter_name, chatmanager.lesson_name) chatmanager.load_next_chapter() time.sleep(0.5) chatmanager.ase_client.send_text("chapter-start", "") def on_initiative(self,data): # 主动call print("User active function call") ex = current_app.extensions uuid = session.get('user_uuid') manager = ex["user_uuid2chatmanager"][uuid] backboard_manager = ex["backboard_manager"] if data['name'] == 'sample_judge': manager.sample_judge(uuid, backboard_manager.get_backboard(uuid)) if data['name'] == 'judge': res = manager.judge(uuid, backboard_manager.get_backboard(uuid)) emit('message', res.message, room=uuid, namespace='/agent') def on_disconnect(self,data): ex = current_app.extensions uuid = session.get('user_uuid') user_uuid2chatmanager = ex["user_uuid2chatmanager"] user_uuid2chatmanager[uuid].disconnect(uuid) print("VSCode client disconnected") print("Disconnect reason:"+str(data))