Для каждого разговора существует два возможных режима второго пилота (на пользовательское сообщение будет отвечать человек, использующий UI) автопилот (сообщение будет автоматически обработано и на него ответит сервер с использованием некоторой цепочки)
Проблема, с которой я столкнулся, заключается в следующем, и я думаю, она связана с логикой отправки сообщений:
когда приложение с client_id=2 отправляет сообщение (это пользователь), независимо от режима диалога, сервер обрабатывает его правильно. проблема возникает, когда приложение с client_id=1 (это я на другой стороне) отправляет сообщение обратно вручную. Это сообщение правильно получено пользователем (client_id=2), но в следующий раз, когда я отправлю сообщение из приложения с client_id=1, оно так и не доходит до сервера. если приложение с client_id=2 отправит мне сообщение, оно никогда не дойдет до меня.
Это заставляет меня думать, что каким-то образом после отправки сообщения приложение с client_id=1 > отключается, но не вызывает никаких перехватов исключений и не удаляется из списков подключений. Этот веб-сокет также никогда не меняет свой статус на ОТКЛЮЧЕН
здесь это мой код обработки веб-сокета:
@dataclass
class Connection:
client_id: int
conversation_id: str
websocket: WebSocket
class ConnectionManager:
def __init__(self):
self.active_connections: List[Connection] = []
async def connect(self, websocket: WebSocket, client_id: int, conversation_id: str):
try:
await websocket.accept()
connection = Connection(
client_id=client_id, conversation_id=conversation_id, websocket=websocket)
self.active_connections.append(connection)
print(f"Connected: {client_id} with conversation {conversation_id}")
except WebSocketDisconnect:
print(f"WebSocket for {client_id} disconnected during connect")
def disconnect(self, websocket: WebSocket):
self.active_connections = [
conn for conn in self.active_connections if conn.websocket != websocket
]
async def broadcast(self, message: str, AI_message: str, conversation_id: str, conversation_mode: Literal["copilot", "autopilot"], client_id: int):
for connection in self.active_connections:
try:
print(f"Connection: {connection.client_id}, WebSocket State: {connection.websocket.client_state}")
if connection.websocket.client_state == WebSocketState.CONNECTED:
if client_id == 2:
if conversation_mode == "autopilot" and connection.client_id == 1:
await connection.websocket.send_text(message)
await connection.websocket.send_text(AI_message)
if conversation_mode == "autopilot" and connection.client_id == 2 and connection.conversation_id == conversation_id:
await connection.websocket.send_text(AI_message)
if conversation_mode == "copilot" and connection.client_id == 1:
await connection.websocket.send_text(message)
if client_id == 1:
if connection.client_id == 2 and connection.conversation_id == conversation_id:
await connection.websocket.send_text(message)
except Exception as e:
print(f"Error in broadcasting: {e}")
connection_manager.disconnect(connection.websocket)
await connection.websocket.close()
затем я создаю экземпляр этого обработчика и использую его в своей конечной точке WS
connection_manager = ConnectionManager()
@app.websocket("/ws/{client_id}/{conversation_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: int, conversation_id: str):
Думаю, проблема связана с методом трансляции, сейчас объясню для него желаемую логику:
- если сервер получает сообщение от пользователя (client_id=2), есть две возможности:
Разговор на автопилоте: сообщение полностью обрабатывается сервером, он генерирует AI_message, затем он отправляет это AI_message пользователю и уведомляет другой конец (client_id=1, это мой интерфейс) сообщением пользователя и AI_message. - Разговор на втором пилоте: сообщение пользователя обрабатывается и отправляется на соединение с client_id=1
async def broadcast(self, message: str, AI_message: str, conversation_id: str, conversation_mode: Literal["copilot", "autopilot"], client_id: int):
for connection in self.active_connections:
try:
print(f"Connection: {connection.client_id}, WebSocket State: {connection.websocket.client_state}")
if connection.websocket.client_state == WebSocketState.CONNECTED:
if client_id == 2:
if conversation_mode == "autopilot" and connection.client_id == 1:
await connection.websocket.send_text(message)
await connection.websocket.send_text(AI_message)
if conversation_mode == "autopilot" and connection.client_id == 2 and connection.conversation_id == conversation_id:
await connection.websocket.send_text(AI_message)
if conversation_mode == "copilot" and connection.client_id == 1:
await connection.websocket.send_text(message)
if client_id == 1:
if connection.client_id == 2 and connection.conversation_id == conversation_id:
await connection.websocket.send_text(message)
except Exception as e:
print(f"Error in broadcasting: {e}")
connection_manager.disconnect(connection.websocket)
await connection.websocket.close()
Хотя я думаю, что это не связано с проблемой, это полезные данные, которые отправляются/получаются:
broadcast_data = {
"suggestion": suggestion.get("output") if suggestion else "",
"eventType": "message",
"message": message_to_send,
"createdAt": str(new_message.created_at),
"sender": sender,
"conversationId": str(conversation["_id"]),
"chatAppClientId": 1,
"phoneNumber": json_data["phoneNumber"],
}`
AI_broadcast_data = {
"suggestion": "",
"eventType": "message",
"message": suggestion.get("output") if suggestion else "",
"createdAt": str(new_message.created_at),
"sender": "assistant",
"conversationId": str(conversation["_id"]),
"chatAppClientId": 1,
"phoneNumber": json_data["phoneNumber"],
}
Подробнее здесь: https://stackoverflow.com/questions/789 ... st-fastapi