mirror of
https://github.com/tiennm99/ccstatusline.git
synced 2026-07-19 06:18:10 +00:00
Handle [1M], (1M), and optional context labels when inferring model context size; use model id + display_name in context widgets and add regression coverage for ctx, ctx(u), and context bar. Closes #193
71 lines
2.9 KiB
TypeScript
71 lines
2.9 KiB
TypeScript
import type { RenderContext } from '../types/RenderContext';
|
|
import type { Settings } from '../types/Settings';
|
|
import type {
|
|
CustomKeybind,
|
|
Widget,
|
|
WidgetEditorDisplay,
|
|
WidgetItem
|
|
} from '../types/Widget';
|
|
import { getContextWindowMetrics } from '../utils/context-window';
|
|
import {
|
|
getContextConfig,
|
|
getModelContextIdentifier
|
|
} from '../utils/model-context';
|
|
|
|
import {
|
|
getContextInverseModifierText,
|
|
handleContextInverseAction,
|
|
isContextInverse
|
|
} from './shared/context-inverse';
|
|
import { formatRawOrLabeledValue } from './shared/raw-or-labeled';
|
|
|
|
export class ContextPercentageUsableWidget implements Widget {
|
|
getDefaultColor(): string { return 'green'; }
|
|
getDescription(): string { return 'Shows percentage of usable context window used or remaining (80% of max before auto-compact)'; }
|
|
getDisplayName(): string { return 'Context % (usable)'; }
|
|
getCategory(): string { return 'Context'; }
|
|
getEditorDisplay(item: WidgetItem): WidgetEditorDisplay {
|
|
return {
|
|
displayText: this.getDisplayName(),
|
|
modifierText: getContextInverseModifierText(item)
|
|
};
|
|
}
|
|
|
|
handleEditorAction(action: string, item: WidgetItem): WidgetItem | null {
|
|
return handleContextInverseAction(action, item);
|
|
}
|
|
|
|
render(item: WidgetItem, context: RenderContext, settings: Settings): string | null {
|
|
const isInverse = isContextInverse(item);
|
|
const modelIdentifier = getModelContextIdentifier(context.data?.model);
|
|
const contextWindowMetrics = getContextWindowMetrics(context.data);
|
|
const contextConfig = getContextConfig(modelIdentifier, contextWindowMetrics.windowSize);
|
|
|
|
if (context.isPreview) {
|
|
const previewValue = isInverse ? '88.4%' : '11.6%';
|
|
return formatRawOrLabeledValue(item, 'Ctx(u): ', previewValue);
|
|
}
|
|
|
|
if (contextWindowMetrics.contextLengthTokens !== null) {
|
|
const usedPercentage = Math.min(100, (contextWindowMetrics.contextLengthTokens / contextConfig.usableTokens) * 100);
|
|
const displayPercentage = isInverse ? (100 - usedPercentage) : usedPercentage;
|
|
return formatRawOrLabeledValue(item, 'Ctx(u): ', `${displayPercentage.toFixed(1)}%`);
|
|
}
|
|
|
|
if (context.tokenMetrics) {
|
|
const usedPercentage = Math.min(100, (context.tokenMetrics.contextLength / contextConfig.usableTokens) * 100);
|
|
const displayPercentage = isInverse ? (100 - usedPercentage) : usedPercentage;
|
|
return formatRawOrLabeledValue(item, 'Ctx(u): ', `${displayPercentage.toFixed(1)}%`);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getCustomKeybinds(): CustomKeybind[] {
|
|
return [
|
|
{ key: 'u', label: '(u)sed/remaining', action: 'toggle-inverse' }
|
|
];
|
|
}
|
|
|
|
supportsRawValue(): boolean { return true; }
|
|
supportsColors(item: WidgetItem): boolean { return true; }
|
|
} |