""" AI助手Web客户端 - Flask应用 100%还原docs/ai-assistant.html原型设计 """ import os import sys import json import logging from flask import Flask, render_template, request, jsonify, Response from flask_cors import CORS # 添加父目录到路径,以便导入api_client sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) try: from api_client import AIAssistantClient from config import APPLICATIONS, AI_ASSISTANT_CONFIG except ImportError: # 如果导入失败,使用模拟数据 AIAssistantClient = None APPLICATIONS = {} AI_ASSISTANT_CONFIG = {} # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # 创建Flask应用 app = Flask(__name__) app.config['SECRET_KEY'] = 'ai-assistant-web-client-secret-key' CORS(app) # 启用CORS # 初始化API客户端 api_client = None if AIAssistantClient: try: api_client = AIAssistantClient() logger.info("API客户端初始化成功") except Exception as e: logger.error(f"API客户端初始化失败: {e}") @app.route('/') def index(): """主页面""" return render_template('index.html') @app.route('/api/applications', methods=['GET']) def get_applications(): """获取应用列表""" try: if api_client: apps = api_client.get_app_list() return jsonify({ 'code': 200, 'message': 'success', 'data': apps }) else: # 返回模拟数据 return jsonify({ 'code': 200, 'message': 'success', 'data': list(APPLICATIONS.values()) if APPLICATIONS else [] }) except Exception as e: logger.error(f"获取应用列表失败: {e}") return jsonify({ 'code': 500, 'message': str(e), 'data': [] }), 500 @app.route('/api/chat/send', methods=['POST']) def send_message(): """发送聊天消息""" try: data = request.get_json() app_id = data.get('appId') message = data.get('message') chat_id = data.get('chatId') stream = data.get('stream', False) if not message: return jsonify({ 'code': 400, 'message': '消息内容不能为空', 'data': None }), 400 if api_client and app_id: # 调用真实API response = api_client.send_message( app_id=app_id, message=message, chat_id=chat_id, stream=stream ) if stream: # 流式响应 def generate(): for chunk in response: yield f"data: {json.dumps(chunk, ensure_ascii=False)}\n\n" yield "data: [DONE]\n\n" return Response(generate(), mimetype='text/event-stream') else: # 普通响应 return jsonify(response) else: # 返回模拟响应 return jsonify({ 'code': 200, 'message': 'success', 'data': { 'answer': f'这是对"{message}"的模拟回复。实际使用时会调用真实的AI助手API。', 'chatId': chat_id or 'mock_chat_id_001', 'messageId': 'mock_message_id_001' } }) except Exception as e: logger.error(f"发送消息失败: {e}") return jsonify({ 'code': 500, 'message': str(e), 'data': None }), 500 @app.route('/api/health', methods=['GET']) def health_check(): """健康检查""" return jsonify({ 'code': 200, 'message': 'OK', 'data': { 'status': 'healthy', 'api_client_available': api_client is not None } }) if __name__ == '__main__': port = int(os.environ.get('PORT', 5000)) debug = os.environ.get('DEBUG', 'True').lower() == 'true' logger.info(f"启动AI助手Web客户端,端口: {port}, 调试模式: {debug}") app.run(host='0.0.0.0', port=port, debug=debug)