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
JavaScript
/**
* 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