From bd5ff6b75a61c5728dd4751379f895296bfabb7a Mon Sep 17 00:00:00 2001 From: Nicolas Varrot Date: Sat, 14 Feb 2026 15:25:17 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20context=20compaction=20button=20in=20to?= =?UTF-8?q?ken=20bar=20(=E2=89=A550%=20usage)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 17 ++++++++++++++++- src/components/Header.tsx | 37 ++++++++++++++++++++++++++++++++++--- src/lib/i18n.ts | 4 ++++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 00813b6..9ce9b2c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -43,6 +43,21 @@ export default function App() { setSplitSession(prev => prev === key ? null : key); }, []); + const handleCompact = useCallback(async (key: string): Promise => { + const client = getClient(); + if (!client) return false; + try { + const res = await client.send('sessions.compact', { key }); + // Reload history after compaction to reflect new state + if (res?.compacted) { + switchSession(key); + } + return !!res?.compacted; + } catch { + return false; + } + }, [getClient, switchSession]); + // Split pane drag useEffect(() => { if (!splitDragging) return; @@ -152,7 +167,7 @@ export default function App() {
{/* Primary pane */}
-
setSidebarOpen(!sidebarOpen)} activeSessionData={sessions.find(s => s.key === activeSession)} onLogout={logout} soundEnabled={soundEnabled} onToggleSound={toggleSound} messages={messages} agentAvatarUrl={agentIdentity?.avatar} agentName={agentIdentity?.name} /> +
setSidebarOpen(!sidebarOpen)} activeSessionData={sessions.find(s => s.key === activeSession)} onLogout={logout} soundEnabled={soundEnabled} onToggleSound={toggleSound} messages={messages} agentAvatarUrl={agentIdentity?.avatar} agentName={agentIdentity?.name} onCompact={handleCompact} />
Loading…
}> diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 2764821..eed2430 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,5 +1,5 @@ -import { useCallback } from 'react'; -import { Menu, Sparkles, LogOut, Volume2, VolumeOff, Cpu, Bot, Download } from 'lucide-react'; +import { useCallback, useState } from 'react'; +import { Menu, Sparkles, LogOut, Volume2, VolumeOff, Cpu, Bot, Download, Minimize2 } from 'lucide-react'; import type { ConnectionStatus, Session, ChatMessage } from '../types'; import { useT } from '../hooks/useLocale'; import { LanguageSelector } from './LanguageSelector'; @@ -18,9 +18,10 @@ interface Props { messages?: ChatMessage[]; agentAvatarUrl?: string; agentName?: string; + onCompact?: (sessionKey: string) => Promise; } -export function Header({ status, sessionKey, onToggleSidebar, activeSessionData, onLogout, soundEnabled, onToggleSound, messages, agentAvatarUrl, agentName }: Props) { +export function Header({ status, sessionKey, onToggleSidebar, activeSessionData, onLogout, soundEnabled, onToggleSound, messages, agentAvatarUrl, agentName, onCompact }: Props) { const t = useT(); const sessionLabel = activeSessionData ? sessionDisplayName(activeSessionData) : (sessionKey.split(':').pop() || sessionKey); @@ -129,9 +130,39 @@ export function Header({ status, sessionKey, onToggleSidebar, activeSessionData, {(total / 1000).toFixed(1)}k / {(ctx / 1000).toFixed(0)}k tokens + {onCompact && pct >= 50 && ( + + )} ); })()} ); } + +function CompactButton({ sessionKey, onCompact }: { sessionKey: string; onCompact: (key: string) => Promise }) { + const [compacting, setCompacting] = useState(false); + const t = useT(); + + const handleCompact = useCallback(async () => { + if (compacting) return; + setCompacting(true); + try { + await onCompact(sessionKey); + } finally { + setCompacting(false); + } + }, [compacting, sessionKey, onCompact]); + + return ( + + ); +} diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index a94e1fb..1afc31b 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -121,6 +121,8 @@ const en = { // Export 'header.export': 'Export conversation as Markdown', + 'header.compact': 'Compact', + 'header.compacting': 'Compacting…', // Theme 'theme.title': 'Theme', @@ -253,6 +255,8 @@ const fr: Record = { 'shortcuts.generalSection': 'Général', 'header.export': 'Exporter la conversation en Markdown', + 'header.compact': 'Compacter', + 'header.compacting': 'Compaction…', 'theme.title': 'Thème', 'theme.mode': 'Mode',