${e(x.repo)}
${e(x.file)} · ${size(x.size)}
Heruntergeladen · Laufzeit noch nicht angebunden
Revision ${e(x.revision)} · ${x.upstream_hash_verified?'SHA-256 mit Quelle geprüft':'SHA-256 lokal erfasst; Größe mit Quelle geprüft'}From f326de18d1487fb69789ad332224cd4defb9a147 Mon Sep 17 00:00:00 2001
From: Mikei386 <44135113+Mikei386@users.noreply.github.com>
Date: Mon, 28 Sep 2026 17:04:42 +0200
Subject: [PATCH] Improve model discovery, variant selection and download
visibility
---
STUDIO.md | 26 ++++++++++++++
catalog-ui.js | 97 ++++++++++++++++++++++++++++++++++++++++++++-------
style.css | 6 ++++
3 files changed, 117 insertions(+), 12 deletions(-)
diff --git a/STUDIO.md b/STUDIO.md
index 8ae06e8..57d93a4 100644
--- a/STUDIO.md
+++ b/STUDIO.md
@@ -75,3 +75,29 @@ Build-Einstellungen und Update-Ansicht geöffnet, deaktivierte Aktionsknöpfe so
Layout kontrolliert. Die Testvorschau verwendet einen eigenen Origin, sodass keine
Entwürfe der eigentlichen Anwendung überschrieben wurden. Keine SSH-/Modell- oder
Build-Aktion für diese GUI-Erweiterung ausgeführt.
+
+## Modellgalerie und Download-Ablauf (2026-09-28)
+
+Die Live-Galerie verwendet eine eigene Deck-Oberfläche, inspiriert von LocalAIs
+[Modellgalerie](https://github.com/mudler/LocalAI/blob/master/core/http/react-ui/src/pages/Models.jsx)
+und [Download-Anzeige](https://github.com/mudler/LocalAI/blob/master/core/http/react-ui/src/components/OperationCard.jsx).
+Es wurde kein LocalAI-Frontendcode übernommen.
+
+- Beim Öffnen erscheinen beliebte Hugging-Face-Repositories des Bereichs.
+- Suche liefert bis zu 20 Treffer; Sortierung nach Downloads oder Namen.
+- Ergebnis auswählen: Modelldetails, Lizenzlink und feste Quellrevision.
+- Dateien nach Name/Quantisierungsbezeichnung und Format filtern; genau eine Datei auswählen.
+- Download explizit starten. Zugangsbeschränkte Repositories, bereits vorhandene
+ Dateien, laufende Downloads und unzureichender Speicher sperren den Button.
+- Fortschritt, Bytes, Abbruch und Fehler werden aus der vorhandenen API angezeigt.
+- Bibliothek zeigt abgeschlossene Dateien einschließlich Version und Integritätsprüfung.
+
+Grenzen: weiterhin Einzeldateien, keine vollständige Pipeline-Installation,
+keine Warteschlange, kein Resume, keine automatischen Modellstarts. Audio-Suche
+ist derzeit auf Text-to-Speech begrenzt. Hardware-/Kontext-Eignung wird in dieser
+Galerie noch nicht berechnet; Dateigröße wird ausdrücklich nicht als VRAM-Bedarf
+angezeigt. Der separate llama.cpp-Einpassungstest bleibt unter Einstellungen.
+
+Validierung: 46 bestehende Python-Tests bestanden; JavaScript-Syntax geprüft;
+Browserprüfung mit echten Hugging-Face-Such- und Dateidaten, Dateifilter,
+Auswahl und Speicherreserve-Sperre. Keine Modellgewichte für den UI-Test geladen.
diff --git a/catalog-ui.js b/catalog-ui.js
index 8cb4760..6375d19 100644
--- a/catalog-ui.js
+++ b/catalog-ui.js
@@ -1,15 +1,88 @@
-const CatalogUI=(()=>{
- const e=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
- const size=n=>(n/1024**3).toFixed(2)+' GiB';
- async function api(path,data){const r=await fetch('/api/v1/catalog'+path,data?{method:'POST',headers:{'Content-Type':'application/json','X-Athena-Deck':'1'},body:JSON.stringify(data)}:{});const v=await r.json();if(!r.ok)throw Error(v.error||'Anfrage fehlgeschlagen');return v;}
- function html(library){return ` Öffentliche Repositories. Downloads laden kein Modell in RAM oder VRAM. Für Bild, Audio und Video können mehrere Dateien und ein eigener Worker nötig sein.${library?'Dateien auf Athena':'Modelle suchen'}
Freier Speicher: ${size(v.free_bytes)} · Reserve: 10 GiB
`+(j?`${e(j.repo)} / ${e(j.file)} · ${e(j.state)} · ${size(j.bytes)} / ${size(j.total)}
${j.error?`${e(j.error)}
`:''}${j.state==='downloading'?'':''}`:'');root.querySelector('#hub-cancel')?.addEventListener('click',async()=>{await api('/cancel',{});message('Abbruch angefordert; laufende Netzwerkabfrage kann noch bis zu 20 Sekunden dauern.');});if(library)root.querySelector('#hub-results').innerHTML=v.entries.filter(x=>x.kind===kind).map(x=>`${e(x.file)} · ${size(x.size)}
Heruntergeladen · Laufzeit noch nicht angebunden
Revision ${e(x.revision)} · ${x.upstream_hash_verified?'SHA-256 mit Quelle geprüft':'SHA-256 lokal erfasst; Größe mit Quelle geprüft'}Noch keine Dateien für diesen Bereich heruntergeladen.
';if(j?.state==='downloading')setTimeout(()=>{if(root.isConnected)refresh();},2000);}catch(err){message(err.message);}} - root.querySelector('#hub-refresh').onclick=refresh; - root.querySelector('#hub-search')?.addEventListener('submit',async event=>{event.preventDefault();message('Suche …');try{const v=await api('/search?'+new URLSearchParams({q:new FormData(event.target).get('q'),kind}));if(!root.isConnected)return;root.querySelector('#hub-results').innerHTML=v.models.map(m=>`${m.gated?'Zugangsbeschränkt':'Öffentlich'} · ${e(m.downloads)} Downloads
Lizenz: ${e(v.license||'Nicht angegeben')} · Modellkarte und Bedingungen lesen
VRAM- und Kontext-Eignung noch nicht berechnet. Dateigröße allein belegt keine Lauffähigkeit.
`+v.files.map((f,i)=>`${e(f.name)} · ${size(f.size)}
${library ? 'Heruntergeladene Dateien mit festgehaltener Version und Integritätsprüfung.' : 'Modell suchen, Variante vergleichen und gezielt auf Athena herunterladen.'}
Wähle ein Ergebnis, um Dateien, Varianten und Lizenz zu prüfen.
Downloads belegen Festplattenspeicher. Sie starten kein Modell. Für Bild, Audio und Video sind häufig mehrere Dateien und ein passender Worker erforderlich.
Versuche einen anderen Namen. Die Suche ist auf den aktuellen Bereich begrenzt.
${escape(x.file)}
${size(x.size)}Laufzeit noch nicht angebunden
Revision ${escape(x.revision)}
${x.upstream_hash_verified ? 'SHA-256 mit Quelle geprüft' : 'SHA-256 lokal erfasst; Größe mit Quelle geprüft'}
Unter „Entdecken“ kannst du Dateien für diesen Bereich auswählen und herunterladen.
${escape(j.file)}
${size(j.bytes)} von ${size(j.total)}${j.state === 'complete' ? ' · geprüft und in der Bibliothek gespeichert' : ''}
${j.error ? `${escape(j.error)}
` : ''}${j.state === 'downloading' ? '' : ''}Keine passenden Dateien. Unterstützt werden GGUF, Safetensors und JSON.
'; + el('hub-variants').onchange = updateSelection; updateSelection(); + } + async function loadFiles(repo) { + const sequence = ++detailSequence; selected = repo; detail = null; renderModels(); + el('hub-files').innerHTML = 'Modelldetails werden geladen …
'; + try { + const result = await api('/files?'+new URLSearchParams({repo})); if (!root.isConnected || sequence !== detailSequence) return; detail = result; + el('hub-files').innerHTML = `MODELLDETAILSLizenz: ${escape(detail.license || 'Nicht angegeben')} · Modellkarte lesen ↗
Dateigröße ist kein VRAM-Bedarf. Kontext, Quantisierung und Laufzeit müssen gemeinsam geprüft werden.
Dieses Repository benötigt eine Freigabe. Downloads mit Hugging-Face-Zugangsdaten werden noch nicht unterstützt.
' : ''}Einzeldatei-Download auf Athena. Geteilte Modelle und Bild-/Audio-/Video-Pipelines benötigen weitere Dateien; dies installiert noch keinen vollständigen Worker.
${escape(detail.revision)}
Details konnten nicht geladen werden. Wähle das Modell erneut, um es noch einmal zu versuchen.
'; message(error.message); } } + } + el('hub-refresh').onclick = refresh; + if (!library) { el('hub-sort').onchange = renderModels; el('hub-search').onsubmit = event => { event.preventDefault(); search(new FormData(event.target).get('q').trim()); }; search(''); } refresh(); } return {html,bind}; diff --git a/style.css b/style.css index e25f409..c9bb790 100644 --- a/style.css +++ b/style.css @@ -6,3 +6,9 @@ label{display:block;margin:18px 0 8px;font-size:13px;color:#c4d1c6}input,select{ aside{overflow-y:auto}nav{gap:3px}nav a{padding:11px 12px}.prototype-banner{display:flex;align-items:center;gap:14px;background:#202b23;border:1px solid #40503f;border-radius:9px;padding:15px 18px;margin:24px 0;color:#bdd0ba;font-size:12px}.studio-tabs{display:flex;gap:7px;border-bottom:1px solid #344038;padding-bottom:10px;margin:28px 0}.studio-tabs button{font-size:13px}.studio-tabs button span{margin-left:8px;opacity:.6}.model-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}.model-card h2{margin-bottom:8px}.model-icon{display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;background:#29372b;color:#d0e5c4;border-radius:10px;font-size:23px}.model-facts{font-size:12px;line-height:1.6}.model-facts>div{display:flex;justify-content:space-between;gap:15px;padding:10px 0;border-bottom:1px solid #2a3430}.model-facts dt{color:#819386}.model-facts dd{margin:0;text-align:right;color:#c9d3ca}.unknown-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:#a2aea5;margin-right:5px}.card-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:22px}.card-actions button{margin-right:0;font-size:12px}.studio-toolbar{display:grid;grid-template-columns:2fr 1fr;gap:18px}.studio-toolbar label{margin-top:0}.studio-toolbar input,.studio-toolbar select{max-width:none;margin-bottom:0}.small{font-size:12px}.section-heading{display:flex;justify-content:space-between;gap:20px;align-items:center;margin-bottom:20px}.section-heading h2{margin-bottom:3px}.section-heading p{margin-top:5px}.section-heading button{white-space:nowrap}.profile-list{display:grid;gap:12px}.profile-row{display:grid;grid-template-columns:1.5fr 1fr .5fr 1fr;gap:18px;align-items:center;padding:22px}.profile-row h2{font-size:18px;margin:9px 0 4px;overflow-wrap:anywhere}.profile-row p{font-size:12px;margin:0}.profile-row strong{display:block;margin-top:10px;font-size:14px;font-weight:500}.profile-actions{grid-column:1/-1;display:flex;border-top:1px solid #303a37;padding-top:14px}.profile-actions button{font-size:12px;margin-bottom:0}.endpoint-preview,.detail-card,.editor{margin-top:24px}pre{background:#101718;padding:20px;border-radius:8px;overflow:auto;font-size:12px;line-height:1.6;color:#bed4b8;max-height:280px}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 24px}.form-grid input,.form-grid select{max-width:none}.checkbox{display:flex;align-items:center;gap:10px}.checkbox input{width:16px;height:16px;margin:0;accent-color:#bfdda9}.editor details{border-top:1px solid #303a37;margin-top:22px;padding-top:18px}summary{cursor:pointer;color:#ccdbc7;font-size:14px}.danger{color:#e9aaa0!important}#studio-notice{color:#c7e4b6}#profile-error{color:#ffc1a7}.runtime-empty{text-align:center;padding:40px;margin-bottom:20px}.runtime-empty a{display:block;margin-top:16px;font-size:13px}.flow{list-style:none;counter-reset:steps;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin:28px 0}.flow li{counter-increment:steps;padding:0 0 0 35px;position:relative}.flow li:before{content:counter(steps,decimal-leading-zero);position:absolute;left:0;color:#b6d2a8;font-size:12px;top:2px}.flow b{font-size:13px;font-weight:500}.flow span{display:block;color:#82968a;font-size:12px;line-height:1.7;margin-top:7px}.runtime-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:15px;margin-bottom:22px}.runtime-stats .card{padding:22px}.runtime-stats h2{font-size:18px}.runtime-stats p{font-size:12px}#studio[data-page=runtime]>.card{margin-top:20px}.release-comparison{display:flex;gap:35px;align-items:center;margin:25px 0}.fit-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}.fit-grid b{font-size:13px}.fit-grid p{font-size:12px}@media(max-width:1100px){.model-grid{grid-template-columns:1fr}.runtime-stats{grid-template-columns:1fr}.profile-row{grid-template-columns:1fr 1fr}.fit-grid{grid-template-columns:1fr}}@media(max-width:600px){.form-grid,.studio-toolbar,.flow{grid-template-columns:1fr}.prototype-banner,.section-heading{align-items:flex-start;flex-direction:column}.studio-tabs{flex-wrap:wrap}.studio-tabs button{padding:10px 12px}.profile-row{gap:18px}.card{padding:20px}.model-facts>div{flex-direction:column;gap:3px}.model-facts dd{text-align:left}} .nav-heading{font-size:10px;letter-spacing:1.5px;color:#75867b;margin:15px 12px 5px} + +/* Live model catalogue: browse, inspect a file, download, then library. */ +.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)} +.hub-search{display:flex;align-items:end;gap:12px;margin:24px 0}.hub-search label{flex:1;margin:0}.hub-search input{max-width:none;margin-bottom:0}.hub-search button{margin:0} +.hub-layout{display:grid;grid-template-columns:minmax(240px,.8fr) minmax(0,1.4fr);gap:24px;align-items:start}.hub-list-heading{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}.hub-list-heading select{width:auto;max-width:160px;font-size:12px;margin:0;padding:8px}.hub-results{display:grid;gap:8px;max-height:850px;overflow-y:auto;padding:3px}.hub-model{display:grid;gap:9px;width:100%;margin:0;text-align:left;padding:18px;background:#181f21;color:#e4eee5;border:1px solid #303a37}.hub-model:hover{background:#222d27}.hub-model.selected{border-color:#bddda9;background:#26342b}.hub-model strong{font-size:14px;overflow-wrap:anywhere}.hub-author,.hub-model-meta{font-size:11px;color:#96a89c}.hub-detail{min-width:0}.hub-detail h2{font-size:22px}.hub-badges{display:flex;gap:8px;flex-wrap:wrap}.hub-fit{padding:16px;background:#202a25;border-radius:9px;font-size:13px;margin:22px 0}.hub-fit p{font-size:12px;margin-bottom:0}.hub-file-controls{display:grid;grid-template-columns:1.3fr 1fr;gap:12px}.hub-file-controls label{margin-top:0}.hub-file-controls input,.hub-file-controls select{font-size:12px;margin-bottom:0}.hub-variants{max-height:380px;overflow:auto;border-top:1px solid #303a37}.hub-variant{display:flex;align-items:center;gap:12px;padding:16px 8px;margin:0;border-bottom:1px solid #303a37;cursor:pointer}.hub-variant:has(input:checked){background:#28362b}.hub-variant input{width:16px;min-width:16px;margin:0;accent-color:#c5edaf}.hub-variant span{flex:1;min-width:0}.hub-variant strong{display:block;font-weight:500;font-size:12px;overflow-wrap:anywhere}.hub-variant small{display:block;margin-top:7px;font-size:10px;color:#95a69b}.hub-variant b{font-size:11px;white-space:nowrap}.hub-review{margin-top:22px}.hub-review button{width:100%;font-size:13px}.hub-filename{overflow-wrap:anywhere}.hub-operation{margin-top:20px;border-color:#647e58}.hub-operation h3{font-size:16px}.hub-operation p{margin:10px 0;font-size:12px}.hub-operation progress{height:9px}.hub-operation .card-top strong{font-size:20px} +@media(max-width:1100px){.hub-layout{grid-template-columns:1fr}.hub-results{max-height:360px}.hub-file-controls{grid-template-columns:1fr 1fr}}@media(max-width:600px){.hub-search{align-items:stretch;flex-direction:column}.hub-file-controls{grid-template-columns:1fr}.hub-variant{gap:8px}}