UNPKG

thoughtmcp

Version:

AI that thinks more like humans do - MCP server with human-like cognitive architecture for enhanced reasoning, memory, and self-monitoring

236 lines 9.12 kB
/** * Performance monitoring and metrics collection for cognitive architecture */ export class PerformanceMonitor { metrics = []; alerts = []; thresholds; maxMetricsHistory = 1000; maxAlertsHistory = 100; constructor(thresholds) { this.thresholds = { responseTimeWarning: 1000, // 1 second responseTimeCritical: 5000, // 5 seconds memoryUsageWarning: 500 * 1024 * 1024, // 500MB memoryUsageCritical: 1024 * 1024 * 1024, // 1GB confidenceThreshold: 0.3, ...thresholds, }; } /** * Start performance measurement for a request */ startMeasurement(requestId, toolName) { return new PerformanceMeasurement(requestId, toolName, this); } /** * Record performance metrics */ recordMetrics(metrics) { this.metrics.push(metrics); // Maintain history limit if (this.metrics.length > this.maxMetricsHistory) { this.metrics.shift(); } // Check for alerts this.checkThresholds(metrics); } /** * Get current memory usage */ getMemoryUsage() { const memUsage = process.memoryUsage(); return { heapUsed: memUsage.heapUsed, heapTotal: memUsage.heapTotal, external: memUsage.external, rss: memUsage.rss, }; } /** * Get performance statistics */ getStatistics(timeWindow) { const now = Date.now(); const windowStart = timeWindow ? now - timeWindow : 0; const relevantMetrics = this.metrics.filter((m) => m.timestamp >= windowStart); if (relevantMetrics.length === 0) { return this.getEmptyStatistics(); } const responseTimes = relevantMetrics.map((m) => m.responseTime); const memoryUsages = relevantMetrics.map((m) => m.memoryUsage.heapUsed); const confidenceScores = relevantMetrics.map((m) => m.cognitiveMetrics.confidenceScore); return { totalRequests: relevantMetrics.length, averageResponseTime: this.calculateAverage(responseTimes), medianResponseTime: this.calculateMedian(responseTimes), p95ResponseTime: this.calculatePercentile(responseTimes, 95), p99ResponseTime: this.calculatePercentile(responseTimes, 99), averageMemoryUsage: this.calculateAverage(memoryUsages), peakMemoryUsage: Math.max(...memoryUsages), averageConfidence: this.calculateAverage(confidenceScores), lowConfidenceRequests: confidenceScores.filter((c) => c < this.thresholds.confidenceThreshold).length, toolUsageStats: this.calculateToolUsageStats(relevantMetrics), timeWindow: timeWindow || now - relevantMetrics[0].timestamp, }; } /** * Get recent alerts */ getAlerts(limit = 10) { return this.alerts.slice(-limit); } /** * Clear metrics history */ clearMetrics() { this.metrics = []; this.alerts = []; } /** * Export metrics for external monitoring systems */ exportMetrics() { return [...this.metrics]; } checkThresholds(metrics) { // Check response time thresholds if (metrics.responseTime > this.thresholds.responseTimeCritical) { this.addAlert("critical", "responseTime", metrics.responseTime, this.thresholds.responseTimeCritical, `Critical response time: ${metrics.responseTime}ms for ${metrics.toolName}`); } else if (metrics.responseTime > this.thresholds.responseTimeWarning) { this.addAlert("warning", "responseTime", metrics.responseTime, this.thresholds.responseTimeWarning, `High response time: ${metrics.responseTime}ms for ${metrics.toolName}`); } // Check memory usage thresholds if (metrics.memoryUsage.heapUsed > this.thresholds.memoryUsageCritical) { this.addAlert("critical", "memoryUsage", metrics.memoryUsage.heapUsed, this.thresholds.memoryUsageCritical, `Critical memory usage: ${Math.round(metrics.memoryUsage.heapUsed / 1024 / 1024)}MB`); } else if (metrics.memoryUsage.heapUsed > this.thresholds.memoryUsageWarning) { this.addAlert("warning", "memoryUsage", metrics.memoryUsage.heapUsed, this.thresholds.memoryUsageWarning, `High memory usage: ${Math.round(metrics.memoryUsage.heapUsed / 1024 / 1024)}MB`); } // Check confidence threshold if (metrics.cognitiveMetrics.confidenceScore < this.thresholds.confidenceThreshold) { this.addAlert("warning", "confidence", metrics.cognitiveMetrics.confidenceScore, this.thresholds.confidenceThreshold, `Low confidence score: ${metrics.cognitiveMetrics.confidenceScore.toFixed(2)} for ${metrics.toolName}`); } } addAlert(type, metric, value, threshold, message) { this.alerts.push({ type, metric, value, threshold, timestamp: Date.now(), message, }); // Maintain alerts history limit if (this.alerts.length > this.maxAlertsHistory) { this.alerts.shift(); } // Log alert console.warn(`[PerformanceAlert] ${type.toUpperCase()}: ${message}`); } calculateAverage(values) { return values.reduce((sum, val) => sum + val, 0) / values.length; } calculateMedian(values) { const sorted = [...values].sort((a, b) => a - b); const mid = Math.floor(sorted.length / 2); return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid]; } calculatePercentile(values, percentile) { const sorted = [...values].sort((a, b) => a - b); const index = Math.ceil((percentile / 100) * sorted.length) - 1; return sorted[Math.max(0, index)]; } calculateToolUsageStats(metrics) { const toolStats = {}; metrics.forEach((metric) => { if (!toolStats[metric.toolName]) { toolStats[metric.toolName] = { count: 0, totalResponseTime: 0, averageResponseTime: 0, averageConfidence: 0, totalConfidence: 0, }; } const stats = toolStats[metric.toolName]; stats.count++; stats.totalResponseTime += metric.responseTime; stats.totalConfidence += metric.cognitiveMetrics.confidenceScore; stats.averageResponseTime = stats.totalResponseTime / stats.count; stats.averageConfidence = stats.totalConfidence / stats.count; }); return toolStats; } getEmptyStatistics() { return { totalRequests: 0, averageResponseTime: 0, medianResponseTime: 0, p95ResponseTime: 0, p99ResponseTime: 0, averageMemoryUsage: 0, peakMemoryUsage: 0, averageConfidence: 0, lowConfidenceRequests: 0, toolUsageStats: {}, timeWindow: 0, }; } } /** * Helper class for measuring performance of individual requests */ export class PerformanceMeasurement { requestId; toolName; monitor; startTime; // Memory usage tracking for future use // private _startMemory: MemoryUsage; cognitiveMetrics = {}; constructor(requestId, toolName, monitor) { this.requestId = requestId; this.toolName = toolName; this.monitor = monitor; this.startTime = Date.now(); // this._startMemory = monitor.getMemoryUsage(); } /** * Record cognitive metrics during processing */ recordCognitiveMetrics(metrics) { this.cognitiveMetrics = { ...this.cognitiveMetrics, ...metrics }; } /** * Complete the measurement and record metrics */ complete() { const endTime = Date.now(); const endMemory = this.monitor.getMemoryUsage(); const metrics = { responseTime: endTime - this.startTime, memoryUsage: endMemory, cognitiveMetrics: { confidenceScore: this.cognitiveMetrics.confidenceScore || 0, reasoningDepth: this.cognitiveMetrics.reasoningDepth || 0, memoryRetrievals: this.cognitiveMetrics.memoryRetrievals || 0, emotionalProcessingTime: this.cognitiveMetrics.emotionalProcessingTime, metacognitionTime: this.cognitiveMetrics.metacognitionTime, workingMemoryLoad: this.cognitiveMetrics.workingMemoryLoad || 0, }, timestamp: endTime, requestId: this.requestId, toolName: this.toolName, }; this.monitor.recordMetrics(metrics); return metrics; } } // Singleton instance for global access export const performanceMonitor = new PerformanceMonitor(); //# sourceMappingURL=PerformanceMonitor.js.map