feat(chat): add context window visualiser bar (M8.6)
Slim progress bar showing estimated token usage (~4 chars/token). Bitcoin-orange fill turns red when >80% of context window used. Tooltip shows exact token estimate on hover. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
68e296278c
commit
87cbd8c4ea
@@ -18,6 +18,8 @@
|
||||
@scroll-to-message="scrollToMessageIndex"
|
||||
/>
|
||||
|
||||
<ContextBar :messages="messages" />
|
||||
|
||||
<!-- Collapsed: prompt index -->
|
||||
<PromptIndex
|
||||
v-if="chatCollapsed"
|
||||
@@ -105,6 +107,7 @@ import StreamingDots from './StreamingDots.vue'
|
||||
import PromptIndex from './PromptIndex.vue'
|
||||
import BranchSwitcher from './BranchSwitcher.vue'
|
||||
import ChatSearch from './ChatSearch.vue'
|
||||
import ContextBar from './ContextBar.vue'
|
||||
import ErrorBoundary from '@/components/ui/ErrorBoundary.vue'
|
||||
import type { Message } from '@aiui/core/types/message'
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="messages.length > 0"
|
||||
class="h-1 mx-3 rounded-full bg-white/5 overflow-hidden shrink-0 group cursor-help relative"
|
||||
:title="tooltipText"
|
||||
>
|
||||
<div
|
||||
class="h-full rounded-full transition-all duration-500"
|
||||
:class="percentage > 80 ? 'bg-red-500' : 'bg-accent'"
|
||||
:style="{ width: `${Math.min(percentage, 100)}%` }"
|
||||
/>
|
||||
<!-- Tooltip on hover -->
|
||||
<div
|
||||
class="absolute -top-8 left-1/2 -translate-x-1/2 hidden group-hover:flex items-center px-2 py-1 rounded-md bg-black/80 text-[10px] text-white/80 whitespace-nowrap pointer-events-none z-10"
|
||||
>
|
||||
{{ tooltipText }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { Message } from '@aiui/core/types/message'
|
||||
|
||||
const props = defineProps<{
|
||||
messages: Message[]
|
||||
contextWindow?: number
|
||||
}>()
|
||||
|
||||
// Default context window sizes per model (tokens)
|
||||
const maxTokens = computed(() => props.contextWindow ?? 200000)
|
||||
|
||||
// Estimate: ~4 chars per token
|
||||
const estimatedTokens = computed(() => {
|
||||
let chars = 0
|
||||
for (const msg of props.messages) {
|
||||
chars += msg.content.length
|
||||
}
|
||||
return Math.ceil(chars / 4)
|
||||
})
|
||||
|
||||
const percentage = computed(() => {
|
||||
if (maxTokens.value === 0) return 0
|
||||
return (estimatedTokens.value / maxTokens.value) * 100
|
||||
})
|
||||
|
||||
const tooltipText = computed(() => {
|
||||
const est = estimatedTokens.value.toLocaleString()
|
||||
const max = maxTokens.value.toLocaleString()
|
||||
return `~${est} / ${max} tokens used`
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user