2026-03-18 17:18:23 +08:00
|
|
|
"""WebSocket 连接管理器:仅负责连接注册/注销和消息收发"""
|
2026-03-19 14:36:14 +08:00
|
|
|
|
2026-03-18 17:18:23 +08:00
|
|
|
from typing import Dict
|
|
|
|
|
|
|
|
|
|
from fastapi import HTTPException, WebSocket
|
|
|
|
|
|
2026-03-20 15:15:35 +08:00
|
|
|
from app.core.logging import get_logger
|
|
|
|
|
|
2026-03-18 17:18:23 +08:00
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ConnectionManager:
|
|
|
|
|
"""WebSocket 连接管理器"""
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.active_connections: Dict[str, WebSocket] = {}
|
|
|
|
|
|
|
|
|
|
async def connect(self, websocket: WebSocket, conversation_id: str):
|
|
|
|
|
"""建立连接"""
|
|
|
|
|
await websocket.accept()
|
|
|
|
|
self.active_connections[conversation_id] = websocket
|
|
|
|
|
|
|
|
|
|
async def disconnect(self, conversation_id: str):
|
|
|
|
|
"""断开连接"""
|
|
|
|
|
if conversation_id in self.active_connections:
|
|
|
|
|
del self.active_connections[conversation_id]
|
|
|
|
|
|
|
|
|
|
async def send_message(self, conversation_id: str, message: dict):
|
|
|
|
|
"""发送消息"""
|
|
|
|
|
if conversation_id in self.active_connections:
|
|
|
|
|
websocket = self.active_connections[conversation_id]
|
|
|
|
|
try:
|
|
|
|
|
await websocket.send_json(message)
|
|
|
|
|
except (RuntimeError, Exception) as e:
|
feat(eval): memoir A/B chapter judging and eval-web parity with dialogue
- Judge baseline excerpt and library chapter separately; build_memoir_compare_summary for gate, nine-dim and leaf deltas.
- Memoir SSE chapter payload: baseline_judge, compare_summary, baseline_judge_error.
- MemoirJudgeOutput: loose score coercion and post-validate clamp; memoir judge prompt caps from settings.
- app-eval-web: two-column MemoirScoreCard layout, MemoirCompareSummary, chapter blocks and CSS.
- Add memoir_compare_summary, log_events, celery_log_context, memoir_pipeline_progress; tests and migration 0014.
- Misc: memory/evidence and enrichment paths, task/orchestrator updates, internal-eval docs, env examples.
2026-04-10 10:23:43 +08:00
|
|
|
logger.warning(
|
|
|
|
|
"发送消息失败 (conversation_id={}): {}", conversation_id, e
|
|
|
|
|
)
|
2026-03-18 17:18:23 +08:00
|
|
|
if conversation_id in self.active_connections:
|
|
|
|
|
del self.active_connections[conversation_id]
|
|
|
|
|
|
|
|
|
|
async def receive_message(self, conversation_id: str) -> dict:
|
|
|
|
|
"""接收消息"""
|
|
|
|
|
if conversation_id in self.active_connections:
|
|
|
|
|
websocket = self.active_connections[conversation_id]
|
|
|
|
|
return await websocket.receive_json()
|
|
|
|
|
raise HTTPException(status_code=404, detail="Connection not found")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
manager = ConnectionManager()
|