UNPKG

@quantumai/quantum-cli-core

Version:

Quantum CLI Core - Multi-LLM Collaboration System

586 lines 25.3 kB
/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ /** * Category of features */ export var FeatureCategory; (function (FeatureCategory) { FeatureCategory["PRODUCTIVITY"] = "productivity"; FeatureCategory["COST_OPTIMIZATION"] = "cost_optimization"; FeatureCategory["QUALITY_IMPROVEMENT"] = "quality_improvement"; FeatureCategory["AUTOMATION"] = "automation"; FeatureCategory["COLLABORATION"] = "collaboration"; FeatureCategory["MONITORING"] = "monitoring"; FeatureCategory["CUSTOMIZATION"] = "customization"; })(FeatureCategory || (FeatureCategory = {})); /** * Default onboarding configuration */ export const DEFAULT_ONBOARDING_CONFIG = { enableOnboarding: true, minUsageForAdvanced: 20, resuggestCooldown: 14, maxConcurrentSuggestions: 3, enableAdaptiveOnboarding: true, confidenceThreshold: 0.7, priorityCategories: [ FeatureCategory.PRODUCTIVITY, FeatureCategory.COST_OPTIMIZATION, FeatureCategory.QUALITY_IMPROVEMENT, ], }; /** * Intelligent onboarding system for feature discovery and adoption */ export class OnboardingSystem { config; userProfiles = new Map(); availableFeatures = new Map(); suggestionHistory = new Map(); constructor(config = {}) { this.config = { ...DEFAULT_ONBOARDING_CONFIG, ...config }; this.initializeFeatures(); } /** * Generates personalized onboarding suggestions */ generateSuggestions(userId, queryHistory, _userStats) { if (!this.config.enableOnboarding) { return []; } // Get or create user profile let profile = this.userProfiles.get(userId); if (!profile) { profile = this.createUserProfile(userId, queryHistory, _userStats); this.userProfiles.set(userId, profile); } // Update profile with recent usage this.updateUserProfile(profile, queryHistory, _userStats); // Analyze usage patterns and identify opportunities const opportunities = this.identifyOnboardingOpportunities(profile, queryHistory, _userStats); // Generate suggestions based on opportunities const suggestions = this.generateFeatureSuggestions(profile, opportunities); // Filter and personalize suggestions const personalizedSuggestions = this.personalizeAndFilterSuggestions(profile, suggestions); // Store suggestion history this.suggestionHistory.set(userId, personalizedSuggestions); return personalizedSuggestions; } /** * Creates initial user profile */ createUserProfile(userId, queryHistory, _userStats) { // Determine expertise level based on usage patterns const expertiseLevel = this.determineExpertiseLevel(queryHistory, _userStats); // Determine learning style based on query patterns const learningStyle = this.determineLearningStyle(queryHistory); // Determine preferred pace const preferredPace = this.determinePreferredPace(queryHistory); return { userId, totalFeatures: this.availableFeatures.size, adoptedFeatures: 0, masteredFeatures: 0, learningStyle, preferredPace, expertiseLevel, lastOnboarding: new Date(), onboardingPreferences: { enableSuggestions: true, maxSuggestionsPerWeek: 2, preferredTime: 'immediate', notificationTypes: ['in_app', 'suggestion'], skipCategories: [], learningGoals: ['productivity', 'cost_savings'], }, featureUsage: new Map(), }; } /** * Updates user profile with recent activity */ updateUserProfile(profile, queryHistory, _userStats) { // Update expertise level if usage has grown significantly const newExpertiseLevel = this.determineExpertiseLevel(queryHistory, _userStats); if (newExpertiseLevel !== profile.expertiseLevel) { profile.expertiseLevel = newExpertiseLevel; } // Track feature usage from query history this.trackFeatureUsageFromHistory(profile, queryHistory); // Update adoption statistics profile.adoptedFeatures = Array.from(profile.featureUsage.values()) .filter(usage => usage.adoptionStage === 'adopted' || usage.adoptionStage === 'mastered').length; profile.masteredFeatures = Array.from(profile.featureUsage.values()) .filter(usage => usage.adoptionStage === 'mastered').length; } /** * Identifies onboarding opportunities */ identifyOnboardingOpportunities(profile, queryHistory, _userStats) { const opportunities = []; // Productivity opportunities if (this.detectProductivityGaps(queryHistory, _userStats)) { opportunities.push({ type: 'productivity', description: 'User could benefit from productivity features', evidence: ['Repetitive query patterns detected', 'High query frequency'], confidence: 0.8, features: ['smart-templates', 'query-shortcuts', 'bulk-processing'], }); } // Cost optimization opportunities if (this.detectCostOptimizationNeeds(queryHistory, _userStats)) { opportunities.push({ type: 'cost_optimization', description: 'User has high costs that could be optimized', evidence: ['Above-average spending', 'Inefficient model usage'], confidence: 0.9, features: ['cost-monitoring', 'smart-routing', 'threshold-optimization'], }); } // Quality improvement opportunities if (this.detectQualityIssues(queryHistory, _userStats)) { opportunities.push({ type: 'quality_improvement', description: 'User satisfaction could be improved', evidence: ['Below-average satisfaction ratings', 'Frequent re-queries'], confidence: 0.7, features: ['verification-system', 'multi-model-comparison', 'quality-presets'], }); } // Automation opportunities if (this.detectAutomationOpportunities(queryHistory, _userStats)) { opportunities.push({ type: 'automation', description: 'Repetitive tasks could be automated', evidence: ['Consistent query patterns', 'Regular usage times'], confidence: 0.8, features: ['scheduled-queries', 'workflow-automation', 'smart-suggestions'], }); } // Advanced features for experienced users if (profile.expertiseLevel === 'advanced' && profile.adoptedFeatures > 5) { opportunities.push({ type: 'advanced', description: 'User ready for advanced features', evidence: ['High feature adoption', 'Advanced usage patterns'], confidence: 0.9, features: ['collaboration-engine', 'custom-providers', 'api-integration'], }); } return opportunities; } /** * Generates feature suggestions based on opportunities */ generateFeatureSuggestions(profile, opportunities) { const suggestions = []; for (const opportunity of opportunities) { for (const featureId of opportunity.features) { const feature = this.availableFeatures.get(featureId); if (!feature) continue; const usage = profile.featureUsage.get(featureId); // Skip if already adopted or recently suggested if (usage && ['adopted', 'mastered'].includes(usage.adoptionStage)) continue; if (this.wasRecentlySuggested(profile.userId, featureId)) continue; const suggestion = this.createFeatureSuggestion(feature, opportunity, profile); suggestions.push(suggestion); } } return suggestions; } /** * Creates a feature suggestion */ createFeatureSuggestion(feature, opportunity, profile) { const relevanceScore = this.calculateRelevanceScore(feature, opportunity, profile); const timeToMastery = this.estimateTimeToMastery(feature, profile); return { id: this.generateId(), featureId: feature.id, title: feature.title, description: feature.description, category: feature.category, benefits: feature.benefits, useCases: feature.useCases, learningCurve: feature.learningCurve, estimatedTimeToValue: feature.timeToValue, priority: this.calculatePriority(relevanceScore, opportunity.confidence), trigger: { type: 'opportunity', condition: opportunity.description, confidence: opportunity.confidence, evidence: opportunity.evidence, threshold: 0.7, }, guidance: this.generateGuidance(feature, profile), success: feature.successCriteria, personalization: { relevanceScore, userLevel: profile.expertiseLevel, similarUsers: [], // Would be populated with similar user IDs adoptionRate: feature.adoptionRate, timeToMastery, }, }; } /** * Personalizes and filters suggestions */ personalizeAndFilterSuggestions(profile, suggestions) { return suggestions .filter(s => { // Filter by user preferences if (profile.onboardingPreferences.skipCategories.includes(s.category)) return false; // Filter by confidence threshold if (s.trigger.confidence < this.config.confidenceThreshold) return false; // Filter by learning curve vs user level if (s.learningCurve === 'advanced' && profile.expertiseLevel === 'beginner') return false; return true; }) .sort((a, b) => { // Sort by priority first, then by relevance score const priorityOrder = { critical: 4, high: 3, medium: 2, low: 1 }; const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority]; if (priorityDiff !== 0) return priorityDiff; return b.personalization.relevanceScore - a.personalization.relevanceScore; }) .slice(0, this.config.maxConcurrentSuggestions); } /** * Helper methods for analysis */ determineExpertiseLevel(queryHistory, _userStats) { if (_userStats.totalQueries < 10) return 'beginner'; if (_userStats.totalQueries < 50) return 'intermediate'; return 'advanced'; } determineLearningStyle(_queryHistory) { // Simplified analysis - would analyze query patterns for learning preferences return 'hands_on'; } determinePreferredPace(queryHistory) { // Analyze query frequency and adaptation speed if (queryHistory.length > 20 && queryHistory[0]) { const timespan = Date.now() - queryHistory[queryHistory.length - 1].timestamp.getTime(); const daysActive = timespan / (1000 * 60 * 60 * 24); const queriesPerDay = queryHistory.length / daysActive; if (queriesPerDay > 5) return 'fast'; if (queriesPerDay < 1) return 'slow'; } return 'normal'; } detectProductivityGaps(queryHistory, _userStats) { // Look for repetitive patterns const queryTypes = queryHistory.map(q => q.analysis.type); const typeFrequency = new Map(); for (const type of queryTypes) { typeFrequency.set(type, (typeFrequency.get(type) || 0) + 1); } // If any query type is used more than 30% of the time, suggest productivity features const maxFrequency = Math.max(...typeFrequency.values()); return maxFrequency / queryHistory.length > 0.3; } detectCostOptimizationNeeds(_queryHistory, _userStats) { return _userStats.averageCost > 0.05 || _userStats.totalCost > 20; // Above threshold spending } detectQualityIssues(queryHistory, _userStats) { return _userStats.averageRating < 3.5; // Below 3.5/5 average rating } detectAutomationOpportunities(queryHistory, _userStats) { // Look for regular patterns in timing and content const hours = queryHistory.map(q => q.timestamp.getHours()); const hourCounts = new Map(); for (const hour of hours) { hourCounts.set(hour, (hourCounts.get(hour) || 0) + 1); } // If more than 40% of queries happen in the same 3-hour window const sortedHours = Array.from(hourCounts.entries()).sort((a, b) => b[1] - a[1]); const topThreeHours = sortedHours.slice(0, 3); const topThreeCount = topThreeHours.reduce((sum, [, count]) => sum + count, 0); return topThreeCount / queryHistory.length > 0.4; } trackFeatureUsageFromHistory(profile, queryHistory) { // Track usage of built-in features based on query characteristics // Verification feature usage const verificationUsage = queryHistory.filter(q => q.alternativeProviders.length > 0).length; if (verificationUsage > 0) { this.updateFeatureUsage(profile, 'verification-system', verificationUsage); } // Multi-model comparison usage const comparisonUsage = queryHistory.filter(q => q.alternativeProviders.length > 1).length; if (comparisonUsage > 0) { this.updateFeatureUsage(profile, 'multi-model-comparison', comparisonUsage); } // Cost monitoring (implicit usage) if (queryHistory.length > 10) { this.updateFeatureUsage(profile, 'cost-monitoring', queryHistory.length); } } updateFeatureUsage(profile, featureId, usageCount) { let usage = profile.featureUsage.get(featureId); if (!usage) { usage = { featureId, userId: profile.userId, firstUsed: new Date(), usageCount: 0, successfulUses: 0, averageSatisfaction: 0.5, adoptionStage: 'learning', onboardingCompleted: false, stepsCompleted: [], }; profile.featureUsage.set(featureId, usage); } usage.usageCount += usageCount; usage.lastUsed = new Date(); // Update adoption stage based on usage if (usage.usageCount > 20) { usage.adoptionStage = 'mastered'; } else if (usage.usageCount > 5) { usage.adoptionStage = 'adopted'; } } wasRecentlySuggested(userId, featureId) { const suggestions = this.suggestionHistory.get(userId) || []; const recentSuggestions = suggestions.filter(s => { const daysSince = (Date.now() - new Date(s.id).getTime()) / (1000 * 60 * 60 * 24); return daysSince < this.config.resuggestCooldown; }); return recentSuggestions.some(s => s.featureId === featureId); } calculateRelevanceScore(feature, opportunity, profile) { let score = 0.5; // Opportunity confidence contributes score += opportunity.confidence * 0.3; // Category priority if (this.config.priorityCategories.includes(feature.category)) { score += 0.2; } // Learning curve vs user level const levelMatch = this.calculateLevelMatch(feature.learningCurve, profile.expertiseLevel); score += levelMatch * 0.2; // User goals alignment const goalAlignment = this.calculateGoalAlignment(feature, profile.onboardingPreferences.learningGoals); score += goalAlignment * 0.3; return Math.max(0, Math.min(1, score)); } calculateLevelMatch(learningCurve, expertiseLevel) { const matches = { easy: { beginner: 1.0, intermediate: 0.8, advanced: 0.6 }, moderate: { beginner: 0.5, intermediate: 1.0, advanced: 0.8 }, advanced: { beginner: 0.2, intermediate: 0.6, advanced: 1.0 }, }; return matches[learningCurve]?.[expertiseLevel] || 0.5; } calculateGoalAlignment(feature, learningGoals) { const featureGoals = feature.benefits.map(b => b.toLowerCase()); const alignedGoals = learningGoals.filter(goal => featureGoals.some(fg => fg.includes(goal.toLowerCase()))); return learningGoals.length > 0 ? alignedGoals.length / learningGoals.length : 0.5; } calculatePriority(relevanceScore, confidence) { const combinedScore = (relevanceScore + confidence) / 2; if (combinedScore > 0.9) return 'critical'; if (combinedScore > 0.7) return 'high'; if (combinedScore > 0.5) return 'medium'; return 'low'; } estimateTimeToMastery(feature, profile) { const baseTime = feature.timeToMastery; // Adjust based on user's pace and expertise if (profile.preferredPace === 'fast' && profile.expertiseLevel === 'advanced') { return 'Half the usual time'; } else if (profile.preferredPace === 'slow' || profile.expertiseLevel === 'beginner') { return 'Longer than average'; } return baseTime; } generateGuidance(feature, profile) { return { introduction: `Let's learn ${feature.title}! This feature will help you ${feature.benefits[0]?.toLowerCase()}.`, steps: feature.onboardingSteps, tips: feature.tips, commonMistakes: feature.commonMistakes || [], resources: feature.resources || [], interactiveDemo: feature.hasDemo || false, }; } /** * Initialize available features */ initializeFeatures() { const features = [ { id: 'verification-system', title: 'Automatic Verification', description: 'Get second opinions on important queries', category: FeatureCategory.QUALITY_IMPROVEMENT, benefits: ['Higher accuracy', 'Reduced errors', 'Increased confidence'], useCases: ['Critical decisions', 'Complex problems', 'Important code'], learningCurve: 'easy', timeToValue: '5 minutes', timeToMastery: '1 week', adoptionRate: 0.8, successCriteria: { usage: { frequency: 3, timeframe: 'week' }, satisfaction: { minRating: 4, sampleSize: 5 }, outcome: { improvement: '20% higher satisfaction', metric: 'user_rating' }, timeline: '2 weeks', }, onboardingSteps: [ { id: 'enable', title: 'Enable Verification', description: 'Turn on automatic verification for uncertain queries', action: 'Go to settings and enable verification', expected: 'Verification toggle is on', duration: '1 minute', difficulty: 'easy', }, { id: 'try', title: 'Try It Out', description: 'Ask a complex question and see verification in action', action: 'Submit a challenging query', expected: 'You receive multiple model responses', duration: '2 minutes', difficulty: 'easy', }, ], tips: ['Use for important decisions', 'Check uncertainty indicators'], }, { id: 'cost-monitoring', title: 'Cost Monitoring', description: 'Track and optimize your API spending', category: FeatureCategory.COST_OPTIMIZATION, benefits: ['Reduce costs', 'Budget awareness', 'Usage insights'], useCases: ['Budget management', 'Cost optimization', 'Usage analysis'], learningCurve: 'easy', timeToValue: '2 minutes', timeToMastery: '3 days', adoptionRate: 0.9, successCriteria: { usage: { frequency: 5, timeframe: 'week' }, satisfaction: { minRating: 4, sampleSize: 3 }, outcome: { improvement: '15% cost reduction', metric: 'monthly_cost' }, timeline: '1 month', }, onboardingSteps: [ { id: 'view', title: 'View Cost Dashboard', description: 'Check your current spending and usage patterns', action: 'Run quantum --stats to see cost breakdown', expected: 'Cost dashboard shows your spending', duration: '1 minute', difficulty: 'easy', }, { id: 'set-budget', title: 'Set Budget Limits', description: 'Configure monthly spending limits', action: 'Set budget in preferences', expected: 'Budget limit is configured', duration: '2 minutes', difficulty: 'easy', }, ], tips: ['Set realistic budgets', 'Review weekly', 'Use cost-effective models'], }, { id: 'smart-routing', title: 'Smart Model Routing', description: 'Automatically select the best model for each query', category: FeatureCategory.AUTOMATION, benefits: ['Better results', 'Cost optimization', 'Time savings'], useCases: ['Regular usage', 'Varied query types', 'Efficiency gains'], learningCurve: 'moderate', timeToValue: '1 day', timeToMastery: '1 week', adoptionRate: 0.7, successCriteria: { usage: { frequency: 10, timeframe: 'week' }, satisfaction: { minRating: 4, sampleSize: 10 }, outcome: { improvement: '25% better satisfaction', metric: 'user_rating' }, timeline: '2 weeks', }, onboardingSteps: [ { id: 'enable-routing', title: 'Enable Smart Routing', description: 'Turn on automatic model selection', action: 'Enable smart routing in settings', expected: 'Smart routing is active', duration: '1 minute', difficulty: 'easy', }, { id: 'customize', title: 'Customize Preferences', description: 'Set your priorities for model selection', action: 'Configure cost/quality/speed preferences', expected: 'Preferences are set', duration: '3 minutes', difficulty: 'medium', }, ], tips: ['Start with balanced settings', 'Adjust based on results', 'Monitor model selection'], }, ]; for (const feature of features) { this.availableFeatures.set(feature.id, feature); } } generateId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); } /** * Records feature adoption for tracking */ recordFeatureAdoption(userId, featureId, stage) { const profile = this.userProfiles.get(userId); if (!profile) return; const usage = profile.featureUsage.get(featureId); if (usage) { usage.adoptionStage = stage; if (stage === 'adopted' || stage === 'mastered') { profile.adoptedFeatures++; } } } /** * Updates configuration */ updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; } /** * Gets current configuration */ getConfig() { return { ...this.config }; } } //# sourceMappingURL=onboarding-system.js.map