Zanny's Persistent Memory Manager
by zannyonear1h1
Verified
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemoryManager = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const crypto_1 = __importDefault(require("crypto"));
const config_1 = require("./config");
const logger_1 = __importDefault(require("./logger"));
class MemoryManager {
memoriesDir;
constructor() {
this.memoriesDir = config_1.config.memoriesDir;
this.ensureMemoriesDirectory();
}
/**
* Ensures the memories directory exists
*/
ensureMemoriesDirectory() {
try {
fs_extra_1.default.ensureDirSync(this.memoriesDir);
logger_1.default.info(`Ensured memories directory exists at: ${this.memoriesDir}`);
}
catch (error) {
logger_1.default.error(`Failed to create memories directory: ${error}`);
throw new Error(`Failed to create memories directory: ${error}`);
}
}
/**
* Generates a file path for a memory
* @param id Memory ID
* @returns Full file path for the memory
*/
getMemoryFilePath(id) {
return path_1.default.join(this.memoriesDir, `${id}.json`);
}
/**
* Stores a new memory or updates an existing one
* @param content Memory content
* @param tags Optional tags for categorization
* @returns Stored memory object
*/
async storeMemory(content, tags) {
try {
// Generate a unique ID based on content hash
const id = crypto_1.default.createHash('md5').update(content).digest('hex');
const filePath = this.getMemoryFilePath(id);
// Check if memory already exists
let memory;
const now = new Date();
if (await fs_extra_1.default.pathExists(filePath)) {
// Update existing memory
memory = await fs_extra_1.default.readJson(filePath);
memory.content = content;
memory.tags = tags || memory.tags;
memory.updatedAt = now;
}
else {
// Create new memory
memory = {
id,
content,
tags: tags || [],
createdAt: now,
updatedAt: now
};
}
// Write memory to file
await fs_extra_1.default.writeJson(filePath, memory, { spaces: 2 });
logger_1.default.info(`Memory stored: ${id}`);
return memory;
}
catch (error) {
logger_1.default.error(`Failed to store memory: ${error}`);
throw new Error(`Failed to store memory: ${error}`);
}
}
/**
* Retrieves a memory by its ID
* @param id Memory ID
* @returns Memory object or null if not found
*/
async getMemoryById(id) {
try {
const filePath = this.getMemoryFilePath(id);
if (await fs_extra_1.default.pathExists(filePath)) {
const memory = await fs_extra_1.default.readJson(filePath);
logger_1.default.info(`Memory retrieved: ${id}`);
return memory;
}
logger_1.default.warn(`Memory not found: ${id}`);
return null;
}
catch (error) {
logger_1.default.error(`Failed to retrieve memory by ID: ${error}`);
throw new Error(`Failed to retrieve memory by ID: ${error}`);
}
}
/**
* Searches for memories that contain specific text or have specific tags
* @param searchText Text to search for in memory content
* @param tags Tags to filter by
* @returns Array of matching memories
*/
async searchMemories(searchText, tags) {
try {
const result = [];
const files = await fs_extra_1.default.readdir(this.memoriesDir);
for (const file of files) {
if (path_1.default.extname(file) === '.json') {
const filePath = path_1.default.join(this.memoriesDir, file);
const memory = await fs_extra_1.default.readJson(filePath);
let match = true;
// Match by content if searchText is provided
if (searchText && !memory.content.toLowerCase().includes(searchText.toLowerCase())) {
match = false;
}
// Match by tags if provided
if (tags && tags.length > 0) {
if (!memory.tags || !tags.some(tag => memory.tags?.includes(tag))) {
match = false;
}
}
if (match) {
result.push(memory);
}
}
}
logger_1.default.info(`Found ${result.length} memories matching search criteria`);
return result;
}
catch (error) {
logger_1.default.error(`Failed to search memories: ${error}`);
throw new Error(`Failed to search memories: ${error}`);
}
}
/**
* Lists all memories
* @returns Array of all memories
*/
async listAllMemories() {
try {
const result = [];
const files = await fs_extra_1.default.readdir(this.memoriesDir);
for (const file of files) {
if (path_1.default.extname(file) === '.json') {
const filePath = path_1.default.join(this.memoriesDir, file);
const memory = await fs_extra_1.default.readJson(filePath);
result.push(memory);
}
}
logger_1.default.info(`Listed all memories: ${result.length} found`);
return result;
}
catch (error) {
logger_1.default.error(`Failed to list all memories: ${error}`);
throw new Error(`Failed to list all memories: ${error}`);
}
}
/**
* Deletes a memory by its ID
* @param id Memory ID
* @returns Whether the memory was deleted
*/
async deleteMemory(id) {
try {
const filePath = this.getMemoryFilePath(id);
if (await fs_extra_1.default.pathExists(filePath)) {
await fs_extra_1.default.unlink(filePath);
logger_1.default.info(`Memory deleted: ${id}`);
return true;
}
logger_1.default.warn(`Cannot delete - Memory not found: ${id}`);
return false;
}
catch (error) {
logger_1.default.error(`Failed to delete memory: ${error}`);
throw new Error(`Failed to delete memory: ${error}`);
}
}
}
exports.MemoryManager = MemoryManager;