@mastra/mongodb 1.20.1 → 1.22.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +35 -1
- package/dist/docs/references/docs-storage.md +1 -0
- package/dist/index.cjs +85 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +85 -9
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +1 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/vector/index.d.ts +29 -1
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +6 -5
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { MessageList } from "@mastra/core/agent";
|
|
|
8
8
|
import { saveScorePayloadSchema } from "@mastra/core/evals";
|
|
9
9
|
import { skillSnapshotFieldValuesEqual } from "@mastra/core/storage/domains/skills";
|
|
10
10
|
//#region package.json
|
|
11
|
-
var version = "1.
|
|
11
|
+
var version = "1.22.0-alpha.0";
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/vector/filter.ts
|
|
14
14
|
/**
|
|
@@ -84,11 +84,22 @@ var MongoDBFilterTranslator = class extends BaseFilterTranslator {
|
|
|
84
84
|
function describeEmbedding(config) {
|
|
85
85
|
return config ? `autoEmbed (path "${config.path}", model "${config.model}")` : "client-side vectors";
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Whether Atlas refused a `$vectorSearch` because the index is still in its initial sync. The
|
|
89
|
+
* server reports it as a generic `UnknownError`, so the state named in the message is the only
|
|
90
|
+
* thing that tells it apart from other failures with the same code.
|
|
91
|
+
*/
|
|
92
|
+
function isInitialSyncError(error) {
|
|
93
|
+
const message = error?.message;
|
|
94
|
+
return typeof message === "string" && message.includes("while in state INITIAL_SYNC");
|
|
95
|
+
}
|
|
87
96
|
var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
88
97
|
client;
|
|
89
98
|
db;
|
|
90
99
|
collections;
|
|
91
100
|
embeddingFieldName;
|
|
101
|
+
/** Automated Embedding defaults applied to indexes created without their own config. */
|
|
102
|
+
defaultAutoEmbed;
|
|
92
103
|
metadataFieldName = "metadata";
|
|
93
104
|
documentFieldName = "document";
|
|
94
105
|
/**
|
|
@@ -124,6 +135,19 @@ var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
|
124
135
|
*/
|
|
125
136
|
static REGISTRY_COLLECTION = "__mastra_vector_indexes__";
|
|
126
137
|
/**
|
|
138
|
+
* Waits between attempts while a queried index is in INITIAL_SYNC, about six seconds in all.
|
|
139
|
+
* On a live Atlas cluster the window lasted around two seconds for both a regular and an
|
|
140
|
+
* autoEmbed index; the budget leaves room for a slower build without holding a failing query
|
|
141
|
+
* for long.
|
|
142
|
+
*/
|
|
143
|
+
static INITIAL_SYNC_RETRY_DELAYS_MS = [
|
|
144
|
+
250,
|
|
145
|
+
500,
|
|
146
|
+
1e3,
|
|
147
|
+
2e3,
|
|
148
|
+
2e3
|
|
149
|
+
];
|
|
150
|
+
/**
|
|
127
151
|
* MongoDB query operators supported inside `$vectorSearch.filter`. Intentionally
|
|
128
152
|
* conservative: filters using any operator outside this set fall back to the
|
|
129
153
|
* `$match` pre-filter, which supports the full query language. Widening this set
|
|
@@ -146,7 +170,7 @@ var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
|
146
170
|
euclidean: "euclidean",
|
|
147
171
|
dotproduct: "dotProduct"
|
|
148
172
|
};
|
|
149
|
-
constructor({ id, uri, dbName, options, embeddingFieldPath }) {
|
|
173
|
+
constructor({ id, uri, dbName, options, embeddingFieldPath, autoEmbed }) {
|
|
150
174
|
super({ id });
|
|
151
175
|
if (!uri) throw new Error("MongoDBVector requires a connection string. Provide \"uri\" in the constructor options.");
|
|
152
176
|
const client = new MongoClient(uri, {
|
|
@@ -160,6 +184,11 @@ var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
|
160
184
|
this.db = this.client.db(dbName);
|
|
161
185
|
this.collections = /* @__PURE__ */ new Map();
|
|
162
186
|
this.embeddingFieldName = embeddingFieldPath ?? "embedding";
|
|
187
|
+
this.defaultAutoEmbed = autoEmbed;
|
|
188
|
+
}
|
|
189
|
+
/** True once the store is configured with Automated Embedding defaults. */
|
|
190
|
+
get isSelfEmbedding() {
|
|
191
|
+
return this.defaultAutoEmbed !== void 0;
|
|
163
192
|
}
|
|
164
193
|
/**
|
|
165
194
|
* Resolve the collection + vector-index names for an index, honoring BYO overrides.
|
|
@@ -441,7 +470,8 @@ var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
|
441
470
|
* "index not found" or "index not ready" errors on subsequent operations.
|
|
442
471
|
*/
|
|
443
472
|
async createIndex(params) {
|
|
444
|
-
const { indexName, dimension, metric = "cosine", filterFields, collectionName, searchIndexName, allowWrites, autoEmbed } = params;
|
|
473
|
+
const { indexName, dimension, metric = "cosine", filterFields, collectionName, searchIndexName, allowWrites, autoEmbed: autoEmbedParam } = params;
|
|
474
|
+
const autoEmbed = autoEmbedParam ?? (dimension === void 0 ? this.defaultAutoEmbed : void 0);
|
|
445
475
|
let mongoMetric;
|
|
446
476
|
try {
|
|
447
477
|
if (autoEmbed) {
|
|
@@ -1029,7 +1059,7 @@ var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
|
1029
1059
|
vectorSearch.filter = pushed.length > 1 ? { $and: pushed } : pushed[0];
|
|
1030
1060
|
}
|
|
1031
1061
|
const pipeline = [{ $vectorSearch: vectorSearch }, ...this.buildProjection(metadataMode, includeVector, "vectorSearchScore", autoEmbed?.path)];
|
|
1032
|
-
return (await
|
|
1062
|
+
return (await this.aggregateVectorSearch(collection, pipeline)).map((result) => ({
|
|
1033
1063
|
id: this.idToString(result._id),
|
|
1034
1064
|
score: result.score,
|
|
1035
1065
|
metadata: result.metadata,
|
|
@@ -1046,6 +1076,24 @@ var MongoDBVector = class MongoDBVector extends MastraVector {
|
|
|
1046
1076
|
}
|
|
1047
1077
|
}
|
|
1048
1078
|
/**
|
|
1079
|
+
* Runs a `$vectorSearch` pipeline, retrying while the index is in INITIAL_SYNC.
|
|
1080
|
+
*
|
|
1081
|
+
* While Atlas first builds a vector search index it usually answers with an empty result, but
|
|
1082
|
+
* for a few seconds it fails with "cannot query vector index ... while in state INITIAL_SYNC"
|
|
1083
|
+
* instead. A caller that creates an index and queries it straight away, as `Memory` does on a
|
|
1084
|
+
* fresh database, can land in that window. Any other error, and an INITIAL_SYNC that outlasts
|
|
1085
|
+
* the retry budget, is thrown unchanged.
|
|
1086
|
+
*/
|
|
1087
|
+
async aggregateVectorSearch(collection, pipeline) {
|
|
1088
|
+
for (const delayMs of MongoDBVector.INITIAL_SYNC_RETRY_DELAYS_MS) try {
|
|
1089
|
+
return await collection.aggregate(pipeline).toArray();
|
|
1090
|
+
} catch (error) {
|
|
1091
|
+
if (!isInitialSyncError(error)) throw error;
|
|
1092
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
1093
|
+
}
|
|
1094
|
+
return collection.aggregate(pipeline).toArray();
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1049
1097
|
* Lists LOGICAL Mastra index names, not physical collection names.
|
|
1050
1098
|
*
|
|
1051
1099
|
* Returns the union of:
|
|
@@ -6464,6 +6512,7 @@ const OM_TABLE = "mastra_observational_memory";
|
|
|
6464
6512
|
var MemoryStorageMongoDB = class MemoryStorageMongoDB extends MemoryStorage {
|
|
6465
6513
|
supportsPartialThreadUpdate = true;
|
|
6466
6514
|
supportsObservationalMemory = true;
|
|
6515
|
+
supportsObservationalMemoryHistorySearch = true;
|
|
6467
6516
|
#connector;
|
|
6468
6517
|
#skipDefaultIndexes;
|
|
6469
6518
|
#indexes;
|
|
@@ -6699,8 +6748,11 @@ var MemoryStorageMongoDB = class MemoryStorageMongoDB extends MemoryStorage {
|
|
|
6699
6748
|
if (!target) continue;
|
|
6700
6749
|
const prevMessages = await collection.find({
|
|
6701
6750
|
thread_id: target.threadId,
|
|
6702
|
-
|
|
6703
|
-
|
|
6751
|
+
...resourceFilter,
|
|
6752
|
+
$or: [{ createdAt: { $lt: target.createdAt } }, {
|
|
6753
|
+
createdAt: target.createdAt,
|
|
6754
|
+
id: { $lte: id }
|
|
6755
|
+
}]
|
|
6704
6756
|
}).sort({
|
|
6705
6757
|
createdAt: -1,
|
|
6706
6758
|
id: -1
|
|
@@ -6709,8 +6761,11 @@ var MemoryStorageMongoDB = class MemoryStorageMongoDB extends MemoryStorage {
|
|
|
6709
6761
|
if (withNextMessages > 0) {
|
|
6710
6762
|
const nextMessages = await collection.find({
|
|
6711
6763
|
thread_id: target.threadId,
|
|
6712
|
-
|
|
6713
|
-
|
|
6764
|
+
...resourceFilter,
|
|
6765
|
+
$or: [{ createdAt: { $gt: target.createdAt } }, {
|
|
6766
|
+
createdAt: target.createdAt,
|
|
6767
|
+
id: { $gt: id }
|
|
6768
|
+
}]
|
|
6714
6769
|
}).sort({
|
|
6715
6770
|
createdAt: 1,
|
|
6716
6771
|
id: 1
|
|
@@ -7504,13 +7559,34 @@ var MemoryStorageMongoDB = class MemoryStorageMongoDB extends MemoryStorage {
|
|
|
7504
7559
|
const lookupKey = this.getOMKey(threadId, resourceId);
|
|
7505
7560
|
const collection = await this.getCollection(OM_TABLE);
|
|
7506
7561
|
const filter = { lookupKey };
|
|
7562
|
+
if (options?.recordId !== void 0) filter["id"] = options.recordId;
|
|
7507
7563
|
if (options?.from || options?.to) {
|
|
7508
7564
|
const createdAtFilter = {};
|
|
7509
7565
|
if (options.from) createdAtFilter["$gte"] = options.from;
|
|
7510
7566
|
if (options.to) createdAtFilter["$lte"] = options.to;
|
|
7511
7567
|
filter["createdAt"] = createdAtFilter;
|
|
7512
7568
|
}
|
|
7513
|
-
|
|
7569
|
+
if (options?.groupId !== void 0) {
|
|
7570
|
+
const prefix = { $literal: `<observation-group id="${options.groupId}"` };
|
|
7571
|
+
filter["$expr"] = { $or: [{ $gte: [{ $indexOfCP: [{ $ifNull: ["$activeObservations", ""] }, prefix] }, 0] }, { $anyElementTrue: [{ $map: {
|
|
7572
|
+
input: { $cond: [
|
|
7573
|
+
{ $isArray: "$bufferedObservationChunks" },
|
|
7574
|
+
"$bufferedObservationChunks",
|
|
7575
|
+
[]
|
|
7576
|
+
] },
|
|
7577
|
+
as: "chunk",
|
|
7578
|
+
in: { $gte: [{ $indexOfCP: [{ $ifNull: ["$$chunk.observations", ""] }, prefix] }, 0] }
|
|
7579
|
+
} }] }] };
|
|
7580
|
+
}
|
|
7581
|
+
if (options?.beforeGeneration !== void 0 || options?.afterGeneration !== void 0) filter["generationCount"] = {
|
|
7582
|
+
...options.beforeGeneration !== void 0 ? { $lt: options.beforeGeneration } : {},
|
|
7583
|
+
...options.afterGeneration !== void 0 ? { $gt: options.afterGeneration } : {}
|
|
7584
|
+
};
|
|
7585
|
+
let cursor = collection.find(filter).sort({
|
|
7586
|
+
generationCount: options?.sortDirection === "ASC" ? 1 : -1,
|
|
7587
|
+
createdAt: 1,
|
|
7588
|
+
id: 1
|
|
7589
|
+
});
|
|
7514
7590
|
if (options?.offset != null) cursor = cursor.skip(options.offset);
|
|
7515
7591
|
return (await cursor.limit(limit).toArray()).map((doc) => this.parseOMDocument(doc));
|
|
7516
7592
|
} catch (error) {
|