mukti-mcp-server
Version:
A Socratic AI assistant MCP server that guides users to think for themselves rather than providing direct answers
487 lines (486 loc) • 21.6 kB
JavaScript
/**
* Response Strategies for the Mukti MCP Server
*
* This module provides sophisticated response strategies for different query types
* and contexts, implementing the Socratic method with tailored approaches for
* coding, creative work, decision-making, personal growth, learning, and problem-solving.
*
* @todo These response strategies are currently under development and will be completed in future releases.
*/
import { QueryType, SocraticTechnique } from "./types.js";
/**
* Response strategy factory for different query types and contexts
*/
export class ResponseStrategyFactory {
/**
* Generate a strategic response based on query type and context
*/
static generateStrategicResponse(query, queryType, preferredTechnique) {
const context = this.analyzeQueryContext(query);
const strategy = this.selectResponseStrategy(queryType, context, preferredTechnique);
return {
questions: this.generateStrategicQuestions(query, queryType, strategy, context),
hints: this.generateContextualHints(query, queryType, context),
resources: this.curateContextualResources(query, queryType, context),
strategy,
context,
nextSteps: this.generateNextSteps(queryType, context),
alternativePaths: this.generateAlternativePaths(queryType, context),
encouragement: this.generateEncouragement(context, strategy),
};
}
/**
* Analyze the query context for better response strategy selection
*/
static analyzeQueryContext(query) {
const lowerQuery = query.toLowerCase();
const stuckIndicators = [];
// Emotional state analysis
let emotionalState = "neutral";
if (lowerQuery.includes("frustrated") ||
lowerQuery.includes("stuck") ||
lowerQuery.includes("confused")) {
emotionalState = "frustrated";
stuckIndicators.push("emotional_frustration");
}
else if (lowerQuery.includes("curious") ||
lowerQuery.includes("wonder") ||
lowerQuery.includes("explore")) {
emotionalState = "curious";
}
else if (lowerQuery.includes("think") ||
lowerQuery.includes("believe") ||
lowerQuery.includes("sure")) {
emotionalState = "confident";
}
else if (lowerQuery.includes("don't understand") ||
lowerQuery.includes("unclear") ||
lowerQuery.includes("confusing")) {
emotionalState = "confused";
stuckIndicators.push("conceptual_confusion");
}
// Complexity analysis
let complexity = "medium";
const complexityIndicators = [
"architecture",
"design",
"system",
"advanced",
"complex",
"sophisticated",
];
const simpleIndicators = ["simple", "basic", "easy", "quick", "beginner"];
if (complexityIndicators.some((indicator) => lowerQuery.includes(indicator))) {
complexity = "high";
}
else if (simpleIndicators.some((indicator) => lowerQuery.includes(indicator))) {
complexity = "low";
}
// Time constraint analysis
let timeConstraint = "unknown";
if (lowerQuery.includes("urgent") ||
lowerQuery.includes("asap") ||
lowerQuery.includes("quickly")) {
timeConstraint = "urgent";
}
else if (lowerQuery.includes("explore") ||
lowerQuery.includes("learn") ||
lowerQuery.includes("understand")) {
timeConstraint = "relaxed";
}
// Prior knowledge analysis
let priorKnowledge = "unknown";
if (lowerQuery.includes("beginner") ||
lowerQuery.includes("new to") ||
lowerQuery.includes("never done")) {
priorKnowledge = "beginner";
}
else if (lowerQuery.includes("experienced") ||
lowerQuery.includes("familiar") ||
lowerQuery.includes("worked with")) {
priorKnowledge = "intermediate";
}
else if (lowerQuery.includes("expert") ||
lowerQuery.includes("advanced") ||
lowerQuery.includes("deep")) {
priorKnowledge = "advanced";
}
// Additional stuck indicators
if (lowerQuery.includes("not working") ||
lowerQuery.includes("broken") ||
lowerQuery.includes("error")) {
stuckIndicators.push("technical_issue");
}
if (lowerQuery.includes("don't know") ||
lowerQuery.includes("no idea") ||
lowerQuery.includes("clueless")) {
stuckIndicators.push("knowledge_gap");
}
return {
complexity,
emotionalState,
timeConstraint,
priorKnowledge,
stuckIndicators,
};
}
/**
* Select the most appropriate response strategy based on query type and context
*/
static selectResponseStrategy(queryType, context, preferredTechnique) {
const baseStrategies = {
[QueryType.CODING]: {
primaryTechnique: SocraticTechnique.ELENCHUS,
secondaryTechniques: [
SocraticTechnique.DIALECTIC,
SocraticTechnique.COUNTERFACTUAL,
],
contextualHints: [
"Break the problem down into smaller, testable components",
"Consider what assumptions you're making about the system",
"Think about edge cases and error conditions",
],
followUpQuestions: [
"What would happen if you simplified this to its core essence?",
"What debugging steps have you already tried?",
"What would you do if you had to explain this to a rubber duck?",
],
avoidancePatterns: [
"Here's the exact code to copy...",
"The answer is...",
"Just do this...",
],
encouragementPhrases: [
"You're thinking like a true problem-solver",
"That's exactly the kind of systematic approach that works",
"You're building valuable debugging skills",
],
},
[QueryType.CREATIVE]: {
primaryTechnique: SocraticTechnique.MAIEUTICS,
secondaryTechniques: [
SocraticTechnique.ANALOGICAL,
SocraticTechnique.COUNTERFACTUAL,
],
contextualHints: [
"Consider combining seemingly unrelated concepts",
"Think about what constraints might actually be liberating",
"Explore what emotions or experiences you want to evoke",
],
followUpQuestions: [
"What would make this uniquely yours?",
"What would happen if you challenged your first instinct?",
"What story are you trying to tell?",
],
avoidancePatterns: [
"You should create...",
"The best approach is...",
"Copy this style...",
],
encouragementPhrases: [
"Your creative instincts are guiding you well",
"That's an interesting direction to explore",
"You're discovering your unique voice",
],
},
[QueryType.DECISION_MAKING]: {
primaryTechnique: SocraticTechnique.DIALECTIC,
secondaryTechniques: [
SocraticTechnique.ELENCHUS,
SocraticTechnique.COUNTERFACTUAL,
],
contextualHints: [
"Consider the reversibility of this decision",
"Think about what you're optimizing for in the long term",
"Examine what values are driving your choice",
],
followUpQuestions: [
"What would your future self think about this decision?",
"What would you advise a friend in this situation?",
"What are you afraid might happen if you choose differently?",
],
avoidancePatterns: [
"You should definitely...",
"The right choice is...",
"Here's what I would do...",
],
encouragementPhrases: [
"You're thinking through this thoughtfully",
"That's excellent reflection on your values",
"You're building strong decision-making skills",
],
},
[QueryType.PERSONAL_GROWTH]: {
primaryTechnique: SocraticTechnique.MAIEUTICS,
secondaryTechniques: [
SocraticTechnique.ELENCHUS,
SocraticTechnique.ANALOGICAL,
],
contextualHints: [
"Focus on systems and habits rather than just outcomes",
"Consider what you might be avoiding or resisting",
"Think about what growth means to you specifically",
],
followUpQuestions: [
"What patterns do you notice in your own behavior?",
"What would the wisest version of yourself say?",
"What would growth look like if fear wasn't a factor?",
],
avoidancePatterns: [
"You need to...",
"The solution is...",
"Here's how to fix yourself...",
],
encouragementPhrases: [
"You're showing real self-awareness",
"That's a powerful insight about yourself",
"You're on a meaningful journey of growth",
],
},
[QueryType.LEARNING]: {
primaryTechnique: SocraticTechnique.MAIEUTICS,
secondaryTechniques: [
SocraticTechnique.DIALECTIC,
SocraticTechnique.ANALOGICAL,
],
contextualHints: [
"Try to connect new information to what you already know",
"Consider teaching the concept to someone else",
"Look for real-world applications and examples",
],
followUpQuestions: [
"What connections can you make to things you already understand?",
"What questions does this raise for you?",
"How might you explain this to someone else?",
],
avoidancePatterns: [
"The answer is...",
"You need to memorize...",
"Here's what it means...",
],
encouragementPhrases: [
"You're building deep understanding",
"That's exactly the kind of question that leads to insight",
"You're developing strong learning skills",
],
},
[QueryType.PROBLEM_SOLVING]: {
primaryTechnique: SocraticTechnique.ELENCHUS,
secondaryTechniques: [
SocraticTechnique.DIALECTIC,
SocraticTechnique.ANALOGICAL,
],
contextualHints: [
"Consider whether you're solving the right problem",
"Think about the problem from different perspectives",
"Look for the simplest solution that could work",
],
followUpQuestions: [
"How do you know this is the real problem?",
"What would happen if you approached this completely differently?",
"What similar problems have you solved before?",
],
avoidancePatterns: [
"The solution is...",
"You should try...",
"Here's how to fix it...",
],
encouragementPhrases: [
"You're thinking systematically about this",
"That's a thoughtful approach to problem-solving",
"You're developing valuable analytical skills",
],
},
};
const baseStrategy = baseStrategies[queryType];
// Adjust strategy based on context
if (preferredTechnique) {
baseStrategy.primaryTechnique = preferredTechnique;
}
// Context-specific adjustments
if (context.emotionalState === "frustrated") {
baseStrategy.encouragementPhrases = [
"It's completely normal to feel stuck sometimes",
"You're working through this methodically",
"Each question brings you closer to understanding",
...baseStrategy.encouragementPhrases,
];
}
if (context.timeConstraint === "urgent") {
baseStrategy.followUpQuestions = [
"What's the simplest approach that could work?",
"What's the most critical piece to figure out first?",
...baseStrategy.followUpQuestions.slice(0, 2),
];
}
return baseStrategy;
}
/**
* Generate strategic questions based on strategy and context
*/
static generateStrategicQuestions(query, queryType, strategy, context) {
const questions = [];
// Add strategy-specific questions
questions.push(...strategy.followUpQuestions);
// Add context-specific questions
if (context.stuckIndicators.includes("technical_issue")) {
questions.push("What was the last thing that worked before this issue appeared?");
questions.push("What would happen if you started with a minimal working example?");
}
if (context.stuckIndicators.includes("knowledge_gap")) {
questions.push("What do you already know that might be related to this?");
questions.push("What would be the smallest step forward you could take?");
}
if (context.priorKnowledge === "beginner") {
questions.push("What foundational concepts might be important to understand first?");
questions.push("What would you want to learn if you had unlimited time?");
}
return questions.slice(0, 5); // Limit to 5 questions to avoid overwhelming
}
/**
* Generate contextual hints based on query type and context
*/
static generateContextualHints(query, queryType, context) {
const hints = [];
// Add base hints from strategy
const strategy = this.selectResponseStrategy(queryType, context);
hints.push(...strategy.contextualHints);
// Add context-specific hints
if (context.complexity === "high") {
hints.push("Consider breaking this into smaller, more manageable pieces");
}
if (context.emotionalState === "frustrated") {
hints.push("Take a step back and approach this with fresh perspective");
hints.push("Sometimes the best insights come when we're not forcing them");
}
if (context.timeConstraint === "urgent") {
hints.push("Focus on the minimum viable solution first");
hints.push("What's the 80/20 approach here?");
}
return hints.slice(0, 4); // Limit to 4 hints
}
/**
* Curate contextual resources based on query type and context
*/
static curateContextualResources(query, queryType, context) {
const resources = [];
// Add base resources for query type
switch (queryType) {
case QueryType.CODING:
resources.push({
title: "Rubber Duck Debugging",
url: "https://rubberduckdebugging.com/",
description: "A method of debugging code by explaining it line-by-line",
category: "debugging",
});
if (context.priorKnowledge === "beginner") {
resources.push({
title: "Problem-Solving for Programmers",
url: "https://www.freecodecamp.org/news/how-to-think-like-a-programmer/",
description: "Learn systematic approaches to programming problems",
category: "learning",
});
}
break;
case QueryType.CREATIVE:
resources.push({
title: "Creative Constraints",
url: "https://www.fastcompany.com/90320616/the-creative-power-of-constraints",
description: "How limitations can actually boost creativity",
category: "creativity",
});
break;
case QueryType.DECISION_MAKING:
resources.push({
title: "Decision-Making Frameworks",
url: "https://fs.blog/decision-making/",
description: "Mental models for better decision making",
category: "decision-making",
});
break;
case QueryType.PERSONAL_GROWTH:
resources.push({
title: "Socratic Self-Reflection",
url: "https://www.philosophy.org/socratic-method/",
description: "Using philosophical inquiry for personal development",
category: "self-improvement",
});
break;
case QueryType.LEARNING:
resources.push({
title: "Learning How to Learn",
url: "https://www.coursera.org/learn/learning-how-to-learn",
description: "Evidence-based techniques for effective learning",
category: "learning",
});
break;
case QueryType.PROBLEM_SOLVING:
resources.push({
title: "Problem-Solving Strategies",
url: "https://www.khanacademy.org/computing/computer-programming/programming/intro-to-programming/a/problem-solving-strategies",
description: "Systematic approaches to problem solving",
category: "problem-solving",
});
break;
}
return resources;
}
/**
* Generate next steps based on query type and context
*/
static generateNextSteps(queryType, context) {
const steps = [];
if (context.stuckIndicators.length > 0) {
steps.push("Take a few minutes to reflect on the questions above");
steps.push("Try one small experiment or test");
}
steps.push("Consider discussing this with someone else");
steps.push("Document your thought process as you work through this");
if (context.timeConstraint === "urgent") {
steps.push("Focus on the most critical aspect first");
}
else {
steps.push("Explore the resources provided for deeper understanding");
}
return steps;
}
/**
* Generate alternative exploration paths
*/
static generateAlternativePaths(queryType, context) {
const paths = [];
switch (queryType) {
case QueryType.CODING:
paths.push("Approach this as a debugging exercise");
paths.push("Think about it as a design problem");
paths.push("Consider it from a testing perspective");
break;
case QueryType.CREATIVE:
paths.push("Explore through constraints and limitations");
paths.push("Approach through emotional resonance");
paths.push("Consider the audience's perspective");
break;
case QueryType.DECISION_MAKING:
paths.push("Analyze through different value systems");
paths.push("Consider long-term vs. short-term implications");
paths.push("Evaluate through risk assessment");
break;
}
return paths;
}
/**
* Generate encouragement based on context and strategy
*/
static generateEncouragement(context, strategy) {
const encouragements = strategy.encouragementPhrases;
if (context.emotionalState === "frustrated") {
return ("Remember, feeling stuck is part of the learning process. " +
encouragements[Math.floor(Math.random() * encouragements.length)]);
}
if (context.emotionalState === "curious") {
return ("Your curiosity is your greatest asset here. " +
encouragements[Math.floor(Math.random() * encouragements.length)]);
}
return encouragements[Math.floor(Math.random() * encouragements.length)];
}
}