From 38bdb4408c5acd16532d9edb11ec54e03b56daa9 Mon Sep 17 00:00:00 2001 From: Meleki Date: Sun, 1 Mar 2026 16:19:51 +0100 Subject: [PATCH] feat: Chain-Meta Anzeige-Einstellung + Darstellung verbessern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Settings: 'Chain-Info' Dropdown (Immer/Manchmal/Nie), Default 'Manchmal' - Manchmal-Regeln: In+Out >= 10k Tokens, >= 25 Iterationen, >= 90s Dauer - Model-Name: claude-opus-4-6 → Opus 4.6, Unbekanntes → 'Unbekannt' - Tokens: In/Out zu einem Badge zusammengeführt - Cache: Read/Write zu einem Badge zusammengeführt - Iterations → Iterationen --- wwwroot/index.html | 13 +++++++++++++ wwwroot/js/chat.js | 30 ++++++++++++++++++++++++------ wwwroot/js/history.js | 2 +- wwwroot/js/pages/settings-page.js | 12 +++++++++++- wwwroot/js/ui.js | 15 +++++++++++++++ 5 files changed, 64 insertions(+), 8 deletions(-) diff --git a/wwwroot/index.html b/wwwroot/index.html index d3e87e1..af60dd3 100644 --- a/wwwroot/index.html +++ b/wwwroot/index.html @@ -223,6 +223,19 @@ +
+
+ + Tokens, Dauer und Iterationen nach jeder Antwort +
+
+ +
+

Daten

