@quantumai/quantum-cli-core
Version:
Quantum CLI Core - Multi-LLM Collaboration System
806 lines • 28 kB
JavaScript
/**
* @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