UNPKG

education-module-ai

Version:
529 lines (528 loc) 21.1 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LearningSessionController = void 0; const agent_framework_backend_1 = require("@defikitdotnet/agent-framework-backend"); const uuid_1 = require("uuid"); const LearningSession_1 = require("../models/LearningSession"); const LearningPath_1 = require("../models/LearningPath"); const plugin_manager_1 = require("../plugins/plugin-manager"); const ai_service_1 = require("../services/ai-service"); const progress_tracking_service_1 = require("../services/progress-tracking-service"); // In-memory storage for demo purposes const sessionStore = {}; const userSessions = {}; // userId -> sessionIds const learningPaths = {}; // pathId -> path // Create a resource implementation for LearningSessionResource const learningSessionResource = { name: "learning-sessions", findAll: async () => Object.values(sessionStore), findById: async (id) => sessionStore[id] || null, create: async (data) => { const id = (0, uuid_1.v4)(); const newSession = new LearningSession_1.LearningSessionResource(); Object.assign(newSession, data, { id, startTime: new Date(), active: true, messages: data.messages || [], }); sessionStore[id] = newSession; // Add to user sessions if (!userSessions[newSession.userId]) { userSessions[newSession.userId] = []; } userSessions[newSession.userId].push(id); return newSession; }, update: async (id, data) => { if (!sessionStore[id]) return null; const updated = { ...sessionStore[id], ...data }; sessionStore[id] = updated; return updated; }, delete: async (id) => { if (!sessionStore[id]) return false; // Remove from user sessions const userId = sessionStore[id].userId; if (userSessions[userId]) { userSessions[userId] = userSessions[userId].filter((sessionId) => sessionId !== id); } delete sessionStore[id]; return true; }, findByUserId: async (userId) => { return Object.values(sessionStore).filter((session) => session.userId === userId); }, findActiveByUserId: async (userId) => { return Object.values(sessionStore).find((session) => session.userId === userId && session.active); }, }; // Create a resource implementation for LearningPathResource const learningPathResource = { name: "learning-paths", findAll: async () => Object.values(learningPaths), findById: async (id) => learningPaths[id] || null, create: async (data) => { const id = data.id || (0, uuid_1.v4)(); const newPath = new LearningPath_1.LearningPathResource(); Object.assign(newPath, data, { id, createdAt: new Date(), updatedAt: new Date(), }); learningPaths[id] = newPath; return newPath; }, update: async (id, data) => { if (!learningPaths[id]) return null; const updated = { ...learningPaths[id], ...data, updatedAt: new Date() }; learningPaths[id] = updated; return updated; }, delete: async (id) => { if (!learningPaths[id]) return false; delete learningPaths[id]; return true; }, findByUserId: async (userId) => { return Object.values(learningPaths).filter((path) => path.userId === userId); }, }; /** * Learning Session API controller */ let LearningSessionController = class LearningSessionController extends agent_framework_backend_1.ResourceController { constructor() { super(learningSessionResource); this.educationModuleAdapter = null; } setEducationModuleAdapter(adapter) { this.educationModuleAdapter = adapter; console.log("EducationModuleAdapter set in controller"); } /** * Get learning sessions for a user using the database adapter */ async getUserLearningSessions(req, res) { const { userId } = req.params; if (this.educationModuleAdapter) { const sessions = await this.educationModuleAdapter.getLearningSessionsForUser(userId); res.status(200).json({ data: sessions }); } else { res.status(500).json({ error: "EducationModuleAdapter not set" }); } } /** * Get a learning session by ID using the database adapter */ async getLearningSession(req, res) { const { id } = req.params; if (this.educationModuleAdapter) { const session = await this.educationModuleAdapter.getLearningSession(id); res.status(200).json({ data: session }); } else { res.status(500).json({ error: "EducationModuleAdapter not set" }); } } /** * Create a new learning session using the database adapter */ async createLearningSession(req, res) { const { userId, subject, level, name } = req.body; if (this.educationModuleAdapter) { const session = await this.educationModuleAdapter.createLearningSession(req.body); res.status(200).json({ data: session }); } } /** * Update a learning session using the database adapter */ async updateLearningSession(req, res) { const { id } = req.params; const { userId, subject, level, name } = req.body; if (this.educationModuleAdapter) { const session = await this.educationModuleAdapter.updateLearningSession(req.body); res.status(200).json({ data: session }); } } /** * Get learning path by ID using the database adapter */ async getDbLearningPath(req, res) { const { id } = req.params; if (this.educationModuleAdapter) { const path = await this.educationModuleAdapter.getLearningPath(id); res.status(200).json({ data: path }); } } /** * Get learning paths for a user using the database adapter */ async getDbLearningPathsForUser(req, res) { const { userId } = req.params; if (this.educationModuleAdapter) { const paths = await this.educationModuleAdapter.getLearningPathsForUser(userId); res.status(200).json({ data: paths }); } } /** * Create a new learning path using the database adapter */ async createDbLearningPath(req, res) { const { userId, subject, level, name } = req.body; if (this.educationModuleAdapter) { const path = await this.educationModuleAdapter.createLearningPath(req.body); res.status(200).json({ data: path }); } } /** * Update a learning path using the database adapter */ async updateDbLearningPath(req, res) { const { id } = req.params; if (this.educationModuleAdapter) { const path = await this.educationModuleAdapter.updateLearningPath(req.body); res.status(200).json({ data: path }); } } /** * Start a new learning session */ async startSession(req, res) { const { userId, subject, level, name } = req.body; if (!userId || !subject || !level) { res.status(400).json({ error: "Missing required fields" }); return; } try { // Check if user already has an active session const activeSession = await learningSessionResource.findActiveByUserId(userId); if (activeSession) { res.status(400).json({ error: "User already has an active session", data: { activeSessionId: activeSession.id }, }); return; } // Create initial system message const initialMessage = { role: "assistant", content: `Welcome to your ${subject} learning session! How can I help you today?`, timestamp: new Date(), interactionType: "answer", }; // Create new session const newSession = await this.resource.create({ userId, subject: subject, level, messages: [initialMessage], }); // Notify plugins await plugin_manager_1.pluginManager.notifySessionStarted(newSession); res.status(201).json({ data: newSession }); } catch (error) { console.error("Error starting learning session:", error); res.status(500).json({ error: "Failed to start learning session" }); } } /** * End an active learning session */ async endSession(req, res) { const { id } = req.params; const { feedback } = req.body; try { const session = await this.resource.findById(id); if (!session) { res.status(404).json({ error: "Session not found" }); return; } if (!session.active) { res.status(400).json({ error: "Session is already ended" }); return; } // Update session const updatedSession = await this.resource.update(id, { active: false, endTime: new Date(), feedback, }); // Track session completion await progress_tracking_service_1.progressTrackingService.trackSessionCompletion(session.userId, session.id, session.subject); // Notify plugins await plugin_manager_1.pluginManager.notifySessionEnded(updatedSession); res.status(200).json({ data: updatedSession }); } catch (error) { console.error("Error ending learning session:", error); res.status(500).json({ error: "Failed to end learning session" }); } } /** * Send a message in a learning session */ async sendMessage(req, res) { const { id } = req.params; const { content, interactionType = "question" } = req.body; if (!content) { res.status(400).json({ error: "Message content is required" }); return; } try { const session = await this.resource.findById(id); if (!session) { res.status(404).json({ error: "Session not found" }); return; } if (!session.active) { res.status(400).json({ error: "Cannot send message to an ended session" }); return; } // Add user message const userMessage = { role: "user", content, timestamp: new Date(), interactionType: interactionType, }; session.messages.push(userMessage); // Process with AI service const aiResponse = await ai_service_1.aiService.processLearningSessionMessage(session.messages, session.subject, session.level, interactionType); // Add assistant response const assistantMessage = { role: "assistant", content: aiResponse.response, timestamp: new Date(), interactionType: "answer", relatedContentIds: aiResponse.relatedContentIds, }; session.messages.push(assistantMessage); // Update session const updatedSession = await this.resource.update(id, { messages: session.messages, }); // Notify plugins await plugin_manager_1.pluginManager.notifySessionMessageSent(updatedSession, userMessage); res.status(200).json({ data: { session: updatedSession, followupSuggestions: aiResponse.followupSuggestions, }, }); } catch (error) { console.error("Error sending message:", error); res.status(500).json({ error: "Failed to send message" }); } } /** * Generate a learning path */ async generateLearningPath(req, res) { const { userId, topic } = req.body; if (!userId || !topic) { res.status(400).json({ error: "User ID and topic are required" }); return; } try { console.log(`Generating learning path for topic: "${topic}" for user: ${userId}`); // Generate learning path with AI service const learningPath = await ai_service_1.aiService.generateLearningPath(topic, userId); // Save the generated learning path await learningPathResource.create(learningPath); // Notify plugins await plugin_manager_1.pluginManager.notifyLearningPathGenerated(learningPath); res.status(200).json({ data: learningPath }); } catch (error) { console.error("Error generating learning path:", error); res.status(500).json({ error: "Failed to generate learning path" }); } } /** * Get all learning paths for a user */ async getUserLearningPaths(req, res) { const { userId } = req.params; try { const paths = await learningPathResource.findByUserId(userId); res.status(200).json({ data: paths }); } catch (error) { console.error("Error retrieving user learning paths:", error); res.status(500).json({ error: "Failed to retrieve user learning paths" }); } } /** * Get a specific learning path */ async getLearningPath(req, res) { const { id } = req.params; try { const path = await learningPathResource.findById(id); if (!path) { res.status(404).json({ error: "Learning path not found" }); return; } res.status(200).json({ data: path }); } catch (error) { console.error("Error retrieving learning path:", error); res.status(500).json({ error: "Failed to retrieve learning path" }); } } /** * Get all sessions for a user */ async getUserSessions(req, res) { const { userId } = req.params; try { const sessions = await learningSessionResource.findByUserId(userId); res.status(200).json({ data: sessions }); } catch (error) { console.error("Error retrieving user sessions:", error); res.status(500).json({ error: "Failed to retrieve user sessions" }); } } /** * Get active session for a user */ async getActiveSession(req, res) { const { userId } = req.params; try { const activeSession = await learningSessionResource.findActiveByUserId(userId); if (!activeSession) { res.status(404).json({ error: "No active session found for user" }); return; } res.status(200).json({ data: activeSession }); } catch (error) { console.error("Error retrieving active session:", error); res.status(500).json({ error: "Failed to retrieve active session" }); } } }; exports.LearningSessionController = LearningSessionController; __decorate([ (0, agent_framework_backend_1.Get)("/user/:userId"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getUserLearningSessions", null); __decorate([ (0, agent_framework_backend_1.Get)("/:id"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getLearningSession", null); __decorate([ (0, agent_framework_backend_1.Post)("/"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "createLearningSession", null); __decorate([ (0, agent_framework_backend_1.Put)("/:id"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "updateLearningSession", null); __decorate([ (0, agent_framework_backend_1.Get)("/paths/:id"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getDbLearningPath", null); __decorate([ (0, agent_framework_backend_1.Get)("/paths/user/:userId"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getDbLearningPathsForUser", null); __decorate([ (0, agent_framework_backend_1.Post)("/paths"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "createDbLearningPath", null); __decorate([ (0, agent_framework_backend_1.Put)("/paths/:id"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "updateDbLearningPath", null); __decorate([ (0, agent_framework_backend_1.Post)("/start"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "startSession", null); __decorate([ (0, agent_framework_backend_1.Post)("/:id/end"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "endSession", null); __decorate([ (0, agent_framework_backend_1.Post)("/:id/message"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "sendMessage", null); __decorate([ (0, agent_framework_backend_1.Post)("/generate-path"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "generateLearningPath", null); __decorate([ (0, agent_framework_backend_1.Get)("/paths/user/:userId"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getUserLearningPaths", null); __decorate([ (0, agent_framework_backend_1.Get)("/paths/:id"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getLearningPath", null); __decorate([ (0, agent_framework_backend_1.Get)("/user/:userId"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getUserSessions", null); __decorate([ (0, agent_framework_backend_1.Get)("/user/:userId/active"), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], LearningSessionController.prototype, "getActiveSession", null); exports.LearningSessionController = LearningSessionController = __decorate([ (0, agent_framework_backend_1.Controller)("/api/learning-sessions"), __metadata("design:paramtypes", []) ], LearningSessionController);