UNPKG

@quantumai/quantum-cli-core

Version:

Quantum CLI Core - Multi-LLM Collaboration System

806 lines 28 kB
/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { QueryType } from './types.js'; import { ModelCharacteristicsService, ModelStrength, ModelWeakness, } from './model-characteristics.js'; // Pattern definitions for use case detection const QUERY_TYPE_PATTERNS = { [QueryType.CODE]: { keywords: [ 'function', 'class', 'method', 'variable', 'algorithm', 'implementation', 'code', 'programming', 'debug', 'error', 'syntax', 'compile', 'runtime', 'API', 'library', 'framework', 'database', 'SQL', 'query', 'endpoint', 'refactor', 'optimize', 'performance', 'memory', 'complexity', 'O(', 'git', 'commit', 'branch', 'merge', 'version control', 'CI/CD', 'deploy', ], patterns: [ /\b(def|function|class|import|from|return)\b/gi, /\b(if|else|for|while|try|catch|finally)\b/gi, /\b(var|let|const|int|string|boolean|array)\b/gi, /\b(console\.log|print|printf|System\.out)\b/gi, /[{}\[\]();]/g, /\b\w+\(\w*\)/g, // Function calls /\b[A-Z][a-zA-Z]*Error\b/g, // Error types ], complexity: { simple: ['hello world', 'basic syntax', 'simple function'], medium: ['algorithm', 'data structure', 'API integration'], complex: [ 'optimization', 'architecture', 'performance tuning', 'distributed system', ], }, }, [QueryType.CREATIVE]: { keywords: [ 'story', 'write', 'creative', 'narrative', 'character', 'plot', 'dialogue', 'poem', 'poetry', 'song', 'lyrics', 'script', 'screenplay', 'novel', 'blog', 'article', 'content', 'marketing', 'copy', 'slogan', 'brand', 'fictional', 'imaginative', 'artistic', 'literary', 'prose', 'style', 'tone', 'voice', 'mood', 'atmosphere', 'metaphor', 'symbolism', ], patterns: [ /\b(write|create|compose|craft|generate)\s+(a|an)?\s*(story|poem|song|script|article)\b/gi, /\b(creative|imaginative|artistic|literary)\b/gi, /\b(character|plot|dialogue|narrative|theme)\b/gi, /\b(tone|style|voice|mood)\b/gi, ], complexity: { simple: ['short paragraph', 'simple description', 'basic copy'], medium: ['article', 'blog post', 'product description', 'social media'], complex: ['novel', 'screenplay', 'brand strategy', 'creative campaign'], }, }, [QueryType.ANALYSIS]: { keywords: [ 'analyze', 'analysis', 'examine', 'evaluate', 'assess', 'review', 'compare', 'contrast', 'summarize', 'explain', 'interpret', 'breakdown', 'pros and cons', 'advantages', 'disadvantages', 'benefits', 'drawbacks', 'trend', 'pattern', 'correlation', 'causation', 'impact', 'effect', 'data', 'statistics', 'metrics', 'performance', 'results', 'findings', 'research', 'study', 'report', 'insight', 'conclusion', 'recommendation', ], patterns: [ /\b(analyze|analysis|examine|evaluate|assess|review)\b/gi, /\b(compare|contrast|vs|versus|difference|similarity)\b/gi, /\b(pros?\s+and\s+cons?|advantages?\s+and\s+disadvantages?)\b/gi, /\b(trend|pattern|correlation|causation)\b/gi, /\b(data|statistics|metrics|performance)\b/gi, ], complexity: { simple: ['basic comparison', 'simple explanation', 'list pros and cons'], medium: ['trend analysis', 'performance review', 'detailed comparison'], complex: [ 'comprehensive analysis', 'multi-factor evaluation', 'strategic assessment', ], }, }, [QueryType.SECURITY]: { keywords: [ 'security', 'vulnerability', 'exploit', 'attack', 'threat', 'risk', 'authentication', 'authorization', 'encryption', 'decrypt', 'hash', 'password', 'token', 'JWT', 'OAuth', 'SSL', 'TLS', 'HTTPS', 'firewall', 'intrusion', 'malware', 'virus', 'phishing', 'XSS', 'CSRF', 'SQL injection', 'buffer overflow', 'privilege escalation', 'backdoor', 'audit', 'compliance', 'GDPR', 'HIPAA', 'PCI', 'SOX', 'ISO 27001', 'penetration testing', 'red team', 'blue team', 'SIEM', 'SOC', ], patterns: [ /\b(security|vulnerability|exploit|attack|threat)\b/gi, /\b(authentication|authorization|encrypt|decrypt)\b/gi, /\b(password|token|JWT|OAuth|SSL|TLS)\b/gi, /\b(XSS|CSRF|SQL\s+injection|buffer\s+overflow)\b/gi, /\b(GDPR|HIPAA|PCI|SOX|ISO\s+27001)\b/gi, /\b(pentest|penetration\s+testing|red\s+team|blue\s+team)\b/gi, ], complexity: { simple: ['basic security', 'password policy', 'simple encryption'], medium: [ 'security audit', 'vulnerability assessment', 'compliance check', ], complex: [ 'threat modeling', 'security architecture', 'incident response', ], }, }, [QueryType.GENERAL]: { keywords: [ 'help', 'how', 'what', 'why', 'when', 'where', 'explain', 'tell me', 'question', 'answer', 'information', 'advice', 'suggestion', 'recommendation', 'best practice', 'tutorial', 'guide', 'step by step', 'example', 'general', 'basic', 'simple', 'beginner', 'learn', 'understand', ], patterns: [ /\b(how\s+to|what\s+is|why\s+does|when\s+should|where\s+can)\b/gi, /\b(help|explain|tell\s+me|show\s+me)\b/gi, /\b(question|answer|information|advice)\b/gi, /\b(best\s+practice|tutorial|guide|example)\b/gi, ], complexity: { simple: ['basic question', 'simple explanation', 'general help'], medium: ['detailed explanation', 'how-to guide', 'best practices'], complex: ['comprehensive tutorial', 'advanced concepts', 'expert advice'], }, }, }; // Domain-specific patterns const DOMAIN_PATTERNS = { 'web-development': [ 'HTML', 'CSS', 'JavaScript', 'React', 'Vue', 'Angular', 'Node.js', 'frontend', 'backend', 'fullstack', ], 'machine-learning': [ 'ML', 'AI', 'neural network', 'deep learning', 'TensorFlow', 'PyTorch', 'model', 'training', 'dataset', ], 'mobile-development': [ 'iOS', 'Android', 'React Native', 'Flutter', 'Swift', 'Kotlin', 'mobile app', ], 'data-science': [ 'pandas', 'numpy', 'scipy', 'matplotlib', 'data visualization', 'statistics', 'regression', ], devops: [ 'Docker', 'Kubernetes', 'CI/CD', 'Jenkins', 'deployment', 'infrastructure', 'cloud', 'AWS', 'Azure', ], database: [ 'SQL', 'NoSQL', 'MongoDB', 'PostgreSQL', 'MySQL', 'Redis', 'database design', 'query optimization', ], finance: [ 'trading', 'investment', 'portfolio', 'risk management', 'financial modeling', 'cryptocurrency', ], healthcare: [ 'medical', 'patient', 'diagnosis', 'treatment', 'clinical', 'pharmaceutical', 'HIPAA', ], 'e-commerce': [ 'shopping', 'payment', 'checkout', 'inventory', 'product catalog', 'order management', ], gaming: [ 'game development', 'Unity', 'Unreal', 'graphics', 'physics', 'multiplayer', 'gameplay', ], }; export class UseCaseAnalyzer { /** * Analyze a query to determine its use case characteristics */ static analyzeQuery(query) { const queryLower = query.toLowerCase(); const queryTypes = Object.keys(QUERY_TYPE_PATTERNS); // Calculate scores for each query type const typeScores = queryTypes.map((type) => { const patterns = QUERY_TYPE_PATTERNS[type]; let score = 0; const matchedPatterns = []; // Keyword matching const keywordMatches = patterns.keywords.filter((keyword) => queryLower.includes(keyword.toLowerCase())); score += keywordMatches.length * 2; matchedPatterns.push(...keywordMatches); // Pattern matching patterns.patterns.forEach((pattern) => { const matches = query.match(pattern); if (matches) { score += matches.length; matchedPatterns.push(`Pattern: ${pattern.source}`); } }); return { type, score, patterns: matchedPatterns }; }); // Find the highest scoring type const bestMatch = typeScores.reduce((best, current) => current.score > best.score ? current : best); // Determine complexity const complexity = this.determineComplexity(query, bestMatch.type); // Detect domain const domain = this.detectDomain(query); // Detect frameworks and languages const frameworks = this.detectFrameworks(query); const languages = this.detectLanguages(query); // Detect special requirements const specialRequirements = this.detectSpecialRequirements(query); // Calculate confidence based on score strength const confidence = Math.min(bestMatch.score / 10, 1); return { queryType: bestMatch.type, confidence, reasoning: this.generateReasoning(bestMatch, domain, frameworks, languages), detectedPatterns: bestMatch.patterns, complexity, domain, frameworks, languages, specialRequirements, }; } /** * Get model recommendations based on use case analysis */ static getRecommendations(query, maxCost, preferredLatency) { const analysis = this.analyzeQuery(query); const allModels = ModelCharacteristicsService.getAllModels(); // Score models for this specific use case const recommendations = allModels .map((model) => { const recommendation = this.scoreModelForUseCase(model, analysis, query); // Apply cost filter if (maxCost && recommendation.estimatedCost > maxCost) { recommendation.score *= 0.3; // Heavily penalize over-budget models recommendation.reasoning.push(`Exceeds budget: $${recommendation.estimatedCost.toFixed(4)} > $${maxCost.toFixed(4)}`); } // Apply latency preference if (preferredLatency && recommendation.estimatedLatency > preferredLatency) { const latencyPenalty = Math.min((recommendation.estimatedLatency - preferredLatency) / preferredLatency, 0.5); recommendation.score *= 1 - latencyPenalty; recommendation.reasoning.push(`Higher latency than preferred: ${recommendation.estimatedLatency}ms > ${preferredLatency}ms`); } return recommendation; }) .sort((a, b) => b.score - a.score); const primary = recommendations[0]; const alternatives = recommendations.slice(1, 4); // Top 3 alternatives return { query, analysis, primaryRecommendation: primary, alternatives, explanation: this.generateExplanation(analysis, primary, alternatives), }; } /** * Compare models for a specific use case */ static compareModelsForUseCase(modelIds, query) { const analysis = this.analyzeQuery(query); return modelIds .map((modelId) => { const model = ModelCharacteristicsService.getModelCharacteristics(modelId); if (!model) { throw new Error(`Model not found: ${modelId}`); } const recommendation = this.scoreModelForUseCase(model, analysis, query); return { modelId, recommendation }; }) .sort((a, b) => b.recommendation.score - a.recommendation.score); } static scoreModelForUseCase(model, analysis, query) { let score = 0; const reasoning = []; const pros = []; const cons = []; // Base suitability score from model characteristics const useCase = model.useCases.find((uc) => uc.queryType === analysis.queryType); const baseSuitability = useCase ? useCase.suitabilityScore : model.qualityScores.overall * 0.8; score += baseSuitability * 50; // 50% of total score if (useCase) { reasoning.push(`Suitability for ${analysis.queryType}: ${(baseSuitability * 100).toFixed(0)}%`); reasoning.push(...useCase.reasoning); } // Adjust for complexity switch (analysis.complexity) { case 'simple': if (model.strengths.includes(ModelStrength.FAST_RESPONSE)) { score += 10; pros.push('Fast response for simple queries'); } if (model.weaknesses.includes(ModelWeakness.HIGH_COST)) { score -= 5; cons.push('May be unnecessarily expensive for simple tasks'); } break; case 'complex': if (model.strengths.includes(ModelStrength.COMPLEX_REASONING)) { score += 15; pros.push('Excellent for complex reasoning tasks'); } if (model.weaknesses.includes(ModelWeakness.SLOW_RESPONSE)) { score -= 5; cons.push('Slower response time for complex queries'); } break; } // Domain-specific adjustments if (analysis.domain) { const domainBonus = this.getDomainBonus(model, analysis.domain); score += domainBonus.score; if (domainBonus.reason) { reasoning.push(domainBonus.reason); if (domainBonus.score > 0) { pros.push(domainBonus.reason); } else { cons.push(domainBonus.reason); } } } // Framework/language specific adjustments if (analysis.frameworks && analysis.frameworks.length > 0) { const frameworkBonus = this.getFrameworkBonus(model, analysis.frameworks); score += frameworkBonus; if (frameworkBonus > 0) { pros.push(`Good support for detected frameworks: ${analysis.frameworks.join(', ')}`); } } // Quality score adjustment score += model.qualityScores.overall * 20; // 20% of total score // Cost efficiency adjustment const costEfficiency = 1 / model.cost.costPerQualityPoint; score += costEfficiency * 10; // 10% of total score // Performance adjustment const latencyPenalty = Math.max(0, (model.performance.averageLatency - 2000) / 1000); score -= latencyPenalty * 5; // Special requirements if (analysis.specialRequirements) { const requirementPenalty = this.checkSpecialRequirements(model, analysis.specialRequirements); score += requirementPenalty.score; if (requirementPenalty.reason) { reasoning.push(requirementPenalty.reason); if (requirementPenalty.score < 0) { cons.push(requirementPenalty.reason); } } } // Calculate estimated cost (500 input + 200 output tokens) const estimatedCost = model.cost.inputTokenCost * 0.5 + model.cost.outputTokenCost * 0.2; // Calculate confidence based on how well we understand this use case for this model const confidence = Math.min(analysis.confidence * (useCase ? useCase.confidence : 0.7), 1); return { modelId: model.id, score: Math.max(0, Math.min(100, score)), reasoning, tradeoffs: { pros, cons }, estimatedCost, estimatedLatency: model.performance.averageLatency, confidence, }; } static determineComplexity(query, queryType) { const patterns = QUERY_TYPE_PATTERNS[queryType]?.complexity; if (!patterns) return 'medium'; const queryLower = query.toLowerCase(); // Check for complex indicators for (const indicator of patterns.complex) { if (queryLower.includes(indicator.toLowerCase())) { return 'complex'; } } // Check for simple indicators for (const indicator of patterns.simple) { if (queryLower.includes(indicator.toLowerCase())) { return 'simple'; } } // Default to medium, but consider query length if (query.length > 500) return 'complex'; if (query.length < 50) return 'simple'; return 'medium'; } static detectDomain(query) { const queryLower = query.toLowerCase(); for (const [domain, keywords] of Object.entries(DOMAIN_PATTERNS)) { const matches = keywords.filter((keyword) => queryLower.includes(keyword.toLowerCase())); if (matches.length >= 2) { return domain; } } return undefined; } static detectFrameworks(query) { const frameworks = []; const queryLower = query.toLowerCase(); const frameworkPatterns = { React: /\b(react|jsx|component|hook|state|props)\b/gi, Vue: /\b(vue|vuex|nuxt|composition api)\b/gi, Angular: /\b(angular|typescript|rxjs|observable)\b/gi, 'Node.js': /\b(node\.js|npm|express|fastify)\b/gi, Python: /\b(python|django|flask|fastapi|pandas)\b/gi, Java: /\b(java|spring|hibernate|maven|gradle)\b/gi, 'C#': /\b(c#|\.net|asp\.net|entity framework)\b/gi, Docker: /\b(docker|container|dockerfile|compose)\b/gi, Kubernetes: /\b(kubernetes|k8s|helm|kubectl)\b/gi, }; for (const [framework, pattern] of Object.entries(frameworkPatterns)) { if (pattern.test(query)) { frameworks.push(framework); } } return frameworks; } static detectLanguages(query) { const languages = []; const queryLower = query.toLowerCase(); const languageKeywords = { JavaScript: ['javascript', 'js', 'node', 'npm', 'yarn'], Python: ['python', 'py', 'pip', 'conda'], Java: ['java', 'jvm', 'maven', 'gradle'], 'C++': ['c++', 'cpp', 'g++', 'cmake'], 'C#': ['c#', 'csharp', '.net', 'dotnet'], Go: ['golang', 'go lang', 'go '], Rust: ['rust', 'cargo', 'rustc'], PHP: ['php', 'composer', 'laravel'], Ruby: ['ruby', 'rails', 'gem'], Swift: ['swift', 'ios', 'xcode'], Kotlin: ['kotlin', 'android studio'], TypeScript: ['typescript', 'ts', 'tsc'], }; for (const [language, keywords] of Object.entries(languageKeywords)) { if (keywords.some((keyword) => queryLower.includes(keyword))) { languages.push(language); } } return languages; } static detectSpecialRequirements(query) { const requirements = []; const queryLower = query.toLowerCase(); const requirementPatterns = { 'real-time': /\b(real[- ]?time|live|instant|immediate)\b/gi, 'high-performance': /\b(fast|performance|optimize|speed|efficient)\b/gi, 'low-latency': /\b(low[- ]?latency|quick|rapid|responsive)\b/gi, 'high-accuracy': /\b(accurate|precise|correct|exact|perfect)\b/gi, 'cost-sensitive': /\b(cheap|budget|cost[- ]?effective|affordable)\b/gi, scalable: /\b(scalable?|scale|scaling|distributed|cluster)\b/gi, secure: /\b(secure|security|safe|protected|encrypted)\b/gi, compliant: /\b(complian[tc]e|gdpr|hipaa|sox|pci|regulation)\b/gi, }; for (const [requirement, pattern] of Object.entries(requirementPatterns)) { if (pattern.test(query)) { requirements.push(requirement); } } return requirements; } static getDomainBonus(model, domain) { // Domain-specific model preferences const domainPreferences = { 'web-development': { 'gpt-4': 8, 'claude-3-sonnet': 6, 'gemini-2.5-pro': 9, }, 'machine-learning': { 'gpt-4': 7, 'claude-3-sonnet': 8, 'gemini-2.5-pro': 9, }, security: { 'gpt-4': 6, 'claude-3-sonnet': 8, 'gemini-2.5-pro': 8, }, 'data-science': { 'gpt-4': 7, 'claude-3-sonnet': 9, 'gemini-2.5-pro': 8, }, }; const preference = domainPreferences[domain]?.[model.id]; if (preference !== undefined) { return { score: preference, reason: `${preference > 6 ? 'Strong' : 'Moderate'} performance in ${domain} domain`, }; } return { score: 0 }; } static getFrameworkBonus(model, frameworks) { // Framework-specific bonuses const frameworkBonuses = { React: { 'gpt-4': 5, 'gemini-2.5-pro': 7, }, Python: { 'claude-3-sonnet': 6, 'gpt-4': 5, 'gemini-2.5-pro': 7, }, 'Node.js': { 'gpt-4': 6, 'gemini-2.5-pro': 8, }, }; let totalBonus = 0; frameworks.forEach((framework) => { const bonus = frameworkBonuses[framework]?.[model.id] || 0; totalBonus += bonus; }); return totalBonus; } static checkSpecialRequirements(model, requirements) { let score = 0; const reasons = []; requirements.forEach((requirement) => { switch (requirement) { case 'real-time': case 'low-latency': if (model.performance.averageLatency < 2000) { score += 5; reasons.push('Good latency for real-time requirements'); } else { score -= 5; reasons.push('May be too slow for real-time requirements'); } break; case 'high-accuracy': if (model.qualityScores.accuracy > 0.9) { score += 5; reasons.push('High accuracy model'); } break; case 'cost-sensitive': if (model.cost.costEfficiencyRank <= 5) { score += 5; reasons.push('Cost-efficient option'); } else { score -= 3; reasons.push('Higher cost model'); } break; case 'secure': if (model.provider === 'google' || model.provider === 'anthropic') { score += 3; reasons.push('Strong security and privacy practices'); } break; } }); return { score, reason: reasons.length > 0 ? reasons.join('; ') : undefined, }; } static generateReasoning(bestMatch, domain, frameworks, languages) { const reasoning = []; reasoning.push(`Classified as ${bestMatch.type} query (score: ${bestMatch.score})`); if (bestMatch.patterns.length > 0) { reasoning.push(`Detected patterns: ${bestMatch.patterns.slice(0, 3).join(', ')}`); } if (domain) { reasoning.push(`Domain: ${domain}`); } if (frameworks && frameworks.length > 0) { reasoning.push(`Frameworks: ${frameworks.join(', ')}`); } if (languages && languages.length > 0) { reasoning.push(`Languages: ${languages.join(', ')}`); } return reasoning; } static generateExplanation(analysis, primary, alternatives) { const parts = []; parts.push(`This query was classified as a ${analysis.queryType} task with ${analysis.complexity} complexity.`); if (analysis.domain) { parts.push(`The detected domain is ${analysis.domain}.`); } parts.push(`${primary.modelId} is recommended with a score of ${primary.score.toFixed(1)}/100.`); if (primary.tradeoffs.pros.length > 0) { parts.push(`Key advantages: ${primary.tradeoffs.pros.slice(0, 2).join(', ')}.`); } if (alternatives.length > 0) { const topAlt = alternatives[0]; parts.push(`Alternative: ${topAlt.modelId} (score: ${topAlt.score.toFixed(1)}).`); } return parts.join(' '); } } //# sourceMappingURL=use-case-analyzer.js.map