feat(metrics): lokaler LLM-Verbrauch + Claude-Ersparnis in Diagnostic
metrics.jsonl-Eintraege tragen jetzt 'source' (claude|local|fast-path). - log_local_call(): echte usage-Tokens vom Adapter (prompt/completion), sonst chars/4-Schaetzung. Geloggt pro Tool-Runde im lokalen Fast-Lane. - log_fast_path(): reiner Skill, 0 Prompt-Tokens — gesparter Claude-Call. - aggregate() liefert zusaetzlich by_source (calls/tokens_in/tokens_out). Alt-Eintraege ohne source zaehlen als claude (rueckwaerts-kompatibel). Diagnostic Gehirn-Tab: neue Card "Lokales LLM & Claude-Ersparnis" — pro Fenster (1h/5h/24h/30d) gesparte Claude-Calls (local + fast-path) und lokale Token-Last (eigene HW, kein Quota) + Info-Block. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1028,6 +1028,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h2>Lokales LLM & Claude-Ersparnis <button class="info-btn" onclick="showInfo('local-savings')" title="Wie wird die Ersparnis gerechnet?">ℹ</button></h2>
|
||||
<div class="card">
|
||||
<div style="font-size:11px;color:#8888AA;margin-bottom:10px;">
|
||||
Turns, die das <strong style="color:#B392F0;">lokale LLM</strong> (Qwen) oder ein reiner <strong style="color:#F0B85E;">Skill-Fast-Path</strong> uebernommen hat — jeder davon ist ein Claude-Call, der NICHT passiert ist. Die lokalen Tokens laufen auf deiner eigenen Hardware (kein Subscription-Quota).
|
||||
</div>
|
||||
<div id="savings-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;font-size:12px;">
|
||||
<div class="metric-cell"><div class="metric-label">–</div><div class="metric-value">–</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h2>Bootstrap & Migration <button class="info-btn" onclick="showInfo('bootstrap')" title="Was sind die drei Wege?">ℹ</button></h2>
|
||||
<div class="card" style="line-height:1.6;">
|
||||
@@ -5897,6 +5909,29 @@
|
||||
setCell('metrics-h24', d.h24);
|
||||
setCell('metrics-d30', d.d30);
|
||||
|
||||
// Lokales LLM & Claude-Ersparnis — pro Fenster: wie viele Claude-Calls
|
||||
// durch local/fast-path vermieden wurden + lokale Token-Last.
|
||||
const savingsGrid = document.getElementById('savings-grid');
|
||||
if (savingsGrid) {
|
||||
const wins = [['letzte 1h', d.h1], ['letzte 5h', d.h5],
|
||||
['letzte 24h', d.h24], ['letzte 30 Tage', d.d30]];
|
||||
const z = { calls: 0, tokens_in: 0, tokens_out: 0 };
|
||||
savingsGrid.innerHTML = wins.map(([label, w]) => {
|
||||
const bs = (w && w.by_source) || {};
|
||||
const loc = bs.local || z;
|
||||
const fp = bs['fast-path'] || z;
|
||||
const saved = (loc.calls || 0) + (fp.calls || 0);
|
||||
const locTok = (loc.tokens_in || 0) + (loc.tokens_out || 0);
|
||||
const color = saved > 0 ? '#3FB950' : '#555570';
|
||||
return `<div class="metric-cell">
|
||||
<div class="metric-label">${label}</div>
|
||||
<div class="metric-value" style="color:${color};">${saved} Claude-Calls gespart</div>
|
||||
<div class="metric-sub">lokal ${loc.calls || 0} · fast-path ${fp.calls || 0}</div>
|
||||
<div class="metric-sub">${fmtTokens(locTok)} lokale Tokens (eigene HW)</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// 5h-Fenster gegen Plan-Limit: Warn-Klassen
|
||||
const plan = getActivePlanLimit();
|
||||
const limit = plan.h5;
|
||||
@@ -5939,6 +5974,15 @@
|
||||
|
||||
// Vor-definierte Info-Blocks
|
||||
const INFO_TEXTS = {
|
||||
'local-savings': {
|
||||
title: 'Lokales LLM & Claude-Ersparnis',
|
||||
html: `
|
||||
<p>Jeder Turn, den das <strong>lokale LLM</strong> oder ein <strong>Fast-Path</strong> (reiner Skill, ganz ohne LLM) beantwortet, ist ein Claude-Call, der <strong>nicht</strong> gegen dein Subscription-Quota laeuft.</p>
|
||||
<p><strong>„Claude-Calls gespart"</strong> = Anzahl der local- + fast-path-Antworten im Zeitfenster. Konservativ gezaehlt: 1 Antwort = mindestens 1 gesparter Claude-Call (bei Tool-Use waeren es real oft mehr).</p>
|
||||
<p><strong>„lokale Tokens"</strong> = Prompt+Antwort-Tokens, die auf deiner eigenen Gamebox-GPU verarbeitet wurden (echte <code>usage</code>-Zahlen vom Modell, sonst chars/4-Schaetzung). Die kosten dich nichts ausser Strom.</p>
|
||||
<p>Fast-Path-Antworten (z.B. „nächstes Lied") haben ~0 Tokens — reiner Skill-Aufruf, kein Modell.</p>
|
||||
`,
|
||||
},
|
||||
'local-llm': {
|
||||
title: 'Lokales LLM — schnelle Antworten',
|
||||
html: `
|
||||
|
||||
Reference in New Issue
Block a user