@nanocollective/nanocoder
Version:
A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter
53 lines • 7.39 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* Usage display component for /usage command
*/
import { Box, Text } from 'ink';
import { TitledBoxWithPreferences } from '../../components/ui/titled-box.js';
import { useTerminalWidth } from '../../hooks/useTerminalWidth.js';
import { useTheme } from '../../hooks/useTheme.js';
import { formatTokenCount, getUsageStatusColor } from '../../usage/calculator.js';
import { ProgressBar } from './progress-bar.js';
export function UsageDisplay({ provider, model, contextLimit, currentTokens, breakdown, messages, tokenizerName, getMessageTokens, }) {
const boxWidth = useTerminalWidth();
const { colors } = useTheme();
// Calculate percentages
const percentUsed = contextLimit ? (currentTokens / contextLimit) * 100 : 0;
const statusColor = getUsageStatusColor(percentUsed);
const availableTokens = contextLimit ? contextLimit - currentTokens : 0;
// Get the actual color from theme
const progressColor = statusColor === 'success'
? colors.success
: statusColor === 'warning'
? colors.warning
: colors.error;
// Calculate category percentages for breakdown bars
const systemPercent = currentTokens
? (breakdown.system / currentTokens) * 100
: 0;
const userPercent = currentTokens
? (breakdown.userMessages / currentTokens) * 100
: 0;
const assistantPercent = currentTokens
? (breakdown.assistantMessages / currentTokens) * 100
: 0;
const toolMessagesPercent = currentTokens
? (breakdown.toolResults / currentTokens) * 100
: 0;
const toolDefsPercent = currentTokens
? (breakdown.toolDefinitions / currentTokens) * 100
: 0;
// Calculate recent activity stats using cached token counts
const last5Messages = messages.slice(-5);
const last5TokenCount = last5Messages.reduce((sum, msg) => sum + getMessageTokens(msg), 0);
// Find largest message using cached token counts
const largestMessageTokens = messages.length > 0
? Math.max(...messages.map(msg => getMessageTokens(msg)))
: 0;
// Responsive layout calculations based on terminal width
// For narrow terminals, reduce space for bars
const barMaxWidth = Math.max(10, Math.min(30, boxWidth - 20));
const mainProgressWidth = Math.max(20, Math.min(60, boxWidth - 12));
return (_jsxs(TitledBoxWithPreferences, { title: "Context Usage", width: boxWidth, borderColor: colors.info, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.primary, bold: true, children: "Overall Usage" }) }), _jsxs(Box, { marginBottom: 0, children: [_jsx(ProgressBar, { percent: percentUsed, width: mainProgressWidth, color: progressColor }), _jsxs(Text, { color: colors.text, bold: true, children: [' ', Math.round(percentUsed), "%"] })] }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: colors.secondary, children: [formatTokenCount(currentTokens), " /", ' ', contextLimit ? formatTokenCount(contextLimit) : 'Unknown', " tokens"] }) }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { color: colors.primary, bold: true, children: "Breakdown by Category" }) }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { color: colors.info, children: "System Prompt:" }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(ProgressBar, { percent: systemPercent, width: barMaxWidth, color: colors.info }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: colors.text, children: [Math.round(systemPercent), "% (", formatTokenCount(breakdown.system), ")"] }) })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { color: colors.secondary, children: "User Messages:" }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(ProgressBar, { percent: userPercent, width: barMaxWidth, color: colors.info }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: colors.text, children: [Math.round(userPercent), "% (", formatTokenCount(breakdown.userMessages), ")"] }) })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { color: colors.secondary, children: "Assistant Messages:" }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(ProgressBar, { percent: assistantPercent, width: barMaxWidth, color: colors.info }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: colors.text, children: [Math.round(assistantPercent), "% (", formatTokenCount(breakdown.assistantMessages), ")"] }) })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { color: colors.secondary, children: "Tool Messages:" }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(ProgressBar, { percent: toolMessagesPercent, width: barMaxWidth, color: colors.info }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: colors.text, children: [Math.round(toolMessagesPercent), "% (", formatTokenCount(breakdown.toolResults), ")"] }) })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 0, children: _jsx(Text, { color: colors.secondary, children: "Tool Definitions:" }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(ProgressBar, { percent: toolDefsPercent, width: barMaxWidth, color: colors.info }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: colors.text, children: [Math.round(toolDefsPercent), "% (", formatTokenCount(breakdown.toolDefinitions), ")"] }) })] })] }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsxs(Text, { color: colors.secondary, children: ["Available:", ' ', _jsxs(Text, { color: colors.success, children: [formatTokenCount(availableTokens), " tokens"] })] }) }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { color: colors.primary, bold: true, children: "Model Information" }) }), _jsx(Box, { children: _jsxs(Text, { color: colors.secondary, children: ["Provider: ", _jsx(Text, { color: colors.text, children: provider })] }) }), _jsx(Box, { children: _jsxs(Text, { color: colors.secondary, children: ["Model: ", _jsx(Text, { color: colors.text, children: model })] }) }), _jsx(Box, { children: _jsxs(Text, { color: colors.secondary, children: ["Context Limit:", ' ', _jsx(Text, { color: colors.text, children: contextLimit ? formatTokenCount(contextLimit) : 'Unknown' })] }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: colors.secondary, children: ["Tokenizer: ", _jsx(Text, { color: colors.text, children: tokenizerName })] }) }), _jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { color: colors.primary, bold: true, children: "Recent Activity" }) }), _jsx(Box, { children: _jsxs(Text, { color: colors.secondary, children: ["Last 5 messages:", ' ', _jsxs(Text, { color: colors.text, children: [formatTokenCount(last5TokenCount), " tokens"] })] }) }), _jsx(Box, { children: _jsxs(Text, { color: colors.secondary, children: ["Largest message:", ' ', _jsxs(Text, { color: colors.text, children: [formatTokenCount(largestMessageTokens), " tokens"] })] }) })] }));
}
//# sourceMappingURL=usage-display.js.map