report.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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.bisheng_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. while True:
  51. message = await service_websocket.recv()
  52. print(f"Received from bisheng: {message}")
  53. data = json.loads(message)
  54. files = data.get("files", [])
  55. steps = data.get("intermediate_steps", "")
  56. if len(files) != 0 or steps != "" or data["type"] == "close":
  57. if data["type"] == "close":
  58. t = "close"
  59. else:
  60. t = "stream"
  61. process_files(files, agent_id)
  62. result = {"step_message": steps, "type": t, "files": files}
  63. await websocket.send_json(result)
  64. print(f"Forwarded to client, {chat_id}: {result}")
  65. # 启动两个任务,分别处理客户端和服务端的消息
  66. tasks = [
  67. asyncio.create_task(forward_to_service()),
  68. asyncio.create_task(forward_to_client())
  69. ]
  70. done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
  71. # 取消未完成的任务
  72. for task in pending:
  73. task.cancel()
  74. try:
  75. await task
  76. except asyncio.CancelledError:
  77. pass
  78. except WebSocketDisconnect:
  79. print(f"Client {chat_id} disconnected")
  80. @router.get("/variables/list", response_model=ResponseList)
  81. 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)):
  82. agent = db.query(AgentModel).filter(AgentModel.id == agent_id).first()
  83. if not agent:
  84. return ResponseList(code=404, msg="Agent not found")
  85. bisheng_service = BishengService(base_url=settings.bisheng_base_url)
  86. try:
  87. token = get_bisheng_token(db, current_user.id)
  88. result = await bisheng_service.variable_list(token, agent_id)
  89. except Exception as e:
  90. raise HTTPException(status_code=500, detail=str(e))
  91. return ResponseList(code=200, msg="", data=result)