UNPKG

mcp-workflow-server-enhanced

Version:

Enhanced MCP Workflow Server with smart problem routing, comprehensive validation, guide compliance, and robust error handling. Intelligently routes to appropriate AI functions based on problem type.

167 lines (144 loc) 3.83 kB
import { randomUUID } from 'crypto'; import { WorkflowContext, WorkflowError } from './types.js'; /** * Generate a unique session ID for workflow tracking */ export function generateSessionId(): string { return randomUUID(); } /** * Create a new workflow context */ export function createWorkflowContext( originalPrompt: string, currentStep: WorkflowContext['currentStep'] ): WorkflowContext { return { sessionId: generateSessionId(), originalPrompt, currentStep, stepResults: {}, metadata: {}, timestamp: new Date().toISOString(), }; } /** * Update workflow context with step results */ export function updateWorkflowContext( context: WorkflowContext, step: string, result: any, nextStep?: WorkflowContext['currentStep'] ): WorkflowContext { return { ...context, currentStep: nextStep || context.currentStep, stepResults: { ...context.stepResults, [step]: result, }, timestamp: new Date().toISOString(), }; } /** * Validate and sanitize user input */ export function sanitizeInput(input: string): string { return input.trim().replace(/[<>]/g, ''); } /** * Format error messages for user display */ export function formatError(error: Error): string { if (error instanceof WorkflowError) { return `Error in ${error.step}: ${error.message}`; } return `Error: ${error.message}`; } /** * Deep clone an object */ export function deepClone<T>(obj: T): T { return JSON.parse(JSON.stringify(obj)); } /** * Retry a function with exponential backoff */ export async function retryWithBackoff<T>( fn: () => Promise<T>, maxRetries: number = 3, baseDelay: number = 1000 ): Promise<T> { let lastError: Error; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (error) { lastError = error as Error; if (attempt === maxRetries) { throw lastError; } const delay = baseDelay * Math.pow(2, attempt); await new Promise(resolve => setTimeout(resolve, delay)); } } throw lastError!; } /** * Validate that required environment variables are set */ export function validateEnvironment(requiredVars: string[]): void { const missing = requiredVars.filter(varName => !process.env[varName]); if (missing.length > 0) { throw new Error(`Missing required environment variables: ${missing.join(', ')}`); } } /** * Create a standardized response format */ export function createResponse(success: boolean, data: any, message?: string) { return { success, data, message, timestamp: new Date().toISOString(), }; } /** * Log workflow progress */ export function logWorkflowProgress( context: WorkflowContext, step: string, message: string ): void { console.log(`[${context.sessionId}] ${step}: ${message}`); } /** * Extract key information from text using simple patterns */ export function extractKeyInfo(text: string): { requirements: string[]; constraints: string[]; goals: string[]; } { const requirements: string[] = []; const constraints: string[] = []; const goals: string[] = []; // Simple pattern matching for common requirement indicators const lines = text.split('\n'); for (const line of lines) { const trimmed = line.trim().toLowerCase(); if (trimmed.includes('need') || trimmed.includes('require') || trimmed.includes('must')) { requirements.push(line.trim()); } if (trimmed.includes('cannot') || trimmed.includes('should not') || trimmed.includes('constraint')) { constraints.push(line.trim()); } if (trimmed.includes('goal') || trimmed.includes('objective') || trimmed.includes('want to')) { goals.push(line.trim()); } } return { requirements, constraints, goals }; }