UNPKG

strategic-intelligence-mcp

Version:

Strategic Intelligence MCP Server - connecting technical progress to business outcomes with systematic strategic planning

299 lines (297 loc) 12.1 kB
import { TemplateEngine } from '../templates/conversationTemplates.js'; import { ConversationTools } from './conversationTools.js'; export class TemplateTools { storage; templateEngine; conversationTools; constructor(storage) { this.storage = storage; this.templateEngine = new TemplateEngine(); this.conversationTools = new ConversationTools(storage); } async listConversationTemplates() { try { const templates = this.templateEngine.listTemplates(); const templateSummaries = templates.map(template => ({ id: template.id, name: template.name, type: template.type, description: template.description, purpose: template.context.purpose, typicalTriggers: template.context.typicalTriggers, expectedOutcomes: template.context.expectedOutcomes })); return { success: true, data: templateSummaries, message: `Found ${templates.length} strategic conversation templates` }; } catch (error) { return { success: false, error: `Failed to list conversation templates: ${error}` }; } } async getConversationTemplate(args) { try { const template = this.templateEngine.getTemplate(args.templateId); if (!template) { return { success: false, error: `Template with ID ${args.templateId} not found` }; } return { success: true, data: template, message: `Retrieved template: ${template.name}` }; } catch (error) { return { success: false, error: `Failed to get conversation template: ${error}` }; } } async startTemplatedConversation(args) { try { const template = this.templateEngine.getTemplate(args.templateId); if (!template) { return { success: false, error: `Template with ID ${args.templateId} not found` }; } // Start the conversation using the base conversation tools const conversationResult = await this.conversationTools.startStrategySession({ type: template.type, title: args.title, context: args.context, participants: args.participants }); if (!conversationResult.success) { return conversationResult; } const conversation = conversationResult.data; // Generate template structure for this conversation const templateStructure = this.templateEngine.generateTemplateStructure(args.templateId, args.context); // Add template-specific key questions if (templateStructure) { await this.conversationTools.updateConversationSummary({ conversationId: conversation.id, summary: `Strategic conversation started using ${template.name} template. Template Purpose: ${template.context.purpose} Key Areas to Address: ${templateStructure.sections.map(section => `- ${section.title}: ${section.description}`).join('\n')}`, keyQuestions: templateStructure.keyQuestions, status: 'active' }); } return { success: true, data: { conversation, template: { id: template.id, name: template.name, structure: templateStructure } }, message: `Templated conversation started successfully using ${template.name}. Conversation ID: ${conversation.id}` }; } catch (error) { return { success: false, error: `Failed to start templated conversation: ${error}` }; } } async applyTemplateGuidance(args) { try { const template = this.templateEngine.getTemplate(args.templateId); if (!template) { return { success: false, error: `Template with ID ${args.templateId} not found` }; } const section = template.templateStructure.sections[args.sectionIndex]; if (!section) { return { success: false, error: `Section ${args.sectionIndex} not found in template` }; } const guidance = { sectionTitle: section.title, description: section.description, guidingQuestions: section.guidingQuestions, expectedOutputs: section.expectedOutputs, suggestedInsightCategories: template.suggestedInsightCategories }; return { success: true, data: guidance, message: `Template guidance provided for section: ${section.title}` }; } catch (error) { return { success: false, error: `Failed to apply template guidance: ${error}` }; } } async generateConversationReport(args) { try { // Get the conversation const conversationResult = await this.conversationTools.getConversation({ conversationId: args.conversationId }); if (!conversationResult.success) { return conversationResult; } const conversation = conversationResult.data; // Generate structured report const report = { conversation: { title: conversation.title, type: conversation.type, timestamp: conversation.timestamp, status: conversation.status, participants: conversation.participants }, context: conversation.context, summary: conversation.conversationSummary, keyQuestions: conversation.keyQuestions, insights: { total: conversation.insights.length, byCategory: this.groupInsightsByCategory(conversation.insights), highImpact: conversation.insights.filter((i) => i.impact === 'critical' || i.impact === 'high') }, decisions: { total: conversation.decisions.length, byStatus: this.groupDecisionsByStatus(conversation.decisions), pending: conversation.decisions.filter((d) => d.status === 'pending') }, actionItems: { total: conversation.actionItems.length, byStatus: this.groupActionItemsByStatus(conversation.actionItems), byPriority: this.groupActionItemsByPriority(conversation.actionItems), overdue: this.getOverdueActionItems(conversation.actionItems) } }; // Add template analysis if requested if (args.includeTemplate && args.templateId) { const template = this.templateEngine.getTemplate(args.templateId); if (template) { const templateAnalysis = this.analyzeTemplateCompletion(conversation, template); report['templateAnalysis'] = templateAnalysis; } } return { success: true, data: report, message: `Generated comprehensive report for conversation: ${conversation.title}` }; } catch (error) { return { success: false, error: `Failed to generate conversation report: ${error}` }; } } groupInsightsByCategory(insights) { const grouped = {}; insights.forEach((insight) => { grouped[insight.category] = (grouped[insight.category] || 0) + 1; }); return grouped; } groupDecisionsByStatus(decisions) { const grouped = {}; decisions.forEach((decision) => { grouped[decision.status] = (grouped[decision.status] || 0) + 1; }); return grouped; } groupActionItemsByStatus(actionItems) { const grouped = {}; actionItems.forEach(item => { grouped[item.status] = (grouped[item.status] || 0) + 1; }); return grouped; } groupActionItemsByPriority(actionItems) { const grouped = {}; actionItems.forEach(item => { grouped[item.priority] = (grouped[item.priority] || 0) + 1; }); return grouped; } getOverdueActionItems(actionItems) { const now = new Date(); return actionItems.filter(item => { const dueDate = new Date(item.dueDate); return dueDate < now && item.status !== 'completed'; }); } analyzeTemplateCompletion(conversation, template) { const sections = template.templateStructure.sections; const insights = conversation.insights; const decisions = conversation.decisions; const completion = { sectionsAddressed: 0, keyQuestionsAnswered: 0, expectedOutputsGenerated: 0, overallCompleteness: 0 }; // Analyze how well the conversation followed the template sections.forEach((section) => { const sectionKeywords = this.extractKeywords(section.title + ' ' + section.description); const relevantInsights = insights.filter((insight) => this.hasKeywordOverlap(insight.content, sectionKeywords)); if (relevantInsights.length > 0) { completion.sectionsAddressed++; } }); // Calculate completion percentages completion.overallCompleteness = Math.round((completion.sectionsAddressed / sections.length) * 100); return { completion, recommendations: this.generateTemplateRecommendations(conversation, template, completion) }; } extractKeywords(text) { return text.toLowerCase() .split(/\s+/) .filter(word => word.length > 3) .filter(word => !['that', 'this', 'with', 'from', 'they', 'have', 'will'].includes(word)); } hasKeywordOverlap(text, keywords) { const textLower = text.toLowerCase(); return keywords.some(keyword => textLower.includes(keyword)); } generateTemplateRecommendations(conversation, template, completion) { const recommendations = []; if (completion.overallCompleteness < 50) { recommendations.push('Consider revisiting template sections that haven\'t been fully addressed'); } if (conversation.decisions.length === 0) { recommendations.push('No strategic decisions have been documented - consider what decisions need to be made'); } if (conversation.actionItems.length === 0) { recommendations.push('No action items have been created - identify concrete next steps'); } const pendingItems = conversation.actionItems.filter((item) => item.status === 'pending'); if (pendingItems.length > 5) { recommendations.push('Large number of pending action items - consider prioritizing or consolidating'); } return recommendations; } } //# sourceMappingURL=templateTools.js.map