File size: 5,140 Bytes
e7c953d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
// 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;
|