Skip to content

Commit bedebb5

Browse files
dso2ngGeoffBao
authored andcommitted
fix: sync active session across tabs (nesquena#1359)
Adds a 'storage' event listener for the hermes-webui-session localStorage key. Idle tabs auto-load the new active session and re-render the sidebar; busy tabs show a toast and do not interrupt the active turn. Co-authored-by: Dennis Soong <dso2ng@gmail.com>
1 parent 949fe19 commit bedebb5

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

static/sessions.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,22 @@ function renderSessionListFromCache(){
16251625
}
16261626
}
16271627

1628+
async function _handleActiveSessionStorageEvent(e){
1629+
if(!e || e.key !== 'hermes-webui-session') return;
1630+
const sid = e.newValue;
1631+
if(!sid || (S.session && S.session.session_id === sid)) return;
1632+
if(S.busy){
1633+
if(typeof showToast==='function') showToast('Active session changed in another tab. Finish the current turn before switching.',3000);
1634+
return;
1635+
}
1636+
await loadSession(sid);
1637+
renderSessionListFromCache();
1638+
}
1639+
1640+
if(typeof window!=='undefined'){
1641+
window.addEventListener('storage', (e) => { void _handleActiveSessionStorageEvent(e); });
1642+
}
1643+
16281644
async function deleteSession(sid){
16291645
const ok=await showConfirmDialog({
16301646
message:'Delete this conversation?',
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""Regression tests for cross-tab active session synchronization."""
2+
from pathlib import Path
3+
4+
REPO_ROOT = Path(__file__).parent.parent.resolve()
5+
SESSIONS_JS = (REPO_ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
6+
7+
8+
def test_sessions_js_listens_for_active_session_storage_changes():
9+
assert "addEventListener('storage'" in SESSIONS_JS or 'addEventListener("storage"' in SESSIONS_JS
10+
assert "hermes-webui-session" in SESSIONS_JS
11+
assert "_handleActiveSessionStorageEvent" in SESSIONS_JS
12+
13+
14+
def test_storage_sync_does_not_switch_while_busy():
15+
marker = "if(S.busy)"
16+
assert marker in SESSIONS_JS, "cross-tab storage sync must not switch sessions during an active turn"

0 commit comments

Comments
 (0)