mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-25 19:20:16 +00:00
fix(chat): resolve session model before activating
This commit is contained in:
committed by
nesquena-hermes
parent
a323f49f14
commit
af1ee81f06
+5
-1
@@ -567,10 +567,14 @@ async function loadSession(sid){
|
||||
if (_msgInner && currentSid !== sid) _msgInner.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px;padding:40px;text-align:center;">Loading conversation...</div>';
|
||||
}
|
||||
// Phase 1: Load metadata only (~1KB) for fast session switching.
|
||||
// Resolve model immediately: old sessions can persist stale provider-shaped
|
||||
// IDs (e.g. openai/gpt-5.4-mini) and assigning those to S.session creates a
|
||||
// short race where the composer can display/send the wrong model before the
|
||||
// deferred resolver catches up.
|
||||
// Guard against network/server failures to prevent a permanently stuck loading state.
|
||||
let data;
|
||||
try {
|
||||
data = await api(`/api/session?session_id=${encodeURIComponent(sid)}&messages=0&resolve_model=0`);
|
||||
data = await api(`/api/session?session_id=${encodeURIComponent(sid)}&messages=0&resolve_model=1`);
|
||||
} catch(e) {
|
||||
const _msgInner = $('msgInner');
|
||||
if(_msgInner){
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
"""Regression tests for stale session model hydration in the WebUI.
|
||||
|
||||
Old sessions can persist provider-shaped model IDs such as ``openai/gpt-5.4-mini``
|
||||
after the active runtime moved to OpenAI Codex ``gpt-5.5``. The first
|
||||
``loadSession()`` metadata request must ask the backend for the resolved model so
|
||||
that the composer state cannot briefly use the stale raw value for display or the
|
||||
next chat-start payload.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
SESSIONS_JS = (REPO_ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _extract_function(src: str, signature: str) -> str:
|
||||
start = src.find(signature)
|
||||
assert start >= 0, f"missing function signature: {signature}"
|
||||
brace = src.find("{", start)
|
||||
assert brace >= 0, f"missing function body for: {signature}"
|
||||
depth = 0
|
||||
for idx in range(brace, len(src)):
|
||||
ch = src[idx]
|
||||
if ch == "{":
|
||||
depth += 1
|
||||
elif ch == "}":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return src[start : idx + 1]
|
||||
raise AssertionError(f"unterminated function body for: {signature}")
|
||||
|
||||
|
||||
def test_load_session_initial_metadata_request_resolves_model_before_state_assignment():
|
||||
body = _extract_function(SESSIONS_JS, "async function loadSession(sid")
|
||||
metadata_fetch = "messages=0&resolve_model=1"
|
||||
stale_metadata_fetch = "messages=0&resolve_model=0"
|
||||
assignment = "S.session=data.session"
|
||||
|
||||
assert metadata_fetch in body, (
|
||||
"loadSession() must resolve model metadata on the initial fetch so stale "
|
||||
"persisted models like openai/gpt-5.4-mini cannot become active composer state"
|
||||
)
|
||||
assert stale_metadata_fetch not in body[: body.index(assignment)], (
|
||||
"loadSession() must not assign S.session from unresolved metadata before the "
|
||||
"backend has normalized stale model/provider combinations"
|
||||
)
|
||||
Reference in New Issue
Block a user