@mastra/libsql 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,28 @@
1
1
  # @mastra/libsql
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
+ - Unify transformScoreRow functions across storage adapters ([#10648](https://github.com/mastra-ai/mastra/pull/10648))
14
+
15
+ 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:
16
+ - `preferredTimestampFields`: Preferred source fields for timestamps (PostgreSQL, Cloudflare D1)
17
+ - `convertTimestamps`: Convert timestamp strings to Date objects (MSSQL, MongoDB, ClickHouse)
18
+ - `nullValuePattern`: Skip values matching pattern (ClickHouse's `'_null_'`)
19
+ - `fieldMappings`: Map source column names to schema fields (LibSQL's `additionalLLMContext`)
20
+
21
+ 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.
22
+
23
+ - 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)]:
24
+ - @mastra/core@1.0.0-beta.6
25
+
3
26
  ## 1.0.0-beta.2
4
27
 
5
28
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1119,26 +1119,24 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1119
1119
  if (row.type && row.type !== `v2`) result.type = row.type;
1120
1120
  return result;
1121
1121
  }
1122
- async _getIncludedMessages({
1123
- threadId,
1124
- include
1125
- }) {
1126
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1127
- if (!include) return null;
1122
+ async _getIncludedMessages({ include }) {
1123
+ if (!include || include.length === 0) return null;
1128
1124
  const unionQueries = [];
1129
1125
  const params = [];
1130
1126
  for (const inc of include) {
1131
1127
  const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
1132
- const searchId = inc.threadId || threadId;
1133
1128
  unionQueries.push(
1134
1129
  `
1135
1130
  SELECT * FROM (
1136
- WITH numbered_messages AS (
1131
+ WITH target_thread AS (
1132
+ SELECT thread_id FROM "${storage.TABLE_MESSAGES}" WHERE id = ?
1133
+ ),
1134
+ numbered_messages AS (
1137
1135
  SELECT
1138
1136
  id, content, role, type, "createdAt", thread_id, "resourceId",
1139
1137
  ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
1140
1138
  FROM "${storage.TABLE_MESSAGES}"
1141
- WHERE thread_id = ?
1139
+ WHERE thread_id = (SELECT thread_id FROM target_thread)
1142
1140
  ),
1143
1141
  target_positions AS (
1144
1142
  SELECT row_num as target_pos
@@ -1153,7 +1151,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1153
1151
  `
1154
1152
  // Keep ASC for final sorting after fetching context
1155
1153
  );
1156
- params.push(searchId, id, withPreviousMessages, withNextMessages);
1154
+ params.push(id, id, withPreviousMessages, withNextMessages);
1157
1155
  }
1158
1156
  const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
1159
1157
  const includedResult = await this.client.execute({ sql: finalQuery, args: params });
@@ -1200,15 +1198,16 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1200
1198
  }
1201
1199
  async listMessages(args) {
1202
1200
  const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1203
- if (!threadId.trim()) {
1201
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
1202
+ if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
1204
1203
  throw new error.MastraError(
1205
1204
  {
1206
1205
  id: "STORAGE_LIBSQL_LIST_MESSAGES_INVALID_THREAD_ID",
1207
1206
  domain: error.ErrorDomain.STORAGE,
1208
1207
  category: error.ErrorCategory.THIRD_PARTY,
1209
- details: { threadId }
1208
+ details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
1210
1209
  },
1211
- new Error("threadId must be a non-empty string")
1210
+ new Error("threadId must be a non-empty string or array of non-empty strings")
1212
1211
  );
1213
1212
  }
1214
1213
  if (page < 0) {
@@ -1227,8 +1226,9 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1227
1226
  try {
1228
1227
  const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1229
1228
  const orderByStatement = `ORDER BY "${field}" ${direction}`;
1230
- const conditions = [`thread_id = ?`];
1231
- const queryParams = [threadId];
1229
+ const threadPlaceholders = threadIds.map(() => "?").join(", ");
1230
+ const conditions = [`thread_id IN (${threadPlaceholders})`];
1231
+ const queryParams = [...threadIds];
1232
1232
  if (resourceId) {
1233
1233
  conditions.push(`"resourceId" = ?`);
1234
1234
  queryParams.push(resourceId);
@@ -1268,7 +1268,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1268
1268
  }
1269
1269
  const messageIds = new Set(messages.map((m) => m.id));
1270
1270
  if (include && include.length > 0) {
1271
- const includeMessages = await this._getIncludedMessages({ threadId, include });
1271
+ const includeMessages = await this._getIncludedMessages({ include });
1272
1272
  if (includeMessages) {
1273
1273
  for (const includeMsg of includeMessages) {
1274
1274
  if (!messageIds.has(includeMsg.id)) {
@@ -1289,7 +1289,10 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1289
1289
  }
1290
1290
  return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
1291
1291
  });
1292
- const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1292
+ const threadIdSet = new Set(threadIds);
1293
+ const returnedThreadMessageIds = new Set(
1294
+ finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
1295
+ );
1293
1296
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1294
1297
  const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
1295
1298
  return {
@@ -1306,7 +1309,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1306
1309
  domain: error.ErrorDomain.STORAGE,
1307
1310
  category: error.ErrorCategory.THIRD_PARTY,
1308
1311
  details: {
1309
- threadId,
1312
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
1310
1313
  resourceId: resourceId ?? ""
1311
1314
  }
1312
1315
  },
@@ -2725,45 +2728,14 @@ var ScoresLibSQL = class extends storage.ScoresStorage {
2725
2728
  );
2726
2729
  }
2727
2730
  }
2731
+ /**
2732
+ * LibSQL-specific score row transformation.
2733
+ * Maps additionalLLMContext column to additionalContext field.
2734
+ */
2728
2735
  transformScoreRow(row) {
2729
- const scorerValue = storage.safelyParseJSON(row.scorer);
2730
- const inputValue = storage.safelyParseJSON(row.input ?? "{}");
2731
- const outputValue = storage.safelyParseJSON(row.output ?? "{}");
2732
- const additionalLLMContextValue = row.additionalLLMContext ? storage.safelyParseJSON(row.additionalLLMContext) : null;
2733
- const requestContextValue = row.requestContext ? storage.safelyParseJSON(row.requestContext) : null;
2734
- const metadataValue = row.metadata ? storage.safelyParseJSON(row.metadata) : null;
2735
- const entityValue = row.entity ? storage.safelyParseJSON(row.entity) : null;
2736
- const preprocessStepResultValue = row.preprocessStepResult ? storage.safelyParseJSON(row.preprocessStepResult) : null;
2737
- const analyzeStepResultValue = row.analyzeStepResult ? storage.safelyParseJSON(row.analyzeStepResult) : null;
2738
- return {
2739
- id: row.id,
2740
- traceId: row.traceId,
2741
- spanId: row.spanId,
2742
- runId: row.runId,
2743
- scorer: scorerValue,
2744
- score: row.score,
2745
- reason: row.reason,
2746
- preprocessStepResult: preprocessStepResultValue,
2747
- analyzeStepResult: analyzeStepResultValue,
2748
- analyzePrompt: row.analyzePrompt,
2749
- preprocessPrompt: row.preprocessPrompt,
2750
- generateScorePrompt: row.generateScorePrompt,
2751
- generateReasonPrompt: row.generateReasonPrompt,
2752
- metadata: metadataValue,
2753
- input: inputValue,
2754
- output: outputValue,
2755
- additionalContext: additionalLLMContextValue,
2756
- requestContext: requestContextValue,
2757
- entityType: row.entityType,
2758
- entity: entityValue,
2759
- entityId: row.entityId,
2760
- scorerId: row.scorerId,
2761
- source: row.source,
2762
- resourceId: row.resourceId,
2763
- threadId: row.threadId,
2764
- createdAt: row.createdAt,
2765
- updatedAt: row.updatedAt
2766
- };
2736
+ return storage.transformScoreRow(row, {
2737
+ fieldMappings: { additionalContext: "additionalLLMContext" }
2738
+ });
2767
2739
  }
2768
2740
  async getScoreById({ id }) {
2769
2741
  const result = await this.client.execute({