diff --git a/wwwroot/js/chat.js b/wwwroot/js/chat.js index d3bb3df..7f3df8f 100644 --- a/wwwroot/js/chat.js +++ b/wwwroot/js/chat.js @@ -1,13 +1,30 @@ // ── Helpers ── +function _prettyModelName(model) { + if (!model) return '?'; + // claude-sonnet-4-20250514 → Sonnet 4 + // claude-opus-4-6 → Opus 4.6 + // claude-haiku-3-5 → Haiku 3.5 + const m = model.match(/claude-(\w+)-(\d+)(?:-(\d+))?/); + if (m) { + const family = m[1].charAt(0).toUpperCase() + m[1].slice(1); + const major = m[2]; + const minor = m[3]; + // minor > 20000000 ist ein Datums-Suffix, kein Minor-Version + if (minor && minor.length <= 2) return family + ' ' + major + '.' + minor; + return family + ' ' + major; + } + return 'Unbekannt'; +} + function buildMetaBadges(d) { const badges = []; - badges.push(d.model || '?'); - badges.push('In: ' + (d.inputTokens || 0)); - badges.push('Out: ' + (d.outputTokens || 0)); - if (d.cacheCreationTokens > 0) badges.push('Cache-Write: ' + d.cacheCreationTokens); - if (d.cacheReadTokens > 0) badges.push('Cache-Read: ' + d.cacheReadTokens); - if ((d.iterations || 0) > 1) badges.push('Iterations: ' + d.iterations); + badges.push(_prettyModelName(d.model)); + badges.push('Tokens: ' + (d.inputTokens || 0) + ' / ' + (d.outputTokens || 0)); + if (d.cacheCreationTokens > 0 || d.cacheReadTokens > 0) { + badges.push('Cache: ' + (d.cacheReadTokens || 0) + ' / ' + (d.cacheCreationTokens || 0)); + } + if ((d.iterations || 0) > 1) badges.push('Iterationen: ' + d.iterations); if (d.durationMs) badges.push((d.durationMs / 1000).toFixed(1) + 's'); if (d.stopReason && d.stopReason !== 'end_turn' && d.stopReason !== 'tool_use') badges.push('Stop: ' + d.stopReason); return badges; @@ -17,6 +34,7 @@ function addChainMetaBubble(d, streamed) { if (!d || !d.model) return; // Chain noch nicht finalisiert (läuft noch) → nicht anzeigen if (!d.inputTokens && !d.outputTokens && !d.durationMs) return; + if (!isChainMetaVisible(d)) return; const badges = buildMetaBadges(d); const div = document.createElement('div'); div.className = 'chain-meta'; diff --git a/wwwroot/js/history.js b/wwwroot/js/history.js index 998bc90..82b0528 100644 --- a/wwwroot/js/history.js +++ b/wwwroot/js/history.js @@ -170,7 +170,7 @@ async function loadLatestArchive() { fragment.appendChild(div); } // Chain-Meta-Badges nach jeder Chain einfügen - if (entry.chain) { + if (entry.chain && isChainMetaVisible(entry.chain)) { const badges = buildMetaBadges(entry.chain); const metaDiv = document.createElement('div'); metaDiv.className = 'chain-meta archived'; diff --git a/wwwroot/js/pages/settings-page.js b/wwwroot/js/pages/settings-page.js index 3964cad..3e1dc59 100644 --- a/wwwroot/js/pages/settings-page.js +++ b/wwwroot/js/pages/settings-page.js @@ -4,7 +4,8 @@ const SETTINGS_KEY = 'settings'; const SETTINGS_DEFAULTS = { pageWidth: 900, - toolCallDisplay: 'modifications' // 'all' | 'modifications' | 'hidden' + toolCallDisplay: 'modifications', // 'all' | 'modifications' | 'hidden' + chainMetaDisplay: 'sometimes' // 'always' | 'sometimes' | 'never' }; function loadSettings() { @@ -36,12 +37,14 @@ registerPage('settings', { const slider = document.getElementById('settingPageWidth'); const display = document.getElementById('settingPageWidthValue'); const toolCallSelect = document.getElementById('settingToolCallDisplay'); + const chainMetaSelect = document.getElementById('settingChainMetaDisplay'); const resetBtn = document.getElementById('settingsResetBtn'); const s = loadSettings(); slider.value = s.pageWidth; display.textContent = s.pageWidth + 'px'; toolCallSelect.value = s.toolCallDisplay; + chainMetaSelect.value = s.chainMetaDisplay; slider.addEventListener('input', () => { display.textContent = slider.value + 'px'; @@ -60,6 +63,12 @@ registerPage('settings', { saveSettings(s); }); + chainMetaSelect.addEventListener('change', () => { + const s = loadSettings(); + s.chainMetaDisplay = chainMetaSelect.value; + saveSettings(s); + }); + const backupBtn = document.getElementById('settingsBackupBtn'); if (backupBtn) backupBtn.addEventListener('click', async () => { backupBtn.disabled = true; @@ -82,6 +91,7 @@ registerPage('settings', { slider.value = SETTINGS_DEFAULTS.pageWidth; display.textContent = SETTINGS_DEFAULTS.pageWidth + 'px'; toolCallSelect.value = SETTINGS_DEFAULTS.toolCallDisplay; + chainMetaSelect.value = SETTINGS_DEFAULTS.chainMetaDisplay; }); }, destroy() {} diff --git a/wwwroot/js/ui.js b/wwwroot/js/ui.js index dfd4bef..2070b53 100644 --- a/wwwroot/js/ui.js +++ b/wwwroot/js/ui.js @@ -257,6 +257,21 @@ function isToolVisible(toolName) { return MODIFICATION_TOOLS.includes(toolName); } +// ── Chain Meta Visibility ── + +function isChainMetaVisible(chainData) { + const mode = loadSettings().chainMetaDisplay; + if (mode === 'always') return true; + if (mode === 'never') return false; + // 'sometimes' – nur bei auffälligen Chains anzeigen + if (!chainData) return false; + const inOut = (chainData.inputTokens || 0) + (chainData.outputTokens || 0); + if (inOut >= 10000) return true; + if ((chainData.iterations || 0) >= 25) return true; + if ((chainData.durationMs || 0) >= 90000) return true; + return false; +} + // ── Tool Boxes ── function addToolBoxLoading(name) {