report.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import json
  2. from fastapi import WebSocket, WebSocketDisconnect, APIRouter, Depends, HTTPException, Query
  3. import asyncio
  4. import websockets
  5. from sqlalchemy.orm import Session
  6. from app.api import get_current_user_websocket, ResponseList, get_current_user, format_file_url, process_files
  7. from app.config.config import settings
  8. from app.models.agent_model import AgentModel, AgentType
  9. from app.models.base_model import get_db
  10. from app.models.user_model import UserModel
  11. from app.service.bisheng import BishengService
  12. from app.service.service_token import get_bisheng_token
  13. router = APIRouter()
  14. @router.websocket("/ws/{agent_id}/{chat_id}")
  15. async def report_chat(websocket: WebSocket,
  16. agent_id: str,
  17. chat_id: str,
  18. current_user: UserModel = Depends(get_current_user_websocket),
  19. db: Session = Depends(get_db)):
  20. agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
  21. if not agent:
  22. ret = {"message": "Agent not found", "type": "close"}
  23. return websocket.send_json(ret)
  24. agent_type = agent.agent_type
  25. if chat_id == "" or chat_id == "0":
  26. ret = {"message": "Chat ID not found", "type": "close"}
  27. return websocket.send_json(ret)
  28. if agent_type != AgentType.BISHENG:
  29. ret = {"message": "Agent error", "type": "close"}
  30. return websocket.send_json(ret)
  31. token = get_bisheng_token(db, current_user.id)
  32. service_uri = f"{settings.sgb_websocket_url}/api/v1/chat/{agent_id}?type=L1&t=&chat_id={chat_id}"
  33. headers = {'cookie': f"access_token_cookie={token};"}
  34. await websocket.accept()
  35. print(f"Client {agent_id} connected")
  36. async with websockets.connect(service_uri, extra_headers=headers) as service_websocket:
  37. try:
  38. # 处理客户端发来的消息
  39. async def forward_to_service():
  40. while True:
  41. message = await websocket.receive_json()
  42. print(f"Received from client, {chat_id}: {message}")
  43. # 添加 'agent_id' 和 'chat_id' 字段
  44. message['flow_id'] = agent_id
  45. message['chat_id'] = chat_id
  46. await service_websocket.send(json.dumps(message))
  47. print(f"Forwarded to bisheng: {message}")
  48. # 监听毕昇发来的消息并转发给客户端
  49. async def forward_to_client():
  50. last_message = "step"
  51. while True:
  52. message = await service_websocket.recv()
  53. print(f"Received from bisheng: {message}")
  54. data = json.loads(message)
  55. files = data.get("files", [])
  56. steps = data.get("intermediate_steps", "")
  57. msg = data.get("message", "")
  58. category = data.get("category", "")
  59. if len(files) != 0 or (msg and category != "answer") or data["type"] == "close":
  60. if data["type"] == "close":
  61. t = "close"
  62. else:
  63. t = "stream"
  64. process_files(files, agent_id)
  65. result = {"message": msg, "type": t, "files": files}
  66. await websocket.send_json(result)
  67. elif steps and last_message == "step":
  68. result = {"step_message": steps, "type": "stream", "files": files}
  69. await websocket.send_json(result)
  70. last_message = "message" if msg else "step"
  71. # 启动两个任务,分别处理客户端和服务端的消息
  72. tasks = [
  73. asyncio.create_task(forward_to_service()),
  74. asyncio.create_task(forward_to_client())
  75. ]
  76. done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  77. # 取消未完成的任务
  78. for task in pending:
  79. task.cancel()
  80. try:
  81. await task
  82. except asyncio.CancelledError as e:
  83. print(f"asyncio CancelledError: {e}")
  84. pass
  85. except WebSocketDisconnect as e:
  86. print(f"WebSocket connection closed with code {e.code}: {e.reason}")
  87. await websocket.close()
  88. await service_websocket.close()
  89. except Exception as e:
  90. print(f"Exception occurred: {e}")
  91. finally:
  92. print("Cleaning up resources of bisheng report")
  93. # 取消所有任务
  94. for task in tasks:
  95. if not task.done():
  96. task.cancel()
  97. try:
  98. await task
  99. except asyncio.CancelledError:
  100. pass
  101. @router.get("/variables/list", response_model=ResponseList)
  102. async def get_variables(agent_id: str = Query(..., description="The ID of the agent"), db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_user)):
  103. agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
  104. if not agent:
  105. return ResponseList(code=404, msg="Agent not found")
  106. bisheng_service = BishengService(base_url=settings.sgb_base_url)
  107. try:
  108. token = get_bisheng_token(db, current_user.id)
  109. result = await bisheng_service.variable_list(token, agent_id)
  110. except Exception as e:
  111. raise HTTPException(status_code=500, detail=str(e))
  112. return ResponseList(code=200, msg="", data=result)