diff --git a/src/browser/components/ContextUsageIndicatorButton.tsx b/src/browser/components/ContextUsageIndicatorButton.tsx index 65f2f46832..efe283cb0d 100644 --- a/src/browser/components/ContextUsageIndicatorButton.tsx +++ b/src/browser/components/ContextUsageIndicatorButton.tsx @@ -11,6 +11,18 @@ import { Switch } from "./ui/switch"; import { formatTokens, type TokenMeterData } from "@/common/utils/tokens/tokenMeterUtils"; import { cn } from "@/common/lib/utils"; +/** Output reserve indicator (context limit minus max output tokens) */ +const OutputReserveIndicator: React.FC<{ threshold: number }> = (props) => { + const threshold = props.threshold; + if (threshold <= 0 || threshold >= 100) return null; + + return ( +
+ ); +}; /** Compact threshold tick mark for the button view */ const CompactThresholdIndicator: React.FC<{ threshold: number }> = ({ threshold }) => { if (threshold >= 100) return null; @@ -79,6 +91,25 @@ const AutoCompactSettings: React.FC<{ const showUsageSlider = usageConfig && data.maxTokens; const isIdleEnabled = idleConfig?.hours !== null && idleConfig?.hours !== undefined; + const outputReserveThreshold = (() => { + if (!data.maxTokens || !data.maxOutputTokens) return null; + if (data.maxOutputTokens <= 0 || data.maxOutputTokens >= data.maxTokens) return null; + const raw = ((data.maxTokens - data.maxOutputTokens) / data.maxTokens) * 100; + return Math.max(0, Math.min(100, raw)); + })(); + + const outputReserveTokens = + data.maxTokens && data.maxOutputTokens ? data.maxTokens - data.maxOutputTokens : null; + + const showOutputReserveIndicator = Boolean(showUsageSlider && outputReserveThreshold !== null); + const showOutputReserveWarning = Boolean( + showUsageSlider && + usageConfig && + usageConfig.threshold < 100 && + outputReserveThreshold !== null && + usageConfig.threshold > outputReserveThreshold + ); + const handleIdleToggle = (enabled: boolean) => { if (!idleConfig) return; const parsed = parseInt(idleInputValue, 10); @@ -118,9 +149,26 @@ const AutoCompactSettings: React.FC<{