@mastra/mongodb 1.0.0-beta.2 → 1.0.0-beta.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @mastra/mongodb
2
2
 
3
+ ## 1.0.0-beta.3
4
+
5
+ ### Patch Changes
6
+
7
+ - feat(storage): support querying messages from multiple threads ([#10663](https://github.com/mastra-ai/mastra/pull/10663))
8
+ - Fixed TypeScript errors where `threadId: string | string[]` was being passed to places expecting `Scalar` type
9
+ - Added proper multi-thread support for `listMessages` across all adapters when `threadId` is an array
10
+ - Updated `_getIncludedMessages` to look up message threadId by ID (since message IDs are globally unique)
11
+ - **upstash**: Added `msg-idx:{messageId}` index for O(1) message lookups (backwards compatible with fallback to scan for old messages, with automatic backfill)
12
+
13
+ - fix: ensure score responses match saved payloads for Mastra Stores. ([#10557](https://github.com/mastra-ai/mastra/pull/10557))
14
+
15
+ - Unify transformScoreRow functions across storage adapters ([#10648](https://github.com/mastra-ai/mastra/pull/10648))
16
+
17
+ Added a unified `transformScoreRow` function in `@mastra/core/storage` that provides schema-driven row transformation for score data. This eliminates code duplication across 10 storage adapters while maintaining store-specific behavior through configurable options:
18
+ - `preferredTimestampFields`: Preferred source fields for timestamps (PostgreSQL, Cloudflare D1)
19
+ - `convertTimestamps`: Convert timestamp strings to Date objects (MSSQL, MongoDB, ClickHouse)
20
+ - `nullValuePattern`: Skip values matching pattern (ClickHouse's `'_null_'`)
21
+ - `fieldMappings`: Map source column names to schema fields (LibSQL's `additionalLLMContext`)
22
+
23
+ Each store adapter now uses the unified function with appropriate options, reducing ~200 lines of duplicate transformation logic while ensuring consistent behavior across all storage backends.
24
+
25
+ - Updated dependencies [[`ac0d2f4`](https://github.com/mastra-ai/mastra/commit/ac0d2f4ff8831f72c1c66c2be809706d17f65789), [`1a0d3fc`](https://github.com/mastra-ai/mastra/commit/1a0d3fc811482c9c376cdf79ee615c23bae9b2d6), [`85a628b`](https://github.com/mastra-ai/mastra/commit/85a628b1224a8f64cd82ea7f033774bf22df7a7e), [`c237233`](https://github.com/mastra-ai/mastra/commit/c23723399ccedf7f5744b3f40997b79246bfbe64), [`15f9e21`](https://github.com/mastra-ai/mastra/commit/15f9e216177201ea6e3f6d0bfb063fcc0953444f), [`ff94dea`](https://github.com/mastra-ai/mastra/commit/ff94dea935f4e34545c63bcb6c29804732698809), [`5b2ff46`](https://github.com/mastra-ai/mastra/commit/5b2ff4651df70c146523a7fca773f8eb0a2272f8), [`db41688`](https://github.com/mastra-ai/mastra/commit/db4168806d007417e2e60b4f68656dca4e5f40c9), [`5ca599d`](https://github.com/mastra-ai/mastra/commit/5ca599d0bb59a1595f19f58473fcd67cc71cef58), [`bff1145`](https://github.com/mastra-ai/mastra/commit/bff114556b3cbadad9b2768488708f8ad0e91475), [`5c8ca24`](https://github.com/mastra-ai/mastra/commit/5c8ca247094e0cc2cdbd7137822fb47241f86e77), [`e191844`](https://github.com/mastra-ai/mastra/commit/e1918444ca3f80e82feef1dad506cd4ec6e2875f), [`22553f1`](https://github.com/mastra-ai/mastra/commit/22553f11c63ee5e966a9c034a349822249584691), [`7237163`](https://github.com/mastra-ai/mastra/commit/72371635dbf96a87df4b073cc48fc655afbdce3d), [`2500740`](https://github.com/mastra-ai/mastra/commit/2500740ea23da067d6e50ec71c625ab3ce275e64), [`873ecbb`](https://github.com/mastra-ai/mastra/commit/873ecbb517586aa17d2f1e99283755b3ebb2863f), [`4f9bbe5`](https://github.com/mastra-ai/mastra/commit/4f9bbe5968f42c86f4930b8193de3c3c17e5bd36), [`02e51fe`](https://github.com/mastra-ai/mastra/commit/02e51feddb3d4155cfbcc42624fd0d0970d032c0), [`8f3fa3a`](https://github.com/mastra-ai/mastra/commit/8f3fa3a652bb77da092f913ec51ae46e3a7e27dc), [`cd29ad2`](https://github.com/mastra-ai/mastra/commit/cd29ad23a255534e8191f249593849ed29160886), [`bdf4d8c`](https://github.com/mastra-ai/mastra/commit/bdf4d8cdc656d8a2c21d81834bfa3bfa70f56c16), [`854e3da`](https://github.com/mastra-ai/mastra/commit/854e3dad5daac17a91a20986399d3a51f54bf68b), [`ce18d38`](https://github.com/mastra-ai/mastra/commit/ce18d38678c65870350d123955014a8432075fd9), [`cccf9c8`](https://github.com/mastra-ai/mastra/commit/cccf9c8b2d2dfc1a5e63919395b83d78c89682a0), [`61a5705`](https://github.com/mastra-ai/mastra/commit/61a570551278b6743e64243b3ce7d73de915ca8a), [`db70a48`](https://github.com/mastra-ai/mastra/commit/db70a48aeeeeb8e5f92007e8ede52c364ce15287), [`f0fdc14`](https://github.com/mastra-ai/mastra/commit/f0fdc14ee233d619266b3d2bbdeea7d25cfc6d13), [`db18bc9`](https://github.com/mastra-ai/mastra/commit/db18bc9c3825e2c1a0ad9a183cc9935f6691bfa1), [`9b37b56`](https://github.com/mastra-ai/mastra/commit/9b37b565e1f2a76c24f728945cc740c2b09be9da), [`41a23c3`](https://github.com/mastra-ai/mastra/commit/41a23c32f9877d71810f37e24930515df2ff7a0f), [`5d171ad`](https://github.com/mastra-ai/mastra/commit/5d171ad9ef340387276b77c2bb3e83e83332d729), [`f03ae60`](https://github.com/mastra-ai/mastra/commit/f03ae60500fe350c9d828621006cdafe1975fdd8), [`d1e74a0`](https://github.com/mastra-ai/mastra/commit/d1e74a0a293866dece31022047f5dbab65a304d0), [`39e7869`](https://github.com/mastra-ai/mastra/commit/39e7869bc7d0ee391077ce291474d8a84eedccff), [`5761926`](https://github.com/mastra-ai/mastra/commit/57619260c4a2cdd598763abbacd90de594c6bc76), [`c900fdd`](https://github.com/mastra-ai/mastra/commit/c900fdd504c41348efdffb205cfe80d48c38fa33), [`604a79f`](https://github.com/mastra-ai/mastra/commit/604a79fecf276e26a54a3fe01bb94e65315d2e0e), [`887f0b4`](https://github.com/mastra-ai/mastra/commit/887f0b4746cdbd7cb7d6b17ac9f82aeb58037ea5), [`2562143`](https://github.com/mastra-ai/mastra/commit/256214336b4faa78646c9c1776612393790d8784), [`ef11a61`](https://github.com/mastra-ai/mastra/commit/ef11a61920fa0ed08a5b7ceedd192875af119749)]:
26
+ - @mastra/core@1.0.0-beta.6
27
+
3
28
  ## 1.0.0-beta.2
4
29
 
5
30
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -13,7 +13,7 @@ var evals = require('@mastra/core/evals');
13
13
 
14
14
  // package.json
15
15
  var package_default = {
16
- version: "1.0.0-beta.2"};
16
+ version: "1.0.0-beta.3"};
17
17
  var MongoDBFilterTranslator = class extends filter.BaseFilterTranslator {
18
18
  getSupportedOperators() {
19
19
  return {
@@ -838,8 +838,6 @@ var MongoDBConnector = class _MongoDBConnector {
838
838
  }
839
839
  }
840
840
  };
841
-
842
- // src/storage/domains/utils.ts
843
841
  function formatDateForMongoDB(date) {
844
842
  return typeof date === "string" ? new Date(date) : date;
845
843
  }
@@ -870,18 +868,16 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
870
868
  if (row.type && row.type !== "v2") result.type = row.type;
871
869
  return result;
872
870
  }
873
- async _getIncludedMessages({
874
- threadId,
875
- include
876
- }) {
877
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
878
- if (!include) return null;
871
+ async _getIncludedMessages({ include }) {
872
+ if (!include || include.length === 0) return null;
879
873
  const collection = await this.operations.getCollection(storage.TABLE_MESSAGES);
880
874
  const includedMessages = [];
881
875
  for (const inc of include) {
882
876
  const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
883
- const searchThreadId = inc.threadId || threadId;
884
- const allMessages = await collection.find({ thread_id: searchThreadId }).sort({ createdAt: 1 }).toArray();
877
+ const targetMessage = await collection.findOne({ id });
878
+ if (!targetMessage) continue;
879
+ const messageThreadId = targetMessage.thread_id;
880
+ const allMessages = await collection.find({ thread_id: messageThreadId }).sort({ createdAt: 1 }).toArray();
885
881
  const targetIndex = allMessages.findIndex((msg) => msg.id === id);
886
882
  if (targetIndex === -1) continue;
887
883
  const startIndex = Math.max(0, targetIndex - withPreviousMessages);
@@ -922,15 +918,16 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
922
918
  }
923
919
  async listMessages(args) {
924
920
  const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
925
- if (!threadId.trim()) {
921
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
922
+ if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
926
923
  throw new error.MastraError(
927
924
  {
928
925
  id: "STORAGE_MONGODB_LIST_MESSAGES_INVALID_THREAD_ID",
929
926
  domain: error.ErrorDomain.STORAGE,
930
927
  category: error.ErrorCategory.THIRD_PARTY,
931
- details: { threadId }
928
+ details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
932
929
  },
933
- new Error("threadId must be a non-empty string")
930
+ new Error("threadId must be a non-empty string or array of non-empty strings")
934
931
  );
935
932
  }
936
933
  if (page < 0) {
@@ -950,7 +947,7 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
950
947
  const { field, direction } = this.parseOrderBy(orderBy, "ASC");
951
948
  const sortOrder = direction === "ASC" ? 1 : -1;
952
949
  const collection = await this.operations.getCollection(storage.TABLE_MESSAGES);
953
- const query = { thread_id: threadId };
950
+ const query = { thread_id: threadIds.length === 1 ? threadIds[0] : { $in: threadIds } };
954
951
  if (resourceId) {
955
952
  query.resourceId = resourceId;
956
953
  }
@@ -982,7 +979,7 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
982
979
  }
983
980
  const messageIds = new Set(messages.map((m) => m.id));
984
981
  if (include && include.length > 0) {
985
- const includeMessages = await this._getIncludedMessages({ threadId, include });
982
+ const includeMessages = await this._getIncludedMessages({ include });
986
983
  if (includeMessages) {
987
984
  for (const includeMsg of includeMessages) {
988
985
  if (!messageIds.has(includeMsg.id)) {
@@ -1003,7 +1000,10 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
1003
1000
  }
1004
1001
  return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
1005
1002
  });
1006
- const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1003
+ const threadIdSet = new Set(threadIds);
1004
+ const returnedThreadMessageIds = new Set(
1005
+ finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
1006
+ );
1007
1007
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1008
1008
  const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
1009
1009
  return {
@@ -1020,7 +1020,7 @@ var MemoryStorageMongoDB = class extends storage.MemoryStorage {
1020
1020
  domain: error.ErrorDomain.STORAGE,
1021
1021
  category: error.ErrorCategory.THIRD_PARTY,
1022
1022
  details: {
1023
- threadId,
1023
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
1024
1024
  resourceId: resourceId ?? ""
1025
1025
  }
1026
1026
  },
@@ -1900,98 +1900,9 @@ var StoreOperationsMongoDB = class extends storage.StoreOperations {
1900
1900
  }
1901
1901
  };
1902
1902
  function transformScoreRow(row) {
1903
- let scorerValue = null;
1904
- if (row.scorer) {
1905
- try {
1906
- scorerValue = typeof row.scorer === "string" ? storage.safelyParseJSON(row.scorer) : row.scorer;
1907
- } catch (e) {
1908
- console.warn("Failed to parse scorer:", e);
1909
- }
1910
- }
1911
- let preprocessStepResultValue = null;
1912
- if (row.preprocessStepResult) {
1913
- try {
1914
- preprocessStepResultValue = typeof row.preprocessStepResult === "string" ? storage.safelyParseJSON(row.preprocessStepResult) : row.preprocessStepResult;
1915
- } catch (e) {
1916
- console.warn("Failed to parse preprocessStepResult:", e);
1917
- }
1918
- }
1919
- let analyzeStepResultValue = null;
1920
- if (row.analyzeStepResult) {
1921
- try {
1922
- analyzeStepResultValue = typeof row.analyzeStepResult === "string" ? storage.safelyParseJSON(row.analyzeStepResult) : row.analyzeStepResult;
1923
- } catch (e) {
1924
- console.warn("Failed to parse analyzeStepResult:", e);
1925
- }
1926
- }
1927
- let inputValue = null;
1928
- if (row.input) {
1929
- try {
1930
- inputValue = typeof row.input === "string" ? storage.safelyParseJSON(row.input) : row.input;
1931
- } catch (e) {
1932
- console.warn("Failed to parse input:", e);
1933
- }
1934
- }
1935
- let outputValue = null;
1936
- if (row.output) {
1937
- try {
1938
- outputValue = typeof row.output === "string" ? storage.safelyParseJSON(row.output) : row.output;
1939
- } catch (e) {
1940
- console.warn("Failed to parse output:", e);
1941
- }
1942
- }
1943
- let entityValue = null;
1944
- if (row.entity) {
1945
- try {
1946
- entityValue = typeof row.entity === "string" ? storage.safelyParseJSON(row.entity) : row.entity;
1947
- } catch (e) {
1948
- console.warn("Failed to parse entity:", e);
1949
- }
1950
- }
1951
- let requestContextValue = null;
1952
- if (row.requestContext) {
1953
- try {
1954
- requestContextValue = typeof row.requestContext === "string" ? storage.safelyParseJSON(row.requestContext) : row.requestContext;
1955
- } catch (e) {
1956
- console.warn("Failed to parse requestContext:", e);
1957
- }
1958
- }
1959
- let metadataValue = null;
1960
- if (row.metadata) {
1961
- try {
1962
- metadataValue = typeof row.metadata === "string" ? storage.safelyParseJSON(row.metadata) : row.metadata;
1963
- } catch (e) {
1964
- console.warn("Failed to parse metadata:", e);
1965
- }
1966
- }
1967
- return {
1968
- id: row.id,
1969
- entityId: row.entityId,
1970
- entityType: row.entityType,
1971
- scorerId: row.scorerId,
1972
- traceId: row.traceId,
1973
- spanId: row.spanId,
1974
- runId: row.runId,
1975
- scorer: scorerValue,
1976
- preprocessStepResult: preprocessStepResultValue,
1977
- preprocessPrompt: row.preprocessPrompt,
1978
- analyzeStepResult: analyzeStepResultValue,
1979
- generateScorePrompt: row.generateScorePrompt,
1980
- score: row.score,
1981
- analyzePrompt: row.analyzePrompt,
1982
- reasonPrompt: row.reasonPrompt,
1983
- metadata: metadataValue,
1984
- input: inputValue,
1985
- output: outputValue,
1986
- additionalContext: row.additionalContext,
1987
- requestContext: requestContextValue,
1988
- entity: entityValue,
1989
- source: row.source,
1990
- resourceId: row.resourceId,
1991
- threadId: row.threadId,
1992
- createdAt: new Date(row.createdAt),
1993
- updatedAt: new Date(row.updatedAt)
1994
- };
1903
+ return storage.transformScoreRow(row, {
1904
+ convertTimestamps: true
1905
+ });
1995
1906
  }
1996
1907
  var ScoresStorageMongoDB = class extends storage.ScoresStorage {
1997
1908
  operations;
@@ -2036,36 +1947,29 @@ var ScoresStorageMongoDB = class extends storage.ScoresStorage {
2036
1947
  try {
2037
1948
  const now = /* @__PURE__ */ new Date();
2038
1949
  const scoreId = `score-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
2039
- const scoreData = {
2040
- id: scoreId,
2041
- entityId: validatedScore.entityId,
2042
- entityType: validatedScore.entityType,
2043
- scorerId: validatedScore.scorerId,
2044
- traceId: validatedScore.traceId || "",
2045
- spanId: validatedScore.spanId || "",
2046
- runId: validatedScore.runId,
2047
- scorer: typeof validatedScore.scorer === "string" ? storage.safelyParseJSON(validatedScore.scorer) : validatedScore.scorer,
2048
- preprocessStepResult: typeof validatedScore.preprocessStepResult === "string" ? storage.safelyParseJSON(validatedScore.preprocessStepResult) : validatedScore.preprocessStepResult,
2049
- analyzeStepResult: typeof validatedScore.analyzeStepResult === "string" ? storage.safelyParseJSON(validatedScore.analyzeStepResult) : validatedScore.analyzeStepResult,
2050
- score: validatedScore.score,
2051
- reason: validatedScore.reason,
2052
- preprocessPrompt: validatedScore.preprocessPrompt,
2053
- generateScorePrompt: validatedScore.generateScorePrompt,
2054
- generateReasonPrompt: validatedScore.generateReasonPrompt,
2055
- analyzePrompt: validatedScore.analyzePrompt,
2056
- input: typeof validatedScore.input === "string" ? storage.safelyParseJSON(validatedScore.input) : validatedScore.input,
2057
- output: typeof validatedScore.output === "string" ? storage.safelyParseJSON(validatedScore.output) : validatedScore.output,
2058
- additionalContext: validatedScore.additionalContext,
2059
- requestContext: typeof validatedScore.requestContext === "string" ? storage.safelyParseJSON(validatedScore.requestContext) : validatedScore.requestContext,
2060
- entity: typeof validatedScore.entity === "string" ? storage.safelyParseJSON(validatedScore.entity) : validatedScore.entity,
2061
- source: validatedScore.source,
2062
- resourceId: validatedScore.resourceId || "",
2063
- threadId: validatedScore.threadId || "",
2064
- createdAt: now,
2065
- updatedAt: now
1950
+ const scorer = typeof validatedScore.scorer === "string" ? storage.safelyParseJSON(validatedScore.scorer) : validatedScore.scorer;
1951
+ const preprocessStepResult = typeof validatedScore.preprocessStepResult === "string" ? storage.safelyParseJSON(validatedScore.preprocessStepResult) : validatedScore.preprocessStepResult;
1952
+ const analyzeStepResult = typeof validatedScore.analyzeStepResult === "string" ? storage.safelyParseJSON(validatedScore.analyzeStepResult) : validatedScore.analyzeStepResult;
1953
+ const input = typeof validatedScore.input === "string" ? storage.safelyParseJSON(validatedScore.input) : validatedScore.input;
1954
+ const output = typeof validatedScore.output === "string" ? storage.safelyParseJSON(validatedScore.output) : validatedScore.output;
1955
+ const requestContext = typeof validatedScore.requestContext === "string" ? storage.safelyParseJSON(validatedScore.requestContext) : validatedScore.requestContext;
1956
+ const entity = typeof validatedScore.entity === "string" ? storage.safelyParseJSON(validatedScore.entity) : validatedScore.entity;
1957
+ const createdAt = now;
1958
+ const updatedAt = now;
1959
+ const dataToSave = {
1960
+ ...validatedScore,
1961
+ scorer,
1962
+ preprocessStepResult,
1963
+ analyzeStepResult,
1964
+ input,
1965
+ output,
1966
+ requestContext,
1967
+ entity,
1968
+ createdAt,
1969
+ updatedAt
2066
1970
  };
2067
1971
  const collection = await this.operations.getCollection(storage.TABLE_SCORERS);
2068
- await collection.insertOne(scoreData);
1972
+ await collection.insertOne(dataToSave);
2069
1973
  const savedScore = {
2070
1974
  ...score,
2071
1975
  id: scoreId,