betty2 / memory-handler.js
sdgsdggds's picture
Upload folder using huggingface_hub
e7c953d verified
// Conversation memory handler for DubAPI bot
class MemoryHandler {
constructor(options = {}) {
// Maximum number of messages to remember per user
this.maxMessagesPerUser = options.maxMessagesPerUser || 50;
// Maximum age of messages to keep (in milliseconds)
this.maxMemoryAge = options.maxMemoryAge || 30 * 60 * 1000; // Default: 30 minutes
// Memory storage: Map of username -> array of message objects
this.memories = new Map();
console.log(`Memory handler initialized (max ${this.maxMessagesPerUser} messages per user, ${this.maxMemoryAge/60000} minutes retention)`);
// Set up periodic cleanup
this.startCleanupInterval();
}
/**
* Add a message to a user's conversation history
* @param {string} username - The username of the person speaking
* @param {string} message - The message content
* @param {boolean} isBot - Whether this message was from the bot
*/
addMessage(username, message, isBot = false) {
// Normalize username to lowercase for consistent lookups
const normalizedUsername = username.toLowerCase();
// Get or create user's memory array
if (!this.memories.has(normalizedUsername)) {
this.memories.set(normalizedUsername, []);
}
const userMemory = this.memories.get(normalizedUsername);
// Add new message with timestamp
userMemory.push({
timestamp: Date.now(),
message: message,
isBot: isBot
});
// Trim to max size if needed
if (userMemory.length > this.maxMessagesPerUser) {
userMemory.shift(); // Remove oldest message
}
}
/**
* Get conversation history for a user
* @param {string} username - The username to get history for
* @param {number} limit - Maximum number of messages to retrieve (defaults to all)
* @returns {Array} - Array of conversation messages
*/
getConversationHistory(username, limit = null) {
const normalizedUsername = username.toLowerCase();
if (!this.memories.has(normalizedUsername)) {
return [];
}
const userMemory = this.memories.get(normalizedUsername);
const result = limit ? userMemory.slice(-limit) : userMemory;
return result;
}
/**
* Format conversation history for use in AI prompt
* @param {string} username - The username to get history for
* @param {number} limit - Maximum number of messages to include
* @returns {string} - Formatted conversation history
*/
getFormattedHistory(username, limit = 5) {
const history = this.getConversationHistory(username, limit);
if (history.length === 0) {
return "";
}
let formatted = "Previous conversation:\n";
history.forEach(item => {
const speaker = item.isBot ? "Bot" : username;
formatted += `${speaker}: ${item.message}\n`;
});
return formatted;
}
/**
* Remove old messages from memory that exceed the age limit
*/
cleanupOldMessages() {
const now = Date.now();
const cutoffTime = now - this.maxMemoryAge;
// Check each user's memory
for (const [username, messages] of this.memories.entries()) {
// Filter out old messages
const freshMessages = messages.filter(msg => msg.timestamp >= cutoffTime);
if (freshMessages.length === 0) {
// Remove empty memory arrays
this.memories.delete(username);
} else if (freshMessages.length < messages.length) {
// Update with only fresh messages
this.memories.set(username, freshMessages);
}
}
}
/**
* Start automatic cleanup interval
*/
startCleanupInterval() {
// Run cleanup every 5 minutes
setInterval(() => {
this.cleanupOldMessages();
}, 5 * 60 * 1000);
}
/**
* Get stats about the memory system
* @returns {Object} - Stats about memory usage
*/
getStats() {
return {
userCount: this.memories.size,
totalMessages: Array.from(this.memories.values())
.reduce((total, messages) => total + messages.length, 0),
oldestMessage: this.getOldestMessageTime()
};
}
/**
* Get the timestamp of the oldest message in memory
* @returns {number|null} - Timestamp or null if no messages
*/
getOldestMessageTime() {
let oldest = null;
for (const messages of this.memories.values()) {
for (const msg of messages) {
if (oldest === null || msg.timestamp < oldest) {
oldest = msg.timestamp;
}
}
}
return oldest;
}
}
module.exports = MemoryHandler;