Roo-Code/webview-ui/src/utils/model-utils.ts

130 lines
3.7 KiB
TypeScript

/**
* Utility functions for working with language models and tokens
*/
/**
* Default maximum tokens for thinking-capable models when no specific value is provided
*/
export const DEFAULT_THINKING_MODEL_MAX_TOKENS = 16_384
/**
* Model information interface with properties used in token calculations
*/
export interface ModelInfo {
/**
* Maximum number of tokens the model can process
*/
maxTokens?: number
/**
* Whether the model supports thinking/reasoning capabilities
*/
thinking?: boolean
}
/**
* API configuration interface with token-related settings
*/
export interface ApiConfig {
/**
* Maximum tokens to use for model responses
*/
modelMaxTokens?: number
}
/**
* Result of token distribution calculation
*/
export interface TokenDistributionResult {
/**
* Percentage of context window used by current tokens (0-100)
*/
currentPercent: number
/**
* Percentage of context window reserved for model output (0-100)
*/
reservedPercent: number
/**
* Percentage of context window still available (0-100)
*/
availablePercent: number
/**
* Number of tokens reserved for model output
*/
reservedForOutput: number
/**
* Number of tokens still available in the context window
*/
availableSize: number
}
/**
* Determines the maximum tokens based on model configuration
* If the model supports thinking, prioritize the API configuration's modelMaxTokens,
* falling back to the model's own maxTokens. Otherwise, just use the model's maxTokens.
*
* @param modelInfo The model information object with properties like maxTokens and thinking
* @param apiConfig The API configuration object with properties like modelMaxTokens
* @returns The maximum tokens value or undefined if no valid value is available
*/
export const getMaxTokensForModel = (
modelInfo: ModelInfo | undefined,
apiConfig: ApiConfig | undefined,
): number | undefined => {
if (modelInfo?.thinking) {
return apiConfig?.modelMaxTokens || DEFAULT_THINKING_MODEL_MAX_TOKENS
}
return modelInfo?.maxTokens
}
/**
* Calculates distribution of tokens within the context window
* This is used for visualizing the token distribution in the UI
*
* @param contextWindow The total size of the context window
* @param contextTokens The number of tokens currently used
* @param maxTokens Optional override for tokens reserved for model output (otherwise uses 20% of window)
* @returns Distribution of tokens with percentages and raw numbers
*/
export const calculateTokenDistribution = (
contextWindow: number,
contextTokens: number,
maxTokens?: number,
): TokenDistributionResult => {
// Handle potential invalid inputs with positive fallbacks
const safeContextWindow = Math.max(0, contextWindow)
const safeContextTokens = Math.max(0, contextTokens)
// Get the actual max tokens value from the model
// If maxTokens is valid, use it, otherwise reserve 20% of the context window as a default
const reservedForOutput = maxTokens && maxTokens > 0 ? maxTokens : Math.ceil(safeContextWindow * 0.2)
// Calculate sizes directly without buffer display
const availableSize = Math.max(0, safeContextWindow - safeContextTokens - reservedForOutput)
// Calculate percentages - ensure they sum to exactly 100%
// Use the ratio of each part to the total context window
const total = safeContextTokens + reservedForOutput + availableSize
// Safeguard against division by zero
if (total <= 0) {
return {
currentPercent: 0,
reservedPercent: 0,
availablePercent: 0,
reservedForOutput,
availableSize,
}
}
return {
currentPercent: (safeContextTokens / total) * 100,
reservedPercent: (reservedForOutput / total) * 100,
availablePercent: (availableSize / total) * 100,
reservedForOutput,
availableSize,
}
}