@memofs/adapter-transformers
v1.3.0-beta.2
Published
Local Transformers.js ONNX embedder adapter for MemoFS with no API key or cloud dependency.
Maintainers
Readme
@memofs/adapter-transformers
Local Transformers.js ONNX embedder adapter for MemoFS with no API key or cloud dependency.
What is this?
Zero-config local embedder adapter for MemoFS. Runs a small sentence-embedding model in process via Transformers.js (ONNX runtime) — no API key, no cloud, and no network after the first model download.
This is what powers MemoFS's zero-API-key hybrid recall: install it (or let
the runtime lazy-load it) and recall() gains a semantic vector path on top of
the default lexical (BM25 + fuzzy) path, with nothing leaving your machine.
Installation
npm install @memofs/adapter-transformers @memofs/coreRequires Node.js >= 22.
This pulls in @huggingface/transformers and ships an ONNX-compatible embedder
that implements MemoFS's provider-neutral MemoryEmbedder contract.
Quick Start
Standalone
import { createTransformersEmbedder } from "@memofs/adapter-transformers";
const embedder = createTransformersEmbedder({
model: "Xenova/all-MiniLM-L6-v2",
});
// Embed a batch of texts (mean-pooled + L2-normalized vectors)
const { embeddings } = await embedder.embedTexts({
texts: ["MemoFS gives agents durable memory.", "All-MiniLM-L6-v2 is a small model."],
});
console.log(embeddings[0].embedding.length); // 384
console.log(embeddings[0].model); // "Xenova/all-MiniLM-L6-v2"The first call downloads the ONNX weights once and caches them; subsequent calls are fully offline.
With MemoFS core
Plug the adapter straight into MemoFS for hybrid recall with your own embedder:
import { MemoFS } from "@memofs/core";
import { createNodeFsMemoryStore } from "@memofs/core/node-fs";
import { createTransformersEmbedder } from "@memofs/adapter-transformers";
const store = createNodeFsMemoryStore({ rootDir: "." });
const memo = new MemoFS({
store,
projectId: "my-app",
embedder: createTransformersEmbedder(),
recall: { engine: "auto" }, // upgrades to hybrid since an embedder is present
});
await memo.notes.record({ content: "User prefers TypeScript and strict mode." });
const hits = await memo.recall("coding language preference"); // semantic matchZero-config (no code)
You usually do not need to touch this package directly. The MemoFS runtime can lazy-load it for you — just enable local embeddings:
export MEMOFS_LOCAL_EMBEDDINGS=true
export MEMOFS_RECALL_ENGINE=autoor in .memofs/config.json:
{
"$schema": "./node_modules/@memofs/cli/schema/config.json",
"runtime": "local",
"recall": { "engine": "auto", "localEmbeddings": true }
}The runtime imports @memofs/adapter-transformers only when the first
embedding is actually requested, so boot stays fast. If the adapter is missing or
fails to load, MemoFS falls back to lexical (BM25 + fuzzy) recall — memory stays
discoverable and writes are never broken.
Configuration
Embedder options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| model | string | "Xenova/all-MiniLM-L6-v2" | Hugging Face model id (or local path under cacheDir) supported by Transformers.js. |
| cacheDir | string | Transformers.js default | Directory used to cache downloaded ONNX weights. |
| device | "cpu" \| "gpu" \| "wasm" | "cpu" | Inference device. Use "gpu" or "wasm" when the runtime supports it. |
| dtype | "fp32" \| "fp16" \| "q8" \| "int8" | "fp32" | ONNX runtime data type. "fp32" is the safest across platforms. |
| batchSize | number | 32 | Maximum texts per inference batch. Larger batches trade memory for throughput. |
| retries | number | 2 | Maximum retry attempts when the initial model download/load fails with a transient network error. Set to 0 to disable. |
| onProgress | (info) => void | — | Callback for model download/load progress. Use it to show a one-time "warming up" notice. |
Default model
Xenova/all-MiniLM-L6-v2 is a 384-dimensional sentence-embedding model: small,
fast, and good enough for local agent memory. To use a different Transformers.js
model, pass its id:
createTransformersEmbedder({ model: "Xenova/all-MiniLM-L12-v2" });When to use this vs. a provider adapter
| Need | Use |
|------|-----|
| Offline / private / zero-cost semantic recall | This package (local ONNX) |
| Highest-quality embeddings, can call an API | @memofs/adapter-openai or @memofs/adapter-voyage |
| Persistent local vector recall | pair any embedder with createFsRecallStore from @memofs/core |
The local embedder pairs with MemoFS's built-in filesystem recall store
(createFsRecallStore, backed by .memofs/indexes/embeddings.jsonl) for a
fully local vector memory. For large shared indices, prefer a provider embedder
plus a managed vector store.
Testing
The embedder accepts an injectable pipelineFactory (an internal type), so tests
never need to download weights or run real inference. Use the bundled fake
factory from the public ./testing subpath:
import { createFakePipelineFactory } from "@memofs/adapter-transformers/testing";
import { createTransformersEmbedder } from "@memofs/adapter-transformers";
const embedder = createTransformersEmbedder({
pipelineFactory: createFakePipelineFactory({ dimensions: 384 }),
});
const { embeddings } = await embedder.embedTexts({ texts: ["hello"] });
console.log(embeddings[0].embedding.length); // 384The fake produces deterministic, hash-derived vectors — identical strings yield identical vectors, token-overlapping strings are partially similar — enough to exercise recall merging without the real model.
Boundary
This package owns the Transformers.js local embedder adapter. It does not own
the MemoFS core MemoryEmbedder contract, other provider adapters, or the
Transformers.js runtime itself.
Contributing
See our central Contributing Guide and development scripts for details on formatting, linting, and testing within the monorepo.
License
MIT
