UNPKG

quantum-cli-core

Version:

Quantum CLI Core - Multi-LLM Collaboration System

282 lines 10.7 kB
/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { UncertaintyLevel } from '../types.js'; export class AutoTriggerSystem { config; constructor(config) { this.config = config; } updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; } shouldTriggerVerification(query, uncertaintyResult, context) { // Check cost limitation first if (this.isOverCostLimit()) { return { shouldVerify: false, shouldCompare: false, reason: 'monthly_cost_limit_exceeded', costImpact: 'high', confidence: 1.0, }; } // Check if domain is in skip list if (this.shouldSkipDomain(context?.domain)) { return { shouldVerify: false, shouldCompare: false, reason: 'domain_in_skip_list', costImpact: 'low', confidence: 0.9, }; } // Force verification for priority domains if (this.isPriorityDomain(context?.domain)) { return { shouldVerify: true, shouldCompare: uncertaintyResult.level === UncertaintyLevel.CRITICAL, reason: 'priority_domain_always_verify', costImpact: 'medium', confidence: 1.0, }; } // Calculate query complexity score const queryComplexityScore = this.calculateQueryComplexity(query); // Apply aggressiveness modifier const aggressivenessModifier = this.getAggressivenessModifier(); // Calculate final decision score const decisionScore = this.calculateDecisionScore(uncertaintyResult, queryComplexityScore, aggressivenessModifier, context); // Determine actions based on thresholds const shouldCompare = this.shouldTriggerCompare(decisionScore, uncertaintyResult.level); const shouldVerify = shouldCompare || this.shouldTriggerVerify(decisionScore, uncertaintyResult.level); // Cost awareness check if (this.config.userPreferences.enableCostAwareMode && this.isNearCostLimit()) { if (shouldCompare && uncertaintyResult.level !== UncertaintyLevel.CRITICAL) { return { shouldVerify, shouldCompare: false, reason: 'cost_aware_downgrade_compare_to_verify', costImpact: 'medium', confidence: 0.7, }; } if (shouldVerify && uncertaintyResult.level === UncertaintyLevel.LOW) { return { shouldVerify: false, shouldCompare: false, reason: 'cost_aware_skip_low_uncertainty', costImpact: 'low', confidence: 0.6, }; } } return { shouldVerify, shouldCompare, reason: this.getDecisionReason(shouldVerify, shouldCompare, decisionScore, uncertaintyResult), costImpact: this.calculateCostImpact(shouldVerify, shouldCompare), confidence: this.calculateConfidence(decisionScore, uncertaintyResult), }; } calculateQueryComplexity(query) { const wordCount = query.split(/\s+/).length; const { shortQuery, longQuery, complexityMultiplier } = this.config.queryLengthFactors; let lengthScore = 0; if (wordCount <= shortQuery) { lengthScore = 0.2; // Short queries might need less verification } else if (wordCount >= longQuery) { lengthScore = 0.8; // Long queries might be more complex } else { // Linear interpolation between short and long lengthScore = 0.2 + ((wordCount - shortQuery) / (longQuery - shortQuery)) * 0.6; } // Check for complexity indicators in the query itself const complexityIndicators = [ /multiple|various|different|compare|analyze/i, /security|production|critical|important/i, /how to|best practice|recommend|suggest/i, /\?.*\?/, // Multiple questions /step.?by.?step|detailed|comprehensive/i, ]; let complexityBonus = 0; for (const indicator of complexityIndicators) { if (indicator.test(query)) { complexityBonus += 0.1; } } return Math.min((lengthScore + complexityBonus) * complexityMultiplier, 1.0); } getAggressivenessModifier() { switch (this.config.userPreferences.aggressiveness) { case 'conservative': return 0.7; // Higher threshold for triggering case 'balanced': return 1.0; // Normal thresholds case 'aggressive': return 1.3; // Lower threshold for triggering default: return 1.0; } } calculateDecisionScore(uncertaintyResult, queryComplexity, aggressivenessModifier, context) { // Base score from uncertainty level let baseScore = 0; switch (uncertaintyResult.level) { case UncertaintyLevel.CRITICAL: baseScore = 1.0; break; case UncertaintyLevel.HIGH: baseScore = 0.8; break; case UncertaintyLevel.MEDIUM: baseScore = 0.5; break; case UncertaintyLevel.LOW: baseScore = 0.2; break; default: { baseScore = 0.1; break; } } // Factor in query complexity (20% weight) const complexityFactor = queryComplexity * 0.2; // Factor in context criticality (10% weight) let contextFactor = 0; if (context?.type) { contextFactor = 0.1; // Any specific context adds some weight } // Apply aggressiveness modifier const finalScore = (baseScore + complexityFactor + contextFactor) * aggressivenessModifier; return Math.min(finalScore, 1.0); } shouldTriggerVerify(score, level) { // Always verify critical unless cost-limited if (level === UncertaintyLevel.CRITICAL) { return true; } // Use score-based threshold for other levels return score >= 0.4; // Configurable threshold } shouldTriggerCompare(score, level) { // Always compare critical if (level === UncertaintyLevel.CRITICAL) { return true; } // High threshold for comparison (more expensive) return score >= 0.7; } isOverCostLimit() { const { monthlyLimit, currentUsage } = this.config.costLimitation; return currentUsage >= monthlyLimit; } isNearCostLimit() { const { monthlyLimit, currentUsage, warningThreshold } = this.config.costLimitation; return currentUsage >= monthlyLimit * warningThreshold; } shouldSkipDomain(domain) { if (!domain) return false; return this.config.userPreferences.skipDomains.some((skipDomain) => domain.toLowerCase().includes(skipDomain.toLowerCase())); } isPriorityDomain(domain) { if (!domain) return false; return this.config.userPreferences.priorityDomains.some((priorityDomain) => domain.toLowerCase().includes(priorityDomain.toLowerCase())); } getDecisionReason(shouldVerify, shouldCompare, score, uncertaintyResult) { if (shouldCompare) { return `high_uncertainty_score_${score.toFixed(2)}_level_${uncertaintyResult.level}`; } if (shouldVerify) { return `medium_uncertainty_score_${score.toFixed(2)}_level_${uncertaintyResult.level}`; } return `low_uncertainty_score_${score.toFixed(2)}_level_${uncertaintyResult.level}`; } calculateCostImpact(shouldVerify, shouldCompare) { if (shouldCompare) { return 'high'; // Multiple API calls } if (shouldVerify) { return 'medium'; // One additional API call } return 'low'; // No additional calls } calculateConfidence(score, uncertaintyResult) { // Higher confidence for extreme scores (very high or very low) const extremeScore = Math.abs(score - 0.5) * 2; // 0-1 range // Base confidence from uncertainty level clarity let baseConfidence = 0.5; if (uncertaintyResult.level === UncertaintyLevel.CRITICAL || uncertaintyResult.level === UncertaintyLevel.LOW) { baseConfidence = 0.8; // Clear cases } return Math.min(baseConfidence + extremeScore * 0.2, 1.0); } // Utility methods for external usage tracking incrementUsage() { this.config.costLimitation.currentUsage += 1; } getRemainingCalls() { return Math.max(0, this.config.costLimitation.monthlyLimit - this.config.costLimitation.currentUsage); } getCostStatus() { const { monthlyLimit, currentUsage, warningThreshold } = this.config.costLimitation; const percentage = currentUsage / monthlyLimit; let status; if (percentage >= 1.0) { status = 'exceeded'; } else if (percentage >= warningThreshold) { status = 'critical'; } else if (percentage >= 0.7) { status = 'warning'; } else { status = 'safe'; } return { usage: currentUsage, limit: monthlyLimit, percentage, status, }; } } // Default configuration factory export function createDefaultAutoTriggerConfig() { return { uncertaintyThresholds: { verify: UncertaintyLevel.MEDIUM, compare: UncertaintyLevel.HIGH, }, queryLengthFactors: { shortQuery: 10, // words longQuery: 50, // words complexityMultiplier: 1.2, }, costLimitation: { monthlyLimit: 1000, // API calls per month currentUsage: 0, warningThreshold: 0.8, // 80% }, userPreferences: { aggressiveness: 'balanced', priorityDomains: ['security', 'production', 'critical', 'financial'], skipDomains: ['tutorial', 'example', 'demo'], enableCostAwareMode: true, }, }; } //# sourceMappingURL=auto-trigger.js.map