Files
assist/src/web/blueprints/chat.py
Jeason 61ef86d779 refactor: 架构改进 前5个缺陷修复
1. Chat 路由从 app.py 拆到 chat_bp 蓝图(14个路由  0个残留在 app.py)
2. 新增 resolve_tenant_id 装饰器,写操作未指定 tenant_id 时记录警告日志
3. dialogue_manager.process_user_message 补齐 tenant_id 参数,知识库搜索和对话保存都传递 tenant_id
4. service_manager 新增直接 manager 访问器(knowledge_manager、dialogue_manager、conversation_history_manager、alert_system、token_monitor),新代码可绕过 TSPAssistant facade
5. TSPAssistant.get_assistant() 标记为 legacy,引导新代码使用具体 manager
2026-04-02 22:09:59 +08:00

127 lines
4.5 KiB
Python

# -*- coding: utf-8 -*-
"""
实时对话蓝图
处理 WebSocket/HTTP 对话相关的 API 路由
"""
import logging
from flask import Blueprint, request, jsonify, Response
from src.web.service_manager import service_manager
logger = logging.getLogger(__name__)
chat_bp = Blueprint('chat', __name__, url_prefix='/api/chat')
@chat_bp.route('/session', methods=['POST'])
def create_session():
"""创建对话会话"""
try:
data = request.get_json()
user_id = data.get('user_id', 'anonymous')
work_order_id = data.get('work_order_id')
tenant_id = data.get('tenant_id')
session_id = service_manager.get_chat_manager().create_session(user_id, work_order_id, tenant_id=tenant_id)
return jsonify({"success": True, "session_id": session_id, "message": "会话创建成功"})
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/message', methods=['POST'])
def send_message():
"""发送聊天消息"""
try:
data = request.get_json()
session_id = data.get('session_id')
message = data.get('message')
if not session_id or not message:
return jsonify({"error": "缺少必要参数"}), 400
result = service_manager.get_chat_manager().process_message(session_id, message)
return jsonify(result)
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/message/stream', methods=['POST'])
def send_message_stream():
"""流式聊天消息 — SSE 逐 token 推送"""
try:
data = request.get_json()
session_id = data.get('session_id')
message = data.get('message')
if not session_id or not message:
return jsonify({"error": "缺少必要参数"}), 400
chat_mgr = service_manager.get_chat_manager()
def generate():
try:
for event in chat_mgr.process_message_stream(session_id, message):
yield event
except Exception as e:
import json
yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n"
return Response(generate(), mimetype='text/event-stream',
headers={'Cache-Control': 'no-cache', 'X-Accel-Buffering': 'no'})
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/history/<session_id>')
def get_history(session_id):
"""获取对话历史"""
try:
history = service_manager.get_chat_manager().get_session_history(session_id)
return jsonify({"success": True, "history": history})
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/work-order', methods=['POST'])
def create_work_order():
"""从对话中创建工单"""
try:
data = request.get_json()
session_id = data.get('session_id')
title = data.get('title')
description = data.get('description')
category = data.get('category', '技术问题')
priority = data.get('priority', 'medium')
if not session_id or not title or not description:
return jsonify({"error": "缺少必要参数"}), 400
result = service_manager.get_chat_manager().create_work_order(session_id, title, description, category, priority)
return jsonify(result)
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/work-order/<int:work_order_id>')
def get_work_order_status(work_order_id):
"""获取工单状态"""
try:
result = service_manager.get_chat_manager().get_work_order_status(work_order_id)
return jsonify(result)
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/session/<session_id>', methods=['DELETE'])
def end_session(session_id):
"""结束对话会话"""
try:
success = service_manager.get_chat_manager().end_session(session_id)
return jsonify({"success": success, "message": "会话已结束" if success else "结束会话失败"})
except Exception as e:
return jsonify({"error": str(e)}), 500
@chat_bp.route('/sessions')
def get_active_sessions():
"""获取活跃会话列表"""
try:
manager = service_manager.get_chat_manager()
sessions = manager.get_active_sessions()
return jsonify({"success": True, "sessions": sessions})
except Exception as e:
logger.error(f"获取活跃会话失败: {e}")
return jsonify({"error": str(e)}), 500