|
|
|
|
|
class MemoryHandler { |
|
|
constructor(options = {}) { |
|
|
|
|
|
this.maxMessagesPerUser = options.maxMessagesPerUser || 50; |
|
|
|
|
|
this.maxMemoryAge = options.maxMemoryAge || 30 * 60 * 1000; |
|
|
|
|
|
this.memories = new Map(); |
|
|
|
|
|
console.log(`Memory handler initialized (max ${this.maxMessagesPerUser} messages per user, ${this.maxMemoryAge/60000} minutes retention)`); |
|
|
|
|
|
|
|
|
this.startCleanupInterval(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addMessage(username, message, isBot = false) { |
|
|
|
|
|
const normalizedUsername = username.toLowerCase(); |
|
|
|
|
|
|
|
|
if (!this.memories.has(normalizedUsername)) { |
|
|
this.memories.set(normalizedUsername, []); |
|
|
} |
|
|
|
|
|
const userMemory = this.memories.get(normalizedUsername); |
|
|
|
|
|
|
|
|
userMemory.push({ |
|
|
timestamp: Date.now(), |
|
|
message: message, |
|
|
isBot: isBot |
|
|
}); |
|
|
|
|
|
|
|
|
if (userMemory.length > this.maxMessagesPerUser) { |
|
|
userMemory.shift(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cleanupOldMessages() { |
|
|
const now = Date.now(); |
|
|
const cutoffTime = now - this.maxMemoryAge; |
|
|
|
|
|
|
|
|
for (const [username, messages] of this.memories.entries()) { |
|
|
|
|
|
const freshMessages = messages.filter(msg => msg.timestamp >= cutoffTime); |
|
|
|
|
|
if (freshMessages.length === 0) { |
|
|
|
|
|
this.memories.delete(username); |
|
|
} else if (freshMessages.length < messages.length) { |
|
|
|
|
|
this.memories.set(username, freshMessages); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
startCleanupInterval() { |
|
|
|
|
|
setInterval(() => { |
|
|
this.cleanupOldMessages(); |
|
|
}, 5 * 60 * 1000); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getStats() { |
|
|
return { |
|
|
userCount: this.memories.size, |
|
|
totalMessages: Array.from(this.memories.values()) |
|
|
.reduce((total, messages) => total + messages.length, 0), |
|
|
oldestMessage: this.getOldestMessageTime() |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|