mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-23 10:50:14 +00:00
104 lines
4.6 KiB
Python
104 lines
4.6 KiB
Python
import re
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def test_messages_zero_skips_effective_model_resolution():
|
|
src = (ROOT / "api" / "routes.py").read_text(encoding="utf-8")
|
|
|
|
assert re.search(
|
|
r"effective_model\s*=\s*\(\s*"
|
|
r"_resolve_effective_session_model_for_display\(s\)\s*"
|
|
r"if resolve_model\s*else None\s*\)",
|
|
src,
|
|
), "messages=0 metadata requests must not resolve the model catalog"
|
|
assert 'resolve_model_default = "1" if load_messages else "0"' in src
|
|
|
|
|
|
def test_full_message_load_updates_viewed_count_after_metadata_fast_path():
|
|
src = (ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
|
|
|
assert "_setSessionViewedCount(S.session.session_id, Number(data.session.message_count || 0));" in src
|
|
assert "_setSessionViewedCount(sid, Number(S.session.message_count || msgs.length));" in src
|
|
|
|
|
|
def test_lazy_message_load_skips_model_resolution():
|
|
src = (ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
|
|
|
assert "messages=1&resolve_model=0" in src
|
|
|
|
|
|
def test_session_switch_defers_model_resolution_without_blocking():
|
|
src = (ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
|
ui = (ROOT / "static" / "ui.js").read_text(encoding="utf-8")
|
|
|
|
assert "messages=0&resolve_model=0" in src
|
|
assert "function _resolveSessionModelForDisplaySoon" in src
|
|
assert "messages=0&resolve_model=1" in src
|
|
assert "_modelResolutionDeferred=true" in src
|
|
assert "deferModelCorrection" in ui
|
|
assert "if(fallback&&!deferModelCorrection)" in ui
|
|
|
|
|
|
def test_deferred_model_resolution_refreshes_context_metadata():
|
|
src = (ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
|
start = src.index("function _resolveSessionModelForDisplaySoon")
|
|
end = src.index("const _INITIAL_MSG_LIMIT", start)
|
|
block = src[start:end]
|
|
|
|
assert "S.session.context_length" in block, (
|
|
"deferred model resolution must also hydrate context_length so a "
|
|
"resumed high-context session does not keep the old model's limit"
|
|
)
|
|
assert "S.session.threshold_tokens" in block
|
|
assert "_syncCtxIndicator" in block
|
|
assert "context_length:data.session.context_length||0" in block.replace(" ", "")
|
|
|
|
|
|
def test_boot_does_not_block_session_restore_on_model_catalog():
|
|
src = (ROOT / "static" / "boot.js").read_text(encoding="utf-8")
|
|
|
|
assert "if(s.default_model){" in src
|
|
assert "window._defaultModel=s.default_model;" in src
|
|
assert "const _hydrateBootModelDropdown=()=>populateModelDropdown().then" in src
|
|
assert "window._modelDropdownReady=null;" in src
|
|
assert "window._ensureModelDropdownReady=_startBootModelDropdown;" in src
|
|
assert "await populateModelDropdown()" not in src
|
|
|
|
|
|
def test_boot_primes_visible_default_model_without_catalog_fetch():
|
|
src = (ROOT / "static" / "boot.js").read_text(encoding="utf-8")
|
|
default_block_start = src.index("if(s.default_model){")
|
|
default_block = src[default_block_start:src.index("window._sessionJumpButtonsEnabled", default_block_start)]
|
|
|
|
assert "if(s.default_model_provider) window._activeProvider=s.default_model_provider;" in src
|
|
assert "const existingDefaultOpt=Array.from(sel.options).find(o=>o.value===s.default_model);" in default_block
|
|
assert "existingDefaultOpt.dataset.provider=window._activeProvider;" in default_block
|
|
assert "if(!existingDefaultOpt)" in default_block
|
|
assert "opt.dataset.custom='1'" in default_block
|
|
assert "opt.dataset.provider=window._activeProvider||''" in default_block
|
|
assert "_applyModelToDropdown(s.default_model,sel,window._activeProvider||null)" in default_block
|
|
assert "populateModelDropdown()" not in default_block
|
|
|
|
|
|
def test_settings_exposes_default_model_provider_for_lazy_boot_catalog():
|
|
src = (ROOT / "api" / "config.py").read_text(encoding="utf-8")
|
|
|
|
assert 'settings["default_model_provider"]' in src
|
|
assert 'model_cfg = get_config().get("model", {})' in src
|
|
|
|
|
|
def test_boot_renders_session_list_before_workspace_and_onboarding_settle():
|
|
src = (ROOT / "static" / "boot.js").read_text(encoding="utf-8")
|
|
workspace_start = src.index("const _workspaceListReady=loadWorkspaceList();")
|
|
onboarding_start = src.index("const _onboardingReady=_bootSettings.onboarding_completed?Promise.resolve(false):loadOnboardingWizard();")
|
|
render_pos = src.index("await renderSessionList();", onboarding_start)
|
|
workspace_await = src.index("await _workspaceListReady;", render_pos)
|
|
onboarding_await = src.index("await _onboardingReady;", render_pos)
|
|
|
|
assert workspace_start < render_pos < workspace_await
|
|
assert onboarding_start < render_pos < onboarding_await
|
|
assert "_bootSettings.onboarding_completed" in src
|