fix: display (#2766)

This commit is contained in:
DennisYu07 2026-04-19 15:25:29 +08:00 committed by GitHub
parent 8ad9a5b467
commit eae247b50e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 97 additions and 8 deletions

View file

@ -1897,6 +1897,11 @@ export default {
// Context Usage Component
// ============================================================================
'Context Usage': 'Kontextnutzung',
'% used': '% verwendet',
'% context used': '% Kontext verwendet',
'Context exceeds limit! Use /compress or /clear to reduce.':
'Kontext überschreitet Limit! Verwenden Sie /compress oder /clear zum Reduzieren.',
'Use /compress or /clear': 'Verwenden Sie /compress oder /clear',
'No API response yet. Send a message to see actual usage.':
'Noch keine API-Antwort. Senden Sie eine Nachricht, um die tatsächliche Nutzung anzuzeigen.',
'Estimated pre-conversation overhead':

View file

@ -1947,6 +1947,11 @@ export default {
// Context Usage Component
// ============================================================================
'Context Usage': 'Context Usage',
'% used': '% used',
'% context used': '% context used',
'Context exceeds limit! Use /compress or /clear to reduce.':
'Context exceeds limit! Use /compress or /clear to reduce.',
'Use /compress or /clear': 'Use /compress or /clear',
'No API response yet. Send a message to see actual usage.':
'No API response yet. Send a message to see actual usage.',
'Estimated pre-conversation overhead': 'Estimated pre-conversation overhead',

View file

@ -1395,6 +1395,11 @@ export default {
// Context Usage Component
// ============================================================================
'Context Usage': 'コンテキスト使用量',
'% used': '% 使用',
'% context used': '% コンテキスト使用',
'Context exceeds limit! Use /compress or /clear to reduce.':
'コンテキストが制限を超えています!/compress または /clear を使用して減らしてください。',
'Use /compress or /clear': '/compress または /clear を使用',
'No API response yet. Send a message to see actual usage.':
'API応答はありません。メッセージを送信して実際の使用量を確認してください。',
'Estimated pre-conversation overhead': '推定事前会話オーバーヘッド',

View file

@ -1892,6 +1892,11 @@ export default {
// Context Usage Component
// ============================================================================
'Context Usage': 'Uso do Contexto',
'% used': '% usado',
'% context used': '% contexto usado',
'Context exceeds limit! Use /compress or /clear to reduce.':
'Contexto excede o limite! Use /compress ou /clear para reduzir.',
'Use /compress or /clear': 'Use /compress ou /clear',
'No API response yet. Send a message to see actual usage.':
'Ainda não há resposta da API. Envie uma mensagem para ver o uso real.',
'Estimated pre-conversation overhead': 'Sobrecarga estimada pré-conversa',

View file

@ -1823,6 +1823,11 @@ export default {
// Context Usage Component
// ============================================================================
'Context Usage': 'Использование контекста',
'% used': '% использовано',
'% context used': '% контекста использовано',
'Context exceeds limit! Use /compress or /clear to reduce.':
'Контекст превышает лимит! Используйте /compress или /clear для уменьшения.',
'Use /compress or /clear': 'Используйте /compress или /clear',
'No API response yet. Send a message to see actual usage.':
'Пока нет ответа от API. Отправьте сообщение, чтобы увидеть фактическое использование.',
'Estimated pre-conversation overhead':

View file

@ -1760,6 +1760,11 @@ export default {
// Context Usage
// ============================================================================
'Context Usage': '上下文使用情况',
'% used': '% 已用',
'% context used': '% 上下文已用',
'Context exceeds limit! Use /compress or /clear to reduce.':
'上下文超出限制!请使用 /compress 或 /clear 来减少上下文。',
'Use /compress or /clear': '使用 /compress 或 /clear',
'Context window': '上下文窗口',
Used: '已用',
Free: '空闲',

View file

@ -6,6 +6,17 @@
import { Text } from 'ink';
import { theme } from '../semantic-colors.js';
import { t } from '../../i18n/index.js';
/**
* Format percentage for display, showing ">100" when exceeding limit.
*/
function formatPercentageUsed(percentage: number): string {
if (percentage > 1) {
return '>100';
}
return (percentage * 100).toFixed(1);
}
export const ContextUsageDisplay = ({
promptTokenCount,
@ -21,9 +32,22 @@ export const ContextUsageDisplay = ({
}
const percentage = promptTokenCount / contextWindowSize;
const percentageUsed = (percentage * 100).toFixed(1);
const percentageUsed = formatPercentageUsed(percentage);
const isOverLimit = percentage > 1;
const label = terminalWidth < 100 ? '% used' : '% context used';
const label = terminalWidth < 100 ? t('% used') : t('% context used');
// Show warning when over limit
if (isOverLimit) {
return (
<>
<Text color={theme.status.error}>
{percentageUsed}
{label}
</Text>
</>
);
}
return (
<Text color={theme.text.secondary}>

View file

@ -90,6 +90,18 @@ const ProgressBar: React.FC<{
);
};
/**
* Format percentage for display, showing ">100%" when exceeding limit.
*/
function formatPercentage(tokens: number, contextWindowSize: number): string {
if (contextWindowSize <= 0) return '0.0';
const percentage = (tokens / contextWindowSize) * 100;
if (percentage > 100) {
return '>100';
}
return percentage.toFixed(1);
}
/**
* A row showing a category with its token count and percentage.
*/
@ -99,9 +111,17 @@ const CategoryRow: React.FC<{
tokens: number;
contextWindowSize: number;
symbolColor?: string;
}> = ({ symbol, label, tokens, contextWindowSize, symbolColor }) => {
const percentage = ((tokens / contextWindowSize) * 100).toFixed(1);
const tokenStr = `${formatTokens(tokens)} ${t('tokens')} (${percentage}%)`;
isOverLimit?: boolean;
}> = ({
symbol,
label,
tokens,
contextWindowSize,
symbolColor,
isOverLimit,
}) => {
const percentageStr = formatPercentage(tokens, contextWindowSize);
const tokenStr = `${formatTokens(tokens)} ${t('tokens')} (${percentageStr}%)`;
return (
<Box width={CONTENT_WIDTH}>
@ -112,7 +132,9 @@ const CategoryRow: React.FC<{
<Text color={theme.text.primary}>{label}</Text>
</Box>
<Box flexGrow={1} justifyContent="flex-end">
<Text color={theme.text.secondary}>{tokenStr}</Text>
<Text color={isOverLimit ? theme.status.error : theme.text.secondary}>
{tokenStr}
</Text>
</Box>
</Box>
);
@ -158,6 +180,7 @@ export const ContextUsage: React.FC<ContextUsageProps> = ({
}) => {
const percentage =
contextWindowSize > 0 ? (totalTokens / contextWindowSize) * 100 : 0;
const isOverLimit = percentage > 100;
// Sort detail items by token count (descending) for better readability
const sortedBuiltinTools = [...builtinTools].sort(
@ -236,6 +259,14 @@ export const ContextUsage: React.FC<ContextUsageProps> = ({
width={CONTENT_WIDTH}
/>
</Box>
{/* Warning when context exceeds limit */}
{isOverLimit && (
<Box marginBottom={1}>
<Text color={theme.status.error}>
{t('Context exceeds limit! Use /compress or /clear to reduce.')}
</Text>
</Box>
)}
<Box height={1} />
{/* Legend — same layout as CategoryRow for alignment */}
<CategoryRow
@ -243,7 +274,8 @@ export const ContextUsage: React.FC<ContextUsageProps> = ({
label={t('Used')}
tokens={totalTokens}
contextWindowSize={contextWindowSize}
symbolColor={theme.text.accent}
symbolColor={isOverLimit ? theme.status.error : theme.text.accent}
isOverLimit={isOverLimit}
/>
<CategoryRow
symbol={EMPTY}