@phoenixaihub/mem-gc
v1.0.0
Published
Garbage collection runtime for agent memory stores — decay, dedup, contradiction detection, health scoring
Maintainers
Readme
mem-gc
Garbage collection runtime for agent memory stores. Zero LLM dependency — all algorithms are deterministic.
Features
- Generational Decay — Weibull TTL with access-frequency reinforcement
- Semantic Deduplication — TF-IDF cosine similarity (no external APIs)
- Contradiction Detection — Finds conflicting facts via negation analysis
- Memory Health Score — Composite 0-100: freshness, uniqueness, consistency, retrieval utility
- Adapter Pattern — JSON file adapter built-in, extensible interface for custom backends
- CLI —
mem-gc scan,mem-gc prune,mem-gc health,mem-gc report
Install
npm install @phoenixaihub/mem-gcCLI Usage
# Scan a memory file
mem-gc scan --file ./memories.json
# Get health score
mem-gc health --file ./memories.json
# Prune expired and duplicate memories
mem-gc prune --file ./memories.json
# Dry run (show what would be pruned)
mem-gc prune --file ./memories.json --dry-run
# JSON output
mem-gc report --file ./memories.json --json
# Custom thresholds
mem-gc scan --file ./memories.json --threshold 0.2 --similarity 0.9Library Usage
import { MemGC, JsonAdapter } from '@phoenixaihub/mem-gc';
const adapter = new JsonAdapter('./memories.json');
const gc = new MemGC(adapter, {
decay: { shape: 1.5, scale: 30, accessBonus: 0.1, threshold: 0.1 },
dedup: { similarityThreshold: 0.85 },
});
// Scan for issues
const report = await gc.scan();
console.log(`Health: ${report.health.score}/100`);
console.log(`Expired: ${report.health.expiredCount}`);
console.log(`Duplicates: ${report.health.duplicateCount}`);
console.log(`Contradictions: ${report.health.contradictionCount}`);
// Prune (remove expired + duplicates)
const { pruned } = await gc.prune();
console.log(`Removed ${pruned.length} records`);Memory Record Format
interface MemoryRecord {
id: string;
content: string;
metadata?: Record<string, unknown>;
createdAt: number; // unix ms
lastAccessedAt: number; // unix ms
accessCount: number;
tags?: string[];
confidence?: number; // 0-1
}Custom Adapters
Implement the MemoryAdapter interface:
import { MemoryAdapter, MemoryRecord } from '@phoenixaihub/mem-gc';
class MyAdapter implements MemoryAdapter {
async loadAll(): Promise<MemoryRecord[]> { /* ... */ }
async deleteMany(ids: string[]): Promise<void> { /* ... */ }
async update(record: MemoryRecord): Promise<void> { /* ... */ }
async saveAll(records: MemoryRecord[]): Promise<void> { /* ... */ }
}How It Works
Decay Engine
Uses a Weibull survival function: S(t) = exp(-(t/λ')^k) where λ' is scaled by access frequency. Frequently accessed memories live longer.
Deduplication
Builds TF-IDF vectors for all memories, computes pairwise cosine similarity, and clusters near-duplicates. Keeps the most-accessed record as canonical.
Contradiction Detection
Identifies pairs of memories that are topically similar (cosine similarity > threshold) but contain opposing sentiment via negation word analysis.
Health Score
Weighted average of four dimensions (25% each):
- Freshness — % of non-expired records
- Uniqueness — % of non-duplicate records
- Consistency — penalizes contradictions
- Retrieval Utility — average survival score
License
MIT
