Skip to main content
Glama
metacognitive-tools.test.ts41 kB
/** * Metacognitive MCP Tools Tests * * Tests for metacognitive operation MCP tools (assess_confidence, detect_bias, detect_emotion, analyze_reasoning). * Following TDD principles - these tests define expected behavior before implementation. * * Requirements: 7.1, 7.2, 7.3, 8.1, 8.2, 8.3, 9.1, 9.2, 9.3 */ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { CognitiveMCPServer } from "../../../server/mcp-server.js"; // Mock all dependencies vi.mock("../../../memory/memory-repository.js"); vi.mock("../../../reasoning/orchestrator.js"); vi.mock("../../../framework/framework-selector.js"); vi.mock("../../../confidence/multi-dimensional-assessor.js"); vi.mock("../../../bias/bias-pattern-recognizer.js"); vi.mock("../../../emotion/circumplex-analyzer.js"); vi.mock("../../../metacognitive/performance-monitoring-system.js"); vi.mock("../../../database/connection-manager.js"); vi.mock("../../../embeddings/embedding-engine.js"); vi.mock("../../../utils/logger.js", () => ({ Logger: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn(), }, })); describe("Metacognitive MCP Tools", () => { let server: CognitiveMCPServer; let mockConfidenceAssessor: any; let mockBiasDetector: any; let mockEmotionAnalyzer: any; let mockPerformanceMonitor: any; beforeEach(async () => { vi.clearAllMocks(); // Create mock components mockConfidenceAssessor = { assessConfidence: vi.fn(), }; mockBiasDetector = { detectBiases: vi.fn(), detectBiasesFromText: vi.fn(), monitorContinuously: vi.fn(), }; mockEmotionAnalyzer = { analyzeCircumplex: vi.fn(), classifyEmotions: vi.fn(), }; mockPerformanceMonitor = { trackReasoningQuality: vi.fn(), generatePerformanceReport: vi.fn(), }; // Create server (but don't initialize to avoid registering real tools) server = new CognitiveMCPServer(); // Create mock bias corrector const mockBiasCorrector = { getSuggestion: vi.fn().mockReturnValue({ biasType: "confirmation", suggestion: "Actively seek disconfirming evidence", techniques: ["Search for contradicting evidence", "Ask opposing viewpoints"], challengeQuestions: ["What evidence would prove this wrong?"], }), addCorrections: vi.fn(), getConciseSuggestion: vi.fn(), getAllTemplates: vi.fn().mockReturnValue(new Map()), formatCorrection: vi.fn().mockReturnValue("Formatted correction"), }; // Set up mock components directly without initialization server.confidenceAssessor = mockConfidenceAssessor; server.biasDetector = mockBiasDetector; server.biasCorrector = mockBiasCorrector; server.emotionAnalyzer = mockEmotionAnalyzer; server.performanceMonitor = mockPerformanceMonitor; (server as any).databaseManager = { healthCheck: vi.fn().mockResolvedValue(true), }; server.isInitialized = true; // Mark as initialized for executeTool to work // Register the metacognitive tools manually for testing (server as any).registerMetacognitiveTools(); }); afterEach(async () => { // Clear tool registry to prevent "Tool already registered" errors server.toolRegistry.clear(); server.isInitialized = false; vi.clearAllMocks(); }); describe("assess_confidence tool", () => { // Note: Tool is already registered by server.initialize() // No need to register again in beforeEach it("should assess confidence with multi-dimensional analysis", async () => { const mockAssessment = { overallConfidence: 0.85, dimensions: { evidenceQuality: 0.9, reasoningCoherence: 0.85, completeness: 0.8, uncertaintyLevel: 0.15, biasFreedom: 0.9, }, interpretation: "High confidence - strong evidence and coherent reasoning", recommendations: ["Proceed with implementation", "Monitor for edge cases"], }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); const result = await server.executeTool("assess_confidence", { reasoning: "Based on performance metrics, the optimization will improve throughput by 40%", evidence: ["Benchmark results show 40% improvement", "Load tests confirm scalability"], context: "Production optimization decision", }); expect(result.success).toBe(true); expect((result.data as any).overallConfidence).toBe(0.85); expect((result.data as any).dimensions).toBeDefined(); expect((result.data as any).dimensions.evidenceQuality).toBe(0.9); expect((result.data as any).dimensions.reasoningCoherence).toBe(0.85); expect((result.data as any).dimensions.completeness).toBe(0.8); expect((result.data as any).dimensions.uncertaintyLevel).toBe(0.15); expect((result.data as any).dimensions.biasFreedom).toBe(0.9); expect((result.data as any).interpretation).toBeDefined(); expect((result.data as any).recommendations).toHaveLength(2); }); it("should assess confidence with minimal evidence", async () => { const mockAssessment = { overallConfidence: 0.45, dimensions: { evidenceQuality: 0.3, reasoningCoherence: 0.6, completeness: 0.4, uncertaintyLevel: 0.6, biasFreedom: 0.7, }, interpretation: "Low confidence - insufficient evidence", recommendations: [ "Gather more evidence", "Consider alternative approaches", "Seek expert review", ], }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); const result = await server.executeTool("assess_confidence", { reasoning: "This approach might work based on intuition", }); expect(result.success).toBe(true); expect((result.data as any).overallConfidence).toBeLessThan(0.5); expect((result.data as any).dimensions.evidenceQuality).toBeLessThan(0.5); expect((result.data as any).recommendations).toContain("Gather more evidence"); }); it("should detect high uncertainty and provide warnings", async () => { const mockAssessment = { overallConfidence: 0.35, dimensions: { evidenceQuality: 0.4, reasoningCoherence: 0.5, completeness: 0.3, uncertaintyLevel: 0.8, biasFreedom: 0.6, }, interpretation: "Very low confidence - high uncertainty detected", warnings: ["Insufficient data for reliable conclusion", "Consider delaying decision"], recommendations: ["Collect more data", "Run pilot test", "Consult domain experts"], }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); const result = await server.executeTool("assess_confidence", { reasoning: "We could try this new approach", context: "Experimental feature", }); expect(result.success).toBe(true); expect((result.data as any).overallConfidence).toBeLessThan(0.5); expect((result.data as any).dimensions.uncertaintyLevel).toBeGreaterThan(0.7); expect((result.data as any).warnings).toBeDefined(); expect((result.data as any).warnings.length).toBeGreaterThan(0); }); it("should assess confidence within 100ms", async () => { const mockAssessment = { overallConfidence: 0.75, dimensions: { evidenceQuality: 0.8, reasoningCoherence: 0.75, completeness: 0.7, uncertaintyLevel: 0.25, biasFreedom: 0.8, }, interpretation: "Moderate to high confidence", recommendations: [], }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); const startTime = Date.now(); const result = await server.executeTool("assess_confidence", { reasoning: "Test reasoning", }); const duration = Date.now() - startTime; expect(result.success).toBe(true); expect(duration).toBeLessThan(100); }); it("should validate required parameters", async () => { const result = await server.executeTool("assess_confidence", { evidence: ["Some evidence"], // Missing reasoning }); expect(result.success).toBe(false); expect(result.error).toContain("reasoning"); }); it("should handle assessment errors gracefully", async () => { mockConfidenceAssessor.assessConfidence.mockRejectedValue(new Error("Assessment failed")); const result = await server.executeTool("assess_confidence", { reasoning: "Test reasoning", }); expect(result.success).toBe(false); expect(result.error).toContain("Assessment failed"); }); it("should include metadata in response", async () => { const mockAssessment = { overallConfidence: 0.8, dimensions: { evidenceQuality: 0.8, reasoningCoherence: 0.8, completeness: 0.8, uncertaintyLevel: 0.2, biasFreedom: 0.8, }, interpretation: "High confidence", recommendations: [], }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); const result = await server.executeTool("assess_confidence", { reasoning: "Test reasoning", }); expect(result.success).toBe(true); expect(result.metadata).toBeDefined(); expect(result.metadata?.timestamp).toBeDefined(); expect(result.metadata?.processingTime).toBeDefined(); }); it("should extract evidence from reasoning when no explicit evidence provided (Requirement 7.3)", async () => { const mockAssessment = { overallConfidence: 0.75, evidenceQuality: 0.7, reasoningCoherence: 0.8, completeness: 0.7, uncertaintyLevel: 0.3, uncertaintyType: "epistemic", factors: [], timestamp: new Date(), processingTime: 10, }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); // Set up evidence extractor on the server const { EvidenceExtractor } = await import("../../../confidence/evidence-extractor.js"); server.evidenceExtractor = new EvidenceExtractor(); const result = await server.executeTool("assess_confidence", { reasoning: "Research shows that this approach improves performance by 30%. " + "The data indicates consistent results across all test cases. " + "We observed significant improvements in response time.", }); expect(result.success).toBe(true); // Evidence should be extracted from reasoning text expect((result.data as any).extractedEvidence).toBeDefined(); expect((result.data as any).extractedEvidence.length).toBeGreaterThan(0); // Metadata should indicate evidence was extracted expect(result.metadata?.evidenceSource).toBe("extracted"); expect(result.metadata?.componentsUsed).toContain("evidenceExtractor"); }); it("should include extracted evidence items in response (Requirement 7.4)", async () => { const mockAssessment = { overallConfidence: 0.8, evidenceQuality: 0.75, reasoningCoherence: 0.85, completeness: 0.8, uncertaintyLevel: 0.2, uncertaintyType: "aleatory", factors: [], timestamp: new Date(), processingTime: 8, }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); // Set up evidence extractor on the server const { EvidenceExtractor } = await import("../../../confidence/evidence-extractor.js"); server.evidenceExtractor = new EvidenceExtractor(); const result = await server.executeTool("assess_confidence", { reasoning: "Studies found that the new algorithm is 2x faster. " + "According to the documentation, this is the recommended approach.", }); expect(result.success).toBe(true); expect((result.data as any).extractedEvidence).toBeDefined(); // Each extracted evidence should have statement, type, and confidence const extracted = (result.data as any).extractedEvidence; expect(extracted.length).toBeGreaterThan(0); expect(extracted[0].statement).toBeDefined(); expect(extracted[0].type).toBeDefined(); expect(extracted[0].confidence).toBeDefined(); }); it("should not extract evidence when explicit evidence is provided", async () => { const mockAssessment = { overallConfidence: 0.9, evidenceQuality: 0.9, reasoningCoherence: 0.9, completeness: 0.85, uncertaintyLevel: 0.1, uncertaintyType: "aleatory", factors: [], timestamp: new Date(), processingTime: 5, }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockAssessment); // Set up evidence extractor on the server const { EvidenceExtractor } = await import("../../../confidence/evidence-extractor.js"); server.evidenceExtractor = new EvidenceExtractor(); const result = await server.executeTool("assess_confidence", { reasoning: "The optimization will improve performance.", evidence: ["Benchmark shows 40% improvement", "Load tests confirm scalability"], }); expect(result.success).toBe(true); // Should not have extractedEvidence since explicit evidence was provided expect((result.data as any).extractedEvidence).toBeUndefined(); // Metadata should indicate evidence was provided expect(result.metadata?.evidenceSource).toBe("provided"); }); }); describe("detect_bias tool", () => { // Note: Tool is already registered by server.initialize() // No need to register again in beforeEach it("should detect confirmation bias", async () => { const mockBiases = [ { type: "confirmation", severity: 0.7, description: "Seeking only supporting evidence", evidence: ["Ignored contradictory data", "Cherry-picked favorable results"], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "All the data I looked at supports my hypothesis, so it must be correct", }); expect(result.success).toBe(true); expect((result.data as any).biases).toHaveLength(1); expect((result.data as any).biases[0].type).toBe("confirmation"); expect((result.data as any).biases[0].severity).toBe(0.7); // Correction is now added by BiasCorrector (Requirements 10.6, 10.10) expect((result.data as any).biases[0].correction).toBeDefined(); expect((result.data as any).biases[0].correction.suggestion).toBeDefined(); }); it("should detect anchoring bias", async () => { const mockBiases = [ { type: "anchoring", severity: 0.65, description: "Over-reliance on initial information", evidence: ["First estimate heavily influenced final decision"], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "The initial estimate was $100k, so I'll adjust to $95k", }); expect(result.success).toBe(true); expect((result.data as any).biases[0].type).toBe("anchoring"); }); it("should detect availability bias", async () => { const mockBiases = [ { type: "availability", severity: 0.6, description: "Over-weighting recent or memorable events", evidence: ["Recent incident influenced risk assessment"], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "Since we just had a security breach, security is our biggest risk", }); expect(result.success).toBe(true); expect((result.data as any).biases[0].type).toBe("availability"); }); it("should detect multiple biases simultaneously", async () => { const mockBiases = [ { type: "confirmation", severity: 0.7, description: "Confirmation bias detected", evidence: ["Selective evidence"], }, { type: "recency", severity: 0.5, description: "Recency bias detected", evidence: ["Over-weighting recent data"], }, { type: "framing", severity: 0.6, description: "Framing effects detected", evidence: ["Presentation influenced judgment"], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "Recent positive results confirm our approach is working", }); expect(result.success).toBe(true); expect((result.data as any).biases).toHaveLength(3); expect((result.data as any).biases.map((b: any) => b.type)).toContain("confirmation"); expect((result.data as any).biases.map((b: any) => b.type)).toContain("recency"); expect((result.data as any).biases.map((b: any) => b.type)).toContain("framing"); }); it("should detect biases within 2-3 seconds", async () => { const mockBiases = [ { type: "confirmation", severity: 0.6, description: "Bias detected", evidence: [], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "Test reasoning", }); expect(result.success).toBe(true); expect((result.data as any).detectionTime).toBeLessThan(3); }); it("should not enable continuous monitoring (not supported by BiasPatternRecognizer)", async () => { const mockBiases: unknown[] = []; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "Test reasoning", monitorContinuously: true, }); expect(result.success).toBe(true); // Continuous monitoring is not supported by BiasPatternRecognizer // Use BiasMonitoringSystem for continuous monitoring capabilities expect((result.data as { monitoringActive: boolean }).monitoringActive).toBe(false); }); it("should assess bias severity on 0-1 scale", async () => { const mockBiases = [ { type: "confirmation", severity: 0.85, description: "Severe confirmation bias", evidence: ["Strong selective evidence"], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "Test reasoning", }); expect(result.success).toBe(true); expect((result.data as any).biases[0].severity).toBeGreaterThanOrEqual(0); expect((result.data as any).biases[0].severity).toBeLessThanOrEqual(1); }); it("should provide correction strategies for detected biases", async () => { const mockBiases = [ { type: "anchoring", severity: 0.7, description: "Anchoring bias", evidence: ["Initial anchor influenced estimate"], }, ]; mockBiasDetector.detectBiasesFromText.mockReturnValue(mockBiases); const result = await server.executeTool("detect_bias", { reasoning: "Test reasoning", }); expect(result.success).toBe(true); // Correction is now an object with suggestion, techniques, and challengeQuestions (Requirements 10.6, 10.10) expect((result.data as any).biases[0].correction).toBeDefined(); expect((result.data as any).biases[0].correction.suggestion).toBeDefined(); expect((result.data as any).biases[0].correction.techniques).toBeDefined(); }); it("should handle no biases detected", async () => { mockBiasDetector.detectBiasesFromText.mockReturnValue([]); const result = await server.executeTool("detect_bias", { reasoning: "Objective analysis based on comprehensive data", }); expect(result.success).toBe(true); expect((result.data as any).biases).toHaveLength(0); }); it("should validate required parameters", async () => { const result = await server.executeTool("detect_bias", { context: "Test context", // Missing reasoning }); expect(result.success).toBe(false); expect(result.error).toContain("reasoning"); }); it("should handle detection errors gracefully", async () => { mockBiasDetector.detectBiasesFromText.mockImplementation(() => { throw new Error("Detection failed"); }); const result = await server.executeTool("detect_bias", { reasoning: "Test reasoning", }); expect(result.success).toBe(false); expect(result.error).toContain("Detection failed"); }); }); describe("detect_emotion tool", () => { // Note: Tool is already registered by server.initialize() // No need to register again in beforeEach it("should detect emotions using Circumplex model", async () => { const mockCircumplex = { valence: 0.7, arousal: 0.6, dominance: 0.5, confidence: 0.85, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue([]); const result = await server.executeTool("detect_emotion", { text: "I'm really excited about this new project!", }); expect(result.success).toBe(true); expect((result.data as any).circumplex).toBeDefined(); expect((result.data as any).circumplex.valence).toBe(0.7); expect((result.data as any).circumplex.arousal).toBe(0.6); expect((result.data as any).circumplex.dominance).toBe(0.5); expect((result.data as any).circumplex.confidence).toBe(0.85); }); it("should validate valence range (-1 to +1)", async () => { const mockCircumplex = { valence: -0.8, arousal: 0.7, dominance: -0.3, confidence: 0.8, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue([]); const result = await server.executeTool("detect_emotion", { text: "This is terrible and frustrating", }); expect(result.success).toBe(true); expect((result.data as any).circumplex.valence).toBeGreaterThanOrEqual(-1); expect((result.data as any).circumplex.valence).toBeLessThanOrEqual(1); }); it("should validate arousal range (0 to 1)", async () => { const mockCircumplex = { valence: 0.2, arousal: 0.9, dominance: 0.6, confidence: 0.75, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue([]); const result = await server.executeTool("detect_emotion", { text: "I'm so energized and ready to go!", }); expect(result.success).toBe(true); expect((result.data as any).circumplex.arousal).toBeGreaterThanOrEqual(0); expect((result.data as any).circumplex.arousal).toBeLessThanOrEqual(1); }); it("should validate dominance range (-1 to +1)", async () => { const mockCircumplex = { valence: -0.5, arousal: 0.4, dominance: -0.7, confidence: 0.8, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue([]); const result = await server.executeTool("detect_emotion", { text: "I feel powerless and overwhelmed", }); expect(result.success).toBe(true); expect((result.data as any).circumplex.dominance).toBeGreaterThanOrEqual(-1); expect((result.data as any).circumplex.dominance).toBeLessThanOrEqual(1); }); it("should classify discrete emotions", async () => { const mockCircumplex = { valence: 0.8, arousal: 0.7, dominance: 0.6, confidence: 0.85, }; const mockDiscrete = [ { emotion: "joy", intensity: 0.85, confidence: 0.9, }, { emotion: "excitement", intensity: 0.7, confidence: 0.8, }, ]; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue(mockDiscrete); const result = await server.executeTool("detect_emotion", { text: "I'm so happy and excited about this!", includeDiscrete: true, }); expect(result.success).toBe(true); expect((result.data as any).discrete).toBeDefined(); expect((result.data as any).discrete).toHaveLength(2); expect((result.data as any).discrete[0].emotion).toBe("joy"); expect((result.data as any).discrete[0].intensity).toBe(0.85); }); it("should detect all 11 discrete emotion types", async () => { const mockCircumplex = { valence: 0.0, arousal: 0.5, dominance: 0.0, confidence: 0.7, }; const mockDiscrete = [ { emotion: "joy", intensity: 0.1, confidence: 0.5 }, { emotion: "sadness", intensity: 0.2, confidence: 0.6 }, { emotion: "anger", intensity: 0.1, confidence: 0.5 }, { emotion: "fear", intensity: 0.15, confidence: 0.55 }, { emotion: "disgust", intensity: 0.1, confidence: 0.5 }, { emotion: "surprise", intensity: 0.2, confidence: 0.6 }, { emotion: "pride", intensity: 0.1, confidence: 0.5 }, { emotion: "shame", intensity: 0.1, confidence: 0.5 }, { emotion: "guilt", intensity: 0.1, confidence: 0.5 }, { emotion: "gratitude", intensity: 0.15, confidence: 0.55 }, { emotion: "awe", intensity: 0.1, confidence: 0.5 }, ]; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue(mockDiscrete); const result = await server.executeTool("detect_emotion", { text: "Complex emotional text", includeDiscrete: true, }); expect(result.success).toBe(true); expect((result.data as any).discrete).toHaveLength(11); const emotionTypes = (result.data as any).discrete.map((e: any) => e.emotion); expect(emotionTypes).toContain("joy"); expect(emotionTypes).toContain("sadness"); expect(emotionTypes).toContain("anger"); expect(emotionTypes).toContain("fear"); expect(emotionTypes).toContain("disgust"); expect(emotionTypes).toContain("surprise"); expect(emotionTypes).toContain("pride"); expect(emotionTypes).toContain("shame"); expect(emotionTypes).toContain("guilt"); expect(emotionTypes).toContain("gratitude"); expect(emotionTypes).toContain("awe"); }); it("should skip discrete classification when requested", async () => { const mockCircumplex = { valence: 0.5, arousal: 0.5, dominance: 0.5, confidence: 0.8, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); const result = await server.executeTool("detect_emotion", { text: "Test text", includeDiscrete: false, }); expect(result.success).toBe(true); expect((result.data as any).circumplex).toBeDefined(); expect((result.data as any).discrete).toBeNull(); expect(mockEmotionAnalyzer.classifyEmotions).not.toHaveBeenCalled(); }); it("should detect emotions within 200ms", async () => { const mockCircumplex = { valence: 0.5, arousal: 0.5, dominance: 0.5, confidence: 0.8, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue([]); const result = await server.executeTool("detect_emotion", { text: "Test text", }); expect(result.success).toBe(true); expect((result.data as any).detectionTime).toBeLessThan(200); }); it("should validate required parameters", async () => { const result = await server.executeTool("detect_emotion", { includeDiscrete: true, // Missing text }); expect(result.success).toBe(false); expect(result.error).toContain("text"); }); it("should handle detection errors gracefully", async () => { mockEmotionAnalyzer.analyzeCircumplex.mockImplementation(() => { throw new Error("Emotion detection failed"); }); const result = await server.executeTool("detect_emotion", { text: "Test text", }); expect(result.success).toBe(false); expect(result.error).toContain("Emotion detection failed"); }); it("should include metadata in response", async () => { const mockCircumplex = { valence: 0.5, arousal: 0.5, dominance: 0.5, confidence: 0.8, }; mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockCircumplex); mockEmotionAnalyzer.classifyEmotions.mockReturnValue([]); const result = await server.executeTool("detect_emotion", { text: "Test text", }); expect(result.success).toBe(true); expect(result.metadata).toBeDefined(); expect(result.metadata?.timestamp).toBeDefined(); expect(result.metadata?.processingTime).toBeDefined(); }); }); describe("analyze_reasoning tool", () => { // Note: Tool is already registered by server.initialize() // No need to register again in beforeEach it("should analyze reasoning quality comprehensively", async () => { mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.8, dimensions: { evidenceQuality: 0.8, reasoningCoherence: 0.85, completeness: 0.75, uncertaintyLevel: 0.2, biasFreedom: 0.85, }, }); mockBiasDetector.detectBiases.mockReturnValue([]); const result = await server.executeTool("evaluate", { reasoning: "Based on comprehensive analysis, the proposed solution is optimal", context: "Technical decision", }); expect(result.success).toBe(true); expect((result.data as any).quality).toBeDefined(); expect((result.data as any).quality.coherence).toBeGreaterThan(0.8); expect((result.data as any).quality.completeness).toBeGreaterThan(0.7); expect((result.data as any).quality.logicalValidity).toBeGreaterThan(0.8); expect((result.data as any).quality.evidenceSupport).toBeGreaterThan(0.7); }); it("should identify reasoning strengths", async () => { mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.85, dimensions: { evidenceQuality: 0.9, reasoningCoherence: 0.9, completeness: 0.8, uncertaintyLevel: 0.15, biasFreedom: 0.85, }, }); mockBiasDetector.detectBiases.mockReturnValue([]); const result = await server.executeTool("evaluate", { reasoning: "Well-structured argument with strong evidence", }); expect(result.success).toBe(true); expect((result.data as any).strengths).toBeDefined(); expect((result.data as any).strengths.length).toBeGreaterThan(0); }); it("should identify reasoning weaknesses", async () => { mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.5, dimensions: { evidenceQuality: 0.4, reasoningCoherence: 0.6, completeness: 0.5, uncertaintyLevel: 0.5, biasFreedom: 0.6, }, }); mockBiasDetector.detectBiases.mockReturnValue([ { type: "confirmation", severity: 0.6, description: "Confirmation bias detected", evidence: [], correction: "Consider alternatives", }, ]); const result = await server.executeTool("evaluate", { reasoning: "Weak argument with limited support", }); expect(result.success).toBe(true); expect((result.data as any).weaknesses).toBeDefined(); expect((result.data as any).weaknesses.length).toBeGreaterThan(0); }); it("should provide improvement recommendations", async () => { mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.65, dimensions: { evidenceQuality: 0.6, reasoningCoherence: 0.7, completeness: 0.6, uncertaintyLevel: 0.35, biasFreedom: 0.7, }, }); mockBiasDetector.detectBiases.mockReturnValue([]); const result = await server.executeTool("evaluate", { reasoning: "Moderate quality reasoning", }); expect(result.success).toBe(true); expect((result.data as any).recommendations).toBeDefined(); expect((result.data as any).recommendations.length).toBeGreaterThan(0); }); it("should include confidence assessment when requested", async () => { const mockConfidence = { overallConfidence: 0.8, dimensions: { evidenceQuality: 0.8, reasoningCoherence: 0.85, completeness: 0.75, uncertaintyLevel: 0.2, biasFreedom: 0.85, }, interpretation: "High confidence", recommendations: [], }; mockConfidenceAssessor.assessConfidence.mockResolvedValue(mockConfidence); mockBiasDetector.detectBiases.mockReturnValue([]); const result = await server.executeTool("evaluate", { reasoning: "Test reasoning", includeConfidence: true, }); expect(result.success).toBe(true); expect((result.data as any).confidence).toBeDefined(); expect((result.data as any).confidence.overallConfidence).toBe(0.8); }); it("should include bias detection when requested", async () => { const mockBiases = [ { type: "confirmation", severity: 0.6, description: "Confirmation bias", evidence: [], correction: "Consider alternatives", }, ]; mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.7, dimensions: { evidenceQuality: 0.7, reasoningCoherence: 0.7, completeness: 0.7, uncertaintyLevel: 0.3, biasFreedom: 0.7, }, }); mockBiasDetector.detectBiases.mockReturnValue(mockBiases); const result = await server.executeTool("evaluate", { reasoning: "Test reasoning", includeBias: true, }); expect(result.success).toBe(true); expect((result.data as any).biases).toBeDefined(); expect((result.data as any).biases).toHaveLength(1); }); it("should include emotion analysis when requested", async () => { const mockEmotion = { valence: 0.6, arousal: 0.5, dominance: 0.4, confidence: 0.8, }; mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.75, dimensions: { evidenceQuality: 0.75, reasoningCoherence: 0.75, completeness: 0.75, uncertaintyLevel: 0.25, biasFreedom: 0.75, }, }); mockBiasDetector.detectBiases.mockReturnValue([]); mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue(mockEmotion); const result = await server.executeTool("evaluate", { reasoning: "Test reasoning", includeEmotion: true, }); expect(result.success).toBe(true); expect((result.data as any).emotion).toBeDefined(); expect((result.data as any).emotion.valence).toBe(0.6); }); it("should skip optional analyses when not requested", async () => { mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.75, dimensions: { evidenceQuality: 0.75, reasoningCoherence: 0.75, completeness: 0.75, uncertaintyLevel: 0.25, biasFreedom: 0.75, }, }); mockBiasDetector.detectBiases.mockReturnValue([]); const result = await server.executeTool("evaluate", { reasoning: "Test reasoning", includeConfidence: false, includeBias: false, includeEmotion: false, }); expect(result.success).toBe(true); expect((result.data as any).quality).toBeDefined(); expect((result.data as any).confidence).toBeUndefined(); expect((result.data as any).biases).toBeUndefined(); expect((result.data as any).emotion).toBeUndefined(); }); it("should validate required parameters", async () => { const result = await server.executeTool("evaluate", { context: "Test context", // Missing reasoning }); expect(result.success).toBe(false); expect(result.error).toContain("reasoning"); }); it("should handle analysis errors gracefully", async () => { mockConfidenceAssessor.assessConfidence.mockRejectedValue(new Error("Analysis failed")); const result = await server.executeTool("evaluate", { reasoning: "Test reasoning", }); expect(result.success).toBe(false); expect(result.error).toContain("Analysis failed"); }); it("should include metadata in response", async () => { mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.75, dimensions: { evidenceQuality: 0.75, reasoningCoherence: 0.75, completeness: 0.75, uncertaintyLevel: 0.25, biasFreedom: 0.75, }, }); mockBiasDetector.detectBiases.mockReturnValue([]); const result = await server.executeTool("evaluate", { reasoning: "Test reasoning", }); expect(result.success).toBe(true); expect(result.metadata).toBeDefined(); expect(result.metadata?.timestamp).toBeDefined(); expect(result.metadata?.processingTime).toBeDefined(); }); }); describe("Parameter Validation", () => { it("should validate all tools have proper schemas", () => { // Note: Tools are already registered by server.initialize() const expectedTools = ["assess_confidence", "detect_bias", "detect_emotion", "evaluate"]; expectedTools.forEach((toolName) => { const tool = server.toolRegistry.getTool(toolName); expect(tool).toBeDefined(); expect(tool?.inputSchema).toBeDefined(); expect(tool?.inputSchema.type).toBe("object"); expect(tool?.inputSchema.properties).toBeDefined(); expect(tool?.inputSchema.required).toBeDefined(); }); }); it("should validate response format consistency", async () => { // Setup mocks mockConfidenceAssessor.assessConfidence.mockResolvedValue({ overallConfidence: 0.8, dimensions: { evidenceQuality: 0.8, reasoningCoherence: 0.8, completeness: 0.8, uncertaintyLevel: 0.2, biasFreedom: 0.8, }, interpretation: "High confidence", recommendations: [], }); mockBiasDetector.detectBiases.mockReturnValue([]); mockBiasDetector.detectBiasesFromText.mockReturnValue([]); mockEmotionAnalyzer.analyzeCircumplex.mockReturnValue({ valence: 0.5, arousal: 0.5, dominance: 0.5, confidence: 0.8, }); // Note: Tools are already registered by server.initialize() // Test all tools with mocked components const tools = [ { name: "assess_confidence", params: { reasoning: "test" } }, { name: "detect_bias", params: { reasoning: "test" } }, { name: "detect_emotion", params: { text: "test" } }, { name: "evaluate", params: { reasoning: "test" } }, ]; for (const tool of tools) { const result = await server.executeTool(tool.name, tool.params); expect(result).toHaveProperty("success"); expect(result).toHaveProperty("data"); expect(result).toHaveProperty("metadata"); expect(result.metadata).toHaveProperty("timestamp"); expect(result.metadata).toHaveProperty("processingTime"); } }); }); });

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/keyurgolani/ThoughtMcp'

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