UNPKG

blax

Version:

Blax - HMS-Powered Multi-Agent Platform with Government Agency Analysis, Deep Research, and Enterprise-Ready Deployment. No local LLM keys required.

521 lines 22.2 kB
import { EventEmitter } from 'events'; /** * Deal Evaluator for agent decision-making * Implements value delta calculation and metrics assessment */ export class DealEvaluator extends EventEmitter { dealRegistry; config; evaluationCache = new Map(); constructor(dealRegistry, config) { super(); this.dealRegistry = dealRegistry; this.config = { riskAversion: config?.riskAversion ?? 0.3, timeDiscountRate: config?.timeDiscountRate ?? 0.05, qualityWeight: config?.qualityWeight ?? 0.4, complianceWeight: config?.complianceWeight ?? 0.3, stakeholderSatisfactionWeight: config?.stakeholderSatisfactionWeight ?? 0.3, ...config }; } /** * Evaluate an action's impact on a deal * Returns YES/NO recommendation based on value delta */ async evaluateDeal(dealId, actionContext) { const startTime = Date.now(); try { const deal = await this.dealRegistry.getDeal(dealId); if (!deal) { throw new Error(`Deal ${dealId} not found`); } // Calculate current expected value const expectedValueBefore = this.calculateExpectedValue(deal); // Simulate action impact const expectedValueAfter = await this.simulateActionImpact(deal, actionContext); const valueDelta = expectedValueAfter - expectedValueBefore; // Assess metrics impact const metricsImpact = this.assessMetricsImpact(deal, actionContext); // Calculate risk score const riskAssessment = this.assessRisk(deal, actionContext); // Evaluate compliance impact const complianceImpact = this.evaluateComplianceImpact(deal, actionContext); // Generate recommendation const recommendation = this.generateRecommendation(valueDelta, riskAssessment.riskScore, metricsImpact, complianceImpact); const evaluation = { dealId, actionId: actionContext.actionId, agentId: actionContext.agentId, expectedValueBefore, expectedValueAfter, valueDelta, valueConfidence: this.calculateValueConfidence(deal, actionContext), metricsImpact, riskScore: riskAssessment.riskScore, riskFactors: riskAssessment.riskFactors, complianceImpact, recommendation: recommendation.decision, confidence: recommendation.confidence, reasoning: recommendation.reasoning, suggestedModifications: recommendation.modifications, evaluatedAt: new Date(), evaluationDuration: Date.now() - startTime, evaluationMethod: 'value_delta_analysis', dataSourcesUsed: ['deal_metrics', 'risk_model', 'compliance_rules'], assumptionsMade: this.getAssumptions(deal, actionContext) }; // Cache the evaluation this.evaluationCache.set(`${dealId}_${actionContext.actionId}`, evaluation); this.emit('dealEvaluated', evaluation); return evaluation; } catch (error) { this.emit('evaluationError', { dealId, actionContext, error }); throw error; } } /** * Calculate the current expected value of a deal */ calculateExpectedValue(deal) { let baseValue = deal.financing.totalBudget; // Adjust for progress const progressMultiplier = 1 + (deal.progress * 0.2); // 20% bonus for progress baseValue *= progressMultiplier; // Adjust for quality metrics const qualityScore = this.calculateQualityScore(deal); const qualityAdjustment = (qualityScore - 0.5) * this.config.qualityWeight; baseValue *= (1 + qualityAdjustment); // Adjust for compliance const complianceScore = this.calculateComplianceScore(deal); const complianceAdjustment = (complianceScore - 0.5) * this.config.complianceWeight; baseValue *= (1 + complianceAdjustment); // Adjust for stakeholder satisfaction const stakeholderScore = this.calculateStakeholderSatisfaction(deal); const stakeholderAdjustment = (stakeholderScore - 0.5) * this.config.stakeholderSatisfactionWeight; baseValue *= (1 + stakeholderAdjustment); // Apply risk discount const riskScore = this.calculateRiskScore(deal); const riskDiscount = riskScore * this.config.riskAversion; baseValue *= (1 - riskDiscount); // Apply time discount if deadline is set if (deal.deadline) { const timeToDeadline = (deal.deadline.getTime() - Date.now()) / (1000 * 60 * 60 * 24 * 365); const timeDiscount = Math.pow(1 + this.config.timeDiscountRate, timeToDeadline); baseValue /= timeDiscount; } return Math.max(0, baseValue); } /** * Simulate the impact of an action on deal value */ async simulateActionImpact(deal, actionContext) { // Create a simulation copy of the deal const simulatedDeal = { ...deal }; // Apply action effects simulatedDeal.progress = Math.min(1.0, simulatedDeal.progress + (actionContext.estimatedDuration / 100)); // Adjust metrics based on action type const metricsAdjustment = this.simulateMetricsImpact(deal, actionContext); // Adjust for action-specific risks const actionRiskAdjustment = actionContext.riskLevel * 0.1; // 10% max negative impact // Calculate new expected value const baseValue = this.calculateExpectedValue(simulatedDeal); const adjustedValue = baseValue * (1 + metricsAdjustment - actionRiskAdjustment); return Math.max(0, adjustedValue); } /** * Assess the impact of an action on deal metrics */ assessMetricsImpact(deal, actionContext) { return deal.metrics.map(metric => { const impact = this.calculateMetricImpact(metric, actionContext); return { metricId: metric.metricId, currentValue: metric.currentValue, projectedValue: metric.currentValue + impact.deltaValue, improvement: impact.deltaValue, attainabilityChange: impact.attainabilityChange }; }); } /** * Calculate the impact of an action on a specific metric */ calculateMetricImpact(metric, actionContext) { let deltaValue = 0; let attainabilityChange = 0; // Base impact based on action type and metric type const typeCompatibility = this.getActionMetricCompatibility(actionContext.actionType, metric.type); deltaValue = typeCompatibility * actionContext.confidence * 10; // Scaled impact // Adjust for resource investment const resourceFactor = Math.min(1.0, actionContext.resourceCost / 1000); // Normalize deltaValue *= (1 + resourceFactor * 0.5); // Adjust for risk deltaValue *= (1 - actionContext.riskLevel * 0.3); // Calculate attainability change if (!metric.attainable && deltaValue > 0) { attainabilityChange = 0.2; // Positive action might make unattainable metrics achievable } return { deltaValue, attainabilityChange }; } /** * Assess risk factors for the action */ assessRisk(deal, actionContext) { const riskFactors = []; // Base action risk riskFactors.push({ factor: 'Action inherent risk', probability: actionContext.riskLevel, impact: 0.3, mitigation: 'Proper testing and validation' }); // Complexity risk if (actionContext.dependencies.length > 3) { riskFactors.push({ factor: 'High dependency complexity', probability: 0.4, impact: 0.5, mitigation: 'Dependency mapping and contingency planning' }); } // Resource risk const resourceRisk = Math.min(1.0, actionContext.resourceCost / deal.financing.totalBudget); if (resourceRisk > 0.2) { riskFactors.push({ factor: 'High resource consumption', probability: resourceRisk, impact: 0.4, mitigation: 'Budget monitoring and resource optimization' }); } // Timeline risk if (deal.deadline) { const timeRemaining = (deal.deadline.getTime() - Date.now()) / (1000 * 60 * 60); const timeRisk = Math.max(0, (actionContext.estimatedDuration - timeRemaining) / timeRemaining); if (timeRisk > 0.1) { riskFactors.push({ factor: 'Timeline pressure', probability: Math.min(1.0, timeRisk), impact: 0.6, mitigation: 'Scope adjustment or deadline extension' }); } } // Calculate overall risk score const riskScore = riskFactors.reduce((total, risk) => { return total + (risk.probability * risk.impact); }, 0) / riskFactors.length; return { riskScore: Math.min(1.0, riskScore), riskFactors }; } /** * Evaluate compliance impact */ evaluateComplianceImpact(deal, actionContext) { const impact = {}; for (const standard of deal.requiredStandards) { if (actionContext.standards.includes(standard)) { impact[standard] = 'positive'; } else if (this.hasComplianceRisk(standard, actionContext)) { impact[standard] = 'negative'; } else { impact[standard] = 'neutral'; } } return impact; } /** * Generate recommendation based on analysis */ generateRecommendation(valueDelta, riskScore, metricsImpact, complianceImpact) { const modifications = []; let reasoning = ''; // Primary decision based on value delta const primaryDecision = valueDelta > 0 ? 'approve' : 'reject'; // Check for red flags const hasNegativeCompliance = Object.values(complianceImpact).includes('negative'); const highRisk = riskScore > 0.7; const negativeMetrics = metricsImpact.filter(m => m.improvement < 0).length > metricsImpact.length / 2; // Decision logic if (hasNegativeCompliance) { reasoning += 'Negative compliance impact detected. '; modifications.push('Address compliance concerns before proceeding'); if (valueDelta > 100) { // High value might justify some compliance risks return { decision: 'modify', confidence: 0.6, reasoning: reasoning + 'High value potential but requires compliance modifications.', modifications }; } else { return { decision: 'reject', confidence: 0.8, reasoning: reasoning + 'Compliance risks outweigh value benefits.', modifications }; } } if (highRisk) { reasoning += `High risk score (${(riskScore * 100).toFixed(1)}%). `; modifications.push('Implement additional risk mitigation measures'); if (valueDelta > 200) { // Very high value might justify high risk return { decision: 'modify', confidence: 0.7, reasoning: reasoning + 'High value potential justifies modified approach with risk mitigation.', modifications }; } else if (valueDelta > 0) { return { decision: 'escalate', confidence: 0.6, reasoning: reasoning + 'Risk-value tradeoff requires human judgment.', modifications }; } else { return { decision: 'reject', confidence: 0.9, reasoning: reasoning + 'High risk with negative value delta.', modifications }; } } if (negativeMetrics) { reasoning += 'Majority of metrics show negative impact. '; modifications.push('Review and optimize metrics impact'); if (valueDelta > 50) { return { decision: 'modify', confidence: 0.6, reasoning: reasoning + 'Value positive but metrics need optimization.', modifications }; } } // Standard decisions if (valueDelta > 100) { return { decision: 'approve', confidence: 0.9, reasoning: `Strong positive value delta (${valueDelta.toFixed(2)}). Low risk and positive metrics impact.`, modifications }; } else if (valueDelta > 0) { return { decision: 'approve', confidence: 0.7, reasoning: `Positive value delta (${valueDelta.toFixed(2)}). Acceptable risk level.`, modifications }; } else if (valueDelta > -50) { return { decision: 'escalate', confidence: 0.5, reasoning: `Small negative value delta (${valueDelta.toFixed(2)}). Requires human judgment for intangible benefits.`, modifications }; } else { return { decision: 'reject', confidence: 0.8, reasoning: `Significant negative value delta (${valueDelta.toFixed(2)}).`, modifications }; } } // Helper methods calculateQualityScore(deal) { const qualityMetrics = deal.metrics.filter(m => m.type === 'quality'); if (qualityMetrics.length === 0) return 0.5; const avgQuality = qualityMetrics.reduce((sum, m) => sum + (m.currentValue / m.targetValue), 0) / qualityMetrics.length; return Math.min(1.0, Math.max(0.0, avgQuality)); } calculateComplianceScore(deal) { if (deal.requiredStandards.length === 0) return 1.0; const compliantCount = Object.values(deal.complianceStatus).filter(s => s === 'compliant').length; return compliantCount / deal.requiredStandards.length; } calculateStakeholderSatisfaction(deal) { // In a full implementation, this would aggregate actual stakeholder feedback // For now, return a default value based on progress return 0.5 + (deal.progress * 0.3); } calculateRiskScore(deal) { if (deal.proposedSolutions.length === 0) return 0.5; let totalRisk = 0; let riskCount = 0; for (const solution of deal.proposedSolutions) { for (const risk of solution.risks) { totalRisk += risk.probability * risk.impact; riskCount++; } } return riskCount > 0 ? totalRisk / riskCount : 0.2; } calculateValueConfidence(deal, actionContext) { let confidence = actionContext.confidence; // Reduce confidence for complex deals if (deal.proposedSolutions.length > 3) { confidence *= 0.9; } // Reduce confidence for high-risk actions confidence *= (1 - actionContext.riskLevel * 0.3); // Increase confidence for well-defined metrics const measurableMetrics = deal.metrics.filter(m => m.measurable).length; if (measurableMetrics > 0) { confidence *= (1 + (measurableMetrics / deal.metrics.length) * 0.2); } return Math.min(1.0, Math.max(0.1, confidence)); } simulateMetricsImpact(deal, actionContext) { if (deal.metrics.length === 0) return 0; const totalImpact = deal.metrics.reduce((sum, metric) => { const impact = this.calculateMetricImpact(metric, actionContext); return sum + (impact.deltaValue / metric.targetValue); }, 0); return totalImpact / deal.metrics.length; } getActionMetricCompatibility(actionType, metricType) { // Define compatibility matrix const compatibility = { 'implementation': { 'operational': 0.8, 'quality': 0.6, 'financial': 0.3, 'time': 0.7, 'compliance': 0.4 }, 'testing': { 'quality': 0.9, 'compliance': 0.7, 'operational': 0.5, 'financial': 0.2, 'time': -0.2 }, 'optimization': { 'operational': 0.9, 'financial': 0.6, 'quality': 0.5, 'time': 0.4, 'compliance': 0.3 }, 'documentation': { 'compliance': 0.8, 'quality': 0.4, 'operational': 0.3, 'financial': 0.1, 'time': -0.1 }, 'deployment': { 'operational': 0.7, 'time': 0.8, 'financial': 0.4, 'quality': 0.2, 'compliance': 0.5 } }; return compatibility[actionType]?.[metricType] ?? 0.5; } hasComplianceRisk(standard, actionContext) { // In a full implementation, this would check specific compliance rules // For now, return true if action doesn't explicitly support the standard return !actionContext.standards.includes(standard) && actionContext.riskLevel > 0.5; } getAssumptions(deal, actionContext) { const assumptions = [ 'Linear relationship between effort and progress', 'Stakeholder requirements remain stable', 'No external market changes during execution' ]; if (deal.deadline) { assumptions.push('Deadline is fixed and non-negotiable'); } if (actionContext.dependencies.length > 0) { assumptions.push('All dependencies will be resolved as planned'); } return assumptions; } /** * Generate financial provenance for audit trail */ async generateFinancialProvenance(dealId, actionContext) { const deal = await this.dealRegistry.getDeal(dealId); if (!deal) { throw new Error(`Deal ${dealId} not found`); } const traceId = `trace_${dealId}_${actionContext.actionId}_${Date.now()}`; return { dealId, actionId: actionContext.actionId, traceId, costBreakdown: { directCosts: actionContext.resourceCost, indirectCosts: actionContext.resourceCost * 0.2, opportunityCosts: this.calculateOpportunityCost(deal, actionContext), riskCosts: actionContext.riskLevel * actionContext.resourceCost * 0.1 }, valueChain: this.generateValueChain(deal, actionContext), calculations: [ { formula: 'expectedValue = baseValue * progressMultiplier * qualityAdjustment * complianceAdjustment', inputs: { baseValue: deal.financing.totalBudget, progressMultiplier: 1 + (deal.progress * 0.2), qualityAdjustment: this.calculateQualityScore(deal), complianceAdjustment: this.calculateComplianceScore(deal) }, output: this.calculateExpectedValue(deal), timestamp: new Date() } ], validationRules: [ 'Value delta must be calculated consistently', 'Risk assessment must include all identified factors', 'Compliance impact must be evaluated for all required standards' ], validationResults: [ { rule: 'Value delta calculation', passed: true }, { rule: 'Risk factor completeness', passed: true }, { rule: 'Compliance coverage', passed: true } ] }; } calculateOpportunityCost(deal, actionContext) { // Simplified opportunity cost calculation const timeValue = (actionContext.estimatedDuration / 40) * 1000; // $1000 per week const resourceOpportunity = actionContext.resourceCost * 0.1; // 10% opportunity cost return timeValue + resourceOpportunity; } generateValueChain(deal, actionContext) { return [ { step: 'Action execution', valueContribution: actionContext.resourceCost * 1.5, confidence: actionContext.confidence, dependencies: actionContext.dependencies }, { step: 'Metrics improvement', valueContribution: deal.metrics.length * 100, confidence: 0.7, dependencies: ['successful_execution'] }, { step: 'Stakeholder satisfaction', valueContribution: deal.stakeholders.length * 50, confidence: 0.6, dependencies: ['metrics_improvement'] } ]; } /** * Get cached evaluation */ getCachedEvaluation(dealId, actionId) { return this.evaluationCache.get(`${dealId}_${actionId}`) || null; } /** * Clear evaluation cache */ clearCache() { this.evaluationCache.clear(); } /** * Health check */ async healthCheck() { return { status: 'healthy', details: { cacheSize: this.evaluationCache.size, config: this.config } }; } } //# sourceMappingURL=dealEvaluator.js.map