contaigents
Version:
Modular AI Content Ecosystem with Audio Generation
145 lines (144 loc) • 5.57 kB
JavaScript
export class MemoryManager {
constructor(toolManager, config) {
this.toolManager = toolManager;
this.config = {
maxConversationHistory: 20, // Keep last 20 messages
maxToolResponseAge: 1, // Tool responses active for 1 turn only
autoStoreToolResults: true,
enableEndOfTurnMemory: true,
...config
};
}
/**
* Process tool responses and handle automatic memory storage
*/
async processToolResponses(session, toolResponses) {
if (!this.config.autoStoreToolResults)
return;
const memoryTool = this.toolManager.getTool('memory');
if (!memoryTool)
return;
// Store non-memory tool results in memory
for (const response of toolResponses) {
if (response.tool_call.tool_name !== 'memory') {
await memoryTool.storeToolResponse(response.tool_call.tool_name, response.result, response.tool_call.parameters);
}
}
}
/**
* Trim conversation history and move old messages to memory
*/
async trimConversationHistory(session) {
if (session.messages.length <= this.config.maxConversationHistory) {
return;
}
const memoryTool = this.toolManager.getTool('memory');
if (!memoryTool)
return;
// Keep system message and recent messages
const systemMessages = session.messages.filter(m => m.role === 'system');
const nonSystemMessages = session.messages.filter(m => m.role !== 'system');
if (nonSystemMessages.length <= this.config.maxConversationHistory) {
return;
}
// Messages to move to memory (older messages)
const messagesToArchive = nonSystemMessages.slice(0, -this.config.maxConversationHistory);
const messagesToKeep = nonSystemMessages.slice(-this.config.maxConversationHistory);
// Store conversation summary in memory
if (messagesToArchive.length > 0) {
await memoryTool.storeConversationSummary(messagesToArchive);
}
// Update session with trimmed messages
session.messages = [...systemMessages, ...messagesToKeep];
session.updatedAt = Date.now();
console.log(`🧠 Trimmed conversation: moved ${messagesToArchive.length} messages to memory, kept ${messagesToKeep.length} recent messages`);
}
/**
* Remove old tool responses from conversation history
*/
cleanupToolResponses(session, currentTurn) {
// Mark tool responses older than maxToolResponseAge for removal
session.messages = session.messages.filter(message => {
const chatMessage = message;
if (chatMessage.isToolResponse && chatMessage.toolResponseTurn) {
const age = currentTurn - chatMessage.toolResponseTurn;
return age <= this.config.maxToolResponseAge;
}
return true;
});
}
/**
* Check if response contains only memory tool calls (end-of-turn memory)
*/
isEndOfTurnMemoryOnly(toolCalls) {
if (!this.config.enableEndOfTurnMemory || toolCalls.length === 0) {
return false;
}
// Check if all tool calls are memory operations
return toolCalls.every(call => call.tool_name === 'memory');
}
/**
* Process end-of-turn memory calls without triggering new LLM turn
*/
async processEndOfTurnMemory(session, toolCalls, assistantMessage) {
if (!this.isEndOfTurnMemoryOnly(toolCalls)) {
return false;
}
console.log(`🧠 Processing ${toolCalls.length} end-of-turn memory calls...`);
// Execute memory tool calls
const toolResponses = [];
for (const toolCall of toolCalls) {
const result = await this.toolManager.executeTool(toolCall);
toolResponses.push({
id: toolCall.id || `memory_${Date.now()}`,
tool_call: toolCall,
result
});
if (result.success) {
console.log(` ✅ Memory operation successful: ${result.message}`);
}
else {
console.log(` ❌ Memory operation failed: ${result.error}`);
}
}
// Add assistant message to session (without tool responses in conversation)
session.messages.push(assistantMessage);
session.updatedAt = Date.now();
return true; // Indicates this was handled as end-of-turn memory
}
/**
* Get memory statistics for debugging
*/
async getMemoryStats() {
const memoryTool = this.toolManager.getTool('memory');
if (!memoryTool) {
return { error: 'Memory tool not available' };
}
try {
const result = await memoryTool.execute({ operation: 'read' });
if (result.success) {
return {
totalEntries: result.data.total_entries,
memoryFile: result.data.memory_file,
config: this.config
};
}
return { error: result.error };
}
catch (error) {
return { error: error.message };
}
}
/**
* Update memory configuration
*/
updateConfig(newConfig) {
this.config = { ...this.config, ...newConfig };
}
/**
* Get current memory configuration
*/
getConfig() {
return { ...this.config };
}
}