education-module-ai
Version:
AI Education Module using Agent Framework
529 lines (528 loc) • 21.1 kB
JavaScript
;
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);