( tokenUsage: number, model: string, )
| 91 | } |
| 92 | |
| 93 | export function calculateTokenWarningState( |
| 94 | tokenUsage: number, |
| 95 | model: string, |
| 96 | ): { |
| 97 | percentLeft: number |
| 98 | isAboveWarningThreshold: boolean |
| 99 | isAboveErrorThreshold: boolean |
| 100 | isAboveAutoCompactThreshold: boolean |
| 101 | isAtBlockingLimit: boolean |
| 102 | } { |
| 103 | const autoCompactThreshold = getAutoCompactThreshold(model) |
| 104 | const threshold = isAutoCompactEnabled() |
| 105 | ? autoCompactThreshold |
| 106 | : getEffectiveContextWindowSize(model) |
| 107 | |
| 108 | const percentLeft = Math.max( |
| 109 | 0, |
| 110 | Math.round(((threshold - tokenUsage) / threshold) * 100), |
| 111 | ) |
| 112 | |
| 113 | const warningThreshold = threshold - WARNING_THRESHOLD_BUFFER_TOKENS |
| 114 | const errorThreshold = threshold - ERROR_THRESHOLD_BUFFER_TOKENS |
| 115 | |
| 116 | const isAboveWarningThreshold = tokenUsage >= warningThreshold |
| 117 | const isAboveErrorThreshold = tokenUsage >= errorThreshold |
| 118 | |
| 119 | const isAboveAutoCompactThreshold = |
| 120 | isAutoCompactEnabled() && tokenUsage >= autoCompactThreshold |
| 121 | |
| 122 | const actualContextWindow = getEffectiveContextWindowSize(model) |
| 123 | const defaultBlockingLimit = |
| 124 | actualContextWindow - MANUAL_COMPACT_BUFFER_TOKENS |
| 125 | |
| 126 | // Allow override for testing |
| 127 | const blockingLimitOverride = process.env.CLAUDE_CODE_BLOCKING_LIMIT_OVERRIDE |
| 128 | const parsedOverride = blockingLimitOverride |
| 129 | ? parseInt(blockingLimitOverride, 10) |
| 130 | : NaN |
| 131 | const blockingLimit = |
| 132 | !isNaN(parsedOverride) && parsedOverride > 0 |
| 133 | ? parsedOverride |
| 134 | : defaultBlockingLimit |
| 135 | |
| 136 | const isAtBlockingLimit = tokenUsage >= blockingLimit |
| 137 | |
| 138 | return { |
| 139 | percentLeft, |
| 140 | isAboveWarningThreshold, |
| 141 | isAboveErrorThreshold, |
| 142 | isAboveAutoCompactThreshold, |
| 143 | isAtBlockingLimit, |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | export function isAutoCompactEnabled(): boolean { |
| 148 | if (isEnvTruthy(process.env.DISABLE_COMPACT)) { |
no test coverage detected