fix model selector loading

This commit is contained in:
Dobromir Popov
2026-07-09 08:28:32 +03:00
parent 9ec4ca9ce1
commit 5b1655fcca
2 changed files with 32 additions and 22 deletions

View File

@@ -1223,11 +1223,9 @@ function switchDashboardTab(name) {
const button = $("tab-" + tabName); const button = $("tab-" + tabName);
if (button) button.classList.toggle("active", tabName === dashboardTab); if (button) button.classList.toggle("active", tabName === dashboardTab);
} }
if (name === "chat") { void refreshActiveTab(true).then(() => {
const promptEl = $("chat-prompt"); if (dashboardTab === "chat") $("chat-prompt")?.focus();
if (promptEl) promptEl.focus(); });
}
refreshActiveTab(true);
} }
function updateSectionVisibility() { function updateSectionVisibility() {
@@ -1636,7 +1634,7 @@ async function loadAccountSummary(force) {
} }
if (!r.ok) { setSession(null); renderAuthForms(); return false; } if (!r.ok) { setSession(null); renderAuthForms(); return false; }
applyAccountSummary(r.data, force); applyAccountSummary(r.data, force);
if (dashboardTab === "chat" && !refreshBlocked()) renderChatModels(force); if (availableModels.length) renderChatModels(Boolean(force));
return true; return true;
} }
@@ -1830,6 +1828,9 @@ function bindChatPromptShortcuts() {
promptEl.style.height = "auto"; promptEl.style.height = "auto";
promptEl.style.height = Math.min(promptEl.scrollHeight, 200) + "px"; promptEl.style.height = Math.min(promptEl.scrollHeight, 200) + "px";
}); });
promptEl.addEventListener("blur", () => {
if (pendingChatModelRefresh) renderChatModels(true);
});
} }
async function cancelProxyRequest(requestId) { async function cancelProxyRequest(requestId) {
@@ -1866,6 +1867,21 @@ function applyAvailableModels(models, map) {
}).filter(model => model.id); }).filter(model => model.id);
} }
async function preloadChatModels(forceRender) {
const [map, models, routing] = await Promise.all([
fetchJson("/v1/network/map"),
fetchJson("/v1/models"),
fetchJson("/v1/routing"),
]);
if (routing) lastRouting = routing;
applyAvailableModels(models, map);
if (forceRender !== false) {
panelSig.chatModels = null;
renderChatModels(true);
}
return { map, models, routing };
}
function markRefreshed() { function markRefreshed() {
$("refreshed").textContent = "refreshed " + new Date().toLocaleTimeString(); $("refreshed").textContent = "refreshed " + new Date().toLocaleTimeString();
} }
@@ -1893,20 +1909,10 @@ async function fetchOverviewTab() {
} }
async function fetchChatTab() { async function fetchChatTab() {
const fetches = [ await preloadChatModels(true);
fetchJson("/v1/network/map"), if (isLoggedIn) {
fetchJson("/v1/models"), const accountResp = await apiCall("/v1/account");
fetchJson("/v1/routing"), if (accountResp && accountResp.ok) applyAccountSummary(accountResp.data, false);
];
if (isLoggedIn) fetches.push(apiCall("/v1/account"));
const [map, models, routing, accountResp] = await Promise.all(fetches);
lastRouting = routing;
applyAvailableModels(models, map);
if (accountResp && accountResp.ok) applyAccountSummary(accountResp.data, false);
if (!refreshBlocked()) {
renderChatModels(true);
} else {
pendingChatModelRefresh = true;
} }
} }
@@ -2003,10 +2009,12 @@ bindChatPromptShortcuts();
(async () => { (async () => {
if (sessionToken) await loadAccountSummary(true); if (sessionToken) await loadAccountSummary(true);
else renderAuthForms(); else renderAuthForms();
await refreshActiveTab(true); await Promise.all([
preloadChatModels(true),
refreshActiveTab(true),
]);
renderChatHistory(true); renderChatHistory(true);
renderChatAuthHint(); renderChatAuthHint();
if (dashboardTab === "chat") renderChatModels(true);
})(); })();
setInterval(pollCallWallIfIdle, CALL_WALL_POLL_MS); setInterval(pollCallWallIfIdle, CALL_WALL_POLL_MS);
</script> </script>

View File

@@ -50,6 +50,8 @@ def test_dashboard_chat_uses_streaming_fetch():
assert ".body.getReader()" in html assert ".body.getReader()" in html
assert '=== "[DONE]"' in html assert '=== "[DONE]"' in html
assert 'console.error("chat stream failed", err)' in html assert 'console.error("chat stream failed", err)' in html
assert "preloadChatModels" in html
assert "renderChatModels(true)" in html
def test_network_map_includes_node_friendly_name(): def test_network_map_includes_node_friendly_name():