From ab95af24ae358f4b63ecdbe581df9583d589c433 Mon Sep 17 00:00:00 2001 From: Eddy Date: Tue, 14 Apr 2026 14:03:31 +0200 Subject: [PATCH] =?UTF-8?q?Token-basiertes=20Compacting=20mit=20Best=C3=A4?= =?UTF-8?q?tigungs-Dialog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Warnung bei ~40k Token (statt plumpe Nachrichtenanzahl) - Dialog zeigt aktuelle Token-Schätzung - User entscheidet ob kompaktiert wird - Zeigt was nach Compacting übrig bleibt (30 neueste) - "Später" Button um Dialog zu schließen Co-Authored-By: Claude Opus 4.5 --- src/lib/components/ChatPanel.svelte | 144 +++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/src/lib/components/ChatPanel.svelte b/src/lib/components/ChatPanel.svelte index 0a29f99..0981832 100644 --- a/src/lib/components/ChatPanel.svelte +++ b/src/lib/components/ChatPanel.svelte @@ -90,6 +90,14 @@ let editingMessageId: string | null = $state(null); let editingContent: string = $state(''); + // Auto-Compacting State + let lastMessageCount = 0; + let compactingWarningShown = false; + let showCompactingDialog = $state(false); + let estimatedTokens = $state(0); + const TOKEN_WARNING_THRESHOLD = 40000; // ~40k Token = Warnung zeigen + const KEEP_LAST_MESSAGES = 30; + async function scrollToBottom() { await tick(); if (messagesContainer) { @@ -99,6 +107,17 @@ $: if ($messages.length) scrollToBottom(); + // Bei Session-Wechsel: Compacting-Flag zurücksetzen + $: if ($currentSessionId) { + compactingWarningShown = false; + showCompactingDialog = false; + } + + // Token-Schätzung: ~4 Zeichen pro Token + function estimateTokensForMessages(msgs: Message[]): number { + return msgs.reduce((total, msg) => total + Math.ceil(msg.content.length / 4), 0); + } + // Nachricht in DB speichern async function saveMessageToDb(msg: Message) { const sessionId = get(currentSessionId); @@ -112,8 +131,7 @@ } } - // Neue Nachrichten automatisch speichern - let lastMessageCount = 0; + // Neue Nachrichten automatisch speichern + Token-Warnung const unsubscribe = messages.subscribe(async (msgs) => { if (msgs.length > lastMessageCount && lastMessageCount > 0) { // Neue Nachricht(en) hinzugefügt @@ -125,9 +143,45 @@ } } } + + // Token-Schätzung aktualisieren + estimatedTokens = estimateTokensForMessages(msgs); + + // Warnung zeigen wenn Token-Schwelle überschritten (einmalig pro Session) + if (!compactingWarningShown && estimatedTokens > TOKEN_WARNING_THRESHOLD && !$isProcessing) { + compactingWarningShown = true; + showCompactingDialog = true; + } + lastMessageCount = msgs.length; }); + async function performCompacting() { + const sessionId = get(currentSessionId); + if (!sessionId) return; + + showCompactingDialog = false; + + try { + const compacted: number = await invoke('compact_session', { + sessionId, + keepLast: KEEP_LAST_MESSAGES + }); + + if (compacted > 0) { + addMessage('system', `📦 Compacting: ${compacted} ältere Nachrichten wurden zusammengefasst. Die letzten ${KEEP_LAST_MESSAGES} bleiben erhalten.`); + } + } catch (err) { + console.error('Compacting fehlgeschlagen:', err); + addMessage('system', `⚠️ Compacting fehlgeschlagen: ${err}`); + } + } + + function dismissCompactingDialog() { + showCompactingDialog = false; + // Warnung für diese Session nicht erneut zeigen + } + onDestroy(() => { unsubscribe(); }); @@ -552,6 +606,49 @@ {/if} + +{#if showCompactingDialog} + +{/if} +