99 lines
3.0 KiB
Python
99 lines
3.0 KiB
Python
|
|
"""
|
|||
|
|
聊天 API 路由
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import logging
|
|||
|
|
from uuid import uuid4
|
|||
|
|
from fastapi import APIRouter, HTTPException, status
|
|||
|
|
from fastapi.responses import JSONResponse
|
|||
|
|
|
|||
|
|
from models.chat import ChatRequest, ChatResponse, ErrorResponse
|
|||
|
|
from services.conductor_service import conductor_service
|
|||
|
|
|
|||
|
|
logger = logging.getLogger(__name__)
|
|||
|
|
|
|||
|
|
router = APIRouter()
|
|||
|
|
|
|||
|
|
|
|||
|
|
@router.post("/chat", response_model=ChatResponse)
|
|||
|
|
async def chat(request: ChatRequest):
|
|||
|
|
"""
|
|||
|
|
聊天接口
|
|||
|
|
|
|||
|
|
接收前端消息,转发给 Conductor Agent,返回 AI 回复
|
|||
|
|
同时将对话记录和设备操作记录存储到数据库
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
# 如果没有提供 context_id,生成一个新的
|
|||
|
|
context_id = request.context_id or f"session-{uuid4().hex[:16]}"
|
|||
|
|
|
|||
|
|
logger.info(f"💬 收到聊天请求: {request.query[:50]}... (user: {request.system_user_id}, context: {context_id})")
|
|||
|
|
|
|||
|
|
# 调用 Conductor Agent(传递用户ID)
|
|||
|
|
# conductor_service 已经处理了数据库存储逻辑
|
|||
|
|
result = await conductor_service.send_message(
|
|||
|
|
user_message=request.query,
|
|||
|
|
system_user_id=request.system_user_id,
|
|||
|
|
context_id=context_id
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 构建响应
|
|||
|
|
response = ChatResponse(
|
|||
|
|
content=result["content"],
|
|||
|
|
context_id=result["context_id"],
|
|||
|
|
task_id=result.get("task_id"),
|
|||
|
|
status=result["status"]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 根据状态记录不同的日志
|
|||
|
|
if result["status"] == "success":
|
|||
|
|
logger.info(f"✅ 聊天响应成功: {len(result['content'])} 字符")
|
|||
|
|
else:
|
|||
|
|
logger.warning(f"⚠️ 聊天响应包含错误: status={result['status']}")
|
|||
|
|
|
|||
|
|
return response
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.error(f"❌ 聊天请求失败: {e}", exc_info=True)
|
|||
|
|
# 注意:conductor_service 已经保存了错误到数据库
|
|||
|
|
raise HTTPException(
|
|||
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|||
|
|
detail={
|
|||
|
|
"error": "ChatError",
|
|||
|
|
"message": str(e)
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@router.get("/chat/health")
|
|||
|
|
async def chat_health():
|
|||
|
|
"""检查聊天服务健康状态"""
|
|||
|
|
try:
|
|||
|
|
is_connected = await conductor_service.test_connection()
|
|||
|
|
|
|||
|
|
if is_connected:
|
|||
|
|
return {
|
|||
|
|
"status": "healthy",
|
|||
|
|
"conductor_agent": "connected",
|
|||
|
|
"url": conductor_service.base_url
|
|||
|
|
}
|
|||
|
|
else:
|
|||
|
|
return JSONResponse(
|
|||
|
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|||
|
|
content={
|
|||
|
|
"status": "unhealthy",
|
|||
|
|
"conductor_agent": "disconnected",
|
|||
|
|
"url": conductor_service.base_url
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
except Exception as e:
|
|||
|
|
logger.error(f"健康检查失败: {e}")
|
|||
|
|
return JSONResponse(
|
|||
|
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|||
|
|
content={
|
|||
|
|
"status": "error",
|
|||
|
|
"message": str(e)
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|