Skip to main content
Glama
conflict-resolution.test.ts35.4 kB
/** * Tests for ConflictResolutionEngine * * Following TDD methodology - these tests are written first and should fail * until the conflict resolution engine implementation is complete. * * Tests cover: * - Automatic conflict identification for all 5 types * - Conflict classification * - Severity assessment (LOW/MEDIUM/HIGH/CRITICAL) * - Resolution framework generation * - Pattern tracking * - Edge cases (no conflicts, all conflicts, partial) * - Error scenarios */ import { beforeEach, describe, expect, it } from "vitest"; import { ConflictResolutionEngine } from "../../../reasoning/conflict-resolution-engine"; import { ConflictSeverity, ConflictType, StreamStatus, StreamType, type Conflict, type StreamResult, } from "../../../reasoning/types"; describe("ConflictResolutionEngine", () => { let engine: ConflictResolutionEngine; beforeEach(() => { engine = new ConflictResolutionEngine(); }); // Helper function to create mock stream results function createMockStreamResult( type: StreamType, conclusion: string, confidence: number = 0.8, insights: string[] = [] ): StreamResult { return { streamId: `${type}-stream`, streamType: type, conclusion, reasoning: [`${type} reasoning step 1`, `${type} reasoning step 2`], insights: insights.map((content, idx) => ({ content, source: type, confidence: 0.8 - idx * 0.1, importance: 0.7 - idx * 0.1, })), confidence, processingTime: 100, status: StreamStatus.COMPLETED, }; } describe("detectConflicts", () => { it("should detect no conflicts when all streams agree", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "The solution is X"), createMockStreamResult(StreamType.CREATIVE, "The solution is X"), createMockStreamResult(StreamType.CRITICAL, "The solution is X"), createMockStreamResult(StreamType.SYNTHETIC, "The solution is X"), ]; const conflicts = engine.detectConflicts(results); expect(conflicts).toBeInstanceOf(Array); expect(conflicts).toHaveLength(0); }); it("should detect factual conflicts when streams contradict on facts", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "The data shows 100 users", 0.9, [ "Data analysis reveals 100 active users", ]), createMockStreamResult(StreamType.CREATIVE, "The data shows 200 users", 0.9, [ "Creative interpretation suggests 200 users", ]), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const factualConflict = conflicts.find((c) => c.type === ConflictType.FACTUAL); expect(factualConflict).toBeDefined(); expect(factualConflict?.sourceStreams).toContain("analytical-stream"); expect(factualConflict?.sourceStreams).toContain("creative-stream"); }); it("should detect logical conflicts when reasoning is inconsistent", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "If A then B, A is true, therefore B", 0.9), createMockStreamResult(StreamType.CRITICAL, "If A then B, A is true, but B is false", 0.9), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const logicalConflict = conflicts.find((c) => c.type === ConflictType.LOGICAL); expect(logicalConflict).toBeDefined(); }); it("should detect methodological conflicts between different approaches", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "Use quantitative analysis", 0.8, [ "Data-driven approach is best", ]), createMockStreamResult(StreamType.CREATIVE, "Use qualitative exploration", 0.8, [ "Intuitive approach is better", ]), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const methodologicalConflict = conflicts.find((c) => c.type === ConflictType.METHODOLOGICAL); expect(methodologicalConflict).toBeDefined(); }); it("should detect evaluative conflicts when value judgments differ", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.CRITICAL, "Prioritize security over usability", 0.8, [ "Security is paramount", ]), createMockStreamResult(StreamType.CREATIVE, "Prioritize usability over security", 0.8, [ "User experience matters most", ]), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const evaluativeConflict = conflicts.find((c) => c.type === ConflictType.EVALUATIVE); expect(evaluativeConflict).toBeDefined(); }); it("should detect predictive conflicts when forecasts differ", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "Market will grow by 10%", 0.7, [ "Historical trends suggest 10% growth", ]), createMockStreamResult(StreamType.SYNTHETIC, "Market will decline by 5%", 0.7, [ "Synthesis indicates 5% decline", ]), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const predictiveConflict = conflicts.find((c) => c.type === ConflictType.PREDICTIVE); expect(predictiveConflict).toBeDefined(); }); it("should detect multiple conflicts in complex scenarios", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "Data shows X, use method A", 0.9), createMockStreamResult(StreamType.CREATIVE, "Data shows Y, use method B", 0.9), createMockStreamResult(StreamType.CRITICAL, "Data shows X, but method B is better", 0.8), createMockStreamResult(StreamType.SYNTHETIC, "Data shows Z, method C is optimal", 0.7), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(1); // Should detect multiple types of conflicts const conflictTypes = new Set(conflicts.map((c) => c.type)); expect(conflictTypes.size).toBeGreaterThan(1); }); it("should handle edge case with only one stream result", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "Single stream conclusion"), ]; const conflicts = engine.detectConflicts(results); expect(conflicts).toBeInstanceOf(Array); expect(conflicts).toHaveLength(0); }); it("should handle edge case with empty results array", () => { const results: StreamResult[] = []; const conflicts = engine.detectConflicts(results); expect(conflicts).toBeInstanceOf(Array); expect(conflicts).toHaveLength(0); }); }); describe("classifyConflict", () => { it("should classify factual conflicts correctly", () => { const result1 = createMockStreamResult(StreamType.ANALYTICAL, "Fact: X is 100"); const result2 = createMockStreamResult(StreamType.CREATIVE, "Fact: X is 200"); const conflictType = engine.classifyConflict(result1, result2); expect(conflictType).toBe(ConflictType.FACTUAL); }); it("should classify logical conflicts correctly", () => { const result1 = createMockStreamResult(StreamType.ANALYTICAL, "If A then B, A is true"); const result2 = createMockStreamResult(StreamType.CRITICAL, "If A then B, but not B"); const conflictType = engine.classifyConflict(result1, result2); expect(conflictType).toBe(ConflictType.LOGICAL); }); it("should classify methodological conflicts correctly", () => { const result1 = createMockStreamResult(StreamType.ANALYTICAL, "Use quantitative method"); const result2 = createMockStreamResult(StreamType.CREATIVE, "Use qualitative method"); const conflictType = engine.classifyConflict(result1, result2); expect(conflictType).toBe(ConflictType.METHODOLOGICAL); }); it("should classify evaluative conflicts correctly", () => { const result1 = createMockStreamResult(StreamType.CRITICAL, "Prioritize X over Y"); const result2 = createMockStreamResult(StreamType.CREATIVE, "Prioritize Y over X"); const conflictType = engine.classifyConflict(result1, result2); expect(conflictType).toBe(ConflictType.EVALUATIVE); }); it("should classify predictive conflicts correctly", () => { const result1 = createMockStreamResult(StreamType.ANALYTICAL, "Will increase by 10%"); const result2 = createMockStreamResult(StreamType.SYNTHETIC, "Will decrease by 5%"); const conflictType = engine.classifyConflict(result1, result2); expect(conflictType).toBe(ConflictType.PREDICTIVE); }); }); describe("assessSeverity", () => { it("should assess LOW severity for minor disagreements", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.LOW, // Will be overridden sourceStreams: ["analytical-stream", "creative-stream"], description: "Minor methodological difference", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Use method A", reasoning: "Method A is slightly better", confidence: 0.5, // Low confidence for LOW severity }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Use method B", reasoning: "Method B is slightly better", confidence: 0.5, // Low confidence for LOW severity }, ], detectedAt: new Date(), }; const severity = engine.assessSeverity(conflict); expect(severity).toBe(ConflictSeverity.LOW); }); it("should assess MEDIUM severity for significant disagreements", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["analytical-stream", "creative-stream"], description: "Moderate factual disagreement", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Value is 100", reasoning: "Data shows 100", confidence: 0.7, // Moderate confidence for MEDIUM severity }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Value is 150", reasoning: "Interpretation suggests 150", confidence: 0.7, // Moderate confidence for MEDIUM severity }, ], detectedAt: new Date(), }; const severity = engine.assessSeverity(conflict); expect(severity).toBe(ConflictSeverity.MEDIUM); }); it("should assess HIGH severity for major contradictions", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.LOGICAL, severity: ConflictSeverity.HIGH, sourceStreams: ["analytical-stream", "critical-stream"], description: "Major logical contradiction", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "A implies B", reasoning: "Logical deduction", confidence: 0.88, // High but not critical confidence for HIGH severity }, { streamId: "critical-stream", streamType: StreamType.CRITICAL, claim: "A but not B", reasoning: "Critical analysis", confidence: 0.88, // High but not critical confidence for HIGH severity }, ], detectedAt: new Date(), }; const severity = engine.assessSeverity(conflict); expect(severity).toBe(ConflictSeverity.HIGH); }); it("should assess CRITICAL severity for fundamental incompatibilities", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.CRITICAL, sourceStreams: ["analytical-stream", "synthetic-stream"], description: "Critical factual contradiction", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "System is safe", reasoning: "All safety checks passed", confidence: 0.95, }, { streamId: "synthetic-stream", streamType: StreamType.SYNTHETIC, claim: "System is unsafe", reasoning: "Critical vulnerabilities found", confidence: 0.95, }, ], detectedAt: new Date(), }; const severity = engine.assessSeverity(conflict); expect(severity).toBe(ConflictSeverity.CRITICAL); }); }); describe("generateResolutionFramework", () => { it("should generate resolution framework for factual conflicts", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["analytical-stream", "creative-stream"], description: "Factual disagreement", evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toBeTruthy(); expect(framework.steps).toBeInstanceOf(Array); expect(framework.steps.length).toBeGreaterThan(0); expect(framework.considerations).toBeInstanceOf(Array); expect(framework.considerations.length).toBeGreaterThan(0); expect(framework.recommendedAction).toBeTruthy(); }); it("should generate resolution framework for logical conflicts", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.LOGICAL, severity: ConflictSeverity.HIGH, sourceStreams: ["analytical-stream", "critical-stream"], description: "Logical inconsistency", evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toContain("logical"); expect(framework.steps.length).toBeGreaterThan(0); }); it("should generate resolution framework for methodological conflicts", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["analytical-stream", "creative-stream"], description: "Methodological difference", evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toContain("method"); expect(framework.steps.length).toBeGreaterThan(0); }); it("should generate resolution framework for evaluative conflicts", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.EVALUATIVE, severity: ConflictSeverity.MEDIUM, sourceStreams: ["critical-stream", "creative-stream"], description: "Value judgment difference", evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toContain("value"); expect(framework.steps.length).toBeGreaterThan(0); }); it("should generate resolution framework for predictive conflicts", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.PREDICTIVE, severity: ConflictSeverity.HIGH, sourceStreams: ["analytical-stream", "synthetic-stream"], description: "Prediction disagreement", evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toContain("predict"); expect(framework.steps.length).toBeGreaterThan(0); }); it("should tailor resolution framework based on severity", () => { const lowSeverityConflict: Conflict = { id: "low-conflict", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "creative-stream"], description: "Minor difference", evidence: [], detectedAt: new Date(), }; const criticalConflict: Conflict = { id: "critical-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.CRITICAL, sourceStreams: ["analytical-stream", "synthetic-stream"], description: "Critical contradiction", evidence: [], detectedAt: new Date(), }; const lowFramework = engine.generateResolutionFramework(lowSeverityConflict); const criticalFramework = engine.generateResolutionFramework(criticalConflict); expect(lowFramework.recommendedAction).not.toBe(criticalFramework.recommendedAction); // Critical conflicts should have more urgent language expect(criticalFramework.recommendedAction.toLowerCase()).toMatch( /immediate|urgent|critical|priority/ ); }); it("should generate default resolution framework for unknown conflict types", () => { // Create a conflict with an unknown type by casting const unknownConflict: Conflict = { id: "unknown-conflict", type: "UNKNOWN_TYPE" as ConflictType, severity: ConflictSeverity.MEDIUM, sourceStreams: ["analytical-stream", "creative-stream"], description: "Unknown conflict type", evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(unknownConflict); expect(framework).toBeDefined(); expect(framework.approach).toBe("Systematic analysis and evidence-based resolution"); expect(framework.steps).toBeInstanceOf(Array); expect(framework.steps.length).toBeGreaterThan(0); expect(framework.steps).toContain("Clearly define the conflict"); expect(framework.steps).toContain("Gather additional evidence"); expect(framework.considerations).toContain("Context and constraints"); expect(framework.considerations).toContain("Evidence quality"); expect(framework.recommendedAction).toBe("Conduct systematic analysis to resolve conflict"); }); }); describe("trackConflictPattern", () => { it("should track conflict patterns over time", () => { const conflicts: Conflict[] = [ { id: "conflict-1", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["analytical-stream", "creative-stream"], description: "Method conflict 1", evidence: [], detectedAt: new Date(), }, { id: "conflict-2", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["analytical-stream", "creative-stream"], description: "Method conflict 2", evidence: [], detectedAt: new Date(), }, ]; conflicts.forEach((conflict) => engine.trackConflictPattern(conflict)); const patterns = engine.getConflictPatterns(); expect(patterns).toBeInstanceOf(Array); expect(patterns.length).toBeGreaterThan(0); const methodologicalPattern = patterns.find((p) => p.conflictTypes.includes(ConflictType.METHODOLOGICAL) ); expect(methodologicalPattern).toBeDefined(); expect(methodologicalPattern?.frequency).toBeGreaterThan(1); }); it("should identify common source streams in patterns", () => { const conflicts: Conflict[] = [ { id: "conflict-1", type: ConflictType.EVALUATIVE, severity: ConflictSeverity.LOW, sourceStreams: ["critical-stream", "creative-stream"], description: "Evaluative conflict 1", evidence: [], detectedAt: new Date(), }, { id: "conflict-2", type: ConflictType.EVALUATIVE, severity: ConflictSeverity.LOW, sourceStreams: ["critical-stream", "creative-stream"], description: "Evaluative conflict 2", evidence: [], detectedAt: new Date(), }, ]; conflicts.forEach((conflict) => engine.trackConflictPattern(conflict)); const patterns = engine.getConflictPatterns(); const evaluativePattern = patterns.find((p) => p.conflictTypes.includes(ConflictType.EVALUATIVE) ); expect(evaluativePattern).toBeDefined(); expect(evaluativePattern?.commonSources).toContain("critical-stream"); expect(evaluativePattern?.commonSources).toContain("creative-stream"); }); it("should track resolution success rate", () => { const conflict: Conflict = { id: "conflict-1", type: ConflictType.LOGICAL, severity: ConflictSeverity.HIGH, sourceStreams: ["analytical-stream", "critical-stream"], description: "Logical conflict", evidence: [], detectedAt: new Date(), }; engine.trackConflictPattern(conflict, true); // Resolved successfully const patterns = engine.getConflictPatterns(); const logicalPattern = patterns.find((p) => p.conflictTypes.includes(ConflictType.LOGICAL)); expect(logicalPattern).toBeDefined(); expect(logicalPattern?.resolutionSuccess).toBeGreaterThan(0); expect(logicalPattern?.resolutionSuccess).toBeLessThanOrEqual(1); }); }); describe("error handling", () => { it("should handle null or undefined results gracefully", () => { expect(() => engine.detectConflicts(null as any)).not.toThrow(); expect(() => engine.detectConflicts(undefined as any)).not.toThrow(); }); it("should handle malformed stream results", () => { const malformedResults = [ { streamId: "test", // Missing required fields } as any, ]; expect(() => engine.detectConflicts(malformedResults)).not.toThrow(); }); it("should handle conflicts with missing evidence", () => { const conflict: Conflict = { id: "test-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["stream1", "stream2"], description: "Test conflict", evidence: [], // Empty evidence detectedAt: new Date(), }; expect(() => engine.generateResolutionFramework(conflict)).not.toThrow(); expect(() => engine.assessSeverity(conflict)).not.toThrow(); }); }); describe("integration scenarios", () => { it("should handle complete workflow: detect, classify, assess, resolve", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "Solution A is optimal", 0.9), createMockStreamResult(StreamType.CREATIVE, "Solution B is optimal", 0.9), ]; // Detect conflicts const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); // Each conflict should have classification conflicts.forEach((conflict) => { expect(conflict.type).toBeDefined(); expect(Object.values(ConflictType)).toContain(conflict.type); }); // Each conflict should have severity assessment conflicts.forEach((conflict) => { expect(conflict.severity).toBeDefined(); expect(Object.values(ConflictSeverity)).toContain(conflict.severity); }); // Generate resolution frameworks conflicts.forEach((conflict) => { const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toBeTruthy(); expect(framework.steps.length).toBeGreaterThan(0); }); // Track patterns conflicts.forEach((conflict) => engine.trackConflictPattern(conflict)); const patterns = engine.getConflictPatterns(); expect(patterns.length).toBeGreaterThan(0); }); }); describe("severity calibration based on contradiction degree (Requirement 6.1)", () => { it("should assess higher severity for direct contradictions", () => { // Direct contradiction: safe vs unsafe const directContradiction: Conflict = { id: "direct-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "synthetic-stream"], description: "Direct contradiction", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "System is safe", reasoning: "All checks passed", confidence: 0.9, }, { streamId: "synthetic-stream", streamType: StreamType.SYNTHETIC, claim: "System is unsafe", reasoning: "Vulnerabilities found", confidence: 0.9, }, ], detectedAt: new Date(), }; // Indirect disagreement: different methods const indirectDisagreement: Conflict = { id: "indirect-conflict", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "creative-stream"], description: "Indirect disagreement", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Use approach A", reasoning: "Approach A is good", confidence: 0.9, }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Use approach B", reasoning: "Approach B is good", confidence: 0.9, }, ], detectedAt: new Date(), }; const directSeverity = engine.assessSeverity(directContradiction); const indirectSeverity = engine.assessSeverity(indirectDisagreement); // Direct contradictions should have higher or equal severity const directScore = severityToScore(directSeverity); const indirectScore = severityToScore(indirectSeverity); expect(directScore).toBeGreaterThanOrEqual(indirectScore); }); it("should assess higher severity for factual conflicts than methodological at same confidence", () => { const factualConflict: Conflict = { id: "factual-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "creative-stream"], description: "Factual conflict", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Value is 100", reasoning: "Data shows 100", confidence: 0.8, }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Value is 200", reasoning: "Data shows 200", confidence: 0.8, }, ], detectedAt: new Date(), }; const methodConflict: Conflict = { id: "method-conflict", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "creative-stream"], description: "Method conflict", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Use method A", reasoning: "Method A is better", confidence: 0.8, }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Use method B", reasoning: "Method B is better", confidence: 0.8, }, ], detectedAt: new Date(), }; const factualSeverity = engine.assessSeverity(factualConflict); const methodSeverity = engine.assessSeverity(methodConflict); // Factual conflicts should have higher or equal severity const factualScore = severityToScore(factualSeverity); const methodScore = severityToScore(methodSeverity); expect(factualScore).toBeGreaterThanOrEqual(methodScore); }); it("should vary severity based on confidence levels", () => { const highConfConflict: Conflict = { id: "high-conf-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "creative-stream"], description: "High confidence conflict", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Value is 100", reasoning: "Data shows 100", confidence: 0.95, }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Value is 200", reasoning: "Data shows 200", confidence: 0.95, }, ], detectedAt: new Date(), }; const lowConfConflict: Conflict = { id: "low-conf-conflict", type: ConflictType.FACTUAL, severity: ConflictSeverity.LOW, sourceStreams: ["analytical-stream", "creative-stream"], description: "Low confidence conflict", evidence: [ { streamId: "analytical-stream", streamType: StreamType.ANALYTICAL, claim: "Value is 100", reasoning: "Data shows 100", confidence: 0.5, }, { streamId: "creative-stream", streamType: StreamType.CREATIVE, claim: "Value is 200", reasoning: "Data shows 200", confidence: 0.5, }, ], detectedAt: new Date(), }; const highSeverity = engine.assessSeverity(highConfConflict); const lowSeverity = engine.assessSeverity(lowConfConflict); // Higher confidence should lead to higher or equal severity const highScore = severityToScore(highSeverity); const lowScore = severityToScore(lowSeverity); expect(highScore).toBeGreaterThanOrEqual(lowScore); }); }); describe("description specificity (Requirement 6.2)", () => { it("should generate specific descriptions explaining the nature of disagreement", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "The data shows 100 users", 0.9), createMockStreamResult(StreamType.CREATIVE, "The data shows 200 users", 0.9), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const conflict = conflicts[0]; // Description should not be generic expect(conflict.description).not.toBe("FACTUAL conflict between analytical and creative"); // Description should contain specific claims expect(conflict.description.length).toBeGreaterThan(50); // Description should explain the nature of disagreement expect( conflict.description.includes("claims") || conflict.description.includes("disagreement") || conflict.description.includes("contradictory") ).toBe(true); }); it("should include both claims in the description", () => { const results: StreamResult[] = [ createMockStreamResult(StreamType.ANALYTICAL, "System is safe", 0.9), createMockStreamResult(StreamType.SYNTHETIC, "System is unsafe", 0.9), ]; const conflicts = engine.detectConflicts(results); expect(conflicts.length).toBeGreaterThan(0); const conflict = conflicts[0]; // Description should reference both claims expect( conflict.description.toLowerCase().includes("safe") || conflict.description.toLowerCase().includes("unsafe") ).toBe(true); }); }); describe("resolution suggestions (Requirement 6.4)", () => { it("should provide resolution suggestions for all conflict types", () => { const conflictTypes = [ ConflictType.FACTUAL, ConflictType.LOGICAL, ConflictType.METHODOLOGICAL, ConflictType.EVALUATIVE, ConflictType.PREDICTIVE, ]; for (const type of conflictTypes) { const conflict: Conflict = { id: `${type}-conflict`, type, severity: ConflictSeverity.MEDIUM, sourceStreams: ["stream1", "stream2"], description: `${type} conflict`, evidence: [], detectedAt: new Date(), }; const framework = engine.generateResolutionFramework(conflict); expect(framework).toBeDefined(); expect(framework.approach).toBeTruthy(); expect(framework.steps.length).toBeGreaterThan(0); expect(framework.considerations.length).toBeGreaterThan(0); expect(framework.recommendedAction).toBeTruthy(); } }); it("should tailor resolution suggestions based on conflict type", () => { const factualConflict: Conflict = { id: "factual", type: ConflictType.FACTUAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["stream1", "stream2"], description: "Factual conflict", evidence: [], detectedAt: new Date(), }; const methodConflict: Conflict = { id: "method", type: ConflictType.METHODOLOGICAL, severity: ConflictSeverity.MEDIUM, sourceStreams: ["stream1", "stream2"], description: "Method conflict", evidence: [], detectedAt: new Date(), }; const factualFramework = engine.generateResolutionFramework(factualConflict); const methodFramework = engine.generateResolutionFramework(methodConflict); // Different conflict types should have different approaches expect(factualFramework.approach).not.toBe(methodFramework.approach); }); }); }); /** * Helper function to convert severity to numeric score for comparison */ function severityToScore(severity: ConflictSeverity): number { switch (severity) { case ConflictSeverity.LOW: return 1; case ConflictSeverity.MEDIUM: return 2; case ConflictSeverity.HIGH: return 3; case ConflictSeverity.CRITICAL: return 4; default: return 0; } }

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