from flask import Flask, session, request, jsonify, render_template, send_from_directory from flask_cors import CORS from flask_socketio import SocketIO, join_room, emit, Namespace import markdown import os import uuid import shutil import sys import json parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, parent_dir) current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) sys.path.insert(0, current_dir) from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager app = Flask(__name__) # socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 import logging app.secret_key = 'cakebaker' app.logger.setLevel(logging.DEBUG) # 配置 CORS # CORS(app, resources={r"/*": {"origins": "http://localhost:9888"}}, supports_credentials=True) userid_recorder = {} # user_id&path -> session['user_id'] ''' Backboard ''' from backboardManager import BackBoardManager, Backboard backboard_manager = BackBoardManager() uuid2user_id = {} user_id2uuid = {} # 定义命名空间:用于和 VSCode 插件交流 class VSCodeNamespace(Namespace): def on_login(self,data): print(f"New login from VSCode client: {data}") def on_message(self, data): print(f"Received from VSCode client: {data}") data = json.loads(data) datatype = data['type'] dataconfig = data['config'] user_id = dataconfig.get('user_id') path = dataconfig.get('path') print(f"User {user_id} connected with path: {path}") emit('response', {'message': 'Config data received and connection established'}) def on_disconnect(self): print("VSCode client disconnected") @app.route('/backboard') def backboard(): return jsonify({'status': 'success'}) def realtime_response(config, realtime_action): user_id = config['user_id'] folder_path = config['path'] useruuid = user_id2uuid[user_id] if backboard_manager.get_backboard(useruuid) == None: backboard_manager.add_backboard(useruuid, folder_path) bb = backboard_manager.get_backboard(useruuid) assert type(bb) == Backboard bb.add_history(realtime_action) if realtime_action['type'] == 'workspaceFolders': bb.file_tree = realtime_action['fileTree'] if realtime_action['type'] == 'activeFile': file_path = realtime_action['filePath'] assert type(file_path) == str file_path = "".join(file_path.split(f'/{user_id}/{folder_path}/')[1:]) bb.active_file_path = file_path with open(f"../{user_id}/{folder_path}/{file_path}") as f: bb.active_file_content = f.read() if realtime_action['type'] == 'paste': file_path = realtime_action['filePath'] file_path = "".join(file_path.split(f'/{user_id}/{folder_path}/')[1:]) bb.pasted_file_path = file_path bb.pasted_content = realtime_action['content'] print("config"+str(config)) print("realtime_action"+str(realtime_action)) pass ''' Agent and Chat ''' agent_manager = AgentManager() class AgentNamespace(Namespace): def on_login(self, data): data = json.loads(data) user = data['username'] folder_name = data['folder'] user_uuid = user_id2uuid[user] session['user_id'] = user_uuid print(f'User connected with session user_id: {user_uuid}') # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent with open(f'books/markdown/{folder_name}.md','r') as fmd,\ open(f'books/markdown_prompts/{folder_name}.md','r')as fmdp,\ open(f'books/score_prompts/{folder_name}.md','r') as fsp: markdown = fmd.read() markdown_prompts = fmdp.read() score_prompts = fsp.read() user_uuid, agent = agent_manager.new_agent(markdown, markdown_prompts, score_prompts, id=user_uuid) join_room(user_uuid) # 将该用户加入以user_id为名的room def on_message(self, data): print(f"Message from client: {data}") id = session.get('user_id') print(id) # 构造回复消息 res = agent_manager.invoke(id, data, backboard_manager.get_backboard(id).get_info_prompt()) reply = f"AI: {res.content['speak']}" # 将回复发送回前端 emit('message', reply) def on_disconnect(self): print("VSCode client disconnected") ''' Markdown to HTML ''' # 配置文件路径 MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 @app.route('/-markdown', methods=['GET']) def convert_md(filename): md_file_path = os.path.join(MARKDOWN_DIR, f'{filename}.md') if not os.path.exists(md_file_path): return jsonify({'error': 'Markdown file not found'}), 404 # 读取 markdown 文件内容 with open(md_file_path, 'r', encoding='utf-8') as file: md_content = file.read() # 将 markdown 转换为 HTML html_content = markdown.markdown(md_content) # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 html_with_styles = f""" {html_content} """ # 保存 HTML 文件到 static 文件夹 html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') with open(html_output_path, 'w', encoding='utf-8') as html_file: html_file.write(html_with_styles) # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx image_source_dir = os.path.join(MARKDOWN_DIR, IMAGE_DIR, filename) image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) print(f"Copying image resources from {image_source_dir} to {image_target_dir}") if os.path.exists(image_source_dir): # 确保 static/image/xxx 目录存在 if not os.path.exists(image_target_dir): os.makedirs(image_target_dir) # 拷贝图片资源 for image_file in os.listdir(image_source_dir): full_image_file_path = os.path.join(image_source_dir, image_file) if os.path.isfile(full_image_file_path): shutil.copy(full_image_file_path, image_target_dir) return jsonify({'html_url': f'/static/{filename}.html'}) # 静态文件(HTML 和图片资源)的访问 @app.route('/static/') def serve_static(filename): return send_from_directory(STATIC_DIR, filename) ''' Vscode ''' @app.route('/desktop//') def hello_world(user_id, path): if 'user_id' not in session: session['user_id'] = 'user_' + str(uuid.uuid4()) print("user "+ user_id + "uuid is"+ session['user_id']) user_id2uuid[user_id] = session['user_id'] uuid2user_id[session['user_id']] = user_id userid_recorder[user_id+'&'+path] = session['user_id'] # 在上层 目录下创建一个名为 user_id_path 的文件夹 path_dir = os.path.join(parent_dir, user_id, path) os.makedirs(path_dir, exist_ok=True) # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path config_path = os.path.join(path_dir, '.config') with open(config_path, 'w') as f: f.write(f"user_id={user_id}\npath={path}") return render_template('index.html', user_id=user_id, path=path) @app.route('/vscode_data', methods=['POST']) def vscode_data(): data = request.json config = data['config'] realtime_response(config,data) print(f"Received data from VSCode: {data}") return jsonify({"status": "success", "received": data}) @app.route('/get_session') def get_session(): user_session = session.get('user_id', 'default_session') return jsonify({"session": user_session}) if __name__ == '__main__': socketio.on_namespace(VSCodeNamespace('/vscode')) socketio.on_namespace(AgentNamespace('/agent')) socketio.run(app, host='localhost', port=5500, debug=True)