fix(#5021): keep boot model budget across restore paths
This commit is contained in:
1 parent
a18ddae930
commit
288cbb55bc
4 files changed
+46
-23
No files matched your search
+3
-1
@@ -2278,7 +2278,9 @@ window._applyTitlebarProfileVisibility=_applyTitlebarProfileVisibility;
|
||||
let consumed=false;
|
||||
const readAttempted=(storage=sessionStorage)=>{
|
||||
try{
|
||||
return storage&&storage.getItem?storage.getItem(markerKey)==='1':false;
|
||||
const attempted=storage&&storage.getItem?storage.getItem(markerKey)==='1':false;
|
||||
if(attempted) consumed=true;
|
||||
return attempted;
|
||||
}catch(_){
|
||||
return false;
|
||||
}
|
||||
|
||||
+11
-7
@@ -1294,14 +1294,18 @@ async function loadSession(sid){
|
||||
S._pendingSessionToolsets=null;
|
||||
if(typeof populateModelDropdown==='function'){
|
||||
const modelRefreshSid=sid;
|
||||
const modelRefreshPromise=Promise.resolve().then(()=>{
|
||||
if(_loadingSessionId!==modelRefreshSid) return;
|
||||
if(!S._bootReady&&typeof window!=='undefined'&&typeof window._startBootModelDropdown==='function'){
|
||||
if(!S._bootReady&&typeof window!=='undefined'&&typeof window._startBootModelDropdown==='function'){
|
||||
Promise.resolve().then(()=>{
|
||||
if(_loadingSessionId!==modelRefreshSid) return;
|
||||
return window._startBootModelDropdown();
|
||||
}
|
||||
return populateModelDropdown({freshness:'session_visit'});
|
||||
}).catch(()=>{});
|
||||
if(typeof window!=='undefined') window._modelDropdownReady=modelRefreshPromise;
|
||||
}).catch(()=>{});
|
||||
}else{
|
||||
const modelRefreshPromise=Promise.resolve().then(()=>{
|
||||
if(_loadingSessionId!==modelRefreshSid) return;
|
||||
return populateModelDropdown({freshness:'session_visit'});
|
||||
}).catch(()=>{});
|
||||
if(typeof window!=='undefined') window._modelDropdownReady=modelRefreshPromise;
|
||||
}
|
||||
}
|
||||
if(typeof _hydrateTodosFromSession==='function') _hydrateTodosFromSession(S.session);
|
||||
S.session._modelResolutionDeferred=true;
|
||||
|
||||
@@ -12,6 +12,7 @@ ROOT = Path(__file__).resolve().parent.parent
|
||||
BOOT_JS = ROOT / "static" / "boot.js"
|
||||
UI_JS = ROOT / "static" / "ui.js"
|
||||
NODE = shutil.which("node")
|
||||
BOOT_MARKER_KEY = "hermes-webui-active-profile-bootstrap-401"
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
@@ -436,18 +437,31 @@ def test_boot_model_401_does_not_reopen_redirect_after_active_profile_fallback(d
|
||||
|
||||
|
||||
def test_boot_model_401_consumes_budget_when_profile_load_succeeds(driver_path):
|
||||
payload = _run(
|
||||
first = _run(
|
||||
driver_path,
|
||||
{
|
||||
"kind": "boot-model-only",
|
||||
},
|
||||
)
|
||||
|
||||
assert payload["redirects"] == ["login?next=%2Fsession%2Fabc%3Fworkspace%3Dtest"]
|
||||
assert payload["results"][0]["state"]["status"] == "resolved"
|
||||
assert payload["jsonCalls"] == 0
|
||||
assert payload["activeProvider"] is None
|
||||
assert payload["defaultModel"] is None
|
||||
second = _run(
|
||||
driver_path,
|
||||
{
|
||||
"kind": "boot-model-only",
|
||||
"initialStorage": first["storage"],
|
||||
},
|
||||
)
|
||||
|
||||
assert first["redirects"] == ["login?next=%2Fsession%2Fabc%3Fworkspace%3Dtest"]
|
||||
assert first["results"][0]["state"]["status"] == "resolved"
|
||||
assert first["storage"] == {BOOT_MARKER_KEY: "1"}
|
||||
assert first["jsonCalls"] == 0
|
||||
assert first["activeProvider"] is None
|
||||
assert first["defaultModel"] is None
|
||||
assert second["redirects"] == []
|
||||
assert second["results"][0]["state"]["status"] == "resolved"
|
||||
assert second["storage"] == {}
|
||||
assert second["jsonCalls"] == 0
|
||||
|
||||
|
||||
def test_boot_model_success_still_stores_active_provider(driver_path):
|
||||
|
||||
@@ -328,22 +328,25 @@ def test_load_session_schedules_async_session_visit_model_refresh_after_metadata
|
||||
body = _extract_function_body(_read_static("sessions.js"), "async function loadSession(")
|
||||
|
||||
assign_idx = body.index("S.session=data.session")
|
||||
promise_idx = body.index("const modelRefreshPromise=Promise.resolve().then(")
|
||||
boot_guard_idx = body.index("if(!S._bootReady&&typeof window!=='undefined'&&typeof window._startBootModelDropdown==='function'){")
|
||||
boot_promise_idx = body.index("Promise.resolve().then(()=>{", boot_guard_idx)
|
||||
boot_refresh_idx = body.index("return window._startBootModelDropdown();")
|
||||
else_idx = body.index("}else{", boot_refresh_idx)
|
||||
promise_idx = body.index("const modelRefreshPromise=Promise.resolve().then(", else_idx)
|
||||
ready_idx = body.index("window._modelDropdownReady=modelRefreshPromise")
|
||||
refresh_idx = body.index("populateModelDropdown({freshness:'session_visit'})")
|
||||
stale_guard_idx = body.index("_loadingSessionId!==modelRefreshSid")
|
||||
|
||||
assert assign_idx < promise_idx < boot_guard_idx < boot_refresh_idx < refresh_idx < ready_idx
|
||||
assert promise_idx < stale_guard_idx < boot_guard_idx
|
||||
assert assign_idx < boot_guard_idx < boot_promise_idx < boot_refresh_idx < else_idx < promise_idx < refresh_idx < ready_idx
|
||||
assert boot_promise_idx < stale_guard_idx < boot_refresh_idx
|
||||
assert promise_idx < body.index("_loadingSessionId!==modelRefreshSid", promise_idx) < refresh_idx
|
||||
|
||||
|
||||
def test_boot_model_dropdown_reuses_inflight_session_visit_refresh():
|
||||
body = _extract_function_body(_read_static("boot.js"), "const _startBootModelDropdown=()=>")
|
||||
def test_boot_model_dropdown_clears_cached_ready_on_401():
|
||||
body = _extract_function_body(_read_static("boot.js"), "const _redirectBootModelDropdownIfUnauth=(res)=>")
|
||||
|
||||
ready_idx = body.index("const ready=window._modelDropdownReady;")
|
||||
reuse_idx = body.index("if(ready&&typeof ready.then==='function') return ready;")
|
||||
hydrate_idx = body.index("const next=_hydrateModelDropdown({redirectIfUnauth:_redirectBootModelDropdownIfUnauth});")
|
||||
status_idx = body.index("if(!res||res.status!==401) return false;")
|
||||
clear_idx = body.index("window._modelDropdownReady=null;")
|
||||
consumed_idx = body.index("if(_bootActiveProfileUnauthRedirectBudget.isConsumed()) return true;")
|
||||
|
||||
assert ready_idx < reuse_idx < hydrate_idx
|
||||
assert status_idx < clear_idx < consumed_idx
|
||||
Reference in new issue
Block a user