feat(v9): Phase 10 Schritt 1 — Modell-Capabilities aus GGUF-Metadaten

- model_caps.py: dependency-freier GGUF-Header-Reader (architecture,
  expert_count, context_length, parameter_count) — offline/authoritativ,
  bricht vor dem Tokenizer-Array ab. Leitet Tag-Set ab: MoE(+aktive B),
  Tools (yes via --jinja/Template | likely via Familie | no), Vision,
  Coder, Reasoning, Embedding, native ctx/params. Familien-Liste nur Fallback.
- models.py status(): meta.capabilities ergänzt.
- ModelsPanel: "KANN"-Spalte zeigt jetzt Capability-Chips statt Text/Code/Bild.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-24 18:08:31 +02:00
parent d66f51ab8b
commit 9fa065908d
4 changed files with 195 additions and 33 deletions
+13 -8
View File
@@ -94,13 +94,18 @@
} catch (e: any) { toast(e.message, true) }
}
function capTags(caps: string[]) {
if (!caps?.length) return ''
return caps.map((c: string) =>
c === 'Code' ? '<span class="tag code">Code</span>'
: c === 'Bild' ? '<span class="tag img">Bild</span>'
: '<span class="tag text">Text</span>'
).join(' ')
function capChips(cap: any) {
if (!cap) return ''
const chips: string[] = []
if (cap.coder) chips.push('<span class="tag code">Code</span>')
if (cap.vision) chips.push('<span class="tag img">Bild</span>')
if (cap.reasoning) chips.push('<span class="tag" style="border-color:#a78bfa;color:#a78bfa">🧠 Reason</span>')
if (cap.moe) chips.push(`<span class="tag" style="border-color:#f59e0b;color:#f59e0b">🧩 MoE${cap.active_b ? ' ·' + cap.active_b + 'B' : ''}</span>`)
if (cap.tools === 'yes') chips.push('<span class="tag" style="border-color:var(--accent);color:var(--accent)" title="Tool-Calling vom Template/Flag unterstützt">🛠 Tools</span>')
else if (cap.tools === 'likely') chips.push('<span class="tag" style="opacity:.55" title="laut Modell-Familie wahrscheinlich tool-fähig">🛠 Tools?</span>')
if (cap.embedding) chips.push('<span class="tag" style="opacity:.7">🔢 Embed</span>')
if (!cap.coder && !cap.vision && !cap.embedding) chips.unshift('<span class="tag text">Text</span>')
return chips.length ? chips.join(' ') : ''
}
function details(meta: any) {
@@ -183,7 +188,7 @@
{/each}
</div>
</td>
<td>{@html capTags(m.meta?.caps)}</td>
<td>{@html capChips(m.meta?.capabilities)}</td>
<td>{@html details(m.meta)}</td>
<td>{@html badge(m.state, m.download_progress)}</td>
<td class="port">{m.port ?? 'auto'}</td>