diff --git a/packages/cli/src/i18n/locales/de.js b/packages/cli/src/i18n/locales/de.js index 2dbf30e01..a8fe75003 100644 --- a/packages/cli/src/i18n/locales/de.js +++ b/packages/cli/src/i18n/locales/de.js @@ -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': diff --git a/packages/cli/src/i18n/locales/en.js b/packages/cli/src/i18n/locales/en.js index 1fbe33948..5683a01ce 100644 --- a/packages/cli/src/i18n/locales/en.js +++ b/packages/cli/src/i18n/locales/en.js @@ -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', diff --git a/packages/cli/src/i18n/locales/ja.js b/packages/cli/src/i18n/locales/ja.js index 589374bbd..36e79f50f 100644 --- a/packages/cli/src/i18n/locales/ja.js +++ b/packages/cli/src/i18n/locales/ja.js @@ -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': '推定事前会話オーバーヘッド', diff --git a/packages/cli/src/i18n/locales/pt.js b/packages/cli/src/i18n/locales/pt.js index 11c525f9f..beb49eb54 100644 --- a/packages/cli/src/i18n/locales/pt.js +++ b/packages/cli/src/i18n/locales/pt.js @@ -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', diff --git a/packages/cli/src/i18n/locales/ru.js b/packages/cli/src/i18n/locales/ru.js index 715250123..9a9f0f1e8 100644 --- a/packages/cli/src/i18n/locales/ru.js +++ b/packages/cli/src/i18n/locales/ru.js @@ -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': diff --git a/packages/cli/src/i18n/locales/zh.js b/packages/cli/src/i18n/locales/zh.js index 3f4de6d60..bf182ddda 100644 --- a/packages/cli/src/i18n/locales/zh.js +++ b/packages/cli/src/i18n/locales/zh.js @@ -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: '空闲', diff --git a/packages/cli/src/ui/components/ContextUsageDisplay.tsx b/packages/cli/src/ui/components/ContextUsageDisplay.tsx index dc2e22d7c..9c613211c 100644 --- a/packages/cli/src/ui/components/ContextUsageDisplay.tsx +++ b/packages/cli/src/ui/components/ContextUsageDisplay.tsx @@ -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 ( + <> + + {percentageUsed} + {label} + + + ); + } return ( diff --git a/packages/cli/src/ui/components/views/ContextUsage.tsx b/packages/cli/src/ui/components/views/ContextUsage.tsx index f6bed1d26..fefe90956 100644 --- a/packages/cli/src/ui/components/views/ContextUsage.tsx +++ b/packages/cli/src/ui/components/views/ContextUsage.tsx @@ -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 ( @@ -112,7 +132,9 @@ const CategoryRow: React.FC<{ {label} - {tokenStr} + + {tokenStr} + ); @@ -158,6 +180,7 @@ export const ContextUsage: React.FC = ({ }) => { 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 = ({ width={CONTENT_WIDTH} /> + {/* Warning when context exceeds limit */} + {isOverLimit && ( + + + {t('Context exceeds limit! Use /compress or /clear to reduce.')} + + + )} {/* Legend — same layout as CategoryRow for alignment */} = ({ label={t('Used')} tokens={totalTokens} contextWindowSize={contextWindowSize} - symbolColor={theme.text.accent} + symbolColor={isOverLimit ? theme.status.error : theme.text.accent} + isOverLimit={isOverLimit} /> ( metadata.contextWindowSize !== undefined && ( 100 ? '>100' : metadata.contextUsagePercent}% of ${formatTokenLimit(metadata.contextWindowSize)}`} + valueClass={ + metadata.contextUsagePercent > 100 ? 'text-red' : undefined + } /> )} {metadata.totalTokens !== undefined && (