@hivetechs/hive-ai
Version:
Real-time streaming AI consensus platform with HTTP+SSE MCP integration for Claude Code, VS Code, Cursor, and Windsurf - powered by OpenRouter's unified API
285 lines • 13.9 kB
JavaScript
/**
* Usage Tracking and Limit Management
* Monitors conversation usage and prompts users when approaching limits
*/
import { LicenseGate } from './license-gate.js';
export class UsageTracker {
static instance;
static getInstance() {
if (!UsageTracker.instance) {
UsageTracker.instance = new UsageTracker();
}
return UsageTracker.instance;
}
/**
* Check usage before allowing a conversation
* Returns notification if user should be warned about limits
*/
async checkUsageBeforeConversation() {
try {
const licenseGate = LicenseGate.getInstance();
const subscription = await licenseGate.getSubscriptionDetails();
const usage = await licenseGate.getUsageStatistics();
// Calculate usage percentages
const dailyPercentage = (usage.daily_used / subscription.daily_limit) * 100;
const monthlyPercentage = (usage.monthly_used / subscription.monthly_limit) * 100;
// Check if limits are exceeded
if (usage.daily_used >= subscription.daily_limit && usage.monthly_used >= subscription.monthly_limit) {
// Check if user has credits
if (usage.credits_remaining > 0) {
return {
allowed: true,
notification: {
type: 'info',
title: '💳 Using Bonus Credits',
message: `Daily and monthly limits reached. Using 1 of your ${usage.credits_remaining} bonus credits for this conversation.`,
action: {
label: 'Buy More Credits',
url: 'https://hivetechs.io/pricing'
}
}
};
}
else {
return {
allowed: false,
notification: {
type: 'blocked',
title: '🚫 Usage Limit Reached',
message: this.generateLimitReachedMessage(subscription, usage),
action: {
label: 'Upgrade Now',
url: this.getUpgradeUrl(subscription.tier)
}
}
};
}
}
// Check for warning thresholds
const notification = this.generateUsageWarning(subscription, usage, dailyPercentage, monthlyPercentage);
return {
allowed: true,
notification
};
}
catch (error) {
console.warn('Usage check failed:', error);
// Allow the conversation to proceed if usage check fails
return { allowed: true };
}
}
/**
* Record successful conversation usage
*/
async recordConversationUsage() {
try {
// This would typically sync with the cloud API
// For now, we'll just log locally
console.log('Conversation usage recorded');
}
catch (error) {
console.warn('Failed to record usage:', error);
}
}
/**
* Generate appropriate usage warning based on current usage
*/
generateUsageWarning(subscription, usage, dailyPercentage, monthlyPercentage) {
// Critical warning (90%+ usage)
if (dailyPercentage >= 90 || monthlyPercentage >= 90) {
return {
type: 'critical',
title: '🚨 Approaching Usage Limit',
message: this.generateCriticalWarningMessage(subscription, usage, dailyPercentage, monthlyPercentage),
action: {
label: 'Upgrade Now',
url: this.getUpgradeUrl(subscription.tier)
}
};
}
// High usage warning (75%+ usage)
if (dailyPercentage >= 75 || monthlyPercentage >= 75) {
return {
type: 'warning',
title: '⚠️ High Usage Alert',
message: this.generateHighUsageMessage(subscription, usage, dailyPercentage, monthlyPercentage),
action: {
label: 'View Plans',
url: 'https://hivetechs.io/pricing'
}
};
}
// Moderate usage (50%+ usage) - only for free tier
if (subscription.tier === 'free' && (dailyPercentage >= 50 || monthlyPercentage >= 50)) {
return {
type: 'info',
title: '📊 Usage Update',
message: this.generateModerateUsageMessage(subscription, usage, dailyPercentage, monthlyPercentage),
action: {
label: 'Start Free Trial',
url: 'https://hivetechs.io/pricing'
}
};
}
return undefined;
}
generateLimitReachedMessage(subscription, usage) {
let message = `You've reached your ${subscription.tier} tier limits:\n\n`;
message += `**Daily Limit**: ${usage.daily_used}/${subscription.daily_limit} conversations (100%)\n`;
message += `**Monthly Limit**: ${usage.monthly_used}/${subscription.monthly_limit} conversations (100%)\n\n`;
if (subscription.tier === 'free') {
message += `**🚀 Start Your 7-Day FREE Trial**\n`;
message += `Get unlimited access to all premium features:\n`;
message += `• Multi-model consensus pipeline\n`;
message += `• Advanced analytics and cost tracking\n`;
message += `• Performance benchmarking\n`;
message += `• Priority support\n\n`;
message += `After your trial, choose a plan that fits your needs:\n`;
message += `• **Basic ($5/month)**: 50 daily, 1,000 monthly conversations\n`;
message += `• **Standard ($10/month)**: 100 daily, 2,000 monthly conversations\n`;
message += `• **Premium ($20/month)**: 200 daily, 4,000 monthly conversations\n`;
}
else {
message += `**Upgrade Options:**\n`;
const nextTier = this.getNextTier(subscription.tier);
if (nextTier) {
message += `• **${nextTier.name} (${nextTier.price})**: ${nextTier.daily} daily, ${nextTier.monthly} monthly conversations\n`;
}
message += `\n**Or purchase additional credits:**\n`;
message += `• **Starter Pack (25 credits)**: $3\n`;
message += `• **Value Pack (75 credits)**: $7\n`;
message += `• **Power Pack (200 credits)**: $15\n`;
}
message += `\nLimits reset tomorrow (daily) and next month (monthly).`;
return message;
}
generateCriticalWarningMessage(subscription, usage, dailyPercentage, monthlyPercentage) {
const highestPercentage = Math.max(dailyPercentage, monthlyPercentage);
const isDaily = dailyPercentage >= monthlyPercentage;
let message = `You're at ${Math.round(highestPercentage)}% of your ${isDaily ? 'daily' : 'monthly'} limit.\n\n`;
message += `**Current Usage:**\n`;
message += `• Daily: ${usage.daily_used}/${subscription.daily_limit} (${Math.round(dailyPercentage)}%)\n`;
message += `• Monthly: ${usage.monthly_used}/${subscription.monthly_limit} (${Math.round(monthlyPercentage)}%)\n\n`;
if (usage.credits_remaining > 0) {
message += `**Good news!** You have ${usage.credits_remaining} bonus credits available when you reach your limits.\n\n`;
}
message += `**Avoid interruptions** by upgrading now or purchasing credits.`;
return message;
}
generateHighUsageMessage(subscription, usage, dailyPercentage, monthlyPercentage) {
let message = `You're using your ${subscription.tier} subscription heavily this period.\n\n`;
message += `**Current Usage:**\n`;
message += `• Daily: ${usage.daily_used}/${subscription.daily_limit} (${Math.round(dailyPercentage)}%)\n`;
message += `• Monthly: ${usage.monthly_used}/${subscription.monthly_limit} (${Math.round(monthlyPercentage)}%)\n\n`;
if (subscription.tier === 'free') {
message += `**🚀 Ready for more?** Start your 7-day unlimited trial!`;
}
else {
message += `**Consider upgrading** if you frequently reach these usage levels.`;
}
return message;
}
generateModerateUsageMessage(subscription, usage, dailyPercentage, monthlyPercentage) {
let message = `You're getting good use out of hive-tools!\n\n`;
message += `**Today's Usage**: ${usage.daily_used}/${subscription.daily_limit} conversations (${Math.round(dailyPercentage)}%)\n`;
message += `**This Month**: ${usage.monthly_used}/${subscription.monthly_limit} conversations (${Math.round(monthlyPercentage)}%)\n\n`;
message += `**💡 Tip**: Start your 7-day free trial to unlock unlimited conversations and premium features!`;
return message;
}
getUpgradeUrl(currentTier) {
const tierUrls = {
free: 'https://hivetechs.io/pricing',
basic: 'https://hivetechs.io/pricing',
standard: 'https://hivetechs.io/pricing',
premium: 'https://hivetechs.io/pricing'
};
return tierUrls[currentTier] || 'https://hivetechs.io/pricing';
}
getNextTier(currentTier) {
const tiers = {
free: { name: 'Basic', price: '$5/month', daily: 50, monthly: 1000 },
basic: { name: 'Standard', price: '$10/month', daily: 100, monthly: 2000 },
standard: { name: 'Premium', price: '$20/month', daily: 200, monthly: 4000 },
premium: { name: 'Team', price: '$50/month', daily: 600, monthly: 12000 }
};
return tiers[currentTier] || null;
}
/**
* Get formatted usage display for user interface
*/
async getUsageDisplay() {
try {
const licenseGate = LicenseGate.getInstance();
const subscription = await licenseGate.getSubscriptionDetails();
const usage = await licenseGate.getUsageStatistics();
const dailyPercentage = Math.round((usage.daily_used / subscription.daily_limit) * 100);
const monthlyPercentage = Math.round((usage.monthly_used / subscription.monthly_limit) * 100);
let display = `📊 **Usage Overview (${subscription.tier.toUpperCase()} TIER)**\n\n`;
// Progress bars with visual indicators
const dailyBar = this.generateProgressBar(dailyPercentage);
const monthlyBar = this.generateProgressBar(monthlyPercentage);
display += `**Today**: ${usage.daily_used}/${subscription.daily_limit} conversations\n`;
display += `${dailyBar} ${dailyPercentage}%\n\n`;
display += `**This Month**: ${usage.monthly_used}/${subscription.monthly_limit} conversations\n`;
display += `${monthlyBar} ${monthlyPercentage}%\n\n`;
if (usage.credits_remaining > 0) {
display += `💳 **Bonus Credits**: ${usage.credits_remaining} available\n\n`;
}
// Status indicator
const maxPercentage = Math.max(dailyPercentage, monthlyPercentage);
if (maxPercentage >= 90) {
display += `🚨 **Status**: Approaching limits - consider upgrading soon\n`;
}
else if (maxPercentage >= 75) {
display += `⚠️ **Status**: High usage - upgrade recommended\n`;
}
else if (maxPercentage >= 50) {
display += `📈 **Status**: Moderate usage - you're on track\n`;
}
else {
display += `✅ **Status**: Plenty of conversations remaining\n`;
}
// Quick actions
display += `\n**Quick Actions**:\n`;
display += `• Detailed usage: \`view_usage_stats\`\n`;
display += `• Credit tracking: \`credit_tracker\`\n`;
display += `• Buy credits: \`purchase_credits\`\n`;
display += `• Upgrade plan: \`upgrade_subscription\`\n`;
display += `• Get help: \`freemium_help\`\n`;
// Reset information
const now = new Date();
const tomorrow = new Date(now);
tomorrow.setDate(tomorrow.getDate() + 1);
const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1);
display += `\n**Resets**: Daily (${tomorrow.toLocaleDateString()}) | Monthly (${nextMonth.toLocaleDateString()})`;
return display;
}
catch (error) {
return '📊 Usage information unavailable - please check your connection and try again';
}
}
/**
* Generate a visual progress bar for usage percentages
*/
generateProgressBar(percentage) {
const width = 20;
const filled = Math.round((percentage / 100) * width);
const empty = width - filled;
// Use different colors based on usage level
let fillChar = '▓';
if (percentage >= 90) {
fillChar = '🔴'; // Red for critical
}
else if (percentage >= 75) {
fillChar = '🟠'; // Orange for warning
}
else if (percentage >= 50) {
fillChar = '🟡'; // Yellow for moderate
}
else {
fillChar = '🟢'; // Green for low usage
}
return `[${fillChar.repeat(Math.max(0, Math.floor(filled / 4)))}${'░'.repeat(Math.max(0, Math.floor(empty / 4)))}]`;
}
}
//# sourceMappingURL=usage-tracker.js.map