mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(web): raise uvicorn WS frame cap for Desktop file.attach
Uvicorn's 16 MiB default drops one-shot base64 remote attachments before Hermes sees them. Raise ws_max_size to fit the 256 MiB attach reader after base64 expansion, and bump DESKTOP_BACKEND_CONTRACT to v5 so older remotes surface skew instead of silent disconnects. Co-authored-by: Börje <borje@dqsverige.se>
This commit is contained in:
parent
9dc191d437
commit
612b23f6c0
3 changed files with 24 additions and 1 deletions
|
|
@ -318,6 +318,13 @@ def _apply_ssh_owner_nonce(nonce: Optional[str]) -> None:
|
|||
# injection share a single, testable seam.
|
||||
_DASHBOARD_EMBEDDED_CHAT_ENABLED = True
|
||||
|
||||
# Desktop's file.attach compatibility transport sends a complete base64 data
|
||||
# URL in one JSON-RPC frame. Uvicorn defaults to 16 MiB, which rejects files at
|
||||
# the preview ceiling before the dispatcher sees them. Keep the gateway
|
||||
# finite while allowing the 256 MiB raw Desktop attach cap plus base64/JSON
|
||||
# overhead.
|
||||
_DESKTOP_ATTACHMENT_WS_MAX_BYTES = 384 * 1024 * 1024
|
||||
|
||||
# Simple rate limiter for the reveal endpoint
|
||||
_reveal_timestamps: List[float] = []
|
||||
_REVEAL_MAX_PER_WINDOW = 5
|
||||
|
|
@ -20290,6 +20297,7 @@ def start_server(
|
|||
# reaped via the WebSocketDisconnect → disconnect/reap path.
|
||||
ws_ping_interval=None if _is_loopback else 20.0,
|
||||
ws_ping_timeout=None if _is_loopback else 20.0,
|
||||
ws_max_size=_DESKTOP_ATTACHMENT_WS_MAX_BYTES,
|
||||
)
|
||||
server = uvicorn.Server(config)
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,20 @@ def test_start_server_disables_ws_ping_on_loopback(monkeypatch):
|
|||
assert captured["ws_ping_timeout"] is None
|
||||
|
||||
|
||||
def test_start_server_accepts_base64_desktop_attachments_above_preview_limit(monkeypatch):
|
||||
"""The gateway frame cap must fit the Desktop attachment default after
|
||||
base64 expansion and JSON framing; uvicorn's 16 MiB default would reject
|
||||
the request before ``file.attach`` can stage it.
|
||||
"""
|
||||
captured = _stub_uvicorn(monkeypatch)
|
||||
|
||||
web_server.start_server(host="127.0.0.1", port=0, open_browser=False)
|
||||
|
||||
raw_attachment_bytes = 256 * 1024 * 1024
|
||||
base64_bytes = ((raw_attachment_bytes + 2) // 3) * 4
|
||||
assert captured["ws_max_size"] > base64_bytes
|
||||
|
||||
|
||||
def test_start_server_enables_ws_ping_for_half_open_detection(monkeypatch):
|
||||
"""Non-loopback (public) binds MUST keep the ws ping enabled so half-open
|
||||
connections (reverse-proxy 524, dropped Cloudflare Tunnel) raise
|
||||
|
|
|
|||
|
|
@ -4528,7 +4528,8 @@ def _current_profile_name() -> str:
|
|||
# v2: adds the file.attach RPC (remote-gateway non-image file upload).
|
||||
# v3: adds approvals.mode config RPCs and session.info reconciliation.
|
||||
# v4: session.create fast=false is an explicit per-session normal-tier override.
|
||||
DESKTOP_BACKEND_CONTRACT = 4
|
||||
# v5: uvicorn ws_max_size raised for one-shot base64 file.attach frames (>16 MiB).
|
||||
DESKTOP_BACKEND_CONTRACT = 5
|
||||
|
||||
|
||||
def _session_usage_snapshot(session: dict | None) -> dict:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue