Skip to main content

πŸ’Ύ Store Memories

Store information durably with remember. Both engines share the same call shape - what happens underneath differs.

const result = await memory.remember(
'Customer ACME is on the enterprise plan; escalations go to the sev-1 channel.',
{
tags: ['customer', 'escalation'], // optional, used for filtered recall
metadata: { source: 'support-bot' }, // optional structured payload
}
)
console.log(result)

Batched engine: buffering + flushing​

Memories buffer locally as pending and upload in batches - one blob per flushEvery memories (default 10):

import '@lighthouse-ai/store-lighthouse'
import '@lighthouse-ai/embed-local'
import { createEmbedder, createStorage } from '@lighthouse-ai/core'
import { BatchedEngine } from '@lighthouse-ai/engine-batched'

const storage = await createStorage('lh-ipfs-filecoin', { apiKey: process.env.LIGHTHOUSE_API_KEY })
const embedder = await createEmbedder('local') // or `null` for keyword-only
const memory = new BatchedEngine(storage, { namespace: 'demo', embedder, flushEvery: 10 })

const res = await memory.remember('Customer ACME is on enterprise.', { tags: ['customer'] })
// { id: '80cc2055-…', flushed: false, pendingCount: 1 }
// when this write trips flushEvery: { id, flushed: true, pendingCount: 0, cid, gatewayUrl }

Pending memories are searchable immediately but live only on the local machine until flushed:

const flushed = await memory.flush()
// { flushedMemories: 3, cid: 'baf…', gatewayUrl: 'https://gateway…/ipfs/baf…' }
// { flushedMemories: 0 } when nothing was pending

Flush happens automatically once flushEvery memories are pending. Tune it with the constructor option or MEMORY_FLUSH_EVERY - 1 uploads on every write (maximum durability), higher values pack more memories per blob (maximum quota efficiency).

Why batching matters on Walrus

Walrus erasure-codes every blob, so each upload counts ~63 MB against your account quota regardless of its actual size. One batch blob holding many memories costs the same quota as one holding a single memory.

Memwal engine: direct writes, no flush​

Every remember goes straight to the relayer (embed + SEAL-encrypt + Walrus + vector index) and returns immediately usable addresses:

import { MemwalMemory } from '@lighthouse-ai/engine-memwal'

const memory = await MemwalMemory.fromEnv() // MEMWAL_PRIVATE_KEY + MEMWAL_ACCOUNT_ID
const res = await memory.remember('Customer ACME is on enterprise.', { tags: ['customer'] })
// { id, blobId, cid, pinned, gatewayUrl?, walrusUrl, network, namespace }

There is no flush() on memwal. LIGHTHOUSE_API_KEY (unless MEMWAL_IPFS_PIN=off) pins a public IPFS mirror of each record; without it you still get a locally computed CID. memory.analyze(text) extracts discrete facts via the relayer and stores each as its own memory.

Configuration​

Env varDefaultPurpose
MEMORY_ENGINEbatchedbatched or memwal (MCP server / factory)
MEMORY_STORAGElh-ipfs-filecoinlh-ipfs-filecoin (filecoin alias), lh-ipfs-walrus (walrus alias), local-fs, s3
MEMORY_EMBEDDERlocallocal (MiniLM semantic) or keyword (word-match only; = embedder: null)
LIGHTHOUSE_API_KEY- (required for lh-*)Lighthouse API key
MEMORY_NAMESPACE / MEMORY_AGENTdefault / agentIsolates memories per agent/project; agent id recorded on each memory
MEMORY_FLUSH_EVERY10Batch size before automatic flush (batched only)
MEMORY_DIR./.memory-sdkBatched index + local-fs blob location
MEMWAL_PRIVATE_KEY / MEMWAL_ACCOUNT_ID- (required for memwal)Relayer delegate key + account
MEMWAL_NETWORKmainnetmainnet or testnet (staging relayer; creds are per-network)
MEMWAL_NAMESPACE / MEMWAL_AGENT / MEMWAL_MEMORY_DIRdefault / agent / ./.memory-sdk/memwalMemwal namespace, agent tag, state dir
MEMWAL_IPFS_PIN(pin)off skips IPFS pinning (local CIDs only)
S3_BUCKET, S3_REGION (AWS_REGION), S3_ENDPOINT, S3_PREFIX, S3_FORCE_PATH_STYLE, S3_PUBLIC_BASE_URL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY-S3 / R2 / MinIO adapter

What gets stored​

Batched memories are JSON records inside the batch blob (plus per-record vectors in the local index):

{
"v": 1,
"id": "80cc2055-9256-40b9-af83-5ecf8ea522ce",
"namespace": "default",
"agent": "support-bot",
"content": "Customer ACME is on the enterprise plan; …",
"tags": ["customer", "escalation"],
"metadata": { "source": "support-bot" },
"createdAt": "2026-07-22T14:59:03.427Z",
"embedding": [0.0123, -0.0456, "…"],
"embeddingModel": "local:Xenova/all-MiniLM-L6-v2",
"origin": "batched"
}

Memwal records carry blobId (the SEAL-encrypted Walrus blob) plus a local CID mirror. Blobs are content-addressed: same content = same CID.

Anyone with a batch CID, snapshot CID, or pinned memwal CID can read it from the gateway - do not store secrets in batched memory or memwal mirrors.