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} +
+ Diese Konversation hat bereits ~{(estimatedTokens / 1000).toFixed(0)}k Token. +
++ Um Kosten zu sparen und das Context-Limit nicht zu überschreiten, kannst du ältere Nachrichten zusammenfassen lassen. +
++ Die älteren Nachrichten werden zu einer Zusammenfassung komprimiert, bleiben aber in der Datenbank erhalten. +
+