mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-07-18 13:40:22 +00:00
fdfb935b5e
* fix(sidebar): keep active New Chat visible before first message (#3408, @AJV20) Squashed net diff of #3408. Injects ONLY the active ephemeral session into the sidebar render rows (when the server list omits it) so a freshly-created New Chat stays visible/selected before its first turn; inactive empty sessions stay filtered as before. New Chat also resets a CLI source-filter back to webui so the active chat isn't immediately hidden. * fix(sidebar): gate active-row reinjection to 0-message ephemeral only (#3408 Codex follow-up) Codex review found _ensureActiveSessionRowPresent re-injected ANY active session after search-merge — so an active conversation WITH messages that was correctly filtered out by the search query would pollute unrelated search results. Gate the reinjection to Number(activeRow.message_count||0)<=0 so only the freshly-created 0-message ephemeral chat is re-added; an active chat with messages stays filtered by search as before. Added a regression test asserting the gate. --------- Co-authored-by: nesquena-hermes <[email protected]>
49 lines
2.5 KiB
Python
49 lines
2.5 KiB
Python
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SESSIONS_JS = (ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
|
|
|
|
|
def test_active_empty_session_is_injected_into_sidebar_rows():
|
|
assert "function _sessionRowsWithActiveEphemeralSession(rows)" in SESSIONS_JS
|
|
helper_start = SESSIONS_JS.index("function _sessionRowsWithActiveEphemeralSession(rows)")
|
|
helper_end = SESSIONS_JS.index("function renderSessionListFromCache()", helper_start)
|
|
helper = SESSIONS_JS[helper_start:helper_end]
|
|
|
|
assert "S.session" in helper
|
|
assert "message_count:0" in helper
|
|
assert "title:S.session.title||'New Chat'" in helper
|
|
assert "rows.some(s=>s&&s.session_id===sid)" in helper
|
|
|
|
|
|
def test_new_session_switches_sidebar_back_to_webui_source():
|
|
new_session = SESSIONS_JS[SESSIONS_JS.index("async function newSession"):SESSIONS_JS.index("async function loadSession")]
|
|
assert "if(_sessionSourceFilter==='cli') _sessionSourceFilter='webui';" in new_session
|
|
|
|
|
|
def test_sidebar_search_uses_active_ephemeral_rows_before_filtering():
|
|
render_start = SESSIONS_JS.index("function renderSessionListFromCache()")
|
|
render_end = SESSIONS_JS.index("function _showProjectPicker", render_start)
|
|
render_body = SESSIONS_JS[render_start:render_end]
|
|
|
|
assert "const sidebarRows=_sessionRowsWithActiveEphemeralSession(_allSessions);" in render_body
|
|
assert "const searchMatches=_sessionSearchMergeMatches(sidebarRows,searchQueryRaw,_contentSearchResults);" in render_body
|
|
assert "const allMatched=_ensureActiveSessionRowPresent(searchMatches,sidebarRows);" in render_body
|
|
|
|
|
|
def test_active_row_reinjection_gated_to_zero_message_ephemeral_only():
|
|
"""#3408 review (Codex): _ensureActiveSessionRowPresent must only re-add the
|
|
active FRESHLY-CREATED 0-message chat after search-merge. An active conversation
|
|
that already has messages and was filtered out by the search query must stay
|
|
filtered — re-adding it would pollute unrelated search results with the current
|
|
chat."""
|
|
start = SESSIONS_JS.index("function _ensureActiveSessionRowPresent(rows, sourceRows)")
|
|
end = SESSIONS_JS.index("function clearOptimisticSessionStreaming", start)
|
|
body = SESSIONS_JS[start:end]
|
|
|
|
# The reinjection is gated on a 0-message check, not an unconditional prepend.
|
|
assert "Number(activeRow.message_count||0)<=0" in body
|
|
assert "[activeRow,...rows]" in body
|
|
# The unconditional return that shipped in the original PR must be gone.
|
|
assert "return activeRow?[activeRow,...rows]:rows;" not in body
|