report.py 7.4 KB

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