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
+3 -1
View File
@@ -16,9 +16,11 @@ const MAX_HIST = 60;
function statusBadge(s) { return s === "done" ? '<span class="badge b-run">fertig</span>' : s === "failed" ? '<span class="badge b-err">fehler</span>' : s === "canceled" ? '<span class="badge">abgebrochen</span>' : '<span class="badge b-load">läuft…</span>'; }
function dotClass(s) { return s === "done" ? "on" : (s === "failed" || s === "canceled") ? "" : "load"; }
// Fortschritt in % aus der letzten Log-Zeile ziehen (tqdm schreibt z.B. " 45%|…").
// Fortschritt in %: bevorzugt der exakte Wert vom Backend (Download-Datei-Polling),
// sonst Fallback auf eine %-Angabe in der letzten Log-Zeile.
function jobPct(j) {
if (j.state !== "running") return null;
if (typeof j.progress === "number") return Math.min(100, j.progress);
const last = (j.log || [])[j.log.length - 1] || "";
const m = last.match(/(\d+(?:\.\d+)?)\s*%/);
return m ? Math.min(100, parseFloat(m[1])) : null;