Spaces:
Running
Running
File size: 3,406 Bytes
57bd44d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* Warm-up helper for the in-weights backend (Meta Muse Glimmer 30B + ViKernel, GPU unit).
The backend sleeps when idle to save cost. While it wakes, every app shows "Loading the model n%" with the
current start-up step instead of an error. Only apps that need the in-weights model call this (no polling otherwise). */
(() => {
'use strict';
const css = document.createElement('style');
css.textContent = `.vkwarm{border:1px solid var(--border);border-radius:10px;padding:8px 10px;background:var(--card);font:13px system-ui,'Segoe UI',sans-serif}
.vkwarm .vkw-t{display:flex;justify-content:space-between;gap:8px;font-weight:700}.vkwarm .vkw-s{color:var(--muted);font-size:12px;margin-top:2px}
.vkwarm .vkw-b{height:8px;border-radius:99px;background:var(--bg);overflow:hidden;margin-top:6px}.vkwarm .vkw-f{height:100%;width:0;background:linear-gradient(90deg,#6366F1,#0F766E);transition:width .8s ease}
.vkwarm.ready .vkw-f{background:#16A34A}`;
document.head.append(css);
let last = null, maxPct = 0;
async function health() {
const ctl = new AbortController(); const to = setTimeout(() => ctl.abort(), 12000);
try {
const r = await fetch('api/agx/health', {cache:'no-store', signal:ctl.signal, headers:{'X-VK-Session':window.VK_SID || ''}});
if (!r.ok) return null;
return await r.json();
} catch (e) { return null; } finally { clearTimeout(to); }
}
const ready = (h, needGpu) => !!(h && h.live && (!needGpu || (h.gpu_unit && h.gpu_unit.live)));
function info(h, needGpu) {
if (ready(h, needGpu)) { maxPct = 100; return {pct:100, label:'ready', eta:0}; }
const L = (h && h.loading) || {pct:2, label:'waking the in-weights model'};
let pct = Math.min(99, L.pct || 0);
if (h && h.live && needGpu && pct < 80) pct = 80; // chat is up, GPU unit still loading
maxPct = Math.max(maxPct, pct);
return {pct:maxPct, label:L.label || L.stage || 'loading', eta:L.eta_s};
}
// a small progress card; call .set(info) to update
function bar() {
const d = document.createElement('div'); d.className = 'vkwarm';
d.innerHTML = '<div class="vkw-t"><span data-w="t">Loading the model 0%</span><span data-w="e"></span></div><div class="vkw-s" data-w="s">checking the in-weights backend...</div><div class="vkw-b"><div class="vkw-f" data-w="f"></div></div>';
d.set = i => {
const q = k => d.querySelector(`[data-w="${k}"]`);
d.classList.toggle('ready', i.pct >= 100);
q('t').textContent = i.pct >= 100 ? 'Model ready' : `Loading the model ${i.pct}%`;
q('s').textContent = i.pct >= 100 ? 'Meta Muse Glimmer 30B + ViKernel in-weights is live.' : i.label + '. The model sleeps when idle to save cost; the first wake takes about 4 minutes.';
q('e').textContent = i.pct >= 100 || i.eta == null ? '' : `about ${Math.max(1, Math.round(i.eta / 60))} min left`;
q('f').style.width = i.pct + '%';
};
return d;
}
// resolves true when ready; onProgress(info) on every poll. alive() false stops polling (window closed).
async function wait({needGpu = true, onProgress = () => {}, alive = () => true, maxMs = 600000} = {}) {
const t0 = Date.now();
while (Date.now() - t0 < maxMs && alive()) {
const h = await health(); last = h;
const i = info(h, needGpu); onProgress(i, h);
if (i.pct >= 100) return true;
await new Promise(r => setTimeout(r, 5000));
}
return false;
}
window.VK_WARM = {health, wait, bar, ready, info, last:() => last};
})();
|