Skip to main content
Glama
socratic-method.ts10.9 kB
/** * Socratic Method Operation * * Uses Socratic questioning approach to explore ideas and uncover assumptions */ import { BaseOperation, type OperationContext, type OperationResult } from '../base.js'; export class SocraticMethodOperation extends BaseOperation { name = 'socratic_method'; category = 'collaborative'; async execute(context: OperationContext): Promise<OperationResult> { const { sessionState, prompt, parameters } = context; // Extract Socratic method parameters const questionType = this.getParam(parameters, 'questionType', 'clarification'); const depth = this.getParam(parameters, 'depth', 3); const assumptions = (parameters.assumptions as string[]) || []; const previousQuestions = (parameters.previousQuestions as any[]) || []; const responses = (parameters.responses as any[]) || []; // Generate question sequence based on type and depth const questionSequence = this.generateQuestionSequence( prompt, questionType, depth, previousQuestions ); // Analyze assumptions if provided const assumptionAnalysis = assumptions.length > 0 ? this.analyzeAssumptions(assumptions) : this.extractAssumptions(prompt); // Build dialogue tree const dialogueTree = this.buildDialogueTree(questionSequence, responses); const socraticData = { topic: prompt, questionType, depth, questionSequence, assumptions: assumptionAnalysis, dialogueTree, insights: this.extractInsights(questionSequence, responses), nextQuestion: this.generateNextQuestion(questionSequence, responses), sessionId: `socratic-${Date.now()}`, round: this.getParam(parameters, 'round', 1), explorationComplete: this.isExplorationComplete(questionSequence, responses, depth), }; // Update session metrics sessionState.updateKPI('socratic_questions', questionSequence.length); sessionState.updateKPI('assumptions_examined', assumptionAnalysis.length); return this.createResult({ ...socraticData, sessionContext: { sessionId: sessionState.sessionId, stats: sessionState.getStats(), }, }); } private generateQuestionSequence( topic: string, questionType: string, depth: number, previousQuestions: any[] ): any[] { const questionTypes = { clarification: this.generateClarificationQuestions, assumptions: this.generateAssumptionQuestions, evidence: this.generateEvidenceQuestions, perspective: this.generatePerspectiveQuestions, implications: this.generateImplicationQuestions, meta: this.generateMetaQuestions, }; const generator = questionTypes[questionType as keyof typeof questionTypes] || questionTypes.clarification; const newQuestions = generator.call(this, topic, depth); return [...previousQuestions, ...newQuestions.slice(0, depth)]; } private generateClarificationQuestions(topic: string, depth: number): any[] { return [ { type: 'clarification', question: `What do you mean when you say "${topic}"?`, purpose: 'Define key terms and concepts', level: 1, }, { type: 'clarification', question: `Can you give me an example of what you're describing?`, purpose: 'Seek concrete examples', level: 2, }, { type: 'clarification', question: `How does this relate to what we discussed earlier?`, purpose: 'Connect to broader context', level: 3, }, ].slice(0, depth); } private generateAssumptionQuestions(topic: string, depth: number): any[] { return [ { type: 'assumptions', question: `What assumptions are you making about ${topic}?`, purpose: 'Identify underlying assumptions', level: 1, }, { type: 'assumptions', question: `What if the opposite were true?`, purpose: 'Challenge core assumptions', level: 2, }, { type: 'assumptions', question: `How can we verify these assumptions?`, purpose: 'Test assumption validity', level: 3, }, ].slice(0, depth); } private generateEvidenceQuestions(topic: string, depth: number): any[] { return [ { type: 'evidence', question: `What evidence supports your view on ${topic}?`, purpose: 'Examine supporting evidence', level: 1, }, { type: 'evidence', question: `What evidence might contradict this view?`, purpose: 'Consider counter-evidence', level: 2, }, { type: 'evidence', question: `How reliable is this evidence?`, purpose: 'Evaluate evidence quality', level: 3, }, ].slice(0, depth); } private generatePerspectiveQuestions(topic: string, depth: number): any[] { return [ { type: 'perspective', question: `How might someone who disagrees view ${topic}?`, purpose: 'Explore alternative viewpoints', level: 1, }, { type: 'perspective', question: `What are the strengths and weaknesses of this alternative view?`, purpose: 'Analyze competing perspectives', level: 2, }, { type: 'perspective', question: `Why might this perspective exist?`, purpose: 'Understand perspective origins', level: 3, }, ].slice(0, depth); } private generateImplicationQuestions(topic: string, depth: number): any[] { return [ { type: 'implications', question: `What are the implications of your view on ${topic}?`, purpose: 'Explore consequences', level: 1, }, { type: 'implications', question: `If this is true, what follows from it?`, purpose: 'Trace logical implications', level: 2, }, { type: 'implications', question: `How does this affect our original problem?`, purpose: 'Connect back to core issue', level: 3, }, ].slice(0, depth); } private generateMetaQuestions(topic: string, depth: number): any[] { return [ { type: 'meta', question: `Why is this question about ${topic} important?`, purpose: 'Examine question significance', level: 1, }, { type: 'meta', question: `What does this tell us about how we think about such issues?`, purpose: 'Reflect on thinking patterns', level: 2, }, { type: 'meta', question: `How has our understanding changed through this inquiry?`, purpose: 'Assess learning progress', level: 3, }, ].slice(0, depth); } private analyzeAssumptions(assumptions: string[]): any[] { return assumptions.map((assumption, index) => ({ assumption, type: this.categorizeAssumption(assumption), questionable: Math.random() > 0.3, // 70% are questionable evidence: `Evidence level: ${Math.floor(Math.random() * 5) + 1}/5`, alternative: `Alternative to: ${assumption}`, })); } private extractAssumptions(topic: string): any[] { // Simple pattern-based assumption extraction const commonAssumptions = [ `Current approach to ${topic} is optimal`, `The problem with ${topic} has a single solution`, `Past experience with ${topic} predicts future outcomes`, ]; return commonAssumptions.map(assumption => ({ assumption, type: 'implicit', questionable: true, evidence: 'Needs verification', alternative: `Question: ${assumption}`, })); } private categorizeAssumption(assumption: string): string { if (assumption.toLowerCase().includes('always') || assumption.toLowerCase().includes('never')) { return 'absolute'; } if (assumption.toLowerCase().includes('should') || assumption.toLowerCase().includes('must')) { return 'normative'; } if (assumption.toLowerCase().includes('cause') || assumption.toLowerCase().includes('because')) { return 'causal'; } return 'descriptive'; } private buildDialogueTree(questions: any[], responses: any[]): any { const tree = { nodes: questions.map((q, index) => ({ id: `q${index}`, question: q.question, type: q.type, level: q.level, response: responses[index]?.response || null, followUps: responses[index]?.followUps || [], })), connections: questions.map((_, index) => ({ from: index > 0 ? `q${index - 1}` : 'root', to: `q${index}`, relationship: 'follows', })), }; return tree; } private extractInsights(questions: any[], responses: any[]): string[] { const insights: string[] = []; // Extract insights based on question types and responses const questionTypes = [...new Set(questions.map(q => q.type))]; questionTypes.forEach(type => { insights.push(`${type} exploration revealed new perspectives`); }); if (responses.length > 0) { insights.push(`${responses.length} responses provided deeper understanding`); } insights.push('Socratic inquiry uncovered hidden assumptions'); return insights; } private generateNextQuestion(questions: any[], responses: any[]): any { const lastQuestion = questions[questions.length - 1]; const lastResponse = responses[responses.length - 1]; if (!lastQuestion) { return { question: 'What would you like to explore?', type: 'clarification', purpose: 'Begin inquiry', level: 1, }; } // Generate follow-up based on last question type const followUpTemplates = { clarification: 'Can you elaborate on that point?', assumptions: 'What leads you to that assumption?', evidence: 'What other evidence should we consider?', perspective: 'How might others see this differently?', implications: 'What are the broader consequences?', meta: 'What does this reveal about our inquiry process?', }; return { question: followUpTemplates[lastQuestion.type as keyof typeof followUpTemplates] || 'What should we explore next?', type: lastQuestion.type, purpose: 'Follow up on previous response', level: lastQuestion.level + 1, }; } private isExplorationComplete(questions: any[], responses: any[], targetDepth: number): boolean { return questions.length >= targetDepth && responses.length >= Math.floor(targetDepth * 0.8); // 80% response rate } } export default new SocraticMethodOperation();

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/waldzellai/clearthought-onepointfive'

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