Skip to main content
Glama
problem-classifier.test.ts26.9 kB
/** * Tests for ProblemClassifier * * Following TDD methodology - these tests are written first and should fail * until the ProblemClassifier implementation is complete. * * Tests cover all four classification dimensions: * - Complexity (simple/moderate/complex) * - Uncertainty (low/medium/high) * - Stakes (routine/important/critical) * - Time Pressure (none/moderate/high) */ import { beforeEach, describe, expect, it } from "vitest"; import { ProblemClassifier } from "../../../framework/problem-classifier.js"; import type { Problem } from "../../../framework/types.js"; describe("ProblemClassifier", () => { let classifier: ProblemClassifier; beforeEach(() => { classifier = new ProblemClassifier(); }); describe("Complexity Assessment", () => { it("should classify simple problems correctly", () => { const problem: Problem = { id: "test-1", description: "Calculate the sum of two numbers", context: "Basic arithmetic operation", goals: ["Add two numbers"], constraints: [], }; const classification = classifier.classifyProblem(problem); expect(classification.complexity).toBe("simple"); expect(classification.reasoning.complexityReason).toContain("single"); expect(classification.confidence).toBeGreaterThan(0.7); }); it("should classify moderate problems correctly", () => { const problem: Problem = { id: "test-2", description: "Design a user authentication system with email and password", context: "Web application security", goals: ["Secure login", "Password hashing", "Session management"], constraints: ["Must use HTTPS", "Password requirements"], }; const classification = classifier.classifyProblem(problem); expect(classification.complexity).toBe("moderate"); expect(classification.reasoning.complexityReason).toContain("multiple"); expect(classification.confidence).toBeGreaterThan(0.6); }); it("should classify complex problems correctly", () => { const problem: Problem = { id: "test-3", description: "Build a distributed microservices architecture with event sourcing, CQRS, and eventual consistency", context: "Large-scale enterprise system with multiple teams and services", goals: [ "High availability", "Scalability", "Data consistency", "Service isolation", "Event replay", "Monitoring", ], constraints: [ "Must handle 10k requests/sec", "99.99% uptime", "Cross-region deployment", "Legacy system integration", "Compliance requirements", ], }; const classification = classifier.classifyProblem(problem); expect(classification.complexity).toBe("complex"); expect(classification.reasoning.complexityReason).toContain("interdependent"); expect(classification.confidence).toBeGreaterThan(0.5); }); }); describe("Uncertainty Evaluation", () => { it("should classify low uncertainty problems correctly", () => { const problem: Problem = { id: "test-4", description: "Implement a sorting algorithm for a known dataset", context: "Well-defined problem with clear requirements", goals: ["Sort array in ascending order"], constraints: ["Use O(n log n) algorithm"], }; const classification = classifier.classifyProblem(problem); expect(classification.uncertainty).toBe("low"); expect(classification.reasoning.uncertaintyReason).toContain("known"); expect(classification.confidence).toBeGreaterThan(0.7); }); it("should classify medium uncertainty problems correctly", () => { const problem: Problem = { id: "test-5", description: "Optimize database query performance for user dashboard", context: "Some performance issues reported, unclear root cause, need to investigate and improve", goals: ["Reduce query time", "Improve user experience"], constraints: ["Cannot change database schema"], }; const classification = classifier.classifyProblem(problem); expect(classification.uncertainty).toBe("medium"); expect(classification.reasoning.uncertaintyReason).toContain("uncertainty"); expect(classification.confidence).toBeGreaterThan(0.5); }); it("should classify high uncertainty problems correctly", () => { const problem: Problem = { id: "test-6", description: "Predict user behavior in a new market with limited data", context: "Entering unfamiliar market, unclear user preferences, unknown competitors", goals: ["Understand user needs", "Predict adoption rate"], constraints: ["Limited budget for research"], }; const classification = classifier.classifyProblem(problem); expect(classification.uncertainty).toBe("high"); expect(classification.reasoning.uncertaintyReason).toContain("unknown"); expect(classification.confidence).toBeGreaterThan(0.4); }); }); describe("Stakes Assessment", () => { it("should classify routine stakes problems correctly", () => { const problem: Problem = { id: "test-7", description: "Update documentation for internal tool", context: "Minor documentation improvements", goals: ["Clarify usage instructions"], constraints: [], }; const classification = classifier.classifyProblem(problem); expect(classification.stakes).toBe("routine"); expect(classification.reasoning.stakesReason).toContain("low impact"); expect(classification.confidence).toBeGreaterThan(0.7); }); it("should classify important stakes problems correctly", () => { const problem: Problem = { id: "test-8", description: "Redesign customer onboarding flow", context: "Important improvement for user experience affecting all new customers and teams", goals: ["Reduce onboarding time", "Increase completion rate"], constraints: ["Must maintain existing features"], }; const classification = classifier.classifyProblem(problem); expect(classification.stakes).toBe("important"); expect(classification.reasoning.stakesReason).toContain("moderate impact"); expect(classification.confidence).toBeGreaterThan(0.6); }); it("should classify critical stakes problems correctly", () => { const problem: Problem = { id: "test-9", description: "Fix critical security vulnerability in payment system", context: "Active exploit detected, all customer data at risk, affects all users and teams, regulatory implications, permanent damage possible", goals: ["Patch vulnerability", "Protect customer data", "Avoid fines"], constraints: ["Must deploy within 24 hours"], }; const classification = classifier.classifyProblem(problem); expect(classification.stakes).toBe("critical"); expect(classification.reasoning.stakesReason).toContain("high impact"); expect(classification.confidence).toBeGreaterThan(0.7); }); }); describe("Time Pressure Evaluation", () => { it("should classify no time pressure problems correctly", () => { const problem: Problem = { id: "test-10", description: "Research new technology for future projects", context: "Long-term planning, no immediate deadline", goals: ["Evaluate options", "Create recommendation"], constraints: [], }; const classification = classifier.classifyProblem(problem); expect(classification.timePressure).toBe("none"); expect(classification.reasoning.timePressureReason).toContain("no deadline"); expect(classification.confidence).toBeGreaterThan(0.7); }); it("should classify moderate time pressure problems correctly", () => { const problem: Problem = { id: "test-11", description: "Prepare quarterly business review presentation", context: "Presentation due in 2 weeks", goals: ["Summarize Q3 results", "Present recommendations"], constraints: ["Must include all departments"], urgency: "medium", }; const classification = classifier.classifyProblem(problem); expect(classification.timePressure).toBe("moderate"); expect(classification.reasoning.timePressureReason).toContain("medium"); expect(classification.confidence).toBeGreaterThan(0.6); }); it("should classify high time pressure problems correctly", () => { const problem: Problem = { id: "test-12", description: "Respond to production outage affecting all users", context: "System down, customers unable to access service", goals: ["Restore service", "Identify root cause"], constraints: ["Must resolve within 1 hour SLA"], urgency: "high", }; const classification = classifier.classifyProblem(problem); expect(classification.timePressure).toBe("high"); expect(classification.reasoning.timePressureReason).toContain("high"); expect(classification.confidence).toBeGreaterThan(0.6); }); }); describe("Complete Classification", () => { it("should provide complete classification with all dimensions", () => { const problem: Problem = { id: "test-13", description: "Implement new feature for mobile app", context: "User-requested feature with moderate complexity", goals: ["Add feature", "Maintain performance"], constraints: ["iOS and Android support"], }; const classification = classifier.classifyProblem(problem); expect(classification).toHaveProperty("complexity"); expect(classification).toHaveProperty("uncertainty"); expect(classification).toHaveProperty("stakes"); expect(classification).toHaveProperty("timePressure"); expect(classification).toHaveProperty("confidence"); expect(classification).toHaveProperty("reasoning"); expect(classification).toHaveProperty("timestamp"); expect(classification.reasoning).toHaveProperty("complexityReason"); expect(classification.reasoning).toHaveProperty("uncertaintyReason"); expect(classification.reasoning).toHaveProperty("stakesReason"); expect(classification.reasoning).toHaveProperty("timePressureReason"); expect(classification.confidence).toBeGreaterThanOrEqual(0); expect(classification.confidence).toBeLessThanOrEqual(1); expect(classification.timestamp).toBeInstanceOf(Date); }); }); describe("Confidence Scoring", () => { it("should have high confidence for well-defined problems", () => { const problem: Problem = { id: "test-14", description: "Calculate monthly revenue from sales data", context: "Standard financial reporting", goals: ["Sum all sales", "Generate report"], constraints: ["Use existing data format"], }; const classification = classifier.classifyProblem(problem); expect(classification.confidence).toBeGreaterThanOrEqual(0.75); }); it("should have lower confidence for vague problems", () => { const problem: Problem = { id: "test-15", description: "Make the system better", context: "General improvement needed", }; const classification = classifier.classifyProblem(problem); expect(classification.confidence).toBeLessThanOrEqual(0.7); }); it("should have medium confidence for partially defined problems", () => { const problem: Problem = { id: "test-16", description: "Improve application performance", context: "Users reporting slowness", goals: ["Reduce load time"], }; const classification = classifier.classifyProblem(problem); expect(classification.confidence).toBeGreaterThan(0.5); expect(classification.confidence).toBeLessThan(0.8); }); }); describe("Performance", () => { it("should classify problems in less than 1-2 seconds", () => { const problem: Problem = { id: "test-17", description: "Complex problem with many goals and constraints for performance testing", context: "Testing classification speed", goals: Array(10).fill("Goal"), constraints: Array(10).fill("Constraint"), }; const startTime = Date.now(); classifier.classifyProblem(problem); const endTime = Date.now(); const duration = endTime - startTime; expect(duration).toBeLessThan(2000); // Less than 2 seconds }); it("should handle batch classification efficiently", () => { const problems: Problem[] = Array(10) .fill(null) .map((_, i) => ({ id: `test-batch-${i}`, description: `Problem ${i}`, context: "Batch testing", goals: ["Goal 1", "Goal 2"], })); const startTime = Date.now(); problems.forEach((problem) => classifier.classifyProblem(problem)); const endTime = Date.now(); const duration = endTime - startTime; expect(duration).toBeLessThan(5000); // Less than 5 seconds for 10 problems }); }); describe("Edge Cases", () => { it("should handle empty problem description", () => { const problem: Problem = { id: "test-18", description: "", context: "", }; expect(() => { classifier.classifyProblem(problem); }).toThrow("Problem must have id and description"); }); it("should handle minimal problem information", () => { const problem: Problem = { id: "test-19", description: "Do something", context: "", }; const classification = classifier.classifyProblem(problem); expect(classification).toBeDefined(); expect(classification.complexity).toBeDefined(); expect(classification.uncertainty).toBeDefined(); expect(classification.stakes).toBeDefined(); expect(classification.timePressure).toBeDefined(); }); it("should handle problems with only description", () => { const problem: Problem = { id: "test-20", description: "Solve the problem", context: "", }; const classification = classifier.classifyProblem(problem); expect(classification).toBeDefined(); expect(classification.confidence).toBeLessThan(0.7); }); it("should handle problems with missing optional fields", () => { const problem: Problem = { id: "test-21", description: "Complete the task", context: "Some context", // No goals, constraints, urgency, complexity }; const classification = classifier.classifyProblem(problem); expect(classification).toBeDefined(); expect(classification.complexity).toBeDefined(); expect(classification.uncertainty).toBeDefined(); expect(classification.stakes).toBeDefined(); expect(classification.timePressure).toBeDefined(); }); }); describe("Caching", () => { it("should cache classification results for identical problems", () => { const problem: Problem = { id: "test-22", description: "Same problem for caching test", context: "Testing cache", goals: ["Goal 1"], }; const firstClassification = classifier.classifyProblem(problem); const secondClassification = classifier.classifyProblem(problem); expect(firstClassification.complexity).toBe(secondClassification.complexity); expect(firstClassification.uncertainty).toBe(secondClassification.uncertainty); expect(firstClassification.stakes).toBe(secondClassification.stakes); expect(firstClassification.timePressure).toBe(secondClassification.timePressure); }); it("should return different results for different problems", () => { const problem1: Problem = { id: "test-23", description: "Simple problem", context: "Easy task", goals: ["One goal"], }; const problem2: Problem = { id: "test-24", description: "Complex problem with many interdependent goals and constraints", context: "Difficult task", goals: ["Goal 1", "Goal 2", "Goal 3", "Goal 4"], constraints: ["Constraint 1", "Constraint 2", "Constraint 3"], }; const classification1 = classifier.classifyProblem(problem1); const classification2 = classifier.classifyProblem(problem2); expect(classification1.complexity).not.toBe(classification2.complexity); }); }); describe("Error Handling", () => { it("should handle null or undefined gracefully", () => { expect(() => { classifier.classifyProblem(null as any); }).toThrow(); }); it("should handle invalid problem structure", () => { const invalidProblem = { // Missing required fields description: "Test", } as any; expect(() => { classifier.classifyProblem(invalidProblem); }).toThrow(); }); }); describe("Time Pressure Edge Cases", () => { it("should detect urgency negation keywords", () => { const problem: Problem = { id: "test-negation-1", description: "This is not urgent and no immediate action needed", context: "Long-term planning with no urgent requirements", goals: ["Plan for future"], }; const classification = classifier.classifyProblem(problem); // Should not classify as high pressure due to negation expect(classification.timePressure).not.toBe("high"); expect(classification.reasoning.timePressureReason).toBeDefined(); }); it("should handle 'not immediate' negation", () => { const problem: Problem = { id: "test-negation-2", description: "This task is not immediate, we can take our time", context: "Future consideration", goals: ["Research options"], }; const classification = classifier.classifyProblem(problem); // Should not classify as high pressure due to negation expect(classification.timePressure).not.toBe("high"); }); it("should handle 'long-term' keyword", () => { const problem: Problem = { id: "test-negation-3", description: "This is a long-term strategic initiative", context: "Future planning", goals: ["Develop strategy"], }; const classification = classifier.classifyProblem(problem); // Long-term should reduce urgency expect(classification.timePressure).not.toBe("high"); }); it("should handle 'future' keyword", () => { const problem: Problem = { id: "test-negation-4", description: "This is for future consideration", context: "No current deadline", goals: ["Evaluate options"], }; const classification = classifier.classifyProblem(problem); // Future keyword should reduce urgency expect(classification.timePressure).not.toBe("high"); }); it("should detect deadline negation keywords", () => { const problem: Problem = { id: "test-deadline-negation-1", description: "Complete this task with no deadline", context: "Flexible timeline", goals: ["Complete when possible"], }; const classification = classifier.classifyProblem(problem); // No deadline should result in low time pressure expect(classification.reasoning.timePressureReason).toContain("no deadline"); }); it("should detect 'no immediate deadline' negation", () => { const problem: Problem = { id: "test-deadline-negation-2", description: "This has no immediate deadline", context: "Can be done later", goals: ["Complete eventually"], }; const classification = classifier.classifyProblem(problem); // No immediate deadline should reduce urgency expect(classification.timePressure).not.toBe("high"); }); it("should detect 'no specific deadline' negation", () => { const problem: Problem = { id: "test-deadline-negation-3", description: "There is no specific deadline for this", context: "Flexible schedule", goals: ["Complete when ready"], }; const classification = classifier.classifyProblem(problem); // No specific deadline should reduce urgency expect(classification.timePressure).not.toBe("high"); }); it("should calculate days until deadline for 'immediate' keyword", () => { const problem: Problem = { id: "test-days-1", description: "This needs immediate attention with critical deadline", context: "Critical issue requiring immediate action", goals: ["Fix now"], urgency: "high", }; const classification = classifier.classifyProblem(problem); // Immediate with explicit high urgency should be high pressure expect(classification.timePressure).toBe("high"); }); it("should calculate days until deadline for 'now' keyword", () => { const problem: Problem = { id: "test-days-2", description: "We need this now with urgent deadline", context: "Urgent request requiring immediate completion", goals: ["Complete immediately"], urgency: "high", }; const classification = classifier.classifyProblem(problem); // Now with explicit high urgency should be high pressure expect(classification.timePressure).toBe("high"); }); it("should calculate days until deadline for 'outage' keyword", () => { const problem: Problem = { id: "test-days-3", description: "System outage affecting users", context: "Production issue", goals: ["Restore service"], }; const classification = classifier.classifyProblem(problem); // Outage keyword should be detected expect(classification.reasoning.timePressureReason).toBeDefined(); }); it("should calculate days until deadline for 'today' keyword", () => { const problem: Problem = { id: "test-days-4", description: "This must be done today with urgent deadline", context: "Same-day deadline requiring immediate action", goals: ["Complete today"], urgency: "high", }; const classification = classifier.classifyProblem(problem); // Today with explicit high urgency should be high pressure expect(classification.timePressure).toBe("high"); }); it("should calculate days until deadline for 'within 24 hours' keyword", () => { const problem: Problem = { id: "test-days-5", description: "Complete within 24 hours with urgent deadline", context: "Tight deadline requiring immediate action", goals: ["Finish quickly"], urgency: "high", }; const classification = classifier.classifyProblem(problem); // Within 24 hours with explicit high urgency should be high pressure expect(classification.timePressure).toBe("high"); }); it("should calculate days until deadline for 'week' keyword", () => { const problem: Problem = { id: "test-days-6", description: "This is due in a week", context: "One week deadline", goals: ["Complete in 7 days"], }; const classification = classifier.classifyProblem(problem); // Week deadline should be moderate or none expect(["none", "moderate"]).toContain(classification.timePressure); }); it("should calculate days until deadline for '2 weeks' keyword", () => { const problem: Problem = { id: "test-days-7", description: "Deadline is in 2 weeks", context: "Two week timeline", goals: ["Complete in 14 days"], }; const classification = classifier.classifyProblem(problem); // 2 weeks deadline should be moderate or none expect(["none", "moderate"]).toContain(classification.timePressure); }); it("should calculate days until deadline for 'month' keyword", () => { const problem: Problem = { id: "test-days-8", description: "This is due in a month", context: "Monthly deadline", goals: ["Complete in 30 days"], }; const classification = classifier.classifyProblem(problem); // Month deadline should be none or moderate expect(["none", "moderate"]).toContain(classification.timePressure); }); it("should calculate days until deadline for '7 days' explicit", () => { const problem: Problem = { id: "test-days-9", description: "This is due in 7 days", context: "One week timeline", goals: ["Complete in one week"], }; const classification = classifier.classifyProblem(problem); // 7 days deadline should be moderate or none expect(["none", "moderate"]).toContain(classification.timePressure); }); it("should calculate days until deadline for '14 days' explicit", () => { const problem: Problem = { id: "test-days-10", description: "Deadline is in 14 days", context: "Two week period", goals: ["Complete in two weeks"], }; const classification = classifier.classifyProblem(problem); // 14 days deadline should be moderate or none expect(["none", "moderate"]).toContain(classification.timePressure); }); it("should calculate days until deadline for '30 days' explicit", () => { const problem: Problem = { id: "test-days-11", description: "This is due in 30 days", context: "One month period", goals: ["Complete in one month"], }; const classification = classifier.classifyProblem(problem); // 30 days deadline should be none or moderate expect(["none", "moderate"]).toContain(classification.timePressure); }); }); describe("Uncertainty Edge Cases", () => { it("should assess consistency for high uncertainty with no factors", () => { const problem: Problem = { id: "test-consistency-1", description: "Unclear problem with unknown requirements", context: "Very uncertain situation with unclear goals", goals: [], }; const classification = classifier.classifyProblem(problem); expect(classification.uncertainty).toBe("high"); // Confidence should be defined and reasonable expect(classification.confidence).toBeGreaterThan(0); expect(classification.confidence).toBeLessThanOrEqual(1); }); }); });

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