mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-09-04 10:11:46 +03:00
fix(webui): delete unpersisted pane sessions (#5624)
Co-authored-by: chengyongru <chengyongru.ai@gmail.com>
This commit is contained in:
@@ -2333,6 +2333,48 @@ async def test_session_delete_removes_transcript_without_canonical_file(
|
||||
await server_task
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_session_delete_removes_unpersisted_new_chat(
|
||||
bus: MagicMock, tmp_path: Path
|
||||
) -> None:
|
||||
sm = SessionManager(tmp_path / "sessions")
|
||||
project = tmp_path / "project"
|
||||
project.mkdir()
|
||||
channel = _ch(bus, session_manager=sm, workspace_path=tmp_path, port=_free_port())
|
||||
connection = AsyncMock()
|
||||
connection.remote_address = ("127.0.0.1", 50123)
|
||||
|
||||
await channel._dispatch_envelope(
|
||||
connection,
|
||||
"webui-client",
|
||||
{
|
||||
"type": "new_chat",
|
||||
"workspace_scope": {
|
||||
"project_path": str(project),
|
||||
"access_mode": "full",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
attached = next(
|
||||
payload
|
||||
for payload in (
|
||||
json.loads(call.args[0]) for call in connection.send.await_args_list
|
||||
)
|
||||
if payload.get("event") == "attached"
|
||||
)
|
||||
key = f"websocket:{attached['chat_id']}"
|
||||
|
||||
assert sm.list_sessions() == []
|
||||
assert channel.gateway.workspaces.scope_for_session_key(key).project_path == project.resolve()
|
||||
|
||||
response = await _webui_mutate(channel, "session.delete", {"key": key})
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json()["deleted"] is True
|
||||
assert channel.gateway.workspaces.scope_for_session_key(key).project_path == tmp_path.resolve()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_webui_automations_route_lists_all_jobs_and_allows_user_actions(
|
||||
bus: MagicMock, tmp_path: Path
|
||||
|
||||
@@ -357,3 +357,7 @@ class WebUIWorkspaceController:
|
||||
self._draft_scopes.move_to_end(session_key)
|
||||
while len(self._draft_scopes) > _MAX_DRAFT_SCOPES:
|
||||
self._draft_scopes.popitem(last=False)
|
||||
|
||||
def discard_draft_scope(self, session_key: str) -> bool:
|
||||
"""Discard the staged scope for a chat that has not persisted yet."""
|
||||
return self._draft_scopes.pop(session_key, None) is not None
|
||||
|
||||
@@ -952,9 +952,12 @@ class GatewayHTTPHandler:
|
||||
self.local_trigger_store.delete(job.id)
|
||||
elif self.cron_service is not None:
|
||||
self.cron_service.remove_job(job.id)
|
||||
draft_deleted = self.workspaces.discard_draft_scope(decoded_key)
|
||||
session_deleted = self.session_manager.delete_session(decoded_key)
|
||||
transcript_deleted = delete_webui_thread(decoded_key)
|
||||
return _http_json_response({"deleted": bool(session_deleted or transcript_deleted)})
|
||||
return _http_json_response(
|
||||
{"deleted": bool(draft_deleted or session_deleted or transcript_deleted)}
|
||||
)
|
||||
|
||||
# -- Automation routes --------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user