report.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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.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. if len(files) != 0 or (steps and last_message == "step") or msg or data["type"] == "close":
  59. if data["type"] == "close":
  60. t = "close"
  61. else:
  62. t = "stream"
  63. process_files(files, agent_id)
  64. result = {"step_message": steps, "message": msg, "type": t, "files": files}
  65. await websocket.send_json(result)
  66. print(f"Forwarded to client, {chat_id}: {result}")
  67. last_message = "message" if msg else "step"
  68. # 启动两个任务,分别处理客户端和服务端的消息
  69. tasks = [
  70. asyncio.create_task(forward_to_service()),
  71. asyncio.create_task(forward_to_client())
  72. ]
  73. done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  74. # 取消未完成的任务
  75. for task in pending:
  76. task.cancel()
  77. try:
  78. await task
  79. except asyncio.CancelledError:
  80. pass
  81. except WebSocketDisconnect as e:
  82. print(f"WebSocket connection closed with code {e.code}: {e.reason}")
  83. await websocket.close()
  84. await service_websocket.close()
  85. except Exception as e:
  86. print(f"Exception occurred: {e}")
  87. finally:
  88. print("Cleaning up resources of bisheng report")
  89. # 取消所有任务
  90. for task in tasks:
  91. if not task.done():
  92. task.cancel()
  93. try:
  94. await task
  95. except asyncio.CancelledError:
  96. pass
  97. @router.get("/variables/list", response_model=ResponseList)
  98. 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)):
  99. agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
  100. if not agent:
  101. return ResponseList(code=404, msg="Agent not found")
  102. bisheng_service = BishengService(base_url=settings.sgb_base_url)
  103. try:
  104. token = get_bisheng_token(db, current_user.id)
  105. result = await bisheng_service.variable_list(token, agent_id)
  106. except Exception as e:
  107. raise HTTPException(status_code=500, detail=str(e))
  108. return ResponseList(code=200, msg="", data=result)