fix(webui): persist large sidebar ordering state
This commit is contained in:
@@ -81,6 +81,7 @@ from nanobot.webui.session_access import (
|
||||
WebuiSessionAccess,
|
||||
session_mentions_runtime_context,
|
||||
)
|
||||
from nanobot.webui.sidebar_state import write_webui_sidebar_state
|
||||
from nanobot.webui.transcript import WEBUI_TRANSCRIPT_INCOMPLETE_KEY
|
||||
from nanobot.webui.transcription_ws import webui_transcription_event
|
||||
from nanobot.webui.websocket_logging import websockets_server_logger
|
||||
@@ -775,6 +776,30 @@ class WebSocketChannel(BaseChannel):
|
||||
await self._send_event(connection, "attached", chat_id=cid)
|
||||
await self._hydrate_after_subscribe(cid)
|
||||
return
|
||||
if t == "set_sidebar_state":
|
||||
if connection not in self._webui_connections:
|
||||
await self._send_event(connection, "error", detail="access_denied")
|
||||
return
|
||||
state = envelope.get("state")
|
||||
if not isinstance(state, dict):
|
||||
await self._send_event(
|
||||
connection,
|
||||
"error",
|
||||
detail="invalid_sidebar_state",
|
||||
)
|
||||
return
|
||||
try:
|
||||
await asyncio.to_thread(
|
||||
write_webui_sidebar_state,
|
||||
cast(dict[str, Any], state),
|
||||
)
|
||||
except (OSError, ValueError):
|
||||
await self._send_event(
|
||||
connection,
|
||||
"error",
|
||||
detail="invalid_sidebar_state",
|
||||
)
|
||||
return
|
||||
if t == "set_workspace_scope":
|
||||
cid = envelope.get("chat_id")
|
||||
if not _is_valid_chat_id(cid):
|
||||
|
||||
@@ -559,6 +559,34 @@ def test_only_bootstrap_tokens_mark_webui_connections(bus: MagicMock) -> None:
|
||||
assert client_connection not in channel._webui_connections
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_webui_persists_sidebar_state_larger_than_http_request_line(
|
||||
bus: MagicMock,
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr("nanobot.config.paths.get_data_dir", lambda: tmp_path)
|
||||
channel = _ch(bus)
|
||||
conn = AsyncMock()
|
||||
channel._webui_connections.add(conn)
|
||||
session_order = [f"websocket:{index:04d}-{'x' * 48}" for index in range(160)]
|
||||
envelope = {
|
||||
"type": "set_sidebar_state",
|
||||
"state": {
|
||||
"session_order": session_order,
|
||||
"view": {"sort": "manual"},
|
||||
},
|
||||
}
|
||||
assert len(json.dumps(envelope).encode()) > 8_192
|
||||
|
||||
await channel._dispatch_envelope(conn, "webui-client", envelope)
|
||||
|
||||
saved = json.loads((tmp_path / "webui" / "sidebar-state.json").read_text(encoding="utf-8"))
|
||||
assert saved["session_order"] == session_order
|
||||
assert saved["view"]["sort"] == "manual"
|
||||
conn.send.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_client_cannot_self_assert_webui_quote_context(bus: MagicMock) -> None:
|
||||
channel = _ch(bus)
|
||||
|
||||
Reference in New Issue
Block a user