feat: persistent context-window tracker in ChatPane
Adds a floating popover above the chat input showing current context-window usage. Modeled on Paseo's tracker. - New hook useChatContextStats(chatId, messages) finds the latest assistant message in the chat with both ctx_used and ctx_max set, computes percent, and returns null when data unavailable. - New component ChatContextPopover renders a small card with the "Context window" label, big percent, and "used / max tokens" subline. Hidden when stats is null. - Color thresholds: <60% muted, 60-85 amber, >85 destructive. - Not a portal — absolutely positioned inside a new relative wrapper around ChatInput in ChatPane.tsx, so it's pane-local (multi-pane safe). - Live updates via the existing messages-array dependency. - No API / schema / WS changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,10 @@ import { ChevronDown, Square, X } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import { api } from '@/api/client';
|
||||
import { useSessionStream } from '@/hooks/useSessionStream';
|
||||
import { useChatContextStats } from '@/hooks/useChatContextStats';
|
||||
import { MessageList } from '@/components/MessageList';
|
||||
import { ChatInput } from '@/components/ChatInput';
|
||||
import { ChatContextPopover } from '@/components/ChatContextPopover';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -37,6 +39,7 @@ export function ChatPane({ sessionId, chatId, projectId, sessionChats }: Props)
|
||||
|
||||
const chatMessages = stream.messages.filter((m) => m.chat_id === chatId);
|
||||
const streaming = chatMessages.some((m) => m.status === 'streaming');
|
||||
const contextStats = useChatContextStats(chatId, chatMessages);
|
||||
|
||||
// Auto-send next queued message when streaming completes
|
||||
useEffect(() => {
|
||||
@@ -162,7 +165,10 @@ export function ChatPane({ sessionId, chatId, projectId, sessionChats }: Props)
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ChatInput disabled={false} projectId={projectId} onSend={handleSend} onForceSend={streaming ? handleForceSend : undefined} />
|
||||
<div className="relative">
|
||||
<ChatContextPopover stats={contextStats} />
|
||||
<ChatInput disabled={false} projectId={projectId} onSend={handleSend} onForceSend={streaming ? handleForceSend : undefined} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user