完成 WebSocket 与 workspace 架构优化收尾,并修复全量回归阻塞。

本次将握手鉴权、Origin 校验、限流、重连补偿、发送背压与观测字段打通,同时修复 gateway 异常路径与备份清理兼容问题,确保工具历史压缩语义一致并恢复全量测试通过。

Made-with: Cursor
This commit is contained in:
oliver 2026-04-27 20:41:50 +08:00
parent 09836dddfa
commit 7253f6795d
12 changed files with 536 additions and 24 deletions

View file

@ -19,9 +19,19 @@ def _ws_is_disconnected(conn: Any) -> bool:
return False
async def _safe_send_text(conn: Any, text: str) -> None:
async def _safe_send_text(conn: Any, text: str, *, use_queue: bool = True) -> None:
if _ws_is_disconnected(conn):
return
queue_send = getattr(conn, "_queue_send_text", None)
if use_queue and callable(queue_send):
ok = await queue_send(text)
if ok:
return
try:
await conn.ws.close(code=1013, reason="backpressure")
except Exception:
pass
return
try:
await conn.ws.send_text(text)
except Exception as e:
@ -37,7 +47,7 @@ async def send_res(conn: Any, req_id: str, *, ok: bool, payload: Any | None = No
frame["payload"] = payload
if error is not None:
frame["error"] = error
await _safe_send_text(conn, json.dumps(frame, ensure_ascii=False))
await _safe_send_text(conn, json.dumps(frame, ensure_ascii=False), use_queue=False)
async def send_event(conn: Any, event: str, payload: Any | None = None) -> None:
@ -47,7 +57,12 @@ async def send_event(conn: Any, event: str, payload: Any | None = None) -> None:
frame: dict[str, Any] = {"type": "event", "event": str(event or "event"), "seq": int(conn.seq)}
if payload is not None:
frame["payload"] = payload
await _safe_send_text(conn, json.dumps(frame, ensure_ascii=False))
raw = json.dumps(frame, ensure_ascii=False)
frame["_raw"] = raw
remember = getattr(conn, "remember_event", None)
if callable(remember):
remember(frame)
await _safe_send_text(conn, raw)
async def emit_agent_event(conn: Any, *, run_id: str, stream: str, data: dict[str, Any], now_ms: int) -> None: