report.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 Log import logger
  7. from app.api import get_current_user_websocket, ResponseList, get_current_user, format_file_url, process_files
  8. from app.config.config import settings
  9. from app.models import MenuCapacityModel
  10. from app.models.agent_model import AgentModel, AgentType
  11. from app.models.base_model import get_db
  12. from app.models.user_model import UserModel
  13. from app.service.bisheng import BishengService
  14. from app.service.service_token import get_bisheng_token
  15. router = APIRouter()
  16. @router.websocket("/ws/{agent_id}/{chat_id}")
  17. async def report_chat(websocket: WebSocket,
  18. agent_id: str,
  19. chat_id: str,
  20. current_user: UserModel = Depends(get_current_user_websocket),
  21. db: Session = Depends(get_db)):
  22. agent = db.query(MenuCapacityModel).filter(MenuCapacityModel.chat_id == agent_id).first()
  23. if not agent:
  24. agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
  25. agent_type = agent.agent_type
  26. chat_type = agent.type
  27. else:
  28. agent_type = agent.capacity_type
  29. chat_type = agent.chat_type
  30. if not agent:
  31. ret = {"message": "Agent not found", "type": "close"}
  32. return websocket.send_json(ret)
  33. # agent_type = agent.agent_type
  34. if chat_id == "" or chat_id == "0":
  35. ret = {"message": "Chat ID not found", "type": "close"}
  36. return websocket.send_json(ret)
  37. if agent_type != AgentType.BISHENG:
  38. ret = {"message": "Agent error", "type": "close"}
  39. return websocket.send_json(ret)
  40. token = await get_bisheng_token(db, current_user.id)
  41. service_uri = f"{settings.sgb_websocket_url}/api/v1/chat/{agent_id}?type=L1&t=&chat_id={chat_id}"
  42. headers = {'cookie': f"access_token_cookie={token};"}
  43. await websocket.accept()
  44. print(f"Client {agent_id} connected")
  45. async with websockets.connect(service_uri, extra_headers=headers) as service_websocket:
  46. try:
  47. # 处理客户端发来的消息
  48. async def forward_to_service():
  49. while True:
  50. message = await websocket.receive_json()
  51. print(f"Received from client, {chat_id}: {message}")
  52. # 添加 'agent_id' 和 'chat_id' 字段
  53. message['flow_id'] = agent_id
  54. message['chat_id'] = chat_id
  55. await service_websocket.send(json.dumps(message))
  56. print(f"Forwarded to bisheng: {message}")
  57. # 监听毕昇发来的消息并转发给客户端
  58. async def forward_to_client():
  59. is_answer = False
  60. while True:
  61. try:
  62. message = await service_websocket.recv()
  63. # print(f"Received from bisheng: {message}")
  64. data = json.loads(message)
  65. files = data.get("files", [])
  66. steps = data.get("intermediate_steps", "")
  67. msg = data.get("message", "")
  68. category = data.get("category", "")
  69. process_files(files, agent_id)
  70. if category == "question" and steps:
  71. is_answer = False
  72. if not steps:
  73. steps = "\n"
  74. else:
  75. steps = steps + "\n"
  76. result = {"message": steps, "type": "stream", "files": files}
  77. await websocket.send_json(result)
  78. if category == "answer" and not is_answer:
  79. if not steps.endswith("\n"):
  80. steps += "\n\n"
  81. result = {"message": steps, "type": "stream", "files": files}
  82. await websocket.send_json(result)
  83. if category == "answer" and is_answer:
  84. # process_files(files, agent_id)
  85. result = {"message": "\n", "type": "stream", "files": files}
  86. await websocket.send_json(result)
  87. elif data["type"] == "close":
  88. # process_files(files, agent_id)
  89. result = {"message": "", "type": "close", "files": files}
  90. await websocket.send_json(result)
  91. elif category == "processing":
  92. # process_files(files, agent_id)
  93. is_answer = True
  94. result = {"message": msg, "type": "stream", "files": files}
  95. await websocket.send_json(result)
  96. elif files:
  97. # process_files(files, agent_id)
  98. result = {"message": "", "type": "stream", "files": files}
  99. await websocket.send_json(result)
  100. elif category == "system" and steps:
  101. result = {"message": steps, "type": "stream", "files": files}
  102. await websocket.send_json(result)
  103. else:
  104. logger.error("-------------------11111111111111--------------------------")
  105. logger.error(data)
  106. except Exception as e:
  107. logger.error(e)
  108. await websocket.send_json({"message": "连接异常!", "type": "close", "files": []})
  109. # if len(files) != 0 or (msg and category != "answer") or data["type"] == "close":
  110. # if data["type"] == "close":
  111. # t = "close"
  112. # else:
  113. # t = "stream"
  114. # process_files(files, agent_id)
  115. # result = {"message": msg, "type": t, "files": files}
  116. # await websocket.send_json(result)
  117. # elif steps and last_message == "step":
  118. # result = {"step_message": steps, "type": "stream", "files": files}
  119. # await websocket.send_json(result)
  120. # last_message = "message" if msg else "step"
  121. # 启动两个任务,分别处理客户端和服务端的消息
  122. tasks = [
  123. asyncio.create_task(forward_to_service()),
  124. asyncio.create_task(forward_to_client())
  125. ]
  126. done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  127. # 取消未完成的任务
  128. for task in pending:
  129. task.cancel()
  130. try:
  131. await task
  132. except asyncio.CancelledError as e:
  133. print(f"asyncio CancelledError: {e}")
  134. pass
  135. except WebSocketDisconnect as e:
  136. print(f"WebSocket connection closed with code {e.code}: {e.reason}")
  137. await websocket.close()
  138. await service_websocket.close()
  139. except Exception as e:
  140. print(f"Exception occurred: {e}")
  141. finally:
  142. print("Cleaning up resources of bisheng report")
  143. # 取消所有任务
  144. for task in tasks:
  145. if not task.done():
  146. task.cancel()
  147. try:
  148. await task
  149. except asyncio.CancelledError:
  150. pass
  151. @router.get("/variables/list", response_model=ResponseList)
  152. 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)):
  153. agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
  154. if not agent:
  155. return ResponseList(code=404, msg="Agent not found")
  156. bisheng_service = BishengService(base_url=settings.sgb_base_url)
  157. try:
  158. token = await get_bisheng_token(db, current_user.id)
  159. result = await bisheng_service.variable_list(token, agent_id)
  160. except Exception as e:
  161. raise HTTPException(status_code=500, detail=str(e))
  162. return ResponseList(code=200, msg="", data=result)