Skip to main content
Glama
decision-framework.ts8.89 kB
/** * Decision Framework Operation * * Implements structured decision-making frameworks for complex choices */ import { BaseOperation, type OperationContext, type OperationResult } from '../base.js'; export class DecisionFrameworkOperation extends BaseOperation { name = 'decision_framework'; category = 'collaborative'; async execute(context: OperationContext): Promise<OperationResult> { const { sessionState, prompt, parameters } = context; // Extract decision framework parameters const framework = this.getParam(parameters, 'framework', 'pros_cons'); const alternatives = (parameters.alternatives as string[]) || []; const criteria = (parameters.criteria as any[]) || []; const weights = (parameters.weights as Record<string, number>) || {}; const stakeholders = (parameters.stakeholders as string[]) || []; // Generate alternatives if not provided const generatedAlternatives = alternatives.length === 0 ? this.generateAlternatives(prompt) : alternatives; // Generate criteria if not provided const generatedCriteria = criteria.length === 0 ? this.generateCriteria(framework) : criteria; // Apply the selected framework const analysis = this.applyFramework( framework, generatedAlternatives, generatedCriteria, weights, stakeholders ); const decisionData = { decision: prompt, framework, alternatives: generatedAlternatives, criteria: generatedCriteria, weights, stakeholders, analysis, recommendation: this.generateRecommendation(analysis), confidence: this.calculateConfidence(analysis), sessionId: `decision-${Date.now()}`, timestamp: new Date().toISOString(), }; // Update session metrics sessionState.updateKPI('decision_alternatives', generatedAlternatives.length); sessionState.updateKPI('decision_criteria', generatedCriteria.length); return this.createResult({ ...decisionData, sessionContext: { sessionId: sessionState.sessionId, stats: sessionState.getStats(), }, }); } private generateAlternatives(decision: string): string[] { // Simple pattern-based alternative generation if (decision.toLowerCase().includes('buy') || decision.toLowerCase().includes('purchase')) { return ['Buy new', 'Buy used', 'Lease', 'Don\'t buy']; } if (decision.toLowerCase().includes('hire') || decision.toLowerCase().includes('team')) { return ['Hire full-time', 'Hire contractor', 'Upskill existing team', 'Outsource']; } if (decision.toLowerCase().includes('technology') || decision.toLowerCase().includes('software')) { return ['Build in-house', 'Buy commercial solution', 'Use open source', 'Hybrid approach']; } return ['Option A', 'Option B', 'Option C', 'Status quo']; } private generateCriteria(framework: string): any[] { const baseMetrics = { pros_cons: ['Benefits', 'Drawbacks', 'Feasibility'], cost_benefit: ['Initial cost', 'Ongoing cost', 'Expected benefits', 'ROI timeline'], risk_assessment: ['Probability', 'Impact', 'Mitigation cost', 'Risk tolerance'], stakeholder: ['User impact', 'Team impact', 'Business impact', 'Regulatory impact'], time_sensitivity: ['Urgency', 'Implementation time', 'Opportunity cost', 'Deadline pressure'], }; const criteriaNames = baseMetrics[framework as keyof typeof baseMetrics] || baseMetrics.pros_cons; return criteriaNames.map((name, index) => ({ name, weight: 1.0 / criteriaNames.length, type: 'numeric', scale: '1-10', description: `${name} evaluation criterion`, })); } private applyFramework( framework: string, alternatives: string[], criteria: any[], weights: Record<string, number>, stakeholders: string[] ): any { switch (framework) { case 'pros_cons': return this.applyProsConsFramework(alternatives, criteria); case 'cost_benefit': return this.applyCostBenefitFramework(alternatives, criteria); case 'risk_assessment': return this.applyRiskAssessmentFramework(alternatives, criteria); case 'stakeholder': return this.applyStakeholderFramework(alternatives, criteria, stakeholders); default: return this.applyGenericFramework(alternatives, criteria, weights); } } private applyProsConsFramework(alternatives: string[], criteria: any[]): any { return { type: 'pros_cons', evaluations: alternatives.map(alt => ({ alternative: alt, pros: [`Pro 1 for ${alt}`, `Pro 2 for ${alt}`], cons: [`Con 1 for ${alt}`, `Con 2 for ${alt}`], score: Math.random() * 4 + 6, // 6-10 range })), }; } private applyCostBenefitFramework(alternatives: string[], criteria: any[]): any { return { type: 'cost_benefit', evaluations: alternatives.map(alt => ({ alternative: alt, costs: { initial: Math.floor(Math.random() * 50000 + 10000), ongoing: Math.floor(Math.random() * 10000 + 1000), }, benefits: { monetary: Math.floor(Math.random() * 80000 + 20000), strategic: Math.random() * 5 + 5, // 5-10 scale }, roi: Math.random() * 200 + 50, // 50-250% })), }; } private applyRiskAssessmentFramework(alternatives: string[], criteria: any[]): any { return { type: 'risk_assessment', evaluations: alternatives.map(alt => ({ alternative: alt, risks: [{ description: `Primary risk for ${alt}`, probability: Math.random() * 0.5 + 0.1, // 0.1-0.6 impact: Math.random() * 5 + 3, // 3-8 scale mitigation: `Mitigation strategy for ${alt}`, }], overallRisk: Math.random() * 4 + 2, // 2-6 scale })), }; } private applyStakeholderFramework(alternatives: string[], criteria: any[], stakeholders: string[]): any { return { type: 'stakeholder', evaluations: alternatives.map(alt => ({ alternative: alt, stakeholderImpact: stakeholders.map(stakeholder => ({ stakeholder, impact: Math.random() * 4 + 3, // 3-7 scale sentiment: ['positive', 'neutral', 'negative'][Math.floor(Math.random() * 3)], })), overallSupport: Math.random() * 4 + 4, // 4-8 scale })), }; } private applyGenericFramework(alternatives: string[], criteria: any[], weights: Record<string, number>): any { return { type: 'weighted_scoring', evaluations: alternatives.map(alt => ({ alternative: alt, scores: criteria.map(criterion => ({ criterion: criterion.name, score: Math.random() * 4 + 6, // 6-10 range weight: weights[criterion.name] || criterion.weight, })), weightedTotal: Math.random() * 3 + 7, // 7-10 range })), }; } private generateRecommendation(analysis: any): any { const evaluations = analysis.evaluations || []; if (evaluations.length === 0) { return { recommended: 'No alternatives to evaluate', reasoning: 'No alternatives provided for evaluation', confidence: 0, }; } // Simple scoring based on analysis type let bestAlternative = evaluations[0]; let bestScore = 0; evaluations.forEach((evaluation: any) => { let score = 0; if (evaluation.score) score = evaluation.score; else if (evaluation.roi) score = evaluation.roi / 50; // Normalize ROI else if (evaluation.overallSupport) score = evaluation.overallSupport; else if (evaluation.weightedTotal) score = evaluation.weightedTotal; if (score > bestScore) { bestScore = score; bestAlternative = evaluation; } }); return { recommended: bestAlternative.alternative, reasoning: `Highest scoring alternative based on ${analysis.type} framework`, confidence: Math.min(bestScore / 10, 1.0), score: bestScore, }; } private calculateConfidence(analysis: any): number { const evaluations = analysis.evaluations || []; if (evaluations.length === 0) return 0; // Calculate variance in scores to determine confidence const scores = evaluations.map((e: any) => e.score || e.roi || e.overallSupport || e.weightedTotal || 5 ); const mean = scores.reduce((sum: number, score: number) => sum + score, 0) / scores.length; const variance = scores.reduce((sum: number, score: number) => sum + Math.pow(score - mean, 2), 0) / scores.length; // Higher variance = lower confidence return Math.max(0.3, 1 - (variance / 10)); } } export default new DecisionFrameworkOperation();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/waldzellai/clearthought-onepointfive'

If you have feedback or need assistance with the MCP directory API, please join our Discord server