memory_cleanup
Clear outdated or unnecessary data from persistent memory to maintain optimal performance and storage efficiency in LLM sessions.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/modules/MemoryManagement.js:14-47 (registration)Registers the memory_cleanup tool with the server, including description, input schema (dryRun, minQualityScore, maxAge, keepCount), and delegates to handleCleanup method.registerCleanupTool(server) { server.registerTool( 'memory_cleanup', 'Clean up old or low-quality facts based on retention policies', { type: 'object', properties: { dryRun: { type: 'boolean', description: 'If true, show what would be deleted without actually deleting', default: true, }, minQualityScore: { type: 'number', description: 'Minimum quality score to keep facts', default: 40, }, maxAge: { type: 'number', description: 'Maximum age in days to keep facts (0 = no age limit)', default: 0, }, keepCount: { type: 'number', description: 'Minimum number of facts to keep regardless of quality', default: 100, }, }, }, async (args) => { return await this.handleCleanup(args); } ); }
- Executes the cleanup: queries all facts, filters by quality score, age, ensures minimum keep count, performs dry-run preview or actual deletion via factStore.deleteFact, returns formatted response with results or errors.async handleCleanup(args) { try { const { dryRun = true, minQualityScore = 40, maxAge = 0, keepCount = 100 } = args; const allFacts = await this.factStore.queryFacts({ query: '', limit: 10000, }); let toDelete = allFacts.facts.filter(fact => fact.qualityScore < minQualityScore); if (maxAge > 0) { const cutoffDate = new Date(Date.now() - (maxAge * 24 * 60 * 60 * 1000)); toDelete = toDelete.filter(fact => new Date(fact.createdAt) < cutoffDate); } const totalFacts = allFacts.facts.length; const factsToKeep = totalFacts - toDelete.length; if (factsToKeep < keepCount && toDelete.length > 0) { const sortedToDelete = toDelete.sort((a, b) => b.qualityScore - a.qualityScore); const reduceBy = keepCount - factsToKeep; toDelete = sortedToDelete.slice(reduceBy); } if (dryRun) { return { content: [ { type: 'text', text: `π§Ή **Cleanup Preview** (Dry Run)\n\n**Would delete:** ${toDelete.length} facts\n**Would keep:** ${totalFacts - toDelete.length} facts\n**Criteria:** Quality < ${minQualityScore}${maxAge > 0 ? `, Age > ${maxAge} days` : ''}\n\n**Sample facts to delete:**\n${toDelete.slice(0, 5).map(f => `- ${f.type}: ${f.content.substring(0, 60)}... (Score: ${f.qualityScore})`).join('\n')}${toDelete.length > 5 ? `\n... and ${toDelete.length - 5} more` : ''}`, }, ], }; } let deleted = 0; const errors = []; for (const fact of toDelete) { try { await this.factStore.deleteFact(fact.id); deleted++; } catch (error) { errors.push(`Failed to delete fact ${fact.id}: ${error.message}`); } } let response = `π§Ή **Cleanup Complete**\n\n**Deleted:** ${deleted} facts\n**Failed:** ${toDelete.length - deleted} facts\n**Remaining:** ${totalFacts - deleted} facts`; if (errors.length > 0) { response += `\n\n**Errors:**\n${errors.slice(0, 3).join('\n')}${errors.length > 3 ? `\n... and ${errors.length - 3} more errors` : ''}`; } return { content: [ { type: 'text', text: response, }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error during cleanup: ${error.message}`, }, ], isError: true, }; } }
- src/tools/MemoryTools.js:23-29 (registration)MemoryTools.registerTools calls this.management.registerTools(server), which triggers the registration of memory_cleanup among other memory management tools.async registerTools(server) { // Register tools from modular components this.operations.registerTools(server); this.queryHandler.registerTools(server); this.streamingTools.registerTools(server); this.management.registerTools(server); }
- src/tools/MemoryTools.js:60-62 (helper)Wrapper method in MemoryTools that delegates cleanup calls to the MemoryManagement instance.async handleCleanup(args) { return await this.management.handleCleanup(args); }