@defikitdotnet/education-module-ai
Version:
AI Education Module using Agent Framework
480 lines (479 loc) • 27.1 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EducationModuleAdapter = exports.educationSqliteTables = exports.ResourceType = exports.ModuleAdapter = void 0;
exports.initEducationDatabase = initEducationDatabase;
var uuid_1 = require("uuid");
/**
* Base class for module-specific adapters
* Modules can extend this to create specialized database access
* without creating multiple database connections
*/
var ModuleAdapter = /** @class */ (function () {
function ModuleAdapter(databaseAdapter) {
this.databaseAdapter = databaseAdapter;
}
/**
* Get the underlying database instance
*/
ModuleAdapter.prototype.getDatabase = function () {
return this.databaseAdapter["db"];
};
/**
* Get the database adapter this module is using
*/
ModuleAdapter.prototype.getDatabaseAdapter = function () {
return this.databaseAdapter;
};
return ModuleAdapter;
}());
exports.ModuleAdapter = ModuleAdapter;
/**
* Resource type for learning resources
*/
var ResourceType;
(function (ResourceType) {
ResourceType["ARTICLE"] = "article";
ResourceType["VIDEO"] = "video";
ResourceType["EXERCISE"] = "exercise";
ResourceType["BOOK"] = "book";
ResourceType["COURSE"] = "course";
})(ResourceType || (exports.ResourceType = ResourceType = {}));
/**
* SQL schema for education module tables
*/
exports.educationSqliteTables = "\n-- Educational Content table\nCREATE TABLE IF NOT EXISTS educational_contents (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n type TEXT NOT NULL,\n subject TEXT NOT NULL,\n level TEXT NOT NULL,\n keywords TEXT,\n agentId TEXT REFERENCES accounts(id) ON DELETE CASCADE,\n createdAt INTEGER NOT NULL,\n updatedAt INTEGER\n);\n\n-- Learning Sessions table\nCREATE TABLE IF NOT EXISTS learning_sessions (\n id TEXT PRIMARY KEY,\n agentId TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,\n subject TEXT NOT NULL,\n level TEXT NOT NULL,\n startTime INTEGER NOT NULL,\n endTime INTEGER,\n active INTEGER NOT NULL DEFAULT 1,\n messages TEXT NOT NULL,\n feedback TEXT\n);\n\n-- User Profiles table\nCREATE TABLE IF NOT EXISTS user_profiles (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT,\n createdAt INTEGER NOT NULL,\n learningStyles TEXT,\n subjectProgress TEXT,\n recommendations TEXT,\n goals TEXT,\n streak INTEGER NOT NULL DEFAULT 0,\n lastActive INTEGER,\n badges TEXT,\n totalLearningTime INTEGER NOT NULL DEFAULT 0\n);\n\n-- Learning Paths table\nCREATE TABLE IF NOT EXISTS learning_paths (\n id TEXT PRIMARY KEY,\n agentId TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,\n subject TEXT NOT NULL,\n topic TEXT NOT NULL,\n overview TEXT NOT NULL,\n difficultyLevel TEXT NOT NULL,\n estimatedCompletionTime TEXT NOT NULL,\n prerequisites TEXT,\n steps TEXT NOT NULL,\n createdAt INTEGER NOT NULL,\n updatedAt INTEGER NOT NULL\n);\n";
/**
* Initialize the education module database
* @param databaseAdapter The database adapter from the main application
* @returns The education module adapter
*/
function initEducationDatabase(databaseAdapter) {
return __awaiter(this, void 0, void 0, function () {
var db;
return __generator(this, function (_a) {
db = databaseAdapter["db"];
// Execute the table creation SQL
db.exec(exports.educationSqliteTables);
// Create and return the education module adapter
return [2 /*return*/, new EducationModuleAdapter(databaseAdapter)];
});
});
}
/**
* Education Module SQLite Database Adapter
* Handles database operations for the education module
*/
var EducationModuleAdapter = /** @class */ (function (_super) {
__extends(EducationModuleAdapter, _super);
function EducationModuleAdapter(databaseAdapter) {
return _super.call(this, databaseAdapter) || this;
}
/**
* Initialize the database tables
*/
EducationModuleAdapter.prototype.init = function () {
try {
var db = this.getDatabase();
db.exec(exports.educationSqliteTables);
console.log("Education module database tables initialized successfully");
}
catch (error) {
console.error("Failed to initialize education module database tables:", error);
throw error;
}
};
/**
* Get all educational contents
*/
EducationModuleAdapter.prototype.getEducationalContents = function () {
return __awaiter(this, void 0, void 0, function () {
var sql, rows;
return __generator(this, function (_a) {
sql = "SELECT * FROM educational_contents";
rows = this.getDatabase().prepare(sql).all();
return [2 /*return*/, rows.map(function (row) { return (__assign(__assign({}, row), { keywords: JSON.parse(row.keywords || "[]"), createdAt: new Date(row.createdAt), updatedAt: row.updatedAt ? new Date(row.updatedAt) : undefined })); })];
});
});
};
/**
* Get an educational content by ID
*/
EducationModuleAdapter.prototype.getEducationalContent = function (id) {
return __awaiter(this, void 0, void 0, function () {
var sql, row;
return __generator(this, function (_a) {
sql = "SELECT * FROM educational_contents WHERE id = ?";
row = this.getDatabase().prepare(sql).get(id);
if (!row)
return [2 /*return*/, null];
return [2 /*return*/, __assign(__assign({}, row), { keywords: JSON.parse(row.keywords || "[]"), createdAt: new Date(row.createdAt), updatedAt: row.updatedAt ? new Date(row.updatedAt) : undefined })];
});
});
};
/**
* Get educational contents by agentId
*/
EducationModuleAdapter.prototype.getEducationalContentsByAgentId = function (agentId) {
return __awaiter(this, void 0, void 0, function () {
var sql, rows;
return __generator(this, function (_a) {
if (!agentId) {
return [2 /*return*/, []];
}
sql = "SELECT * FROM educational_contents WHERE agentId = ?";
rows = this.getDatabase().prepare(sql).all(agentId);
return [2 /*return*/, rows.map(function (row) { return (__assign(__assign({}, row), { keywords: JSON.parse(row.keywords || "[]"), createdAt: new Date(row.createdAt), updatedAt: row.updatedAt ? new Date(row.updatedAt) : undefined })); })];
});
});
};
/**
* Create a new educational content
*/
EducationModuleAdapter.prototype.createEducationalContent = function (content) {
return __awaiter(this, void 0, void 0, function () {
var id, createdAtTimestamp, updatedAtTimestamp, keywords, sql, db, stmt;
return __generator(this, function (_a) {
try {
console.log("EducationModuleAdapter.createEducationalContent called with:", JSON.stringify(__assign(__assign({}, content), { content: content.content
? content.content.substring(0, 50) + "..."
: undefined }), null, 2));
id = content.id || (0, uuid_1.v4)();
createdAtTimestamp = void 0;
updatedAtTimestamp = null;
// Handle createdAt - convert any possible format to a timestamp
if (content.createdAt instanceof Date) {
createdAtTimestamp = content.createdAt.getTime();
}
else if (typeof content.createdAt === "string") {
createdAtTimestamp = new Date(content.createdAt).getTime();
}
else if (typeof content.createdAt === "number") {
createdAtTimestamp = content.createdAt;
}
else {
createdAtTimestamp = Date.now();
}
// Handle updatedAt - convert any possible format to a timestamp
if (content.updatedAt instanceof Date) {
updatedAtTimestamp = content.updatedAt.getTime();
}
else if (typeof content.updatedAt === "string") {
updatedAtTimestamp = new Date(content.updatedAt).getTime();
}
else if (typeof content.updatedAt === "number") {
updatedAtTimestamp = content.updatedAt;
}
keywords = Array.isArray(content.keywords) ? content.keywords : [];
sql = "\n INSERT INTO educational_contents (\n id, title, content, type, subject, level, keywords, agentId, createdAt, updatedAt\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ";
console.log("SQL parameters:", [
id,
content.title,
content.content,
content.type,
content.subject,
content.level,
JSON.stringify(keywords),
content.agentId,
createdAtTimestamp,
updatedAtTimestamp,
]);
db = this.getDatabase();
if (!db) {
throw new Error("Database not initialized or not accessible");
}
stmt = db.prepare(sql);
console.log("Running SQL insertion");
stmt.run(id, content.title, content.content, content.type, content.subject, content.level, JSON.stringify(keywords), content.agentId, createdAtTimestamp, updatedAtTimestamp);
console.log("Content created with ID:", id);
return [2 /*return*/, id];
}
catch (error) {
console.error("Database error creating educational content:", error);
throw new Error("Failed to create educational content: ".concat(error.message));
}
return [2 /*return*/];
});
});
};
/**
* Update an educational content
*/
EducationModuleAdapter.prototype.updateEducationalContent = function (content) {
return __awaiter(this, void 0, void 0, function () {
var sql, result;
return __generator(this, function (_a) {
sql = "\n UPDATE educational_contents\n SET title = ?, content = ?, type = ?, subject = ?, level = ?,\n keywords = ?, agentId = ?, updatedAt = ?\n WHERE id = ?\n ";
result = this.getDatabase()
.prepare(sql)
.run(content.title, content.content, content.type, content.subject, content.level, JSON.stringify(content.keywords || []), content.agentId || null, Date.now(), content.id);
return [2 /*return*/, result.changes > 0];
});
});
};
/**
* Delete an educational content
*/
EducationModuleAdapter.prototype.deleteEducationalContent = function (id) {
return __awaiter(this, void 0, void 0, function () {
var sql, result;
return __generator(this, function (_a) {
sql = "DELETE FROM educational_contents WHERE id = ?";
result = this.getDatabase().prepare(sql).run(id);
return [2 /*return*/, result.changes > 0];
});
});
};
/**
* Get learning sessions for a user
*/
EducationModuleAdapter.prototype.getLearningSessionsForUser = function (agentId) {
return __awaiter(this, void 0, void 0, function () {
var sql, rows;
return __generator(this, function (_a) {
sql = "SELECT * FROM learning_sessions WHERE agentId = ?";
rows = this.getDatabase().prepare(sql).all(agentId);
return [2 /*return*/, rows.map(function (row) { return (__assign(__assign({}, row), { messages: JSON.parse(row.messages || "[]"), startTime: new Date(row.startTime), endTime: row.endTime ? new Date(row.endTime) : undefined, active: Boolean(row.active) })); })];
});
});
};
/**
* Get a learning session by ID
*/
EducationModuleAdapter.prototype.getLearningSession = function (id) {
return __awaiter(this, void 0, void 0, function () {
var sql, row;
return __generator(this, function (_a) {
sql = "SELECT * FROM learning_sessions WHERE id = ?";
row = this.getDatabase().prepare(sql).get(id);
if (!row)
return [2 /*return*/, null];
return [2 /*return*/, __assign(__assign({}, row), { messages: JSON.parse(row.messages || "[]"), startTime: new Date(row.startTime), endTime: row.endTime ? new Date(row.endTime) : undefined, active: Boolean(row.active) })];
});
});
};
/**
* Create a new learning session
*/
EducationModuleAdapter.prototype.createLearningSession = function (session) {
return __awaiter(this, void 0, void 0, function () {
var id, sql;
return __generator(this, function (_a) {
id = session.id || (0, uuid_1.v4)();
sql = "\n INSERT INTO learning_sessions (\n id, agentId, subject, level, startTime, endTime, active, messages, feedback\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ";
this.getDatabase()
.prepare(sql)
.run(id, session.agentId, session.subject, session.level, session.startTime.getTime(), session.endTime ? session.endTime.getTime() : null, session.active ? 1 : 0, JSON.stringify(session.messages || []), session.feedback || null);
return [2 /*return*/, id];
});
});
};
/**
* Update a learning session
*/
EducationModuleAdapter.prototype.updateLearningSession = function (session) {
return __awaiter(this, void 0, void 0, function () {
var sql, result;
return __generator(this, function (_a) {
sql = "\n UPDATE learning_sessions\n SET subject = ?, level = ?, endTime = ?, active = ?, messages = ?, feedback = ?\n WHERE id = ?\n ";
result = this.getDatabase()
.prepare(sql)
.run(session.subject, session.level, session.endTime ? session.endTime.getTime() : null, session.active ? 1 : 0, JSON.stringify(session.messages || []), session.feedback || null, session.id);
return [2 /*return*/, result.changes > 0];
});
});
};
/**
* Get user profile by ID
*/
EducationModuleAdapter.prototype.getUserProfile = function (id) {
return __awaiter(this, void 0, void 0, function () {
var sql, row;
return __generator(this, function (_a) {
sql = "SELECT * FROM user_profiles WHERE id = ?";
row = this.getDatabase().prepare(sql).get(id);
if (!row)
return [2 /*return*/, null];
return [2 /*return*/, __assign(__assign({}, row), { learningStyles: JSON.parse(row.learningStyles || "[]"), subjectProgress: JSON.parse(row.subjectProgress || "{}"), recommendations: JSON.parse(row.recommendations || "[]"), goals: JSON.parse(row.goals || "[]"), badges: JSON.parse(row.badges || "[]"), createdAt: new Date(row.createdAt), lastActive: row.lastActive ? new Date(row.lastActive) : undefined })];
});
});
};
/**
* Get all user profiles
*/
EducationModuleAdapter.prototype.getAllUserProfiles = function () {
return __awaiter(this, void 0, void 0, function () {
var sql, rows;
return __generator(this, function (_a) {
sql = "SELECT * FROM user_profiles";
rows = this.getDatabase().prepare(sql).all();
return [2 /*return*/, rows.map(function (row) { return (__assign(__assign({}, row), { learningStyles: JSON.parse(row.learningStyles || "[]"), subjectProgress: JSON.parse(row.subjectProgress || "{}"), recommendations: JSON.parse(row.recommendations || "[]"), goals: JSON.parse(row.goals || "[]"), badges: JSON.parse(row.badges || "[]"), createdAt: new Date(row.createdAt), lastActive: row.lastActive ? new Date(row.lastActive) : undefined })); })];
});
});
};
/**
* Create or update a user profile
*/
EducationModuleAdapter.prototype.saveUserProfile = function (profile) {
return __awaiter(this, void 0, void 0, function () {
var id, existingProfile, sql, sql;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
id = profile.id || (0, uuid_1.v4)();
return [4 /*yield*/, this.getUserProfile(id)];
case 1:
existingProfile = _a.sent();
if (existingProfile) {
sql = "\n UPDATE user_profiles\n SET name = ?, email = ?, learningStyles = ?, subjectProgress = ?,\n recommendations = ?, goals = ?, streak = ?, lastActive = ?,\n badges = ?, totalLearningTime = ?\n WHERE id = ?\n ";
this.getDatabase()
.prepare(sql)
.run(profile.name, profile.email || null, JSON.stringify(profile.learningStyles || []), JSON.stringify(profile.subjectProgress || {}), JSON.stringify(profile.recommendations || []), JSON.stringify(profile.goals || []), profile.streak, profile.lastActive ? profile.lastActive.getTime() : null, JSON.stringify(profile.badges || []), profile.totalLearningTime, id);
}
else {
sql = "\n INSERT INTO user_profiles (\n id, name, email, createdAt, learningStyles, subjectProgress,\n recommendations, goals, streak, lastActive, badges, totalLearningTime\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ";
this.getDatabase()
.prepare(sql)
.run(id, profile.name, profile.email || null, profile.createdAt.getTime(), JSON.stringify(profile.learningStyles || []), JSON.stringify(profile.subjectProgress || {}), JSON.stringify(profile.recommendations || []), JSON.stringify(profile.goals || []), profile.streak, profile.lastActive ? profile.lastActive.getTime() : null, JSON.stringify(profile.badges || []), profile.totalLearningTime);
}
return [2 /*return*/, id];
}
});
});
};
/**
* Get all learning paths
*/
EducationModuleAdapter.prototype.getAllLearningPaths = function () {
return __awaiter(this, void 0, void 0, function () {
var sql, rows;
return __generator(this, function (_a) {
sql = "SELECT * FROM learning_paths";
rows = this.getDatabase().prepare(sql).all();
return [2 /*return*/, rows.map(function (row) { return (__assign(__assign({}, row), { prerequisites: JSON.parse(row.prerequisites || "[]"), steps: JSON.parse(row.steps || "[]"), createdAt: new Date(row.createdAt), updatedAt: new Date(row.updatedAt) })); })];
});
});
};
/**
* Get learning path by ID
*/
EducationModuleAdapter.prototype.getLearningPath = function (id) {
return __awaiter(this, void 0, void 0, function () {
var sql, row;
return __generator(this, function (_a) {
sql = "SELECT * FROM learning_paths WHERE id = ?";
row = this.getDatabase().prepare(sql).get(id);
if (!row)
return [2 /*return*/, null];
return [2 /*return*/, __assign(__assign({}, row), { prerequisites: JSON.parse(row.prerequisites || "[]"), steps: JSON.parse(row.steps || "[]"), createdAt: new Date(row.createdAt), updatedAt: new Date(row.updatedAt) })];
});
});
};
/**
* Get learning paths for a user
*/
EducationModuleAdapter.prototype.getLearningPathsForUser = function (agentId) {
return __awaiter(this, void 0, void 0, function () {
var sql, rows;
return __generator(this, function (_a) {
sql = "SELECT * FROM learning_paths WHERE agentId = ?";
rows = this.getDatabase().prepare(sql).all(agentId);
return [2 /*return*/, rows.map(function (row) { return (__assign(__assign({}, row), { prerequisites: JSON.parse(row.prerequisites || "[]"), steps: JSON.parse(row.steps || "[]"), createdAt: new Date(row.createdAt), updatedAt: new Date(row.updatedAt) })); })];
});
});
};
/**
* Create a new learning path
*/
EducationModuleAdapter.prototype.createLearningPath = function (path) {
return __awaiter(this, void 0, void 0, function () {
var id, sql;
return __generator(this, function (_a) {
id = path.id || (0, uuid_1.v4)();
sql = "\n INSERT INTO learning_paths (\n id, agentId, subject, topic, overview, difficultyLevel,\n estimatedCompletionTime, prerequisites, steps, createdAt, updatedAt\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ";
this.getDatabase()
.prepare(sql)
.run(id, path.agentId, path.subject, path.topic, path.overview, path.difficultyLevel, path.estimatedCompletionTime, JSON.stringify(path.prerequisites || []), JSON.stringify(path.steps || []), path.createdAt.getTime(), path.updatedAt.getTime());
return [2 /*return*/, id];
});
});
};
/**
* Update a learning path
*/
EducationModuleAdapter.prototype.updateLearningPath = function (path) {
return __awaiter(this, void 0, void 0, function () {
var sql, result;
return __generator(this, function (_a) {
sql = "\n UPDATE learning_paths\n SET subject = ?, topic = ?, overview = ?, difficultyLevel = ?,\n estimatedCompletionTime = ?, prerequisites = ?, steps = ?, updatedAt = ?\n WHERE id = ?\n ";
result = this.getDatabase()
.prepare(sql)
.run(path.subject, path.topic, path.overview, path.difficultyLevel, path.estimatedCompletionTime, JSON.stringify(path.prerequisites || []), JSON.stringify(path.steps || []), path.updatedAt.getTime(), path.id);
return [2 /*return*/, result.changes > 0];
});
});
};
return EducationModuleAdapter;
}(ModuleAdapter));
exports.EducationModuleAdapter = EducationModuleAdapter;