Mastra¶
Package: @holographic-memory/mastra (peer: @mastra/core >=1.78 <2). Built on @holographic-memory/core (see js-core.md).
HolographicVector implements MastraVector (createIndex, listIndexes, describeIndex, deleteIndex, upsert, query, updateVector, deleteVector, deleteVectors) over the in-process native engine, so it plugs into Mastra Memory semantic recall, MastraVector RAG tools and anything else that takes a vector store.
import { Agent } from '@mastra/core/agent'
import { LibSQLStore } from '@mastra/libsql'
import { Memory } from '@mastra/memory'
import { HolographicVector } from '@holographic-memory/mastra'
const vector = new HolographicVector({ id: 'hms', dimension: 1536, path: './hms-data' })
const agent = new Agent({
id: 'support', name: 'support', instructions: '...', model: 'openai/...',
memory: new Memory({
storage: new LibSQLStore({ id: 'storage', url: 'file:./mastra.db' }),
vector,
embedder: yourEmbeddingModel,
options: { semanticRecall: true },
}),
})
Options¶
id, dimension (vector length of every index; default 1536; fixed for the life of the store), path (storage directory; omit for in-memory), hypervectorDimensions (engine hypervector size, default 4096), maxFetch, overfetch, hmsConfig (native config, e.g. encryption: { encryptionEnabled: true, encryptionPassphraseEnv: 'HMS_PASSPHRASE' }), memory (an existing native store created with embedding model mastra-supplied).
Mapping¶
- An index is a collection inside one engine store. All indexes share
dimension;createIndexwith another dimension fails with aMastraError. Index metadata (dimension, metric, count) is persisted in a registry collection, so indexes survive restarts. Index names may not contain/. queryreturns cosine similarity asscore, best first, with the stored metadata. Filters are applied before ranking (topKis not reduced by non-matching neighbours; verified past 100 candidates). With only afilterit is a metadata query: it returns up totopKmatches withscore0.includeVectorworks: the embedding is kept in the record's metadata (about 20 bytes per dimension) because the engine cannot return it otherwise, andupdateVectorneeds it to change only metadata.- Text: the engine requires non-empty text per record. The record text is
metadata.textwhen it is a non-empty string (Mastra Memory and the RAG chunkers set it), otherwise the id. Vectors are always the ones Mastra supplies; the store never embeds. upsertreplaces by id;deleteFilteris applied first, in the same serialized step (not one engine transaction). Mastra Memory's message ids are stable, so re-saving is idempotent.updateVectormergesupdate.metadatainto existing metadata and replaces the vector when given; byidor byfilter.
Filters¶
Mastra's MongoDB-style syntax: $eq $ne $gt $gte $lt $lte $in $nin $all $elemMatch $exists $regex/$options $not $and $or $nor, dotted keys for nested fields, Date values (compared as ISO strings). Scalar top-level equalities are evaluated by the engine; everything else is evaluated in JS on overfetch * topK candidates capped at maxFetch (default 1000 passages), so a filter with those terms can return fewer than topK results when matches lie deeper than the cap. $not at field level and $nor are translated to negation of the equivalent positive filter. Date values in metadata are stored as ISO strings.
Limits¶
- Metric: cosine only; other metrics fail at
createIndex. Sparse vectors are rejected. describeIndex().countis maintained by this adapter (updated inside every write); writes made outside it (through the native handle) are not counted.- Metadata keys starting with
_hms_are rejected. - One writer process per store directory. Writes inside one
HolographicVectorare serialized. - Hybrid (BM25 + vector) search is not reachable through
MastraVector.query, which has no text parameter; use@holographic-memory/coredirectly for it.
Tested against¶
@mastra/core 1.78.0, @mastra/memory 1.38.0, @mastra/libsql 1.26.2, Node 26.8. npm test --workspace packages/mastra runs 15 contract tests (index lifecycle, validation, cosine scores, every filter operator, pre-ranking filters past 100 candidates, replace, deleteFilter, update by id and filter, delete by ids and filter, index isolation) and one end-to-end test: a real Agent with Memory (LibSQL storage, semanticRecall, lastMessages: 1) driven by a scripted model, asserting that an old message is retrieved through HolographicVector into the prompt. Mastra does not publish its vector-store test suite as a package, so the contract tests follow the operations and filter semantics in its MastraVector types and docs. examples/vector.mjs is a runnable example.