get_lesson_recommendations
Retrieve relevant lessons based on your current context to enhance learning and problem-solving with personalized recommendations.
Instructions
Get relevant lessons based on the current context
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| context | Yes | The current context to find relevant lessons for |
Implementation Reference
- index.ts:845-903 (handler)Main handler function in KnowledgeGraphManager class that implements get_lesson_recommendations tool logic: loads lessons from files, calculates similarity scores based on error patterns, observations, relations, and success rates against provided context, filters and sorts by relevance.async getLessonRecommendations(context: string): Promise<LessonEntity[]> { // Load all files containing lessons const lessonFiles = await this.fileManager.getFilesForEntityType('lesson'); const allLessons: LessonEntity[] = []; // Load and merge lessons from all files for (const filePath of lessonFiles) { try { const fileContent = await fs.readFile(filePath, 'utf-8'); const fileGraph = JSON.parse(fileContent); const lessons = fileGraph.entities.filter((e: Entity): e is LessonEntity => e.entityType === 'lesson' ); allLessons.push(...lessons); } catch (error) { console.error(`Error loading lessons from ${filePath}:`, error); } } // Calculate relevance scores for each lesson const scoredLessons = await Promise.all( allLessons.map(async (lesson) => { let score = 0; // Check error pattern fields if (lesson.errorPattern) { score += this.calculateSimilarity(lesson.errorPattern.type, context) * 0.3; score += this.calculateSimilarity(lesson.errorPattern.message, context) * 0.3; score += this.calculateSimilarity(lesson.errorPattern.context, context) * 0.2; } // Check observations const observationScores = lesson.observations.map(obs => this.calculateSimilarity(obs, context) ); if (observationScores.length > 0) { score += Math.max(...observationScores) * 0.2; } // Check related lessons const relatedLessons = await this.getRelatedLessons(lesson.name); if (relatedLessons.length > 0) { score *= 1.2; // Boost score for lessons with relations } // Consider success rate const successRate = lesson.metadata?.successRate ?? 0; score *= (1 + successRate) / 2; // Weight by success rate return { lesson, score }; }) ); // Filter lessons with a minimum relevance score and sort by score return scoredLessons .filter(({ score }) => score > 0.1) // Minimum relevance threshold .sort((a, b) => b.score - a.score) .map(({ lesson }) => lesson); }
- index.ts:1197-1210 (registration)Tool registration in the ListToolsRequestSchema handler, defining name, description, and input schema.{ name: "get_lesson_recommendations", description: "Get relevant lessons based on the current context", inputSchema: { type: "object", properties: { context: { type: "string", description: "The current context to find relevant lessons for" } }, required: ["context"] } }
- index.ts:1251-1252 (handler)Dispatch case in CallToolRequestSchema handler that invokes the getLessonRecommendations method.case "get_lesson_recommendations": return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.getLessonRecommendations(args.context as string), null, 2) }] };
- index.ts:69-73 (schema)Type definition for LessonEntity used in the tool's return type.interface LessonEntity extends Entity { errorPattern: ErrorPattern; metadata: Metadata; verificationSteps: VerificationStep[]; }
- index.ts:761-786 (helper)Helper function used by getLessonRecommendations to compute similarity between context and lesson components.private calculateSimilarity(str1: string, str2: string): number { const s1 = str1.toLowerCase(); const s2 = str2.toLowerCase(); // Exact match if (s1 === s2) return 1; // Contains full string if (s1.includes(s2) || s2.includes(s1)) return 0.8; // Split into words and check for word matches const words1 = s1.split(/\s+/); const words2 = s2.split(/\s+/); const commonWords = words1.filter(w => words2.includes(w)); if (commonWords.length > 0) { return 0.5 * (commonWords.length / Math.max(words1.length, words2.length)); } // Partial word matches const partialMatches = words1.filter(w1 => words2.some(w2 => w1.includes(w2) || w2.includes(w1)) ); return 0.3 * (partialMatches.length / Math.max(words1.length, words2.length)); }