User Guide
User Guide — Agent Memory Manager
This guide shows how to integrate the module into an agent. It assumes Node.js
= 20.
1. Install and build
cd delivery-package/agent-memory-manager
npm install
npm run build
2. Create a manager
import { MemoryManager } from '@forge/agent-memory-manager';
const memory = new MemoryManager({ namespace: 'my-agent' });
await memory.init();
Defaults: in-process store, local hashing embeddings, extractive summarizer, JSON logger at info, in-memory metrics, automatic tier maintenance.
3. The four operations
store(key, value, metadata?)
await memory.store('fact:slo', 'checkout SLO is 99.9% monthly', {
importance: 0.85, // 0..1, drives tier placement + eviction
type: 'fact', // observation | fact | summary | alert | message | ...
tags: ['slo', 'checkout'],
threadId: 'incident-12', // optional grouping for summarizeThread
shareScope: 'fleet', // 'local' (default) or 'fleet' to replicate
});
Re-storing the same key updates the value/embedding/importance while keeping the original id, createdAt, and access count.
retrieve(query, limit?, options?)
const hits = await memory.retrieve('what is the checkout SLO?', 5, {
tags: ['checkout'], // optional filters + a relevance boost
type: 'fact',
tiers: ['hot', 'warm'],
});
for (const h of hits) console.log(h.score, h.record.value, h.components);
A strongly-matching memory is promoted to the hot tier on retrieval (disable per call with { promote: false }).
summarizeThread(thread, options?)
// By thread id (reads stored messages tagged with that threadId):
const res = await memory.summarizeThread('incident-12', { maxChars: 300, compact: true });
console.log(res.summary);
// Or from an explicit list:
await memory.summarizeThread([
{ role: 'alert', text: 'db-1 pool saturated' },
{ role: 'action', text: 'raised max_connections' },
]);
With compact: true, the importance of the summarized source memories is lowered so the raw lines age out while the summary is retained.
getContextForTask(task)
const ctx = await memory.getContextForTask({
task: 'diagnose the checkout outage',
charBudget: 2000, // hard cap on the assembled context string
tags: ['checkout'],
});
// ctx.context -> ready to drop into a prompt
// ctx.used -> the ScoredMemory[] that made the cut
// ctx.tokensEstimate, ctx.charBudget
4. Using Postgres + pgvector
import { createPgliteMemoryStore, MemoryManager } from '@forge/agent-memory-manager';
const { store } = await createPgliteMemoryStore({ dimensions: 256, dataDir: './memdb' });
const memory = new MemoryManager({ store, namespace: 'my-agent' });
For an external server, construct new PgVectorStore(pgPool, { dimensions: 256 }). The embedding dimension must match the embedding provider.
5. AgentMemoryWrapper (recommended for agents)
import { AgentMemoryWrapper } from '@forge/agent-memory-manager';
const agent = new AgentMemoryWrapper({ agentId: 'agent-A', manager: memory });
await agent.remember('disk on node-3 at 92%', { importance: 0.7, type: 'alert' });
await agent.rememberThreadMessage('incident-12', 'alert', 'pool saturated');
const hits = await agent.recall('disk pressure', 5);
const summary = await agent.summarizeThread('incident-12');
const ctx = await agent.buildContext('plan remediation', 1500);
await agent.shareWithFleet('runbook: restart pool on saturation', { key: 'rb:1' });
6. Observability
console.log(await memory.stats()); // { tiers: { hot, warm, cold }, metrics }
console.log(memory.metrics.snapshot()); // counters / gauges / histograms
Set log verbosity with new MemoryManager({ logger: createLogger({ level: 'debug' }) }) or pass silentLogger.
7. Maintenance
Tier decay/eviction runs automatically after writes. To force a sweep (e.g. on a timer in a long-running agent):
setInterval(() => memory.maintain().catch(() => {}), 60_000);
8. Shut down
await memory.close(); // releases the store (and DB connection, if any)