feat: echter Download-Fortschritt via Datei-Polling

`hf` gibt im Nicht-TTY-Modus keinen Fortschritt aus (am Bosgame verifiziert:
0 CR-Frames). Stattdessen pollt jobengine.attach_download_progress die
wachsende <local-dir>/.cache/huggingface/download/*.incomplete-Datei gegen die
Gesamtgroesse aus der HF-Tree-API (cookbook.hf_file_size) -> exaktes %.

- attach_download_progress an /api/download, install-recipe, install-model
- Frontend (Aktivitaet + Server-Karte): nutzt job.progress bevorzugt,
  Log-%-Parsing bleibt Fallback fuer Tools, die selbst Prozente ausgeben

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-21 18:26:27 +02:00
parent 2cde6ba5a5
commit 3cf36d436b
5 changed files with 68 additions and 7 deletions
+12 -4
View File
@@ -141,12 +141,20 @@ function onJobs(jobs) {
: canceled ? '<span class="badge">abgebrochen</span>'
: '<span class="badge b-load">läuft…</span>';
// Fortschrittsbalken aus der letzten Log-Zeile (tqdm: " 45%|…")
const last = (j.log || [])[j.log.length - 1] || "";
const pm = !terminal && last.match(/(\d+(?:\.\d+)?)\s*%/);
// Fortschrittsbalken: exakter Backend-Wert (Download) bevorzugt, sonst %-Angabe im Log.
let pval = null;
if (!terminal) {
if (typeof j.progress === "number") {
pval = j.progress;
} else {
const last = (j.log || [])[j.log.length - 1] || "";
const pm = last.match(/(\d+(?:\.\d+)?)\s*%/);
if (pm) pval = parseFloat(pm[1]);
}
}
const bar = $("#w-update-bar");
if (bar) {
if (pm) { bar.style.display = ""; bar.querySelector("i").style.width = Math.min(100, parseFloat(pm[1])) + "%"; }
if (pval != null) { bar.style.display = ""; bar.querySelector("i").style.width = Math.min(100, pval) + "%"; }
else bar.style.display = "none";
}
$("#w-update-cancel").style.display = terminal ? "none" : "";