@mastra/mongodb 0.12.2 → 0.12.3-alpha.1

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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/mongodb@0.12.1 build /home/runner/work/mastra/mastra/stores/mongodb
2
+ > @mastra/mongodb@0.12.3-alpha.1 build /home/runner/work/mastra/mastra/stores/mongodb
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 10902ms
9
+ TSC ⚡️ Build success in 11313ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/mongodb/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/mongodb/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 13195ms
16
+ DTS ⚡️ Build success in 14299ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 73.11 KB
21
- ESM ⚡️ Build success in 1823ms
22
- CJS dist/index.cjs 74.40 KB
23
- CJS ⚡️ Build success in 1832ms
20
+ CJS dist/index.cjs 74.73 KB
21
+ CJS ⚡️ Build success in 1938ms
22
+ ESM dist/index.js 73.39 KB
23
+ ESM ⚡️ Build success in 1947ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @mastra/mongodb
2
2
 
3
+ ## 0.12.3-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 9881232: dependencies updates:
8
+ - Updated dependency [`cloudflare@^4.5.0` ↗︎](https://www.npmjs.com/package/cloudflare/v/4.5.0) (from `^4.4.1`, in `dependencies`)
9
+ - eba48c8: Sort getThreads by updatedAt.
10
+ - 14456f3: fix: [MongoDB] batchInsert with process json
11
+ - Updated dependencies [27cc97a]
12
+ - Updated dependencies [41daa63]
13
+ - Updated dependencies [254a36b]
14
+ - Updated dependencies [0b89602]
15
+ - Updated dependencies [4d37822]
16
+ - Updated dependencies [ff9c125]
17
+ - Updated dependencies [b8efbb9]
18
+ - Updated dependencies [71466e7]
19
+ - Updated dependencies [0c99fbe]
20
+ - @mastra/core@0.12.0-alpha.2
21
+
22
+ ## 0.12.3-alpha.0
23
+
24
+ ### Patch Changes
25
+
26
+ - 25f2987: fix: filter.\_id.\$in cannot be empty
27
+ - b0f1e2f: fix: mongodb save scores as an object
28
+ - Updated dependencies [510e2c8]
29
+ - Updated dependencies [2f72fb2]
30
+ - Updated dependencies [3f89307]
31
+ - Updated dependencies [9eda7d4]
32
+ - Updated dependencies [9d49408]
33
+ - Updated dependencies [2ecf658]
34
+ - Updated dependencies [7a7754f]
35
+ - Updated dependencies [fc92d80]
36
+ - Updated dependencies [23a6a7c]
37
+ - Updated dependencies [09bca64]
38
+ - @mastra/core@0.12.0-alpha.0
39
+
3
40
  ## 0.12.2
4
41
 
5
42
  ### Patch Changes
@@ -48,15 +48,12 @@ import type { WorkflowRuns } from '@mastra/core/storage';
48
48
  import type { WorkflowRunState } from '@mastra/core/workflows';
49
49
  import { WorkflowsStorage } from '@mastra/core/storage';
50
50
 
51
- export declare interface ConnectorHandler {
52
- getCollection(collectionName: string): Promise<Collection>;
53
- close(): Promise<void>;
54
- }
55
-
56
- export declare interface ConnectorHandler_alias_1 {
51
+ declare interface ConnectorHandler {
57
52
  getCollection(collectionName: string): Promise<Collection>;
58
53
  close(): Promise<void>;
59
54
  }
55
+ export { ConnectorHandler }
56
+ export { ConnectorHandler as ConnectorHandler_alias_1 }
60
57
 
61
58
  export declare function createExecuteOperationWithRetry({ logger, maxRetries, initialBackoffMs, }: {
62
59
  logger: IMastraLogger;
@@ -173,7 +170,7 @@ export { MONGODB_PROMPT as MONGODB_PROMPT_alias_1 }
173
170
  declare type MongoDBBlacklisted = BlacklistedRootOperators | '$size';
174
171
 
175
172
  export declare type MongoDBConfig = DatabaseConfig | {
176
- connectorHandler: ConnectorHandler_alias_1;
173
+ connectorHandler: ConnectorHandler;
177
174
  };
178
175
 
179
176
  export declare class MongoDBConnector {
@@ -190,7 +187,7 @@ export declare class MongoDBConnector_alias_1 {
190
187
  #private;
191
188
  constructor(options: MongoDBConnectorOptions_2);
192
189
  static fromDatabaseConfig(config: DatabaseConfig): MongoDBConnector_alias_1;
193
- static fromConnectionHandler(handler: ConnectorHandler_alias_1): MongoDBConnector_alias_1;
190
+ static fromConnectionHandler(handler: ConnectorHandler): MongoDBConnector_alias_1;
194
191
  private getConnection;
195
192
  getCollection(collectionName: string): Promise<Collection<Document>>;
196
193
  close(): Promise<void>;
@@ -213,7 +210,7 @@ declare type MongoDBConnectorOptions_2 = {
213
210
  } | {
214
211
  client: undefined;
215
212
  dbName: undefined;
216
- handler: ConnectorHandler_alias_1;
213
+ handler: ConnectorHandler;
217
214
  };
218
215
 
219
216
  /**
@@ -238,7 +235,7 @@ export { MongoDBIndexReadyParams }
238
235
  export { MongoDBIndexReadyParams as MongoDBIndexReadyParams_alias_1 }
239
236
 
240
237
  export declare interface MongoDBOperationsConfig {
241
- connector: ConnectorHandler_alias_1;
238
+ connector: ConnectorHandler;
242
239
  }
243
240
 
244
241
  declare type MongoDBOperatorValueMap = Omit<OperatorValueMap, '$options'> & {
@@ -257,6 +254,7 @@ declare class MongoDBStore extends MastraStorage {
257
254
  resourceWorkingMemory: boolean;
258
255
  hasColumn: boolean;
259
256
  createTable: boolean;
257
+ deleteMessages: boolean;
260
258
  };
261
259
  constructor(config: MongoDBConfig);
262
260
  createTable({ tableName, schema, }: {
@@ -546,6 +544,7 @@ export declare class StoreOperationsMongoDB extends StoreOperations {
546
544
  dropTable({ tableName }: {
547
545
  tableName: TABLE_NAMES;
548
546
  }): Promise<void>;
547
+ private processJsonbFields;
549
548
  insert({ tableName, record }: {
550
549
  tableName: TABLE_NAMES;
551
550
  record: Record<string, any>;
@@ -48,15 +48,12 @@ import type { WorkflowRuns } from '@mastra/core/storage';
48
48
  import type { WorkflowRunState } from '@mastra/core/workflows';
49
49
  import { WorkflowsStorage } from '@mastra/core/storage';
50
50
 
51
- export declare interface ConnectorHandler {
52
- getCollection(collectionName: string): Promise<Collection>;
53
- close(): Promise<void>;
54
- }
55
-
56
- export declare interface ConnectorHandler_alias_1 {
51
+ declare interface ConnectorHandler {
57
52
  getCollection(collectionName: string): Promise<Collection>;
58
53
  close(): Promise<void>;
59
54
  }
55
+ export { ConnectorHandler }
56
+ export { ConnectorHandler as ConnectorHandler_alias_1 }
60
57
 
61
58
  export declare function createExecuteOperationWithRetry({ logger, maxRetries, initialBackoffMs, }: {
62
59
  logger: IMastraLogger;
@@ -173,7 +170,7 @@ export { MONGODB_PROMPT as MONGODB_PROMPT_alias_1 }
173
170
  declare type MongoDBBlacklisted = BlacklistedRootOperators | '$size';
174
171
 
175
172
  export declare type MongoDBConfig = DatabaseConfig | {
176
- connectorHandler: ConnectorHandler_alias_1;
173
+ connectorHandler: ConnectorHandler;
177
174
  };
178
175
 
179
176
  export declare class MongoDBConnector {
@@ -190,7 +187,7 @@ export declare class MongoDBConnector_alias_1 {
190
187
  #private;
191
188
  constructor(options: MongoDBConnectorOptions_2);
192
189
  static fromDatabaseConfig(config: DatabaseConfig): MongoDBConnector_alias_1;
193
- static fromConnectionHandler(handler: ConnectorHandler_alias_1): MongoDBConnector_alias_1;
190
+ static fromConnectionHandler(handler: ConnectorHandler): MongoDBConnector_alias_1;
194
191
  private getConnection;
195
192
  getCollection(collectionName: string): Promise<Collection<Document>>;
196
193
  close(): Promise<void>;
@@ -213,7 +210,7 @@ declare type MongoDBConnectorOptions_2 = {
213
210
  } | {
214
211
  client: undefined;
215
212
  dbName: undefined;
216
- handler: ConnectorHandler_alias_1;
213
+ handler: ConnectorHandler;
217
214
  };
218
215
 
219
216
  /**
@@ -238,7 +235,7 @@ export { MongoDBIndexReadyParams }
238
235
  export { MongoDBIndexReadyParams as MongoDBIndexReadyParams_alias_1 }
239
236
 
240
237
  export declare interface MongoDBOperationsConfig {
241
- connector: ConnectorHandler_alias_1;
238
+ connector: ConnectorHandler;
242
239
  }
243
240
 
244
241
  declare type MongoDBOperatorValueMap = Omit<OperatorValueMap, '$options'> & {
@@ -257,6 +254,7 @@ declare class MongoDBStore extends MastraStorage {
257
254
  resourceWorkingMemory: boolean;
258
255
  hasColumn: boolean;
259
256
  createTable: boolean;
257
+ deleteMessages: boolean;
260
258
  };
261
259
  constructor(config: MongoDBConfig);
262
260
  createTable({ tableName, schema, }: {
@@ -546,6 +544,7 @@ export declare class StoreOperationsMongoDB extends StoreOperations {
546
544
  dropTable({ tableName }: {
547
545
  tableName: TABLE_NAMES;
548
546
  }): Promise<void>;
547
+ private processJsonbFields;
549
548
  insert({ tableName, record }: {
550
549
  tableName: TABLE_NAMES;
551
550
  record: Record<string, any>;
package/dist/index.cjs CHANGED
@@ -343,7 +343,9 @@ var MongoDBVector = class extends vector.MastraVector {
343
343
  };
344
344
  if (Object.keys(combinedFilter).length > 0) {
345
345
  const candidateIds = await collection.aggregate([{ $match: combinedFilter }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
346
- vectorSearch.filter = { _id: { $in: candidateIds } };
346
+ if (candidateIds.length > 0) {
347
+ vectorSearch.filter = { _id: { $in: candidateIds } };
348
+ }
347
349
  }
348
350
  const pipeline = [
349
351
  {
@@ -1211,7 +1213,7 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
1211
1213
  async getThreadsByResourceId({ resourceId }) {
1212
1214
  try {
1213
1215
  const collection = await this.operations.getCollection(storage.TABLE_THREADS);
1214
- const results = await collection.find({ resourceId }).toArray();
1216
+ const results = await collection.find({ resourceId }).sort({ updatedAt: -1 }).toArray();
1215
1217
  if (!results.length) {
1216
1218
  return [];
1217
1219
  }
@@ -1411,18 +1413,21 @@ var StoreOperationsMongoDB = class extends storage.StoreOperations {
1411
1413
  );
1412
1414
  }
1413
1415
  }
1416
+ processJsonbFields(tableName, record) {
1417
+ const schema = storage.TABLE_SCHEMAS[tableName];
1418
+ return Object.fromEntries(
1419
+ Object.entries(schema).map(([key, value]) => {
1420
+ if (value.type === "jsonb" && record[key] && typeof record[key] === "string") {
1421
+ return [key, storage.safelyParseJSON(record[key])];
1422
+ }
1423
+ return [key, record[key]];
1424
+ })
1425
+ );
1426
+ }
1414
1427
  async insert({ tableName, record }) {
1415
1428
  try {
1416
1429
  const collection = await this.getCollection(tableName);
1417
- const schema = storage.TABLE_SCHEMAS[tableName];
1418
- const recordToInsert = Object.fromEntries(
1419
- Object.entries(schema).map(([key, value]) => {
1420
- if (value.type === "jsonb" && record[key] && typeof record[key] === "string") {
1421
- return [key, storage.safelyParseJSON(record[key])];
1422
- }
1423
- return [key, record[key]];
1424
- })
1425
- );
1430
+ const recordToInsert = this.processJsonbFields(tableName, record);
1426
1431
  await collection.insertOne(recordToInsert);
1427
1432
  } catch (error$1) {
1428
1433
  if (error$1 instanceof Error) {
@@ -1446,7 +1451,8 @@ var StoreOperationsMongoDB = class extends storage.StoreOperations {
1446
1451
  }
1447
1452
  try {
1448
1453
  const collection = await this.getCollection(tableName);
1449
- await collection.insertMany(records);
1454
+ const processedRecords = records.map((record) => this.processJsonbFields(tableName, record));
1455
+ await collection.insertMany(processedRecords);
1450
1456
  } catch (error$1) {
1451
1457
  throw new error.MastraError(
1452
1458
  {
@@ -1598,19 +1604,19 @@ var ScoresStorageMongoDB = class extends storage.ScoresStorage {
1598
1604
  scorerId: score.scorerId,
1599
1605
  traceId: score.traceId || "",
1600
1606
  runId: score.runId,
1601
- scorer: typeof score.scorer === "string" ? score.scorer : JSON.stringify(score.scorer),
1602
- extractStepResult: typeof score.extractStepResult === "string" ? score.extractStepResult : JSON.stringify(score.extractStepResult),
1603
- analyzeStepResult: typeof score.analyzeStepResult === "string" ? score.analyzeStepResult : JSON.stringify(score.analyzeStepResult),
1607
+ scorer: typeof score.scorer === "string" ? storage.safelyParseJSON(score.scorer) : score.scorer,
1608
+ extractStepResult: typeof score.extractStepResult === "string" ? storage.safelyParseJSON(score.extractStepResult) : score.extractStepResult,
1609
+ analyzeStepResult: typeof score.analyzeStepResult === "string" ? storage.safelyParseJSON(score.analyzeStepResult) : score.analyzeStepResult,
1604
1610
  score: score.score,
1605
1611
  reason: score.reason,
1606
1612
  extractPrompt: score.extractPrompt,
1607
1613
  analyzePrompt: score.analyzePrompt,
1608
1614
  reasonPrompt: score.reasonPrompt,
1609
- input: typeof score.input === "string" ? score.input : JSON.stringify(score.input),
1610
- output: typeof score.output === "string" ? score.output : JSON.stringify(score.output),
1615
+ input: typeof score.input === "string" ? storage.safelyParseJSON(score.input) : score.input,
1616
+ output: typeof score.output === "string" ? storage.safelyParseJSON(score.output) : score.output,
1611
1617
  additionalContext: score.additionalContext,
1612
- runtimeContext: typeof score.runtimeContext === "string" ? score.runtimeContext : JSON.stringify(score.runtimeContext),
1613
- entity: typeof score.entity === "string" ? score.entity : JSON.stringify(score.entity),
1618
+ runtimeContext: typeof score.runtimeContext === "string" ? storage.safelyParseJSON(score.runtimeContext) : score.runtimeContext,
1619
+ entity: typeof score.entity === "string" ? storage.safelyParseJSON(score.entity) : score.entity,
1614
1620
  source: score.source,
1615
1621
  resourceId: score.resourceId || "",
1616
1622
  threadId: score.threadId || "",
@@ -2054,6 +2060,40 @@ var WorkflowsStorageMongoDB = class extends storage.WorkflowsStorage {
2054
2060
  };
2055
2061
 
2056
2062
  // src/storage/index.ts
2063
+ var loadConnector = (config) => {
2064
+ try {
2065
+ if ("connectorHandler" in config) {
2066
+ return MongoDBConnector.fromConnectionHandler(config.connectorHandler);
2067
+ }
2068
+ } catch (error$1) {
2069
+ throw new error.MastraError(
2070
+ {
2071
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2072
+ domain: error.ErrorDomain.STORAGE,
2073
+ category: error.ErrorCategory.USER,
2074
+ details: { connectionHandler: true }
2075
+ },
2076
+ error$1
2077
+ );
2078
+ }
2079
+ try {
2080
+ return MongoDBConnector.fromDatabaseConfig({
2081
+ options: config.options,
2082
+ url: config.url,
2083
+ dbName: config.dbName
2084
+ });
2085
+ } catch (error$1) {
2086
+ throw new error.MastraError(
2087
+ {
2088
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2089
+ domain: error.ErrorDomain.STORAGE,
2090
+ category: error.ErrorCategory.USER,
2091
+ details: { url: config?.url, dbName: config?.dbName }
2092
+ },
2093
+ error$1
2094
+ );
2095
+ }
2096
+ };
2057
2097
  var MongoDBStore = class extends storage.MastraStorage {
2058
2098
  #connector;
2059
2099
  stores;
@@ -2062,45 +2102,14 @@ var MongoDBStore = class extends storage.MastraStorage {
2062
2102
  selectByIncludeResourceScope: true,
2063
2103
  resourceWorkingMemory: true,
2064
2104
  hasColumn: false,
2065
- createTable: false
2105
+ createTable: false,
2106
+ deleteMessages: false
2066
2107
  };
2067
2108
  }
2068
2109
  constructor(config) {
2069
2110
  super({ name: "MongoDBStore" });
2070
2111
  this.stores = {};
2071
- try {
2072
- if ("connectorHandler" in config) {
2073
- this.#connector = MongoDBConnector.fromConnectionHandler(config.connectorHandler);
2074
- return;
2075
- }
2076
- } catch (error$1) {
2077
- throw new error.MastraError(
2078
- {
2079
- id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2080
- domain: error.ErrorDomain.STORAGE,
2081
- category: error.ErrorCategory.USER,
2082
- details: { connectionHandler: true }
2083
- },
2084
- error$1
2085
- );
2086
- }
2087
- try {
2088
- this.#connector = MongoDBConnector.fromDatabaseConfig({
2089
- options: config.options,
2090
- url: config.url,
2091
- dbName: config.dbName
2092
- });
2093
- } catch (error$1) {
2094
- throw new error.MastraError(
2095
- {
2096
- id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2097
- domain: error.ErrorDomain.STORAGE,
2098
- category: error.ErrorCategory.USER,
2099
- details: { url: config?.url, dbName: config?.dbName }
2100
- },
2101
- error$1
2102
- );
2103
- }
2112
+ this.#connector = loadConnector(config);
2104
2113
  const operations = new StoreOperationsMongoDB({
2105
2114
  connector: this.#connector
2106
2115
  });
package/dist/index.d.cts CHANGED
@@ -3,3 +3,4 @@ export { MongoDBUpsertVectorParams } from './_tsup-dts-rollup.cjs';
3
3
  export { MongoDBIndexReadyParams } from './_tsup-dts-rollup.cjs';
4
4
  export { MongoDBVector } from './_tsup-dts-rollup.cjs';
5
5
  export { MongoDBStore } from './_tsup-dts-rollup.cjs';
6
+ export { ConnectorHandler } from './_tsup-dts-rollup.cjs';
package/dist/index.d.ts CHANGED
@@ -3,3 +3,4 @@ export { MongoDBUpsertVectorParams } from './_tsup-dts-rollup.js';
3
3
  export { MongoDBIndexReadyParams } from './_tsup-dts-rollup.js';
4
4
  export { MongoDBVector } from './_tsup-dts-rollup.js';
5
5
  export { MongoDBStore } from './_tsup-dts-rollup.js';
6
+ export { ConnectorHandler } from './_tsup-dts-rollup.js';
package/dist/index.js CHANGED
@@ -341,7 +341,9 @@ var MongoDBVector = class extends MastraVector {
341
341
  };
342
342
  if (Object.keys(combinedFilter).length > 0) {
343
343
  const candidateIds = await collection.aggregate([{ $match: combinedFilter }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
344
- vectorSearch.filter = { _id: { $in: candidateIds } };
344
+ if (candidateIds.length > 0) {
345
+ vectorSearch.filter = { _id: { $in: candidateIds } };
346
+ }
345
347
  }
346
348
  const pipeline = [
347
349
  {
@@ -1209,7 +1211,7 @@ var MemoryStorageMongoDB = class extends MemoryStorage {
1209
1211
  async getThreadsByResourceId({ resourceId }) {
1210
1212
  try {
1211
1213
  const collection = await this.operations.getCollection(TABLE_THREADS);
1212
- const results = await collection.find({ resourceId }).toArray();
1214
+ const results = await collection.find({ resourceId }).sort({ updatedAt: -1 }).toArray();
1213
1215
  if (!results.length) {
1214
1216
  return [];
1215
1217
  }
@@ -1409,18 +1411,21 @@ var StoreOperationsMongoDB = class extends StoreOperations {
1409
1411
  );
1410
1412
  }
1411
1413
  }
1414
+ processJsonbFields(tableName, record) {
1415
+ const schema = TABLE_SCHEMAS[tableName];
1416
+ return Object.fromEntries(
1417
+ Object.entries(schema).map(([key, value]) => {
1418
+ if (value.type === "jsonb" && record[key] && typeof record[key] === "string") {
1419
+ return [key, safelyParseJSON(record[key])];
1420
+ }
1421
+ return [key, record[key]];
1422
+ })
1423
+ );
1424
+ }
1412
1425
  async insert({ tableName, record }) {
1413
1426
  try {
1414
1427
  const collection = await this.getCollection(tableName);
1415
- const schema = TABLE_SCHEMAS[tableName];
1416
- const recordToInsert = Object.fromEntries(
1417
- Object.entries(schema).map(([key, value]) => {
1418
- if (value.type === "jsonb" && record[key] && typeof record[key] === "string") {
1419
- return [key, safelyParseJSON(record[key])];
1420
- }
1421
- return [key, record[key]];
1422
- })
1423
- );
1428
+ const recordToInsert = this.processJsonbFields(tableName, record);
1424
1429
  await collection.insertOne(recordToInsert);
1425
1430
  } catch (error) {
1426
1431
  if (error instanceof Error) {
@@ -1444,7 +1449,8 @@ var StoreOperationsMongoDB = class extends StoreOperations {
1444
1449
  }
1445
1450
  try {
1446
1451
  const collection = await this.getCollection(tableName);
1447
- await collection.insertMany(records);
1452
+ const processedRecords = records.map((record) => this.processJsonbFields(tableName, record));
1453
+ await collection.insertMany(processedRecords);
1448
1454
  } catch (error) {
1449
1455
  throw new MastraError(
1450
1456
  {
@@ -1596,19 +1602,19 @@ var ScoresStorageMongoDB = class extends ScoresStorage {
1596
1602
  scorerId: score.scorerId,
1597
1603
  traceId: score.traceId || "",
1598
1604
  runId: score.runId,
1599
- scorer: typeof score.scorer === "string" ? score.scorer : JSON.stringify(score.scorer),
1600
- extractStepResult: typeof score.extractStepResult === "string" ? score.extractStepResult : JSON.stringify(score.extractStepResult),
1601
- analyzeStepResult: typeof score.analyzeStepResult === "string" ? score.analyzeStepResult : JSON.stringify(score.analyzeStepResult),
1605
+ scorer: typeof score.scorer === "string" ? safelyParseJSON(score.scorer) : score.scorer,
1606
+ extractStepResult: typeof score.extractStepResult === "string" ? safelyParseJSON(score.extractStepResult) : score.extractStepResult,
1607
+ analyzeStepResult: typeof score.analyzeStepResult === "string" ? safelyParseJSON(score.analyzeStepResult) : score.analyzeStepResult,
1602
1608
  score: score.score,
1603
1609
  reason: score.reason,
1604
1610
  extractPrompt: score.extractPrompt,
1605
1611
  analyzePrompt: score.analyzePrompt,
1606
1612
  reasonPrompt: score.reasonPrompt,
1607
- input: typeof score.input === "string" ? score.input : JSON.stringify(score.input),
1608
- output: typeof score.output === "string" ? score.output : JSON.stringify(score.output),
1613
+ input: typeof score.input === "string" ? safelyParseJSON(score.input) : score.input,
1614
+ output: typeof score.output === "string" ? safelyParseJSON(score.output) : score.output,
1609
1615
  additionalContext: score.additionalContext,
1610
- runtimeContext: typeof score.runtimeContext === "string" ? score.runtimeContext : JSON.stringify(score.runtimeContext),
1611
- entity: typeof score.entity === "string" ? score.entity : JSON.stringify(score.entity),
1616
+ runtimeContext: typeof score.runtimeContext === "string" ? safelyParseJSON(score.runtimeContext) : score.runtimeContext,
1617
+ entity: typeof score.entity === "string" ? safelyParseJSON(score.entity) : score.entity,
1612
1618
  source: score.source,
1613
1619
  resourceId: score.resourceId || "",
1614
1620
  threadId: score.threadId || "",
@@ -2052,6 +2058,40 @@ var WorkflowsStorageMongoDB = class extends WorkflowsStorage {
2052
2058
  };
2053
2059
 
2054
2060
  // src/storage/index.ts
2061
+ var loadConnector = (config) => {
2062
+ try {
2063
+ if ("connectorHandler" in config) {
2064
+ return MongoDBConnector.fromConnectionHandler(config.connectorHandler);
2065
+ }
2066
+ } catch (error) {
2067
+ throw new MastraError(
2068
+ {
2069
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2070
+ domain: ErrorDomain.STORAGE,
2071
+ category: ErrorCategory.USER,
2072
+ details: { connectionHandler: true }
2073
+ },
2074
+ error
2075
+ );
2076
+ }
2077
+ try {
2078
+ return MongoDBConnector.fromDatabaseConfig({
2079
+ options: config.options,
2080
+ url: config.url,
2081
+ dbName: config.dbName
2082
+ });
2083
+ } catch (error) {
2084
+ throw new MastraError(
2085
+ {
2086
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2087
+ domain: ErrorDomain.STORAGE,
2088
+ category: ErrorCategory.USER,
2089
+ details: { url: config?.url, dbName: config?.dbName }
2090
+ },
2091
+ error
2092
+ );
2093
+ }
2094
+ };
2055
2095
  var MongoDBStore = class extends MastraStorage {
2056
2096
  #connector;
2057
2097
  stores;
@@ -2060,45 +2100,14 @@ var MongoDBStore = class extends MastraStorage {
2060
2100
  selectByIncludeResourceScope: true,
2061
2101
  resourceWorkingMemory: true,
2062
2102
  hasColumn: false,
2063
- createTable: false
2103
+ createTable: false,
2104
+ deleteMessages: false
2064
2105
  };
2065
2106
  }
2066
2107
  constructor(config) {
2067
2108
  super({ name: "MongoDBStore" });
2068
2109
  this.stores = {};
2069
- try {
2070
- if ("connectorHandler" in config) {
2071
- this.#connector = MongoDBConnector.fromConnectionHandler(config.connectorHandler);
2072
- return;
2073
- }
2074
- } catch (error) {
2075
- throw new MastraError(
2076
- {
2077
- id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2078
- domain: ErrorDomain.STORAGE,
2079
- category: ErrorCategory.USER,
2080
- details: { connectionHandler: true }
2081
- },
2082
- error
2083
- );
2084
- }
2085
- try {
2086
- this.#connector = MongoDBConnector.fromDatabaseConfig({
2087
- options: config.options,
2088
- url: config.url,
2089
- dbName: config.dbName
2090
- });
2091
- } catch (error) {
2092
- throw new MastraError(
2093
- {
2094
- id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2095
- domain: ErrorDomain.STORAGE,
2096
- category: ErrorCategory.USER,
2097
- details: { url: config?.url, dbName: config?.dbName }
2098
- },
2099
- error
2100
- );
2101
- }
2110
+ this.#connector = loadConnector(config);
2102
2111
  const operations = new StoreOperationsMongoDB({
2103
2112
  connector: this.#connector
2104
2113
  });
@@ -1,6 +1,6 @@
1
1
  services:
2
2
  mongodb-storage:
3
- image: mongo:8.0.11
3
+ image: mongo:8.0.12
4
4
  container_name: 'mongodb-storage-test-db'
5
5
  ports:
6
6
  - '27017:27017'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mongodb",
3
- "version": "0.12.2",
3
+ "version": "0.12.3-alpha.1",
4
4
  "description": "MongoDB provider for Mastra - includes vector store capabilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@types/mongodb": "^4.0.7",
23
- "cloudflare": "^4.4.1",
23
+ "cloudflare": "^4.5.0",
24
24
  "mongodb": "^6.17.0",
25
25
  "uuid": "^11.1.0"
26
26
  },
@@ -31,9 +31,9 @@
31
31
  "tsup": "^8.5.0",
32
32
  "typescript": "^5.8.3",
33
33
  "vitest": "^3.2.4",
34
- "@internal/lint": "0.0.22",
35
- "@internal/storage-test-utils": "0.0.18",
36
- "@mastra/core": "0.11.1"
34
+ "@internal/lint": "0.0.23",
35
+ "@internal/storage-test-utils": "0.0.19",
36
+ "@mastra/core": "0.12.0-alpha.2"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@mastra/core": ">=0.10.7-0 <0.12.0-0"
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './vector';
2
2
  export * from './storage';
3
+ export * from './storage/connectors/base';
3
4
  export { MONGODB_PROMPT } from './vector/prompt';
@@ -1,6 +1,6 @@
1
1
  import { MongoClient } from 'mongodb';
2
2
  import type { Db } from 'mongodb';
3
- import type { ConnectorHandler } from './ConnectorHandler';
3
+ import type { ConnectorHandler } from './connectors/base';
4
4
  import type { DatabaseConfig } from './types';
5
5
 
6
6
  type MongoDBConnectorOptions =
@@ -568,7 +568,7 @@ export class MemoryStorageMongoDB extends MemoryStorage {
568
568
  async getThreadsByResourceId({ resourceId }: { resourceId: string }): Promise<StorageThreadType[]> {
569
569
  try {
570
570
  const collection = await this.operations.getCollection(TABLE_THREADS);
571
- const results = await collection.find<any>({ resourceId }).toArray();
571
+ const results = await collection.find<any>({ resourceId }).sort({ updatedAt: -1 }).toArray();
572
572
  if (!results.length) {
573
573
  return [];
574
574
  }
@@ -78,21 +78,23 @@ export class StoreOperationsMongoDB extends StoreOperations {
78
78
  }
79
79
  }
80
80
 
81
+ private processJsonbFields(tableName: TABLE_NAMES, record: Record<string, any>): Record<string, any> {
82
+ const schema = TABLE_SCHEMAS[tableName];
83
+
84
+ return Object.fromEntries(
85
+ Object.entries(schema).map(([key, value]) => {
86
+ if (value.type === 'jsonb' && record[key] && typeof record[key] === 'string') {
87
+ return [key, safelyParseJSON(record[key])];
88
+ }
89
+ return [key, record[key]];
90
+ }),
91
+ );
92
+ }
93
+
81
94
  async insert({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {
82
95
  try {
83
96
  const collection = await this.getCollection(tableName);
84
-
85
- const schema = TABLE_SCHEMAS[tableName];
86
-
87
- const recordToInsert = Object.fromEntries(
88
- Object.entries(schema).map(([key, value]) => {
89
- if (value.type === 'jsonb' && record[key] && typeof record[key] === 'string') {
90
- return [key, safelyParseJSON(record[key])];
91
- }
92
- return [key, record[key]];
93
- }),
94
- );
95
-
97
+ const recordToInsert = this.processJsonbFields(tableName, record);
96
98
  await collection.insertOne(recordToInsert);
97
99
  } catch (error) {
98
100
  if (error instanceof Error) {
@@ -118,7 +120,8 @@ export class StoreOperationsMongoDB extends StoreOperations {
118
120
 
119
121
  try {
120
122
  const collection = await this.getCollection(tableName);
121
- await collection.insertMany(records);
123
+ const processedRecords = records.map(record => this.processJsonbFields(tableName, record));
124
+ await collection.insertMany(processedRecords);
122
125
  } catch (error) {
123
126
  throw new MastraError(
124
127
  {
@@ -142,26 +142,26 @@ export class ScoresStorageMongoDB extends ScoresStorage {
142
142
  scorerId: score.scorerId,
143
143
  traceId: score.traceId || '',
144
144
  runId: score.runId,
145
- scorer: typeof score.scorer === 'string' ? score.scorer : JSON.stringify(score.scorer),
145
+ scorer: typeof score.scorer === 'string' ? safelyParseJSON(score.scorer) : score.scorer,
146
146
  extractStepResult:
147
147
  typeof score.extractStepResult === 'string'
148
- ? score.extractStepResult
149
- : JSON.stringify(score.extractStepResult),
148
+ ? safelyParseJSON(score.extractStepResult)
149
+ : score.extractStepResult,
150
150
  analyzeStepResult:
151
151
  typeof score.analyzeStepResult === 'string'
152
- ? score.analyzeStepResult
153
- : JSON.stringify(score.analyzeStepResult),
152
+ ? safelyParseJSON(score.analyzeStepResult)
153
+ : score.analyzeStepResult,
154
154
  score: score.score,
155
155
  reason: score.reason,
156
156
  extractPrompt: score.extractPrompt,
157
157
  analyzePrompt: score.analyzePrompt,
158
158
  reasonPrompt: score.reasonPrompt,
159
- input: typeof score.input === 'string' ? score.input : JSON.stringify(score.input),
160
- output: typeof score.output === 'string' ? score.output : JSON.stringify(score.output),
159
+ input: typeof score.input === 'string' ? safelyParseJSON(score.input) : score.input,
160
+ output: typeof score.output === 'string' ? safelyParseJSON(score.output) : score.output,
161
161
  additionalContext: score.additionalContext,
162
162
  runtimeContext:
163
- typeof score.runtimeContext === 'string' ? score.runtimeContext : JSON.stringify(score.runtimeContext),
164
- entity: typeof score.entity === 'string' ? score.entity : JSON.stringify(score.entity),
163
+ typeof score.runtimeContext === 'string' ? safelyParseJSON(score.runtimeContext) : score.runtimeContext,
164
+ entity: typeof score.entity === 'string' ? safelyParseJSON(score.entity) : score.entity,
165
165
  source: score.source,
166
166
  resourceId: score.resourceId || '',
167
167
  threadId: score.threadId || '',
@@ -51,6 +51,11 @@ describe('Validation', () => {
51
51
  it('does not throw on valid config', () => {
52
52
  expect(() => new MongoDBStore(validWithConnectionHandlerConfig)).not.toThrow();
53
53
  });
54
+
55
+ it('should initialize the stores correctly', () => {
56
+ const store = new MongoDBStore(validWithConnectionHandlerConfig);
57
+ expect(Object.keys(store.stores)).not.toHaveLength(0);
58
+ });
54
59
  });
55
60
  });
56
61
 
@@ -1,5 +1,5 @@
1
1
  import type { MastraMessageContentV2 } from '@mastra/core/agent';
2
- import { ErrorDomain, ErrorCategory, MastraError } from '@mastra/core/error';
2
+ import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
3
3
  import type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';
4
4
  import type { ScoreRowData } from '@mastra/core/scores';
5
5
  import type {
@@ -7,15 +7,15 @@ import type {
7
7
  PaginationArgs,
8
8
  PaginationInfo,
9
9
  StorageColumn,
10
+ StorageDomains,
10
11
  StorageGetMessagesArg,
11
12
  StorageGetTracesArg,
13
+ StorageGetTracesPaginatedArg,
14
+ StoragePagination,
15
+ StorageResourceType,
12
16
  TABLE_NAMES,
13
17
  WorkflowRun,
14
18
  WorkflowRuns,
15
- StorageResourceType,
16
- StorageDomains,
17
- StoragePagination,
18
- StorageGetTracesPaginatedArg,
19
19
  } from '@mastra/core/storage';
20
20
  import { MastraStorage } from '@mastra/core/storage';
21
21
  import type { Trace } from '@mastra/core/telemetry';
@@ -29,6 +29,42 @@ import { TracesStorageMongoDB } from './domains/traces';
29
29
  import { WorkflowsStorageMongoDB } from './domains/workflows';
30
30
  import type { MongoDBConfig } from './types';
31
31
 
32
+ const loadConnector = (config: MongoDBConfig): MongoDBConnector => {
33
+ try {
34
+ if ('connectorHandler' in config) {
35
+ return MongoDBConnector.fromConnectionHandler(config.connectorHandler);
36
+ }
37
+ } catch (error) {
38
+ throw new MastraError(
39
+ {
40
+ id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
41
+ domain: ErrorDomain.STORAGE,
42
+ category: ErrorCategory.USER,
43
+ details: { connectionHandler: true },
44
+ },
45
+ error,
46
+ );
47
+ }
48
+
49
+ try {
50
+ return MongoDBConnector.fromDatabaseConfig({
51
+ options: config.options,
52
+ url: config.url,
53
+ dbName: config.dbName,
54
+ });
55
+ } catch (error) {
56
+ throw new MastraError(
57
+ {
58
+ id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
59
+ domain: ErrorDomain.STORAGE,
60
+ category: ErrorCategory.USER,
61
+ details: { url: config?.url, dbName: config?.dbName },
62
+ },
63
+ error,
64
+ );
65
+ }
66
+ };
67
+
32
68
  export class MongoDBStore extends MastraStorage {
33
69
  #connector: MongoDBConnector;
34
70
 
@@ -39,12 +75,14 @@ export class MongoDBStore extends MastraStorage {
39
75
  resourceWorkingMemory: boolean;
40
76
  hasColumn: boolean;
41
77
  createTable: boolean;
78
+ deleteMessages: boolean;
42
79
  } {
43
80
  return {
44
81
  selectByIncludeResourceScope: true,
45
82
  resourceWorkingMemory: true,
46
83
  hasColumn: false,
47
84
  createTable: false,
85
+ deleteMessages: false,
48
86
  };
49
87
  }
50
88
 
@@ -53,40 +91,7 @@ export class MongoDBStore extends MastraStorage {
53
91
 
54
92
  this.stores = {} as StorageDomains;
55
93
 
56
- try {
57
- if ('connectorHandler' in config) {
58
- this.#connector = MongoDBConnector.fromConnectionHandler(config.connectorHandler);
59
- return;
60
- }
61
- } catch (error) {
62
- throw new MastraError(
63
- {
64
- id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
65
- domain: ErrorDomain.STORAGE,
66
- category: ErrorCategory.USER,
67
- details: { connectionHandler: true },
68
- },
69
- error,
70
- );
71
- }
72
-
73
- try {
74
- this.#connector = MongoDBConnector.fromDatabaseConfig({
75
- options: config.options,
76
- url: config.url,
77
- dbName: config.dbName,
78
- });
79
- } catch (error) {
80
- throw new MastraError(
81
- {
82
- id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
83
- domain: ErrorDomain.STORAGE,
84
- category: ErrorCategory.USER,
85
- details: { url: config?.url, dbName: config?.dbName },
86
- },
87
- error,
88
- );
89
- }
94
+ this.#connector = loadConnector(config);
90
95
 
91
96
  const operations = new StoreOperationsMongoDB({
92
97
  connector: this.#connector,
@@ -327,7 +327,9 @@ export class MongoDBVector extends MastraVector<MongoDBVectorFilter> {
327
327
  .map(doc => doc._id)
328
328
  .toArray();
329
329
 
330
- vectorSearch.filter = { _id: { $in: candidateIds } };
330
+ if (candidateIds.length > 0) {
331
+ vectorSearch.filter = { _id: { $in: candidateIds } };
332
+ }
331
333
  }
332
334
 
333
335
  // Build the aggregation pipeline
@@ -1,7 +0,0 @@
1
- import type { Collection } from 'mongodb';
2
-
3
- export interface ConnectorHandler {
4
- getCollection(collectionName: string): Promise<Collection>;
5
-
6
- close(): Promise<void>;
7
- }