fix(diagnostic): Modell-Katalog als Tabelle (Beschreibung + VRAM-Spalten), Button-Layout, Flotte nachziehen
- Katalog jetzt echte Tabelle: Spalten Modell | Kann gut/Beschreibung | VRAM | Status | Ziel-Box | Laden. VRAM aus sizeGB (>=12 GB gelb markiert). - "Von HuggingFace aktualisieren" sitzt jetzt direkt neben der Ueberschrift (statt space-between ans rechte Ende); Card breiter (720→1100px), Tabelle horizontal scrollbar. - loadLlmCatalog() zieht die Worker-Flotte aktiv nach (requestWorkers) — falls ein worker_update-Push waehrend RVS-Flappens verpasst wurde, erscheint die Box beim Oeffnen trotzdem. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+24
-14
@@ -650,18 +650,18 @@
|
||||
|
||||
<!-- Modell-Katalog: GGUF-Modelle herunterladen/aktivieren (Stage D) -->
|
||||
<div class="settings-section">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;">
|
||||
<div style="display:flex;align-items:center;gap:14px;margin-bottom:8px;">
|
||||
<h2 style="margin:0;">Modell-Katalog</h2>
|
||||
<button class="btn secondary" onclick="refreshLlmCatalog()" style="padding:4px 10px;font-size:11px;">Von HuggingFace aktualisieren</button>
|
||||
</div>
|
||||
<div class="card" style="max-width:720px;">
|
||||
<div class="card" style="max-width:1100px;">
|
||||
<p style="color:#8888AA;font-size:12px;margin:0 0 8px;">
|
||||
Gaengige lokale GGUF-Modelle. „Laden" schickt das Modell an die gewaehlte
|
||||
LLM-Box — llama-swap zieht das GGUF beim ersten Mal (mehrere GB) und meldet
|
||||
den Fortschritt. Danach ist es im Modell-Dropdown oben waehlbar.
|
||||
<span style="color:#FFD60A;">Achte auf den VRAM der Box (Groesse je Modell).</span>
|
||||
<span style="color:#FFD60A;">Achte auf den VRAM der Box (Spalte VRAM).</span>
|
||||
</p>
|
||||
<div id="llm-catalog-list" style="font-size:12px;color:#8888AA;">(lade Katalog…)</div>
|
||||
<div id="llm-catalog-list" style="font-size:12px;color:#8888AA;overflow-x:auto;">(lade Katalog…)</div>
|
||||
<div id="llm-catalog-status" style="font-size:11px;color:#6a6a88;margin-top:6px;min-height:14px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -7085,6 +7085,7 @@
|
||||
// ── Modell-Katalog (Stage D) ────────────────────────────
|
||||
let _llmCatalog = [];
|
||||
async function loadLlmCatalog() {
|
||||
if (typeof requestWorkers === 'function') requestWorkers(); // Flotte aktiv nachziehen
|
||||
try {
|
||||
const r = await fetch('/api/llm-catalog');
|
||||
const j = await r.json();
|
||||
@@ -7111,21 +7112,30 @@
|
||||
if (!box) return;
|
||||
if (!_llmCatalog.length) { box.innerHTML = '<span style="color:#6a6a88;">Katalog leer.</span>'; return; }
|
||||
const boxes = onlineLlmBoxes();
|
||||
box.innerHTML = _llmCatalog.map((m, i) => {
|
||||
const th = 'style="padding:6px 8px;text-align:left;position:sticky;top:0;background:#12122A;"';
|
||||
const td = 'style="padding:6px 8px;vertical-align:top;"';
|
||||
const rows = _llmCatalog.map((m, i) => {
|
||||
const have = boxesServing(m.id);
|
||||
const haveTxt = have.length ? `<span style="color:#3FFF3F;">✓ auf ${have.map(b => escapeHtml(b.node)).join(', ')}</span>` : '<span style="color:#6a6a88;">nicht geladen</span>';
|
||||
const sizeTxt = m.sizeGB ? ` · ~${m.sizeGB} GB` : '';
|
||||
const haveTxt = have.length ? `<span style="color:#3FFF3F;">✓ ${have.map(b => escapeHtml(b.node)).join(', ')}</span>` : '<span style="color:#6a6a88;">nicht geladen</span>';
|
||||
const vram = m.sizeGB ? '~' + m.sizeGB + ' GB' : '—';
|
||||
const vramStyle = m.sizeGB >= 12 ? 'color:#FFB020;' : 'color:#AAB;';
|
||||
const opts = boxes.length
|
||||
? boxes.map(b => `<option value="${escapeHtml(b.instanceId)}">${escapeHtml(b.node)}</option>`).join('')
|
||||
: '<option value="">(keine Box online)</option>';
|
||||
return '<div style="display:flex;align-items:center;gap:8px;padding:5px 0;border-bottom:1px solid #1E1E2E;flex-wrap:wrap;">' +
|
||||
'<span style="min-width:150px;"><b>' + escapeHtml(m.id) + '</b>' + sizeTxt + '</span>' +
|
||||
'<span style="color:#8888AA;flex:1;min-width:160px;">' + escapeHtml(m.description || m.hfRepo || '') + '</span>' +
|
||||
haveTxt +
|
||||
'<select id="llm-cat-box-' + i + '" style="background:#1E1E2E;border:1px solid #333;border-radius:4px;padding:3px 6px;color:#E0E0F0;font-size:11px;">' + opts + '</select>' +
|
||||
'<button class="btn secondary" ' + (boxes.length ? '' : 'disabled') + ' onclick="provisionModel(' + i + ')" style="padding:3px 10px;font-size:11px;">Laden</button>' +
|
||||
'</div>';
|
||||
return '<tr style="border-bottom:1px solid #1E1E2E;">' +
|
||||
'<td ' + td + 'white-space:nowrap;"><b>' + escapeHtml(m.id) + '</b></td>' +
|
||||
'<td ' + td + 'color:#9a9ab5;min-width:220px;">' + escapeHtml(m.description || m.hfRepo || '') + '</td>' +
|
||||
'<td ' + td + vramStyle + 'white-space:nowrap;">' + vram + '</td>' +
|
||||
'<td ' + td + 'white-space:nowrap;">' + haveTxt + '</td>' +
|
||||
'<td ' + td + '"><select id="llm-cat-box-' + i + '" style="background:#1E1E2E;border:1px solid #333;border-radius:4px;padding:3px 6px;color:#E0E0F0;font-size:11px;">' + opts + '</select></td>' +
|
||||
'<td ' + td + '"><button class="btn secondary" ' + (boxes.length ? '' : 'disabled') + ' onclick="provisionModel(' + i + ')" style="padding:3px 10px;font-size:11px;">Laden</button></td>' +
|
||||
'</tr>';
|
||||
}).join('');
|
||||
box.innerHTML = '<table style="width:100%;border-collapse:collapse;font-size:12px;min-width:760px;">' +
|
||||
'<thead><tr style="color:#8888AA;border-bottom:1px solid #2A2A3E;">' +
|
||||
'<th ' + th + '>Modell</th><th ' + th + '>Kann gut / Beschreibung</th><th ' + th + '>VRAM</th>' +
|
||||
'<th ' + th + '>Status</th><th ' + th + '>Ziel-Box</th><th ' + th + '></th>' +
|
||||
'</tr></thead><tbody>' + rows + '</tbody></table>';
|
||||
}
|
||||
function provisionModel(i) {
|
||||
const m = _llmCatalog[i];
|
||||
|
||||
Reference in New Issue
Block a user