@shrimp-kit/memory
v0.1.0
Published
> Three-layer memory system with TTL, garbage collection, deduplication, and promotion.
Readme
@shrimp-kit/memory
Three-layer memory system with TTL, garbage collection, deduplication, and promotion.
Install
bun add @shrimp-kit/memoryArchitecture
The memory system uses three layers:
| Layer | Storage | Lifecycle | Description | |-------|---------|-----------|-------------| | L1 | Config files | Permanent | Static configs (read-only, managed externally) | | L2 | Markdown | Permanent | Verified knowledge, promoted from L3 | | L3 | JSON index | TTL-based | Dynamic entries with auto-expiry and GC |
This package manages L3 (dynamic memory). For L2 permanent memory, see @shrimp-kit/companion's PermanentMemory class.
Usage
Basic Operations
import { Logger } from "@shrimp-kit/core";
import { MemoryStore } from "@shrimp-kit/memory";
const logger = new Logger({ name: "agent", level: "info" });
const memory = new MemoryStore("./data/memory-index.json", logger);
await memory.load();
// Add entries
memory.add({
type: "preference", // context | preference | progress | relation | insight
key: "timezone",
value: "User prefers Asia/Taipei timezone",
importance: 4, // 1-5 (affects TTL)
});
memory.add({
type: "context",
key: "chat_session",
value: "User mentioned they are working on a trading bot",
importance: 3,
keywords: ["trading", "bot", "project"], // optional, auto-extracted if omitted
});
// Query by similarity
const results = memory.query("what timezone does the user prefer?", 3);
for (const { entry, score } of results) {
console.log(`${score.toFixed(2)} — ${entry.content}`);
}
// Save to disk
await memory.save();TTL and Importance
Each memory type has a base TTL, modified by importance:
| Type | Base TTL | Imp 1 | Imp 3 | Imp 5 | |------|----------|-------|-------|-------| | context | 14 days | 7d | 14d | 28d | | preference | 30 days | 15d | 30d | 60d | | progress | 7 days | 3.5d | 7d | 14d | | relation | 30 days | 15d | 30d | 60d | | insight | 21 days | 10.5d | 21d | 42d |
Accessed entries get TTL extensions (+7 days per access, max 90 days total).
Garbage Collection
const result = memory.gc();
// → { expired: 3, merged: 1, kept: 42, promotable: ["id1", "id2"] }
// GC performs three phases:
// 1. Remove expired entries (with access-based TTL extension)
// 2. Dedup scan — merge entries with Jaccard similarity >= 0.55
// 3. Mark promotable — entries accessed >= 3 timesDeduplication
When adding a new entry, the store checks for similar existing entries using Jaccard similarity (threshold: 0.55). If a match is found, the existing entry is updated instead of creating a duplicate.
memory.add({ type: "context", key: "k1", value: "User likes TypeScript" });
memory.add({ type: "context", key: "k2", value: "User likes TypeScript a lot" });
// Only 1 entry exists — the second was merged into the firstPromotion
Frequently accessed entries (3+ accesses) are flagged as promotable. Promoted entries are exempt from TTL expiration and GC.
// Record access
memory.access("entry-id");
// Promote to permanent
memory.promote("entry-id");Other Operations
// Get all entries (optionally filtered by type)
const all = memory.getEntries();
const prefs = memory.getEntries("preference");
// Get stats
const stats = memory.getStats();
// → { totalCreated: 50, totalPromoted: 3, totalExpired: 12, totalMerged: 5, lastGc: "..." }
// Remove entry
memory.remove("entry-id");
// Entry count
console.log(memory.size); // 42API Reference
MemoryStore
| Method | Returns | Description |
|--------|---------|-------------|
| load() | Promise<void> | Load index from disk |
| save() | Promise<void> | Save index to disk |
| add(options) | MemoryEntry | Add entry (with dedup) |
| query(text, limit?) | QueryResult[] | Query by keyword similarity |
| gc() | GcResult | Run garbage collection |
| access(id) | MemoryEntry \| undefined | Record an access |
| promote(id) | boolean | Mark as promoted (permanent) |
| getEntries(type?) | MemoryEntry[] | Get all entries |
| getStats() | MemoryStats | Get statistics |
| remove(id) | boolean | Remove an entry |
| size | number | Entry count |
See src/index.ts for all exports.
