Fix new chat empty-session reuse guard

This commit is contained in:
Frank Song authored and nesquena-hermes committed 2026-06-29 18:38:25 +00:00
1 parent 60a45686e6
commit 28c2c37c1c
2 files changed
+37 -10

No files matched your search

+13 -10
View File
@@ -1465,6 +1465,17 @@ window._hermesTtsSynth=function(id, text, opts){
window._voiceModeDeactivate=_deactivate;
window._voiceModeImmediateSend=_voiceModeSend;
})();
function _currentSessionIsReusableEmptyChat(){
if(!S.session) return false;
const hasVisibleMessages=Array.isArray(S.messages)
&& S.messages.some(m=>m&&m.role&&m.role!=='tool');
return (S.session.message_count||0)===0
&& !hasVisibleMessages
&& !S.busy
&& !S.session.active_stream_id
&& !S.session.pending_user_message;
}
$('fileInput').onchange=e=>{addFiles(Array.from(e.target.files));e.target.value='';};
$('btnNewChat').onclick=async()=>{
// If the current session has no messages AND nothing is in flight, just focus
@@ -1478,11 +1489,7 @@ $('btnNewChat').onclick=async()=>{
// couldn't actually start a parallel chat. Use the same in-flight signal as
// `_restoreSettledSession()` in messages.js: an active stream id or a queued
// pending user message means the session is real, not empty.
if(S.session
&& (S.session.message_count||0)===0
&& !S.busy
&& !S.session.active_stream_id
&& !S.session.pending_user_message){
if(_currentSessionIsReusableEmptyChat()){
$('msg').focus();closeMobileSidebar();return;
}
if(typeof _restoreRememberedNewChatDraftSession==='function'
@@ -1746,11 +1753,7 @@ document.addEventListener('keydown',async e=>{
// the composer rather than creating another empty session that will clutter
// the sidebar list (#1171). See the matching guard in $('btnNewChat').onclick
// and bug #1432 for why the in-flight check is needed.
if(S.session
&& (S.session.message_count||0)===0
&& !S.busy
&& !S.session.active_stream_id
&& !S.session.pending_user_message){
if(_currentSessionIsReusableEmptyChat()){
$('msg').focus();return;
}
// Cmd/Ctrl+K should always create a new conversation, even while the current
@@ -53,6 +53,30 @@ def test_new_chat_button_restores_remembered_draft_before_creating_session():
)
def test_new_chat_empty_reuse_guard_checks_loaded_visible_messages():
helper_start = BOOT_JS.find("function _currentSessionIsReusableEmptyChat()")
helper_end = BOOT_JS.find("$('fileInput').onchange", helper_start)
assert helper_start != -1 and helper_end != -1, "empty-chat reuse helper not found"
helper = BOOT_JS[helper_start:helper_end]
assert "S.session.message_count||0" in helper, (
"empty-chat reuse should still honor the server-side session message count"
)
assert "S.messages.some(m=>m&&m.role&&m.role!=='tool')" in helper, (
"empty-chat reuse must not focus-only when loaded transcript messages are visible"
)
assert "S.session.active_stream_id" in helper and "S.session.pending_user_message" in helper, (
"empty-chat reuse must continue to treat in-flight zero-count sessions as real sessions"
)
button_body = _btn_new_chat_handler()
assert "if(_currentSessionIsReusableEmptyChat())" in button_body
shortcut_start = BOOT_JS.find("if((e.metaKey||e.ctrlKey)&&e.key==='k')")
shortcut_end = BOOT_JS.find("// Cmd/Ctrl+, opens/closes Settings", shortcut_start)
assert shortcut_start != -1 and shortcut_end != -1, "Cmd/Ctrl+K handler block not found"
shortcut_body = BOOT_JS[shortcut_start:shortcut_end]
assert "if(_currentSessionIsReusableEmptyChat())" in shortcut_body
def test_restore_helper_validates_candidate_with_session_metadata():
assert "const NEW_CHAT_DRAFT_SESSION_KEY = 'hermes-new-chat-draft-session';" in SESSIONS_JS
assert "async function _restoreRememberedNewChatDraftSession()" in SESSIONS_JS