@mastra/mssql 0.0.0-pgvector-index-fix-20250905222058 → 0.0.0-playground-studio-cloud-20251031080052

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/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
- import { MastraStorage, LegacyEvalsStorage, StoreOperations, TABLE_WORKFLOW_SNAPSHOT, ScoresStorage, TABLE_SCORERS, TracesStorage, TABLE_TRACES, WorkflowsStorage, MemoryStorage, resolveMessageLimit, TABLE_RESOURCES, TABLE_EVALS, TABLE_THREADS, TABLE_MESSAGES } from '@mastra/core/storage';
3
- import sql2 from 'mssql';
4
- import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
2
+ import { MastraStorage, LegacyEvalsStorage, StoreOperations, TABLE_WORKFLOW_SNAPSHOT, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_EVALS, TABLE_SCORERS, TABLE_AI_SPANS, ScoresStorage, WorkflowsStorage, MemoryStorage, resolveMessageLimit, TABLE_RESOURCES, ObservabilityStorage, safelyParseJSON } from '@mastra/core/storage';
3
+ import sql3 from 'mssql';
4
+ import { parseSqlIdentifier } from '@mastra/core/utils';
5
5
  import { MessageList } from '@mastra/core/agent';
6
+ import { randomUUID } from 'crypto';
7
+ import { saveScorePayloadSchema } from '@mastra/core/scores';
6
8
 
7
9
  // src/storage/index.ts
8
10
  function getSchemaName(schema) {
@@ -14,6 +16,69 @@ function getTableName({ indexName, schemaName }) {
14
16
  const quotedSchemaName = schemaName;
15
17
  return quotedSchemaName ? `${quotedSchemaName}.${quotedIndexName}` : quotedIndexName;
16
18
  }
19
+ function buildDateRangeFilter(dateRange, fieldName) {
20
+ const filters = {};
21
+ if (dateRange?.start) {
22
+ filters[`${fieldName}_gte`] = dateRange.start;
23
+ }
24
+ if (dateRange?.end) {
25
+ filters[`${fieldName}_lte`] = dateRange.end;
26
+ }
27
+ return filters;
28
+ }
29
+ function prepareWhereClause(filters, _schema) {
30
+ const conditions = [];
31
+ const params = {};
32
+ let paramIndex = 1;
33
+ Object.entries(filters).forEach(([key, value]) => {
34
+ if (value === void 0) return;
35
+ const paramName = `p${paramIndex++}`;
36
+ if (key.endsWith("_gte")) {
37
+ const fieldName = key.slice(0, -4);
38
+ conditions.push(`[${parseSqlIdentifier(fieldName, "field name")}] >= @${paramName}`);
39
+ params[paramName] = value instanceof Date ? value.toISOString() : value;
40
+ } else if (key.endsWith("_lte")) {
41
+ const fieldName = key.slice(0, -4);
42
+ conditions.push(`[${parseSqlIdentifier(fieldName, "field name")}] <= @${paramName}`);
43
+ params[paramName] = value instanceof Date ? value.toISOString() : value;
44
+ } else if (value === null) {
45
+ conditions.push(`[${parseSqlIdentifier(key, "field name")}] IS NULL`);
46
+ } else {
47
+ conditions.push(`[${parseSqlIdentifier(key, "field name")}] = @${paramName}`);
48
+ params[paramName] = value instanceof Date ? value.toISOString() : value;
49
+ }
50
+ });
51
+ return {
52
+ sql: conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "",
53
+ params
54
+ };
55
+ }
56
+ function transformFromSqlRow({
57
+ tableName,
58
+ sqlRow
59
+ }) {
60
+ const schema = TABLE_SCHEMAS[tableName];
61
+ const result = {};
62
+ Object.entries(sqlRow).forEach(([key, value]) => {
63
+ const columnSchema = schema?.[key];
64
+ if (columnSchema?.type === "jsonb" && typeof value === "string") {
65
+ try {
66
+ result[key] = JSON.parse(value);
67
+ } catch {
68
+ result[key] = value;
69
+ }
70
+ } else if (columnSchema?.type === "timestamp" && value && typeof value === "string") {
71
+ result[key] = new Date(value);
72
+ } else if (columnSchema?.type === "timestamp" && value instanceof Date) {
73
+ result[key] = value;
74
+ } else if (columnSchema?.type === "boolean") {
75
+ result[key] = Boolean(value);
76
+ } else {
77
+ result[key] = value;
78
+ }
79
+ });
80
+ return result;
81
+ }
17
82
 
18
83
  // src/storage/domains/legacy-evals/index.ts
19
84
  function transformEvalRow(row) {
@@ -24,7 +89,7 @@ function transformEvalRow(row) {
24
89
  } catch {
25
90
  }
26
91
  }
27
- if (row.test_info) {
92
+ if (row.result) {
28
93
  try {
29
94
  resultValue = typeof row.result === "string" ? JSON.parse(row.result) : row.result;
30
95
  } catch {
@@ -70,7 +135,7 @@ var LegacyEvalsMSSQL = class extends LegacyEvalsStorage {
70
135
  if (error && error.number === 208 && error.message && error.message.includes("Invalid object name")) {
71
136
  return [];
72
137
  }
73
- console.error("Failed to get evals for the specified agent: " + error?.message);
138
+ this.logger?.error?.("Failed to get evals for the specified agent:", error);
74
139
  throw error;
75
140
  }
76
141
  }
@@ -106,7 +171,7 @@ var LegacyEvalsMSSQL = class extends LegacyEvalsStorage {
106
171
  const countReq = this.pool.request();
107
172
  Object.entries(params).forEach(([key, value]) => {
108
173
  if (value instanceof Date) {
109
- countReq.input(key, sql2.DateTime, value);
174
+ countReq.input(key, sql3.DateTime, value);
110
175
  } else {
111
176
  countReq.input(key, value);
112
177
  }
@@ -125,7 +190,7 @@ var LegacyEvalsMSSQL = class extends LegacyEvalsStorage {
125
190
  const req = this.pool.request();
126
191
  Object.entries(params).forEach(([key, value]) => {
127
192
  if (value instanceof Date) {
128
- req.input(key, sql2.DateTime, value);
193
+ req.input(key, sql3.DateTime, value);
129
194
  } else {
130
195
  req.input(key, value);
131
196
  }
@@ -157,7 +222,7 @@ var LegacyEvalsMSSQL = class extends LegacyEvalsStorage {
157
222
  error
158
223
  );
159
224
  this.logger?.error?.(mastraError.toString());
160
- this.logger?.trackException(mastraError);
225
+ this.logger?.trackException?.(mastraError);
161
226
  throw mastraError;
162
227
  }
163
228
  }
@@ -193,7 +258,7 @@ var MemoryMSSQL = class extends MemoryStorage {
193
258
  }
194
259
  async getThreadById({ threadId }) {
195
260
  try {
196
- const sql7 = `SELECT
261
+ const sql6 = `SELECT
197
262
  id,
198
263
  [resourceId],
199
264
  title,
@@ -204,7 +269,7 @@ var MemoryMSSQL = class extends MemoryStorage {
204
269
  WHERE id = @threadId`;
205
270
  const request = this.pool.request();
206
271
  request.input("threadId", threadId);
207
- const resultSet = await request.query(sql7);
272
+ const resultSet = await request.query(sql6);
208
273
  const thread = resultSet.recordset[0] || null;
209
274
  if (!thread) {
210
275
  return null;
@@ -250,7 +315,8 @@ var MemoryMSSQL = class extends MemoryStorage {
250
315
  };
251
316
  }
252
317
  const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
253
- const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${sortDirection} OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
318
+ const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
319
+ const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir} OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
254
320
  const dataRequest = this.pool.request();
255
321
  dataRequest.input("resourceId", resourceId);
256
322
  dataRequest.input("perPage", perPage);
@@ -307,9 +373,14 @@ var MemoryMSSQL = class extends MemoryStorage {
307
373
  req.input("id", thread.id);
308
374
  req.input("resourceId", thread.resourceId);
309
375
  req.input("title", thread.title);
310
- req.input("metadata", thread.metadata ? JSON.stringify(thread.metadata) : null);
311
- req.input("createdAt", sql2.DateTime2, thread.createdAt);
312
- req.input("updatedAt", sql2.DateTime2, thread.updatedAt);
376
+ const metadata = thread.metadata ? JSON.stringify(thread.metadata) : null;
377
+ if (metadata === null) {
378
+ req.input("metadata", sql3.NVarChar, null);
379
+ } else {
380
+ req.input("metadata", metadata);
381
+ }
382
+ req.input("createdAt", sql3.DateTime2, thread.createdAt);
383
+ req.input("updatedAt", sql3.DateTime2, thread.updatedAt);
313
384
  await req.query(mergeSql);
314
385
  return thread;
315
386
  } catch (error) {
@@ -334,7 +405,8 @@ var MemoryMSSQL = class extends MemoryStorage {
334
405
  try {
335
406
  const baseQuery = `FROM ${getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) })} WHERE [resourceId] = @resourceId`;
336
407
  const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
337
- const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${sortDirection}`;
408
+ const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
409
+ const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir}`;
338
410
  const request = this.pool.request();
339
411
  request.input("resourceId", resourceId);
340
412
  const resultSet = await request.query(dataQuery);
@@ -377,7 +449,7 @@ var MemoryMSSQL = class extends MemoryStorage {
377
449
  };
378
450
  try {
379
451
  const table = getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) });
380
- const sql7 = `UPDATE ${table}
452
+ const sql6 = `UPDATE ${table}
381
453
  SET title = @title,
382
454
  metadata = @metadata,
383
455
  [updatedAt] = @updatedAt
@@ -388,7 +460,7 @@ var MemoryMSSQL = class extends MemoryStorage {
388
460
  req.input("title", title);
389
461
  req.input("metadata", JSON.stringify(mergedMetadata));
390
462
  req.input("updatedAt", /* @__PURE__ */ new Date());
391
- const result = await req.query(sql7);
463
+ const result = await req.query(sql6);
392
464
  let thread = result.recordset && result.recordset[0];
393
465
  if (thread && "seq_id" in thread) {
394
466
  const { seq_id, ...rest } = thread;
@@ -583,7 +655,7 @@ var MemoryMSSQL = class extends MemoryStorage {
583
655
  error
584
656
  );
585
657
  this.logger?.error?.(mastraError.toString());
586
- this.logger?.trackException(mastraError);
658
+ this.logger?.trackException?.(mastraError);
587
659
  return [];
588
660
  }
589
661
  }
@@ -623,7 +695,7 @@ var MemoryMSSQL = class extends MemoryStorage {
623
695
  error
624
696
  );
625
697
  this.logger?.error?.(mastraError.toString());
626
- this.logger?.trackException(mastraError);
698
+ this.logger?.trackException?.(mastraError);
627
699
  return [];
628
700
  }
629
701
  }
@@ -685,7 +757,7 @@ var MemoryMSSQL = class extends MemoryStorage {
685
757
  const parsed = this._parseAndFormatMessages(messages, format);
686
758
  return {
687
759
  messages: parsed,
688
- total: total + excludeIds.length,
760
+ total,
689
761
  page,
690
762
  perPage,
691
763
  hasMore: currentOffset + rows.length < total
@@ -705,7 +777,7 @@ var MemoryMSSQL = class extends MemoryStorage {
705
777
  error
706
778
  );
707
779
  this.logger?.error?.(mastraError.toString());
708
- this.logger?.trackException(mastraError);
780
+ this.logger?.trackException?.(mastraError);
709
781
  return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
710
782
  }
711
783
  }
@@ -757,7 +829,7 @@ var MemoryMSSQL = class extends MemoryStorage {
757
829
  "content",
758
830
  typeof message.content === "string" ? message.content : JSON.stringify(message.content)
759
831
  );
760
- request.input("createdAt", sql2.DateTime2, message.createdAt);
832
+ request.input("createdAt", sql3.DateTime2, message.createdAt);
761
833
  request.input("role", message.role);
762
834
  request.input("type", message.type || "v2");
763
835
  request.input("resourceId", message.resourceId);
@@ -776,7 +848,7 @@ var MemoryMSSQL = class extends MemoryStorage {
776
848
  await request.query(mergeSql);
777
849
  }
778
850
  const threadReq = transaction.request();
779
- threadReq.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
851
+ threadReq.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
780
852
  threadReq.input("id", threadId);
781
853
  await threadReq.query(`UPDATE ${tableThreads} SET [updatedAt] = @updatedAt WHERE id = @id`);
782
854
  await transaction.commit();
@@ -972,8 +1044,10 @@ var MemoryMSSQL = class extends MemoryStorage {
972
1044
  return null;
973
1045
  }
974
1046
  return {
975
- ...result,
976
- workingMemory: typeof result.workingMemory === "object" ? JSON.stringify(result.workingMemory) : result.workingMemory,
1047
+ id: result.id,
1048
+ createdAt: result.createdAt,
1049
+ updatedAt: result.updatedAt,
1050
+ workingMemory: result.workingMemory,
977
1051
  metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
978
1052
  };
979
1053
  } catch (error) {
@@ -987,7 +1061,7 @@ var MemoryMSSQL = class extends MemoryStorage {
987
1061
  error
988
1062
  );
989
1063
  this.logger?.error?.(mastraError.toString());
990
- this.logger?.trackException(mastraError);
1064
+ this.logger?.trackException?.(mastraError);
991
1065
  throw mastraError;
992
1066
  }
993
1067
  }
@@ -996,7 +1070,7 @@ var MemoryMSSQL = class extends MemoryStorage {
996
1070
  tableName: TABLE_RESOURCES,
997
1071
  record: {
998
1072
  ...resource,
999
- metadata: JSON.stringify(resource.metadata)
1073
+ metadata: resource.metadata
1000
1074
  }
1001
1075
  });
1002
1076
  return resource;
@@ -1054,20 +1128,337 @@ var MemoryMSSQL = class extends MemoryStorage {
1054
1128
  error
1055
1129
  );
1056
1130
  this.logger?.error?.(mastraError.toString());
1057
- this.logger?.trackException(mastraError);
1131
+ this.logger?.trackException?.(mastraError);
1058
1132
  throw mastraError;
1059
1133
  }
1060
1134
  }
1061
1135
  };
1136
+ var ObservabilityMSSQL = class extends ObservabilityStorage {
1137
+ pool;
1138
+ operations;
1139
+ schema;
1140
+ constructor({
1141
+ pool,
1142
+ operations,
1143
+ schema
1144
+ }) {
1145
+ super();
1146
+ this.pool = pool;
1147
+ this.operations = operations;
1148
+ this.schema = schema;
1149
+ }
1150
+ get aiTracingStrategy() {
1151
+ return {
1152
+ preferred: "batch-with-updates",
1153
+ supported: ["batch-with-updates", "insert-only"]
1154
+ };
1155
+ }
1156
+ async createAISpan(span) {
1157
+ try {
1158
+ const startedAt = span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt;
1159
+ const endedAt = span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt;
1160
+ const record = {
1161
+ ...span,
1162
+ startedAt,
1163
+ endedAt
1164
+ // Note: createdAt/updatedAt will be set by default values
1165
+ };
1166
+ return this.operations.insert({ tableName: TABLE_AI_SPANS, record });
1167
+ } catch (error) {
1168
+ throw new MastraError(
1169
+ {
1170
+ id: "MSSQL_STORE_CREATE_AI_SPAN_FAILED",
1171
+ domain: ErrorDomain.STORAGE,
1172
+ category: ErrorCategory.USER,
1173
+ details: {
1174
+ spanId: span.spanId,
1175
+ traceId: span.traceId,
1176
+ spanType: span.spanType,
1177
+ spanName: span.name
1178
+ }
1179
+ },
1180
+ error
1181
+ );
1182
+ }
1183
+ }
1184
+ async getAITrace(traceId) {
1185
+ try {
1186
+ const tableName = getTableName({
1187
+ indexName: TABLE_AI_SPANS,
1188
+ schemaName: getSchemaName(this.schema)
1189
+ });
1190
+ const request = this.pool.request();
1191
+ request.input("traceId", traceId);
1192
+ const result = await request.query(
1193
+ `SELECT
1194
+ [traceId], [spanId], [parentSpanId], [name], [scope], [spanType],
1195
+ [attributes], [metadata], [links], [input], [output], [error], [isEvent],
1196
+ [startedAt], [endedAt], [createdAt], [updatedAt]
1197
+ FROM ${tableName}
1198
+ WHERE [traceId] = @traceId
1199
+ ORDER BY [startedAt] DESC`
1200
+ );
1201
+ if (!result.recordset || result.recordset.length === 0) {
1202
+ return null;
1203
+ }
1204
+ return {
1205
+ traceId,
1206
+ spans: result.recordset.map(
1207
+ (span) => transformFromSqlRow({
1208
+ tableName: TABLE_AI_SPANS,
1209
+ sqlRow: span
1210
+ })
1211
+ )
1212
+ };
1213
+ } catch (error) {
1214
+ throw new MastraError(
1215
+ {
1216
+ id: "MSSQL_STORE_GET_AI_TRACE_FAILED",
1217
+ domain: ErrorDomain.STORAGE,
1218
+ category: ErrorCategory.USER,
1219
+ details: {
1220
+ traceId
1221
+ }
1222
+ },
1223
+ error
1224
+ );
1225
+ }
1226
+ }
1227
+ async updateAISpan({
1228
+ spanId,
1229
+ traceId,
1230
+ updates
1231
+ }) {
1232
+ try {
1233
+ const data = { ...updates };
1234
+ if (data.endedAt instanceof Date) {
1235
+ data.endedAt = data.endedAt.toISOString();
1236
+ }
1237
+ if (data.startedAt instanceof Date) {
1238
+ data.startedAt = data.startedAt.toISOString();
1239
+ }
1240
+ await this.operations.update({
1241
+ tableName: TABLE_AI_SPANS,
1242
+ keys: { spanId, traceId },
1243
+ data
1244
+ });
1245
+ } catch (error) {
1246
+ throw new MastraError(
1247
+ {
1248
+ id: "MSSQL_STORE_UPDATE_AI_SPAN_FAILED",
1249
+ domain: ErrorDomain.STORAGE,
1250
+ category: ErrorCategory.USER,
1251
+ details: {
1252
+ spanId,
1253
+ traceId
1254
+ }
1255
+ },
1256
+ error
1257
+ );
1258
+ }
1259
+ }
1260
+ async getAITracesPaginated({
1261
+ filters,
1262
+ pagination
1263
+ }) {
1264
+ const page = pagination?.page ?? 0;
1265
+ const perPage = pagination?.perPage ?? 10;
1266
+ const { entityId, entityType, ...actualFilters } = filters || {};
1267
+ const filtersWithDateRange = {
1268
+ ...actualFilters,
1269
+ ...buildDateRangeFilter(pagination?.dateRange, "startedAt"),
1270
+ parentSpanId: null
1271
+ // Only get root spans for traces
1272
+ };
1273
+ const whereClause = prepareWhereClause(filtersWithDateRange);
1274
+ let actualWhereClause = whereClause.sql;
1275
+ const params = { ...whereClause.params };
1276
+ let currentParamIndex = Object.keys(params).length + 1;
1277
+ if (entityId && entityType) {
1278
+ let name = "";
1279
+ if (entityType === "workflow") {
1280
+ name = `workflow run: '${entityId}'`;
1281
+ } else if (entityType === "agent") {
1282
+ name = `agent run: '${entityId}'`;
1283
+ } else {
1284
+ const error = new MastraError({
1285
+ id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
1286
+ domain: ErrorDomain.STORAGE,
1287
+ category: ErrorCategory.USER,
1288
+ details: {
1289
+ entityType
1290
+ },
1291
+ text: `Cannot filter by entity type: ${entityType}`
1292
+ });
1293
+ throw error;
1294
+ }
1295
+ const entityParam = `p${currentParamIndex++}`;
1296
+ if (actualWhereClause) {
1297
+ actualWhereClause += ` AND [name] = @${entityParam}`;
1298
+ } else {
1299
+ actualWhereClause = ` WHERE [name] = @${entityParam}`;
1300
+ }
1301
+ params[entityParam] = name;
1302
+ }
1303
+ const tableName = getTableName({
1304
+ indexName: TABLE_AI_SPANS,
1305
+ schemaName: getSchemaName(this.schema)
1306
+ });
1307
+ try {
1308
+ const countRequest = this.pool.request();
1309
+ Object.entries(params).forEach(([key, value]) => {
1310
+ countRequest.input(key, value);
1311
+ });
1312
+ const countResult = await countRequest.query(
1313
+ `SELECT COUNT(*) as count FROM ${tableName}${actualWhereClause}`
1314
+ );
1315
+ const total = countResult.recordset[0]?.count ?? 0;
1316
+ if (total === 0) {
1317
+ return {
1318
+ pagination: {
1319
+ total: 0,
1320
+ page,
1321
+ perPage,
1322
+ hasMore: false
1323
+ },
1324
+ spans: []
1325
+ };
1326
+ }
1327
+ const dataRequest = this.pool.request();
1328
+ Object.entries(params).forEach(([key, value]) => {
1329
+ dataRequest.input(key, value);
1330
+ });
1331
+ dataRequest.input("offset", page * perPage);
1332
+ dataRequest.input("limit", perPage);
1333
+ const dataResult = await dataRequest.query(
1334
+ `SELECT * FROM ${tableName}${actualWhereClause} ORDER BY [startedAt] DESC OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`
1335
+ );
1336
+ const spans = dataResult.recordset.map(
1337
+ (row) => transformFromSqlRow({
1338
+ tableName: TABLE_AI_SPANS,
1339
+ sqlRow: row
1340
+ })
1341
+ );
1342
+ return {
1343
+ pagination: {
1344
+ total,
1345
+ page,
1346
+ perPage,
1347
+ hasMore: (page + 1) * perPage < total
1348
+ },
1349
+ spans
1350
+ };
1351
+ } catch (error) {
1352
+ throw new MastraError(
1353
+ {
1354
+ id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
1355
+ domain: ErrorDomain.STORAGE,
1356
+ category: ErrorCategory.USER
1357
+ },
1358
+ error
1359
+ );
1360
+ }
1361
+ }
1362
+ async batchCreateAISpans(args) {
1363
+ if (!args.records || args.records.length === 0) {
1364
+ return;
1365
+ }
1366
+ try {
1367
+ await this.operations.batchInsert({
1368
+ tableName: TABLE_AI_SPANS,
1369
+ records: args.records.map((span) => ({
1370
+ ...span,
1371
+ startedAt: span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt,
1372
+ endedAt: span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt
1373
+ }))
1374
+ });
1375
+ } catch (error) {
1376
+ throw new MastraError(
1377
+ {
1378
+ id: "MSSQL_STORE_BATCH_CREATE_AI_SPANS_FAILED",
1379
+ domain: ErrorDomain.STORAGE,
1380
+ category: ErrorCategory.USER,
1381
+ details: {
1382
+ count: args.records.length
1383
+ }
1384
+ },
1385
+ error
1386
+ );
1387
+ }
1388
+ }
1389
+ async batchUpdateAISpans(args) {
1390
+ if (!args.records || args.records.length === 0) {
1391
+ return;
1392
+ }
1393
+ try {
1394
+ const updates = args.records.map(({ traceId, spanId, updates: data }) => {
1395
+ const processedData = { ...data };
1396
+ if (processedData.endedAt instanceof Date) {
1397
+ processedData.endedAt = processedData.endedAt.toISOString();
1398
+ }
1399
+ if (processedData.startedAt instanceof Date) {
1400
+ processedData.startedAt = processedData.startedAt.toISOString();
1401
+ }
1402
+ return {
1403
+ keys: { spanId, traceId },
1404
+ data: processedData
1405
+ };
1406
+ });
1407
+ await this.operations.batchUpdate({
1408
+ tableName: TABLE_AI_SPANS,
1409
+ updates
1410
+ });
1411
+ } catch (error) {
1412
+ throw new MastraError(
1413
+ {
1414
+ id: "MSSQL_STORE_BATCH_UPDATE_AI_SPANS_FAILED",
1415
+ domain: ErrorDomain.STORAGE,
1416
+ category: ErrorCategory.USER,
1417
+ details: {
1418
+ count: args.records.length
1419
+ }
1420
+ },
1421
+ error
1422
+ );
1423
+ }
1424
+ }
1425
+ async batchDeleteAITraces(args) {
1426
+ if (!args.traceIds || args.traceIds.length === 0) {
1427
+ return;
1428
+ }
1429
+ try {
1430
+ const keys = args.traceIds.map((traceId) => ({ traceId }));
1431
+ await this.operations.batchDelete({
1432
+ tableName: TABLE_AI_SPANS,
1433
+ keys
1434
+ });
1435
+ } catch (error) {
1436
+ throw new MastraError(
1437
+ {
1438
+ id: "MSSQL_STORE_BATCH_DELETE_AI_TRACES_FAILED",
1439
+ domain: ErrorDomain.STORAGE,
1440
+ category: ErrorCategory.USER,
1441
+ details: {
1442
+ count: args.traceIds.length
1443
+ }
1444
+ },
1445
+ error
1446
+ );
1447
+ }
1448
+ }
1449
+ };
1062
1450
  var StoreOperationsMSSQL = class extends StoreOperations {
1063
1451
  pool;
1064
1452
  schemaName;
1065
1453
  setupSchemaPromise = null;
1066
1454
  schemaSetupComplete = void 0;
1067
- getSqlType(type, isPrimaryKey = false) {
1455
+ getSqlType(type, isPrimaryKey = false, useLargeStorage = false) {
1068
1456
  switch (type) {
1069
1457
  case "text":
1070
- return isPrimaryKey ? "NVARCHAR(255)" : "NVARCHAR(MAX)";
1458
+ if (useLargeStorage) {
1459
+ return "NVARCHAR(MAX)";
1460
+ }
1461
+ return isPrimaryKey ? "NVARCHAR(255)" : "NVARCHAR(400)";
1071
1462
  case "timestamp":
1072
1463
  return "DATETIME2(7)";
1073
1464
  case "uuid":
@@ -1080,6 +1471,8 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1080
1471
  return "BIGINT";
1081
1472
  case "float":
1082
1473
  return "FLOAT";
1474
+ case "boolean":
1475
+ return "BIT";
1083
1476
  default:
1084
1477
  throw new MastraError({
1085
1478
  id: "MASTRA_STORAGE_MSSQL_STORE_TYPE_NOT_SUPPORTED",
@@ -1142,20 +1535,26 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1142
1535
  }
1143
1536
  await this.setupSchemaPromise;
1144
1537
  }
1145
- async insert({ tableName, record }) {
1538
+ async insert({
1539
+ tableName,
1540
+ record,
1541
+ transaction
1542
+ }) {
1146
1543
  try {
1147
- const columns = Object.keys(record).map((col) => parseSqlIdentifier(col, "column name"));
1148
- const values = Object.values(record);
1149
- const paramNames = values.map((_, i) => `@param${i}`);
1150
- const insertSql = `INSERT INTO ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} (${columns.map((c) => `[${c}]`).join(", ")}) VALUES (${paramNames.join(", ")})`;
1151
- const request = this.pool.request();
1152
- values.forEach((value, i) => {
1153
- if (value instanceof Date) {
1154
- request.input(`param${i}`, sql2.DateTime2, value);
1155
- } else if (typeof value === "object" && value !== null) {
1156
- request.input(`param${i}`, JSON.stringify(value));
1544
+ const columns = Object.keys(record);
1545
+ const parsedColumns = columns.map((col) => parseSqlIdentifier(col, "column name"));
1546
+ const paramNames = columns.map((_, i) => `@param${i}`);
1547
+ const insertSql = `INSERT INTO ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} (${parsedColumns.map((c) => `[${c}]`).join(", ")}) VALUES (${paramNames.join(", ")})`;
1548
+ const request = transaction ? transaction.request() : this.pool.request();
1549
+ columns.forEach((col, i) => {
1550
+ const value = record[col];
1551
+ const preparedValue = this.prepareValue(value, col, tableName);
1552
+ if (preparedValue instanceof Date) {
1553
+ request.input(`param${i}`, sql3.DateTime2, preparedValue);
1554
+ } else if (preparedValue === null || preparedValue === void 0) {
1555
+ request.input(`param${i}`, this.getMssqlType(tableName, col), null);
1157
1556
  } else {
1158
- request.input(`param${i}`, value);
1557
+ request.input(`param${i}`, preparedValue);
1159
1558
  }
1160
1559
  });
1161
1560
  await request.query(insertSql);
@@ -1179,7 +1578,7 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1179
1578
  try {
1180
1579
  await this.pool.request().query(`TRUNCATE TABLE ${fullTableName}`);
1181
1580
  } catch (truncateError) {
1182
- if (truncateError.message && truncateError.message.includes("foreign key")) {
1581
+ if (truncateError?.number === 4712) {
1183
1582
  await this.pool.request().query(`DELETE FROM ${fullTableName}`);
1184
1583
  } else {
1185
1584
  throw truncateError;
@@ -1202,9 +1601,11 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1202
1601
  getDefaultValue(type) {
1203
1602
  switch (type) {
1204
1603
  case "timestamp":
1205
- return "DEFAULT SYSDATETIMEOFFSET()";
1604
+ return "DEFAULT SYSUTCDATETIME()";
1206
1605
  case "jsonb":
1207
1606
  return "DEFAULT N'{}'";
1607
+ case "boolean":
1608
+ return "DEFAULT 0";
1208
1609
  default:
1209
1610
  return super.getDefaultValue(type);
1210
1611
  }
@@ -1215,13 +1616,29 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1215
1616
  }) {
1216
1617
  try {
1217
1618
  const uniqueConstraintColumns = tableName === TABLE_WORKFLOW_SNAPSHOT ? ["workflow_name", "run_id"] : [];
1619
+ const largeDataColumns = [
1620
+ "workingMemory",
1621
+ "snapshot",
1622
+ "metadata",
1623
+ "content",
1624
+ // messages.content - can be very long conversation content
1625
+ "input",
1626
+ // evals.input - test input data
1627
+ "output",
1628
+ // evals.output - test output data
1629
+ "instructions",
1630
+ // evals.instructions - evaluation instructions
1631
+ "other"
1632
+ // traces.other - additional trace data
1633
+ ];
1218
1634
  const columns = Object.entries(schema).map(([name, def]) => {
1219
1635
  const parsedName = parseSqlIdentifier(name, "column name");
1220
1636
  const constraints = [];
1221
1637
  if (def.primaryKey) constraints.push("PRIMARY KEY");
1222
1638
  if (!def.nullable) constraints.push("NOT NULL");
1223
1639
  const isIndexed = !!def.primaryKey || uniqueConstraintColumns.includes(name);
1224
- return `[${parsedName}] ${this.getSqlType(def.type, isIndexed)} ${constraints.join(" ")}`.trim();
1640
+ const useLargeStorage = largeDataColumns.includes(name);
1641
+ return `[${parsedName}] ${this.getSqlType(def.type, isIndexed, useLargeStorage)} ${constraints.join(" ")}`.trim();
1225
1642
  }).join(",\n");
1226
1643
  if (this.schemaName) {
1227
1644
  await this.setupSchema();
@@ -1308,7 +1725,19 @@ ${columns}
1308
1725
  const columnExists = Array.isArray(checkResult.recordset) && checkResult.recordset.length > 0;
1309
1726
  if (!columnExists) {
1310
1727
  const columnDef = schema[columnName];
1311
- const sqlType = this.getSqlType(columnDef.type);
1728
+ const largeDataColumns = [
1729
+ "workingMemory",
1730
+ "snapshot",
1731
+ "metadata",
1732
+ "content",
1733
+ "input",
1734
+ "output",
1735
+ "instructions",
1736
+ "other"
1737
+ ];
1738
+ const useLargeStorage = largeDataColumns.includes(columnName);
1739
+ const isIndexed = !!columnDef.primaryKey;
1740
+ const sqlType = this.getSqlType(columnDef.type, isIndexed, useLargeStorage);
1312
1741
  const nullable = columnDef.nullable === false ? "NOT NULL" : "";
1313
1742
  const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
1314
1743
  const parsedColumnName = parseSqlIdentifier(columnName, "column name");
@@ -1336,13 +1765,17 @@ ${columns}
1336
1765
  try {
1337
1766
  const keyEntries = Object.entries(keys).map(([key, value]) => [parseSqlIdentifier(key, "column name"), value]);
1338
1767
  const conditions = keyEntries.map(([key], i) => `[${key}] = @param${i}`).join(" AND ");
1339
- const values = keyEntries.map(([_, value]) => value);
1340
- const sql7 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
1768
+ const sql6 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
1341
1769
  const request = this.pool.request();
1342
- values.forEach((value, i) => {
1343
- request.input(`param${i}`, value);
1770
+ keyEntries.forEach(([key, value], i) => {
1771
+ const preparedValue = this.prepareValue(value, key, tableName);
1772
+ if (preparedValue === null || preparedValue === void 0) {
1773
+ request.input(`param${i}`, this.getMssqlType(tableName, key), null);
1774
+ } else {
1775
+ request.input(`param${i}`, preparedValue);
1776
+ }
1344
1777
  });
1345
- const resultSet = await request.query(sql7);
1778
+ const resultSet = await request.query(sql6);
1346
1779
  const result = resultSet.recordset[0] || null;
1347
1780
  if (!result) {
1348
1781
  return null;
@@ -1374,7 +1807,7 @@ ${columns}
1374
1807
  try {
1375
1808
  await transaction.begin();
1376
1809
  for (const record of records) {
1377
- await this.insert({ tableName, record });
1810
+ await this.insert({ tableName, record, transaction });
1378
1811
  }
1379
1812
  await transaction.commit();
1380
1813
  } catch (error) {
@@ -1411,52 +1844,593 @@ ${columns}
1411
1844
  );
1412
1845
  }
1413
1846
  }
1414
- };
1415
- function parseJSON(jsonString) {
1416
- try {
1417
- return JSON.parse(jsonString);
1418
- } catch {
1419
- return jsonString;
1847
+ /**
1848
+ * Prepares a value for database operations, handling Date objects and JSON serialization
1849
+ */
1850
+ prepareValue(value, columnName, tableName) {
1851
+ if (value === null || value === void 0) {
1852
+ return value;
1853
+ }
1854
+ if (value instanceof Date) {
1855
+ return value;
1856
+ }
1857
+ const schema = TABLE_SCHEMAS[tableName];
1858
+ const columnSchema = schema?.[columnName];
1859
+ if (columnSchema?.type === "boolean") {
1860
+ return value ? 1 : 0;
1861
+ }
1862
+ if (columnSchema?.type === "jsonb") {
1863
+ return JSON.stringify(value);
1864
+ }
1865
+ if (typeof value === "object") {
1866
+ return JSON.stringify(value);
1867
+ }
1868
+ return value;
1420
1869
  }
1421
- }
1422
- function transformScoreRow(row) {
1423
- return {
1424
- ...row,
1425
- input: parseJSON(row.input),
1426
- scorer: parseJSON(row.scorer),
1427
- preprocessStepResult: parseJSON(row.preprocessStepResult),
1428
- analyzeStepResult: parseJSON(row.analyzeStepResult),
1429
- metadata: parseJSON(row.metadata),
1430
- output: parseJSON(row.output),
1431
- additionalContext: parseJSON(row.additionalContext),
1432
- runtimeContext: parseJSON(row.runtimeContext),
1433
- entity: parseJSON(row.entity),
1434
- createdAt: row.createdAt,
1435
- updatedAt: row.updatedAt
1436
- };
1437
- }
1438
- var ScoresMSSQL = class extends ScoresStorage {
1439
- pool;
1440
- operations;
1441
- schema;
1442
- constructor({
1443
- pool,
1444
- operations,
1445
- schema
1446
- }) {
1447
- super();
1448
- this.pool = pool;
1449
- this.operations = operations;
1450
- this.schema = schema;
1870
+ /**
1871
+ * Maps TABLE_SCHEMAS types to mssql param types (used when value is null)
1872
+ */
1873
+ getMssqlType(tableName, columnName) {
1874
+ const col = TABLE_SCHEMAS[tableName]?.[columnName];
1875
+ switch (col?.type) {
1876
+ case "text":
1877
+ return sql3.NVarChar;
1878
+ case "timestamp":
1879
+ return sql3.DateTime2;
1880
+ case "uuid":
1881
+ return sql3.UniqueIdentifier;
1882
+ case "jsonb":
1883
+ return sql3.NVarChar;
1884
+ case "integer":
1885
+ return sql3.Int;
1886
+ case "bigint":
1887
+ return sql3.BigInt;
1888
+ case "float":
1889
+ return sql3.Float;
1890
+ case "boolean":
1891
+ return sql3.Bit;
1892
+ default:
1893
+ return sql3.NVarChar;
1894
+ }
1451
1895
  }
1452
- async getScoreById({ id }) {
1896
+ /**
1897
+ * Update a single record in the database
1898
+ */
1899
+ async update({
1900
+ tableName,
1901
+ keys,
1902
+ data,
1903
+ transaction
1904
+ }) {
1453
1905
  try {
1454
- const request = this.pool.request();
1455
- request.input("p1", id);
1456
- const result = await request.query(
1457
- `SELECT * FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE id = @p1`
1458
- );
1459
- if (result.recordset.length === 0) {
1906
+ if (!data || Object.keys(data).length === 0) {
1907
+ throw new MastraError({
1908
+ id: "MASTRA_STORAGE_MSSQL_UPDATE_EMPTY_DATA",
1909
+ domain: ErrorDomain.STORAGE,
1910
+ category: ErrorCategory.USER,
1911
+ text: "Cannot update with empty data payload"
1912
+ });
1913
+ }
1914
+ if (!keys || Object.keys(keys).length === 0) {
1915
+ throw new MastraError({
1916
+ id: "MASTRA_STORAGE_MSSQL_UPDATE_EMPTY_KEYS",
1917
+ domain: ErrorDomain.STORAGE,
1918
+ category: ErrorCategory.USER,
1919
+ text: "Cannot update without keys to identify records"
1920
+ });
1921
+ }
1922
+ const setClauses = [];
1923
+ const request = transaction ? transaction.request() : this.pool.request();
1924
+ let paramIndex = 0;
1925
+ Object.entries(data).forEach(([key, value]) => {
1926
+ const parsedKey = parseSqlIdentifier(key, "column name");
1927
+ const paramName = `set${paramIndex++}`;
1928
+ setClauses.push(`[${parsedKey}] = @${paramName}`);
1929
+ const preparedValue = this.prepareValue(value, key, tableName);
1930
+ if (preparedValue === null || preparedValue === void 0) {
1931
+ request.input(paramName, this.getMssqlType(tableName, key), null);
1932
+ } else {
1933
+ request.input(paramName, preparedValue);
1934
+ }
1935
+ });
1936
+ const whereConditions = [];
1937
+ Object.entries(keys).forEach(([key, value]) => {
1938
+ const parsedKey = parseSqlIdentifier(key, "column name");
1939
+ const paramName = `where${paramIndex++}`;
1940
+ whereConditions.push(`[${parsedKey}] = @${paramName}`);
1941
+ const preparedValue = this.prepareValue(value, key, tableName);
1942
+ if (preparedValue === null || preparedValue === void 0) {
1943
+ request.input(paramName, this.getMssqlType(tableName, key), null);
1944
+ } else {
1945
+ request.input(paramName, preparedValue);
1946
+ }
1947
+ });
1948
+ const tableName_ = getTableName({
1949
+ indexName: tableName,
1950
+ schemaName: getSchemaName(this.schemaName)
1951
+ });
1952
+ const updateSql = `UPDATE ${tableName_} SET ${setClauses.join(", ")} WHERE ${whereConditions.join(" AND ")}`;
1953
+ await request.query(updateSql);
1954
+ } catch (error) {
1955
+ throw new MastraError(
1956
+ {
1957
+ id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_FAILED",
1958
+ domain: ErrorDomain.STORAGE,
1959
+ category: ErrorCategory.THIRD_PARTY,
1960
+ details: {
1961
+ tableName
1962
+ }
1963
+ },
1964
+ error
1965
+ );
1966
+ }
1967
+ }
1968
+ /**
1969
+ * Update multiple records in a single batch transaction
1970
+ */
1971
+ async batchUpdate({
1972
+ tableName,
1973
+ updates
1974
+ }) {
1975
+ const transaction = this.pool.transaction();
1976
+ try {
1977
+ await transaction.begin();
1978
+ for (const { keys, data } of updates) {
1979
+ await this.update({ tableName, keys, data, transaction });
1980
+ }
1981
+ await transaction.commit();
1982
+ } catch (error) {
1983
+ await transaction.rollback();
1984
+ throw new MastraError(
1985
+ {
1986
+ id: "MASTRA_STORAGE_MSSQL_STORE_BATCH_UPDATE_FAILED",
1987
+ domain: ErrorDomain.STORAGE,
1988
+ category: ErrorCategory.THIRD_PARTY,
1989
+ details: {
1990
+ tableName,
1991
+ numberOfRecords: updates.length
1992
+ }
1993
+ },
1994
+ error
1995
+ );
1996
+ }
1997
+ }
1998
+ /**
1999
+ * Delete multiple records by keys
2000
+ */
2001
+ async batchDelete({ tableName, keys }) {
2002
+ if (keys.length === 0) {
2003
+ return;
2004
+ }
2005
+ const tableName_ = getTableName({
2006
+ indexName: tableName,
2007
+ schemaName: getSchemaName(this.schemaName)
2008
+ });
2009
+ const transaction = this.pool.transaction();
2010
+ try {
2011
+ await transaction.begin();
2012
+ for (const keySet of keys) {
2013
+ const conditions = [];
2014
+ const request = transaction.request();
2015
+ let paramIndex = 0;
2016
+ Object.entries(keySet).forEach(([key, value]) => {
2017
+ const parsedKey = parseSqlIdentifier(key, "column name");
2018
+ const paramName = `p${paramIndex++}`;
2019
+ conditions.push(`[${parsedKey}] = @${paramName}`);
2020
+ const preparedValue = this.prepareValue(value, key, tableName);
2021
+ if (preparedValue === null || preparedValue === void 0) {
2022
+ request.input(paramName, this.getMssqlType(tableName, key), null);
2023
+ } else {
2024
+ request.input(paramName, preparedValue);
2025
+ }
2026
+ });
2027
+ const deleteSql = `DELETE FROM ${tableName_} WHERE ${conditions.join(" AND ")}`;
2028
+ await request.query(deleteSql);
2029
+ }
2030
+ await transaction.commit();
2031
+ } catch (error) {
2032
+ await transaction.rollback();
2033
+ throw new MastraError(
2034
+ {
2035
+ id: "MASTRA_STORAGE_MSSQL_STORE_BATCH_DELETE_FAILED",
2036
+ domain: ErrorDomain.STORAGE,
2037
+ category: ErrorCategory.THIRD_PARTY,
2038
+ details: {
2039
+ tableName,
2040
+ numberOfRecords: keys.length
2041
+ }
2042
+ },
2043
+ error
2044
+ );
2045
+ }
2046
+ }
2047
+ /**
2048
+ * Create a new index on a table
2049
+ */
2050
+ async createIndex(options) {
2051
+ try {
2052
+ const { name, table, columns, unique = false, where } = options;
2053
+ const schemaName = this.schemaName || "dbo";
2054
+ const fullTableName = getTableName({
2055
+ indexName: table,
2056
+ schemaName: getSchemaName(this.schemaName)
2057
+ });
2058
+ const indexNameSafe = parseSqlIdentifier(name, "index name");
2059
+ const checkRequest = this.pool.request();
2060
+ checkRequest.input("indexName", indexNameSafe);
2061
+ checkRequest.input("schemaName", schemaName);
2062
+ checkRequest.input("tableName", table);
2063
+ const indexExists = await checkRequest.query(`
2064
+ SELECT 1 as found
2065
+ FROM sys.indexes i
2066
+ INNER JOIN sys.tables t ON i.object_id = t.object_id
2067
+ INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
2068
+ WHERE i.name = @indexName
2069
+ AND s.name = @schemaName
2070
+ AND t.name = @tableName
2071
+ `);
2072
+ if (indexExists.recordset && indexExists.recordset.length > 0) {
2073
+ return;
2074
+ }
2075
+ const uniqueStr = unique ? "UNIQUE " : "";
2076
+ const columnsStr = columns.map((col) => {
2077
+ if (col.includes(" DESC") || col.includes(" ASC")) {
2078
+ const [colName, ...modifiers] = col.split(" ");
2079
+ if (!colName) {
2080
+ throw new Error(`Invalid column specification: ${col}`);
2081
+ }
2082
+ return `[${parseSqlIdentifier(colName, "column name")}] ${modifiers.join(" ")}`;
2083
+ }
2084
+ return `[${parseSqlIdentifier(col, "column name")}]`;
2085
+ }).join(", ");
2086
+ const whereStr = where ? ` WHERE ${where}` : "";
2087
+ const createIndexSql = `CREATE ${uniqueStr}INDEX [${indexNameSafe}] ON ${fullTableName} (${columnsStr})${whereStr}`;
2088
+ await this.pool.request().query(createIndexSql);
2089
+ } catch (error) {
2090
+ throw new MastraError(
2091
+ {
2092
+ id: "MASTRA_STORAGE_MSSQL_INDEX_CREATE_FAILED",
2093
+ domain: ErrorDomain.STORAGE,
2094
+ category: ErrorCategory.THIRD_PARTY,
2095
+ details: {
2096
+ indexName: options.name,
2097
+ tableName: options.table
2098
+ }
2099
+ },
2100
+ error
2101
+ );
2102
+ }
2103
+ }
2104
+ /**
2105
+ * Drop an existing index
2106
+ */
2107
+ async dropIndex(indexName) {
2108
+ try {
2109
+ const schemaName = this.schemaName || "dbo";
2110
+ const indexNameSafe = parseSqlIdentifier(indexName, "index name");
2111
+ const checkRequest = this.pool.request();
2112
+ checkRequest.input("indexName", indexNameSafe);
2113
+ checkRequest.input("schemaName", schemaName);
2114
+ const result = await checkRequest.query(`
2115
+ SELECT t.name as table_name
2116
+ FROM sys.indexes i
2117
+ INNER JOIN sys.tables t ON i.object_id = t.object_id
2118
+ INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
2119
+ WHERE i.name = @indexName
2120
+ AND s.name = @schemaName
2121
+ `);
2122
+ if (!result.recordset || result.recordset.length === 0) {
2123
+ return;
2124
+ }
2125
+ if (result.recordset.length > 1) {
2126
+ const tables = result.recordset.map((r) => r.table_name).join(", ");
2127
+ throw new MastraError({
2128
+ id: "MASTRA_STORAGE_MSSQL_INDEX_AMBIGUOUS",
2129
+ domain: ErrorDomain.STORAGE,
2130
+ category: ErrorCategory.USER,
2131
+ text: `Index "${indexNameSafe}" exists on multiple tables (${tables}) in schema "${schemaName}". Please drop indexes manually or ensure unique index names.`
2132
+ });
2133
+ }
2134
+ const tableName = result.recordset[0].table_name;
2135
+ const fullTableName = getTableName({
2136
+ indexName: tableName,
2137
+ schemaName: getSchemaName(this.schemaName)
2138
+ });
2139
+ const dropSql = `DROP INDEX [${indexNameSafe}] ON ${fullTableName}`;
2140
+ await this.pool.request().query(dropSql);
2141
+ } catch (error) {
2142
+ throw new MastraError(
2143
+ {
2144
+ id: "MASTRA_STORAGE_MSSQL_INDEX_DROP_FAILED",
2145
+ domain: ErrorDomain.STORAGE,
2146
+ category: ErrorCategory.THIRD_PARTY,
2147
+ details: {
2148
+ indexName
2149
+ }
2150
+ },
2151
+ error
2152
+ );
2153
+ }
2154
+ }
2155
+ /**
2156
+ * List indexes for a specific table or all tables
2157
+ */
2158
+ async listIndexes(tableName) {
2159
+ try {
2160
+ const schemaName = this.schemaName || "dbo";
2161
+ let query;
2162
+ const request = this.pool.request();
2163
+ request.input("schemaName", schemaName);
2164
+ if (tableName) {
2165
+ query = `
2166
+ SELECT
2167
+ i.name as name,
2168
+ o.name as [table],
2169
+ i.is_unique as is_unique,
2170
+ CAST(SUM(s.used_page_count) * 8 / 1024.0 AS VARCHAR(50)) + ' MB' as size
2171
+ FROM sys.indexes i
2172
+ INNER JOIN sys.objects o ON i.object_id = o.object_id
2173
+ INNER JOIN sys.schemas sch ON o.schema_id = sch.schema_id
2174
+ LEFT JOIN sys.dm_db_partition_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
2175
+ WHERE sch.name = @schemaName
2176
+ AND o.name = @tableName
2177
+ AND i.name IS NOT NULL
2178
+ GROUP BY i.name, o.name, i.is_unique
2179
+ `;
2180
+ request.input("tableName", tableName);
2181
+ } else {
2182
+ query = `
2183
+ SELECT
2184
+ i.name as name,
2185
+ o.name as [table],
2186
+ i.is_unique as is_unique,
2187
+ CAST(SUM(s.used_page_count) * 8 / 1024.0 AS VARCHAR(50)) + ' MB' as size
2188
+ FROM sys.indexes i
2189
+ INNER JOIN sys.objects o ON i.object_id = o.object_id
2190
+ INNER JOIN sys.schemas sch ON o.schema_id = sch.schema_id
2191
+ LEFT JOIN sys.dm_db_partition_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
2192
+ WHERE sch.name = @schemaName
2193
+ AND i.name IS NOT NULL
2194
+ GROUP BY i.name, o.name, i.is_unique
2195
+ `;
2196
+ }
2197
+ const result = await request.query(query);
2198
+ const indexes = [];
2199
+ for (const row of result.recordset) {
2200
+ const colRequest = this.pool.request();
2201
+ colRequest.input("indexName", row.name);
2202
+ colRequest.input("schemaName", schemaName);
2203
+ const colResult = await colRequest.query(`
2204
+ SELECT c.name as column_name
2205
+ FROM sys.indexes i
2206
+ INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
2207
+ INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
2208
+ INNER JOIN sys.objects o ON i.object_id = o.object_id
2209
+ INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
2210
+ WHERE i.name = @indexName
2211
+ AND s.name = @schemaName
2212
+ ORDER BY ic.key_ordinal
2213
+ `);
2214
+ indexes.push({
2215
+ name: row.name,
2216
+ table: row.table,
2217
+ columns: colResult.recordset.map((c) => c.column_name),
2218
+ unique: row.is_unique || false,
2219
+ size: row.size || "0 MB",
2220
+ definition: ""
2221
+ // MSSQL doesn't store definition like PG
2222
+ });
2223
+ }
2224
+ return indexes;
2225
+ } catch (error) {
2226
+ throw new MastraError(
2227
+ {
2228
+ id: "MASTRA_STORAGE_MSSQL_INDEX_LIST_FAILED",
2229
+ domain: ErrorDomain.STORAGE,
2230
+ category: ErrorCategory.THIRD_PARTY,
2231
+ details: tableName ? {
2232
+ tableName
2233
+ } : {}
2234
+ },
2235
+ error
2236
+ );
2237
+ }
2238
+ }
2239
+ /**
2240
+ * Get detailed statistics for a specific index
2241
+ */
2242
+ async describeIndex(indexName) {
2243
+ try {
2244
+ const schemaName = this.schemaName || "dbo";
2245
+ const request = this.pool.request();
2246
+ request.input("indexName", indexName);
2247
+ request.input("schemaName", schemaName);
2248
+ const query = `
2249
+ SELECT
2250
+ i.name as name,
2251
+ o.name as [table],
2252
+ i.is_unique as is_unique,
2253
+ CAST(SUM(s.used_page_count) * 8 / 1024.0 AS VARCHAR(50)) + ' MB' as size,
2254
+ i.type_desc as method,
2255
+ ISNULL(us.user_scans, 0) as scans,
2256
+ ISNULL(us.user_seeks + us.user_scans, 0) as tuples_read,
2257
+ ISNULL(us.user_lookups, 0) as tuples_fetched
2258
+ FROM sys.indexes i
2259
+ INNER JOIN sys.objects o ON i.object_id = o.object_id
2260
+ INNER JOIN sys.schemas sch ON o.schema_id = sch.schema_id
2261
+ LEFT JOIN sys.dm_db_partition_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
2262
+ LEFT JOIN sys.dm_db_index_usage_stats us ON i.object_id = us.object_id AND i.index_id = us.index_id
2263
+ WHERE i.name = @indexName
2264
+ AND sch.name = @schemaName
2265
+ GROUP BY i.name, o.name, i.is_unique, i.type_desc, us.user_seeks, us.user_scans, us.user_lookups
2266
+ `;
2267
+ const result = await request.query(query);
2268
+ if (!result.recordset || result.recordset.length === 0) {
2269
+ throw new Error(`Index "${indexName}" not found in schema "${schemaName}"`);
2270
+ }
2271
+ const row = result.recordset[0];
2272
+ const colRequest = this.pool.request();
2273
+ colRequest.input("indexName", indexName);
2274
+ colRequest.input("schemaName", schemaName);
2275
+ const colResult = await colRequest.query(`
2276
+ SELECT c.name as column_name
2277
+ FROM sys.indexes i
2278
+ INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
2279
+ INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
2280
+ INNER JOIN sys.objects o ON i.object_id = o.object_id
2281
+ INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
2282
+ WHERE i.name = @indexName
2283
+ AND s.name = @schemaName
2284
+ ORDER BY ic.key_ordinal
2285
+ `);
2286
+ return {
2287
+ name: row.name,
2288
+ table: row.table,
2289
+ columns: colResult.recordset.map((c) => c.column_name),
2290
+ unique: row.is_unique || false,
2291
+ size: row.size || "0 MB",
2292
+ definition: "",
2293
+ method: row.method?.toLowerCase() || "nonclustered",
2294
+ scans: Number(row.scans) || 0,
2295
+ tuples_read: Number(row.tuples_read) || 0,
2296
+ tuples_fetched: Number(row.tuples_fetched) || 0
2297
+ };
2298
+ } catch (error) {
2299
+ throw new MastraError(
2300
+ {
2301
+ id: "MASTRA_STORAGE_MSSQL_INDEX_DESCRIBE_FAILED",
2302
+ domain: ErrorDomain.STORAGE,
2303
+ category: ErrorCategory.THIRD_PARTY,
2304
+ details: {
2305
+ indexName
2306
+ }
2307
+ },
2308
+ error
2309
+ );
2310
+ }
2311
+ }
2312
+ /**
2313
+ * Returns definitions for automatic performance indexes
2314
+ * IMPORTANT: Uses seq_id DESC instead of createdAt DESC for MSSQL due to millisecond accuracy limitations
2315
+ * NOTE: Using NVARCHAR(400) for text columns (800 bytes) leaves room for composite indexes
2316
+ */
2317
+ getAutomaticIndexDefinitions() {
2318
+ const schemaPrefix = this.schemaName ? `${this.schemaName}_` : "";
2319
+ return [
2320
+ // Composite indexes for optimal filtering + sorting performance
2321
+ // NVARCHAR(400) = 800 bytes, plus BIGINT (8 bytes) = 808 bytes total (under 900-byte limit)
2322
+ {
2323
+ name: `${schemaPrefix}mastra_threads_resourceid_seqid_idx`,
2324
+ table: TABLE_THREADS,
2325
+ columns: ["resourceId", "seq_id DESC"]
2326
+ },
2327
+ {
2328
+ name: `${schemaPrefix}mastra_messages_thread_id_seqid_idx`,
2329
+ table: TABLE_MESSAGES,
2330
+ columns: ["thread_id", "seq_id DESC"]
2331
+ },
2332
+ {
2333
+ name: `${schemaPrefix}mastra_traces_name_seqid_idx`,
2334
+ table: TABLE_TRACES,
2335
+ columns: ["name", "seq_id DESC"]
2336
+ },
2337
+ {
2338
+ name: `${schemaPrefix}mastra_evals_agent_name_seqid_idx`,
2339
+ table: TABLE_EVALS,
2340
+ columns: ["agent_name", "seq_id DESC"]
2341
+ },
2342
+ {
2343
+ name: `${schemaPrefix}mastra_scores_trace_id_span_id_seqid_idx`,
2344
+ table: TABLE_SCORERS,
2345
+ columns: ["traceId", "spanId", "seq_id DESC"]
2346
+ },
2347
+ // AI Spans indexes for optimal trace querying
2348
+ {
2349
+ name: `${schemaPrefix}mastra_ai_spans_traceid_startedat_idx`,
2350
+ table: TABLE_AI_SPANS,
2351
+ columns: ["traceId", "startedAt DESC"]
2352
+ },
2353
+ {
2354
+ name: `${schemaPrefix}mastra_ai_spans_parentspanid_startedat_idx`,
2355
+ table: TABLE_AI_SPANS,
2356
+ columns: ["parentSpanId", "startedAt DESC"]
2357
+ },
2358
+ {
2359
+ name: `${schemaPrefix}mastra_ai_spans_name_idx`,
2360
+ table: TABLE_AI_SPANS,
2361
+ columns: ["name"]
2362
+ },
2363
+ {
2364
+ name: `${schemaPrefix}mastra_ai_spans_spantype_startedat_idx`,
2365
+ table: TABLE_AI_SPANS,
2366
+ columns: ["spanType", "startedAt DESC"]
2367
+ }
2368
+ ];
2369
+ }
2370
+ /**
2371
+ * Creates automatic indexes for optimal query performance
2372
+ * Uses getAutomaticIndexDefinitions() to determine which indexes to create
2373
+ */
2374
+ async createAutomaticIndexes() {
2375
+ try {
2376
+ const indexes = this.getAutomaticIndexDefinitions();
2377
+ for (const indexOptions of indexes) {
2378
+ try {
2379
+ await this.createIndex(indexOptions);
2380
+ } catch (error) {
2381
+ this.logger?.warn?.(`Failed to create index ${indexOptions.name}:`, error);
2382
+ }
2383
+ }
2384
+ } catch (error) {
2385
+ throw new MastraError(
2386
+ {
2387
+ id: "MASTRA_STORAGE_MSSQL_STORE_CREATE_PERFORMANCE_INDEXES_FAILED",
2388
+ domain: ErrorDomain.STORAGE,
2389
+ category: ErrorCategory.THIRD_PARTY
2390
+ },
2391
+ error
2392
+ );
2393
+ }
2394
+ }
2395
+ };
2396
+ function transformScoreRow(row) {
2397
+ return {
2398
+ ...row,
2399
+ input: safelyParseJSON(row.input),
2400
+ scorer: safelyParseJSON(row.scorer),
2401
+ preprocessStepResult: safelyParseJSON(row.preprocessStepResult),
2402
+ analyzeStepResult: safelyParseJSON(row.analyzeStepResult),
2403
+ metadata: safelyParseJSON(row.metadata),
2404
+ output: safelyParseJSON(row.output),
2405
+ additionalContext: safelyParseJSON(row.additionalContext),
2406
+ runtimeContext: safelyParseJSON(row.runtimeContext),
2407
+ entity: safelyParseJSON(row.entity),
2408
+ createdAt: row.createdAt,
2409
+ updatedAt: row.updatedAt
2410
+ };
2411
+ }
2412
+ var ScoresMSSQL = class extends ScoresStorage {
2413
+ pool;
2414
+ operations;
2415
+ schema;
2416
+ constructor({
2417
+ pool,
2418
+ operations,
2419
+ schema
2420
+ }) {
2421
+ super();
2422
+ this.pool = pool;
2423
+ this.operations = operations;
2424
+ this.schema = schema;
2425
+ }
2426
+ async getScoreById({ id }) {
2427
+ try {
2428
+ const request = this.pool.request();
2429
+ request.input("p1", id);
2430
+ const result = await request.query(
2431
+ `SELECT * FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE id = @p1`
2432
+ );
2433
+ if (result.recordset.length === 0) {
1460
2434
  return null;
1461
2435
  }
1462
2436
  return transformScoreRow(result.recordset[0]);
@@ -1473,8 +2447,21 @@ var ScoresMSSQL = class extends ScoresStorage {
1473
2447
  }
1474
2448
  }
1475
2449
  async saveScore(score) {
2450
+ let validatedScore;
1476
2451
  try {
1477
- const scoreId = crypto.randomUUID();
2452
+ validatedScore = saveScorePayloadSchema.parse(score);
2453
+ } catch (error) {
2454
+ throw new MastraError(
2455
+ {
2456
+ id: "MASTRA_STORAGE_MSSQL_STORE_SAVE_SCORE_VALIDATION_FAILED",
2457
+ domain: ErrorDomain.STORAGE,
2458
+ category: ErrorCategory.THIRD_PARTY
2459
+ },
2460
+ error
2461
+ );
2462
+ }
2463
+ try {
2464
+ const scoreId = randomUUID();
1478
2465
  const {
1479
2466
  scorer,
1480
2467
  preprocessStepResult,
@@ -1486,21 +2473,21 @@ var ScoresMSSQL = class extends ScoresStorage {
1486
2473
  runtimeContext,
1487
2474
  entity,
1488
2475
  ...rest
1489
- } = score;
2476
+ } = validatedScore;
1490
2477
  await this.operations.insert({
1491
2478
  tableName: TABLE_SCORERS,
1492
2479
  record: {
1493
2480
  id: scoreId,
1494
2481
  ...rest,
1495
- input: JSON.stringify(input) || "",
1496
- output: JSON.stringify(output) || "",
1497
- preprocessStepResult: preprocessStepResult ? JSON.stringify(preprocessStepResult) : null,
1498
- analyzeStepResult: analyzeStepResult ? JSON.stringify(analyzeStepResult) : null,
1499
- metadata: metadata ? JSON.stringify(metadata) : null,
1500
- additionalContext: additionalContext ? JSON.stringify(additionalContext) : null,
1501
- runtimeContext: runtimeContext ? JSON.stringify(runtimeContext) : null,
1502
- entity: entity ? JSON.stringify(entity) : null,
1503
- scorer: scorer ? JSON.stringify(scorer) : null,
2482
+ input: input || "",
2483
+ output: output || "",
2484
+ preprocessStepResult: preprocessStepResult || null,
2485
+ analyzeStepResult: analyzeStepResult || null,
2486
+ metadata: metadata || null,
2487
+ additionalContext: additionalContext || null,
2488
+ runtimeContext: runtimeContext || null,
2489
+ entity: entity || null,
2490
+ scorer: scorer || null,
1504
2491
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1505
2492
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1506
2493
  }
@@ -1520,14 +2507,37 @@ var ScoresMSSQL = class extends ScoresStorage {
1520
2507
  }
1521
2508
  async getScoresByScorerId({
1522
2509
  scorerId,
1523
- pagination
2510
+ pagination,
2511
+ entityId,
2512
+ entityType,
2513
+ source
1524
2514
  }) {
1525
2515
  try {
1526
- const request = this.pool.request();
1527
- request.input("p1", scorerId);
1528
- const totalResult = await request.query(
1529
- `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [scorerId] = @p1`
1530
- );
2516
+ const conditions = ["[scorerId] = @p1"];
2517
+ const params = { p1: scorerId };
2518
+ let paramIndex = 2;
2519
+ if (entityId) {
2520
+ conditions.push(`[entityId] = @p${paramIndex}`);
2521
+ params[`p${paramIndex}`] = entityId;
2522
+ paramIndex++;
2523
+ }
2524
+ if (entityType) {
2525
+ conditions.push(`[entityType] = @p${paramIndex}`);
2526
+ params[`p${paramIndex}`] = entityType;
2527
+ paramIndex++;
2528
+ }
2529
+ if (source) {
2530
+ conditions.push(`[source] = @p${paramIndex}`);
2531
+ params[`p${paramIndex}`] = source;
2532
+ paramIndex++;
2533
+ }
2534
+ const whereClause = conditions.join(" AND ");
2535
+ const tableName = getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) });
2536
+ const countRequest = this.pool.request();
2537
+ Object.entries(params).forEach(([key, value]) => {
2538
+ countRequest.input(key, value);
2539
+ });
2540
+ const totalResult = await countRequest.query(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`);
1531
2541
  const total = totalResult.recordset[0]?.count || 0;
1532
2542
  if (total === 0) {
1533
2543
  return {
@@ -1541,12 +2551,13 @@ var ScoresMSSQL = class extends ScoresStorage {
1541
2551
  };
1542
2552
  }
1543
2553
  const dataRequest = this.pool.request();
1544
- dataRequest.input("p1", scorerId);
1545
- dataRequest.input("p2", pagination.perPage);
1546
- dataRequest.input("p3", pagination.page * pagination.perPage);
1547
- const result = await dataRequest.query(
1548
- `SELECT * FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [scorerId] = @p1 ORDER BY [createdAt] DESC OFFSET @p3 ROWS FETCH NEXT @p2 ROWS ONLY`
1549
- );
2554
+ Object.entries(params).forEach(([key, value]) => {
2555
+ dataRequest.input(key, value);
2556
+ });
2557
+ dataRequest.input("perPage", pagination.perPage);
2558
+ dataRequest.input("offset", pagination.page * pagination.perPage);
2559
+ const dataQuery = `SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY [createdAt] DESC OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
2560
+ const result = await dataRequest.query(dataQuery);
1550
2561
  return {
1551
2562
  pagination: {
1552
2563
  total: Number(total),
@@ -1671,8 +2682,62 @@ var ScoresMSSQL = class extends ScoresStorage {
1671
2682
  );
1672
2683
  }
1673
2684
  }
2685
+ async getScoresBySpan({
2686
+ traceId,
2687
+ spanId,
2688
+ pagination
2689
+ }) {
2690
+ try {
2691
+ const request = this.pool.request();
2692
+ request.input("p1", traceId);
2693
+ request.input("p2", spanId);
2694
+ const totalResult = await request.query(
2695
+ `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [traceId] = @p1 AND [spanId] = @p2`
2696
+ );
2697
+ const total = totalResult.recordset[0]?.count || 0;
2698
+ if (total === 0) {
2699
+ return {
2700
+ pagination: {
2701
+ total: 0,
2702
+ page: pagination.page,
2703
+ perPage: pagination.perPage,
2704
+ hasMore: false
2705
+ },
2706
+ scores: []
2707
+ };
2708
+ }
2709
+ const limit = pagination.perPage + 1;
2710
+ const dataRequest = this.pool.request();
2711
+ dataRequest.input("p1", traceId);
2712
+ dataRequest.input("p2", spanId);
2713
+ dataRequest.input("p3", limit);
2714
+ dataRequest.input("p4", pagination.page * pagination.perPage);
2715
+ const result = await dataRequest.query(
2716
+ `SELECT * FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [traceId] = @p1 AND [spanId] = @p2 ORDER BY [createdAt] DESC OFFSET @p4 ROWS FETCH NEXT @p3 ROWS ONLY`
2717
+ );
2718
+ return {
2719
+ pagination: {
2720
+ total: Number(total),
2721
+ page: pagination.page,
2722
+ perPage: pagination.perPage,
2723
+ hasMore: result.recordset.length > pagination.perPage
2724
+ },
2725
+ scores: result.recordset.slice(0, pagination.perPage).map((row) => transformScoreRow(row))
2726
+ };
2727
+ } catch (error) {
2728
+ throw new MastraError(
2729
+ {
2730
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_SCORES_BY_SPAN_FAILED",
2731
+ domain: ErrorDomain.STORAGE,
2732
+ category: ErrorCategory.THIRD_PARTY,
2733
+ details: { traceId, spanId }
2734
+ },
2735
+ error
2736
+ );
2737
+ }
2738
+ }
1674
2739
  };
1675
- var TracesMSSQL = class extends TracesStorage {
2740
+ var WorkflowsMSSQL = class extends WorkflowsStorage {
1676
2741
  pool;
1677
2742
  operations;
1678
2743
  schema;
@@ -1686,210 +2751,168 @@ var TracesMSSQL = class extends TracesStorage {
1686
2751
  this.operations = operations;
1687
2752
  this.schema = schema;
1688
2753
  }
1689
- /** @deprecated use getTracesPaginated instead*/
1690
- async getTraces(args) {
1691
- if (args.fromDate || args.toDate) {
1692
- args.dateRange = {
1693
- start: args.fromDate,
1694
- end: args.toDate
1695
- };
2754
+ parseWorkflowRun(row) {
2755
+ let parsedSnapshot = row.snapshot;
2756
+ if (typeof parsedSnapshot === "string") {
2757
+ try {
2758
+ parsedSnapshot = JSON.parse(row.snapshot);
2759
+ } catch (e) {
2760
+ this.logger?.warn?.(`Failed to parse snapshot for workflow ${row.workflow_name}:`, e);
2761
+ }
1696
2762
  }
1697
- const result = await this.getTracesPaginated(args);
1698
- return result.traces;
2763
+ return {
2764
+ workflowName: row.workflow_name,
2765
+ runId: row.run_id,
2766
+ snapshot: parsedSnapshot,
2767
+ createdAt: row.createdAt,
2768
+ updatedAt: row.updatedAt,
2769
+ resourceId: row.resourceId
2770
+ };
1699
2771
  }
1700
- async getTracesPaginated(args) {
1701
- const { name, scope, page = 0, perPage: perPageInput, attributes, filters, dateRange } = args;
1702
- const fromDate = dateRange?.start;
1703
- const toDate = dateRange?.end;
1704
- const perPage = perPageInput !== void 0 ? perPageInput : 100;
1705
- const currentOffset = page * perPage;
1706
- const paramMap = {};
1707
- const conditions = [];
1708
- let paramIndex = 1;
1709
- if (name) {
1710
- const paramName = `p${paramIndex++}`;
1711
- conditions.push(`[name] LIKE @${paramName}`);
1712
- paramMap[paramName] = `${name}%`;
1713
- }
1714
- if (scope) {
1715
- const paramName = `p${paramIndex++}`;
1716
- conditions.push(`[scope] = @${paramName}`);
1717
- paramMap[paramName] = scope;
1718
- }
1719
- if (attributes) {
1720
- Object.entries(attributes).forEach(([key, value]) => {
1721
- const parsedKey = parseFieldKey(key);
1722
- const paramName = `p${paramIndex++}`;
1723
- conditions.push(`JSON_VALUE([attributes], '$.${parsedKey}') = @${paramName}`);
1724
- paramMap[paramName] = value;
1725
- });
1726
- }
1727
- if (filters) {
1728
- Object.entries(filters).forEach(([key, value]) => {
1729
- const parsedKey = parseFieldKey(key);
1730
- const paramName = `p${paramIndex++}`;
1731
- conditions.push(`[${parsedKey}] = @${paramName}`);
1732
- paramMap[paramName] = value;
1733
- });
1734
- }
1735
- if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
1736
- const paramName = `p${paramIndex++}`;
1737
- conditions.push(`[createdAt] >= @${paramName}`);
1738
- paramMap[paramName] = fromDate.toISOString();
1739
- }
1740
- if (toDate instanceof Date && !isNaN(toDate.getTime())) {
1741
- const paramName = `p${paramIndex++}`;
1742
- conditions.push(`[createdAt] <= @${paramName}`);
1743
- paramMap[paramName] = toDate.toISOString();
1744
- }
1745
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1746
- const countQuery = `SELECT COUNT(*) as total FROM ${getTableName({ indexName: TABLE_TRACES, schemaName: getSchemaName(this.schema) })} ${whereClause}`;
1747
- let total = 0;
2772
+ async updateWorkflowResults({
2773
+ workflowName,
2774
+ runId,
2775
+ stepId,
2776
+ result,
2777
+ runtimeContext
2778
+ }) {
2779
+ const table = getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
2780
+ const transaction = this.pool.transaction();
1748
2781
  try {
1749
- const countRequest = this.pool.request();
1750
- Object.entries(paramMap).forEach(([key, value]) => {
1751
- if (value instanceof Date) {
1752
- countRequest.input(key, sql2.DateTime, value);
1753
- } else {
1754
- countRequest.input(key, value);
1755
- }
1756
- });
1757
- const countResult = await countRequest.query(countQuery);
1758
- total = parseInt(countResult.recordset[0].total, 10);
2782
+ await transaction.begin();
2783
+ const selectRequest = new sql3.Request(transaction);
2784
+ selectRequest.input("workflow_name", workflowName);
2785
+ selectRequest.input("run_id", runId);
2786
+ const existingSnapshotResult = await selectRequest.query(
2787
+ `SELECT snapshot FROM ${table} WITH (UPDLOCK, HOLDLOCK) WHERE workflow_name = @workflow_name AND run_id = @run_id`
2788
+ );
2789
+ let snapshot;
2790
+ if (!existingSnapshotResult.recordset || existingSnapshotResult.recordset.length === 0) {
2791
+ snapshot = {
2792
+ context: {},
2793
+ activePaths: [],
2794
+ timestamp: Date.now(),
2795
+ suspendedPaths: {},
2796
+ resumeLabels: {},
2797
+ serializedStepGraph: [],
2798
+ value: {},
2799
+ waitingPaths: {},
2800
+ status: "pending",
2801
+ runId,
2802
+ runtimeContext: {}
2803
+ };
2804
+ } else {
2805
+ const existingSnapshot = existingSnapshotResult.recordset[0].snapshot;
2806
+ snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
2807
+ }
2808
+ snapshot.context[stepId] = result;
2809
+ snapshot.runtimeContext = { ...snapshot.runtimeContext, ...runtimeContext };
2810
+ const upsertReq = new sql3.Request(transaction);
2811
+ upsertReq.input("workflow_name", workflowName);
2812
+ upsertReq.input("run_id", runId);
2813
+ upsertReq.input("snapshot", JSON.stringify(snapshot));
2814
+ upsertReq.input("createdAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2815
+ upsertReq.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2816
+ await upsertReq.query(
2817
+ `MERGE ${table} AS target
2818
+ USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
2819
+ ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
2820
+ WHEN MATCHED THEN UPDATE SET snapshot = @snapshot, [updatedAt] = @updatedAt
2821
+ WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, snapshot, [createdAt], [updatedAt])
2822
+ VALUES (@workflow_name, @run_id, @snapshot, @createdAt, @updatedAt);`
2823
+ );
2824
+ await transaction.commit();
2825
+ return snapshot.context;
1759
2826
  } catch (error) {
2827
+ try {
2828
+ await transaction.rollback();
2829
+ } catch {
2830
+ }
1760
2831
  throw new MastraError(
1761
2832
  {
1762
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TOTAL_COUNT",
2833
+ id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_WORKFLOW_RESULTS_FAILED",
1763
2834
  domain: ErrorDomain.STORAGE,
1764
2835
  category: ErrorCategory.THIRD_PARTY,
1765
2836
  details: {
1766
- name: args.name ?? "",
1767
- scope: args.scope ?? ""
2837
+ workflowName,
2838
+ runId,
2839
+ stepId
1768
2840
  }
1769
2841
  },
1770
2842
  error
1771
2843
  );
1772
2844
  }
1773
- if (total === 0) {
1774
- return {
1775
- traces: [],
1776
- total: 0,
1777
- page,
1778
- perPage,
1779
- hasMore: false
1780
- };
1781
- }
1782
- const dataQuery = `SELECT * FROM ${getTableName({ indexName: TABLE_TRACES, schemaName: getSchemaName(this.schema) })} ${whereClause} ORDER BY [seq_id] DESC OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`;
1783
- const dataRequest = this.pool.request();
1784
- Object.entries(paramMap).forEach(([key, value]) => {
1785
- if (value instanceof Date) {
1786
- dataRequest.input(key, sql2.DateTime, value);
1787
- } else {
1788
- dataRequest.input(key, value);
1789
- }
1790
- });
1791
- dataRequest.input("offset", currentOffset);
1792
- dataRequest.input("limit", perPage);
2845
+ }
2846
+ async updateWorkflowState({
2847
+ workflowName,
2848
+ runId,
2849
+ opts
2850
+ }) {
2851
+ const table = getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
2852
+ const transaction = this.pool.transaction();
1793
2853
  try {
1794
- const rowsResult = await dataRequest.query(dataQuery);
1795
- const rows = rowsResult.recordset;
1796
- const traces = rows.map((row) => ({
1797
- id: row.id,
1798
- parentSpanId: row.parentSpanId,
1799
- traceId: row.traceId,
1800
- name: row.name,
1801
- scope: row.scope,
1802
- kind: row.kind,
1803
- status: JSON.parse(row.status),
1804
- events: JSON.parse(row.events),
1805
- links: JSON.parse(row.links),
1806
- attributes: JSON.parse(row.attributes),
1807
- startTime: row.startTime,
1808
- endTime: row.endTime,
1809
- other: row.other,
1810
- createdAt: row.createdAt
1811
- }));
1812
- return {
1813
- traces,
1814
- total,
1815
- page,
1816
- perPage,
1817
- hasMore: currentOffset + traces.length < total
1818
- };
2854
+ await transaction.begin();
2855
+ const selectRequest = new sql3.Request(transaction);
2856
+ selectRequest.input("workflow_name", workflowName);
2857
+ selectRequest.input("run_id", runId);
2858
+ const existingSnapshotResult = await selectRequest.query(
2859
+ `SELECT snapshot FROM ${table} WITH (UPDLOCK, HOLDLOCK) WHERE workflow_name = @workflow_name AND run_id = @run_id`
2860
+ );
2861
+ if (!existingSnapshotResult.recordset || existingSnapshotResult.recordset.length === 0) {
2862
+ await transaction.rollback();
2863
+ return void 0;
2864
+ }
2865
+ const existingSnapshot = existingSnapshotResult.recordset[0].snapshot;
2866
+ const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
2867
+ if (!snapshot || !snapshot?.context) {
2868
+ await transaction.rollback();
2869
+ throw new MastraError(
2870
+ {
2871
+ id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_WORKFLOW_STATE_SNAPSHOT_NOT_FOUND",
2872
+ domain: ErrorDomain.STORAGE,
2873
+ category: ErrorCategory.SYSTEM,
2874
+ details: {
2875
+ workflowName,
2876
+ runId
2877
+ }
2878
+ },
2879
+ new Error(`Snapshot not found for runId ${runId}`)
2880
+ );
2881
+ }
2882
+ const updatedSnapshot = { ...snapshot, ...opts };
2883
+ const updateRequest = new sql3.Request(transaction);
2884
+ updateRequest.input("snapshot", JSON.stringify(updatedSnapshot));
2885
+ updateRequest.input("workflow_name", workflowName);
2886
+ updateRequest.input("run_id", runId);
2887
+ updateRequest.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2888
+ await updateRequest.query(
2889
+ `UPDATE ${table} SET snapshot = @snapshot, [updatedAt] = @updatedAt WHERE workflow_name = @workflow_name AND run_id = @run_id`
2890
+ );
2891
+ await transaction.commit();
2892
+ return updatedSnapshot;
1819
2893
  } catch (error) {
2894
+ try {
2895
+ await transaction.rollback();
2896
+ } catch {
2897
+ }
1820
2898
  throw new MastraError(
1821
2899
  {
1822
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TRACES",
2900
+ id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_WORKFLOW_STATE_FAILED",
1823
2901
  domain: ErrorDomain.STORAGE,
1824
2902
  category: ErrorCategory.THIRD_PARTY,
1825
2903
  details: {
1826
- name: args.name ?? "",
1827
- scope: args.scope ?? ""
2904
+ workflowName,
2905
+ runId
1828
2906
  }
1829
2907
  },
1830
2908
  error
1831
2909
  );
1832
2910
  }
1833
2911
  }
1834
- async batchTraceInsert({ records }) {
1835
- this.logger.debug("Batch inserting traces", { count: records.length });
1836
- await this.operations.batchInsert({
1837
- tableName: TABLE_TRACES,
1838
- records
1839
- });
1840
- }
1841
- };
1842
- function parseWorkflowRun(row) {
1843
- let parsedSnapshot = row.snapshot;
1844
- if (typeof parsedSnapshot === "string") {
1845
- try {
1846
- parsedSnapshot = JSON.parse(row.snapshot);
1847
- } catch (e) {
1848
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
1849
- }
1850
- }
1851
- return {
1852
- workflowName: row.workflow_name,
1853
- runId: row.run_id,
1854
- snapshot: parsedSnapshot,
1855
- createdAt: row.createdAt,
1856
- updatedAt: row.updatedAt,
1857
- resourceId: row.resourceId
1858
- };
1859
- }
1860
- var WorkflowsMSSQL = class extends WorkflowsStorage {
1861
- pool;
1862
- operations;
1863
- schema;
1864
- constructor({
1865
- pool,
1866
- operations,
1867
- schema
1868
- }) {
1869
- super();
1870
- this.pool = pool;
1871
- this.operations = operations;
1872
- this.schema = schema;
1873
- }
1874
- updateWorkflowResults({
1875
- // workflowName,
1876
- // runId,
1877
- // stepId,
1878
- // result,
1879
- // runtimeContext,
1880
- }) {
1881
- throw new Error("Method not implemented.");
1882
- }
1883
- updateWorkflowState({
1884
- // workflowName,
1885
- // runId,
1886
- // opts,
1887
- }) {
1888
- throw new Error("Method not implemented.");
1889
- }
1890
2912
  async persistWorkflowSnapshot({
1891
2913
  workflowName,
1892
2914
  runId,
2915
+ resourceId,
1893
2916
  snapshot
1894
2917
  }) {
1895
2918
  const table = getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
@@ -1898,17 +2921,19 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
1898
2921
  const request = this.pool.request();
1899
2922
  request.input("workflow_name", workflowName);
1900
2923
  request.input("run_id", runId);
2924
+ request.input("resourceId", resourceId);
1901
2925
  request.input("snapshot", JSON.stringify(snapshot));
1902
- request.input("createdAt", sql2.DateTime2, new Date(now));
1903
- request.input("updatedAt", sql2.DateTime2, new Date(now));
2926
+ request.input("createdAt", sql3.DateTime2, new Date(now));
2927
+ request.input("updatedAt", sql3.DateTime2, new Date(now));
1904
2928
  const mergeSql = `MERGE INTO ${table} AS target
1905
2929
  USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
1906
2930
  ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
1907
2931
  WHEN MATCHED THEN UPDATE SET
2932
+ resourceId = @resourceId,
1908
2933
  snapshot = @snapshot,
1909
2934
  [updatedAt] = @updatedAt
1910
- WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, snapshot, [createdAt], [updatedAt])
1911
- VALUES (@workflow_name, @run_id, @snapshot, @createdAt, @updatedAt);`;
2935
+ WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, resourceId, snapshot, [createdAt], [updatedAt])
2936
+ VALUES (@workflow_name, @run_id, @resourceId, @snapshot, @createdAt, @updatedAt);`;
1912
2937
  await request.query(mergeSql);
1913
2938
  } catch (error) {
1914
2939
  throw new MastraError(
@@ -1980,7 +3005,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
1980
3005
  if (!result.recordset || result.recordset.length === 0) {
1981
3006
  return null;
1982
3007
  }
1983
- return parseWorkflowRun(result.recordset[0]);
3008
+ return this.parseWorkflowRun(result.recordset[0]);
1984
3009
  } catch (error) {
1985
3010
  throw new MastraError(
1986
3011
  {
@@ -2017,7 +3042,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2017
3042
  conditions.push(`[resourceId] = @resourceId`);
2018
3043
  paramMap["resourceId"] = resourceId;
2019
3044
  } else {
2020
- console.warn(`[${TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
3045
+ this.logger?.warn?.(`[${TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
2021
3046
  }
2022
3047
  }
2023
3048
  if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
@@ -2034,7 +3059,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2034
3059
  const request = this.pool.request();
2035
3060
  Object.entries(paramMap).forEach(([key, value]) => {
2036
3061
  if (value instanceof Date) {
2037
- request.input(key, sql2.DateTime, value);
3062
+ request.input(key, sql3.DateTime, value);
2038
3063
  } else {
2039
3064
  request.input(key, value);
2040
3065
  }
@@ -2051,7 +3076,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2051
3076
  request.input("offset", offset);
2052
3077
  }
2053
3078
  const result = await request.query(query);
2054
- const runs = (result.recordset || []).map((row) => parseWorkflowRun(row));
3079
+ const runs = (result.recordset || []).map((row) => this.parseWorkflowRun(row));
2055
3080
  return { runs, total: total || runs.length };
2056
3081
  } catch (error) {
2057
3082
  throw new MastraError(
@@ -2091,7 +3116,7 @@ var MSSQLStore = class extends MastraStorage {
2091
3116
  }
2092
3117
  }
2093
3118
  this.schema = config.schemaName || "dbo";
2094
- this.pool = "connectionString" in config ? new sql2.ConnectionPool(config.connectionString) : new sql2.ConnectionPool({
3119
+ this.pool = "connectionString" in config ? new sql3.ConnectionPool(config.connectionString) : new sql3.ConnectionPool({
2095
3120
  server: config.server,
2096
3121
  database: config.database,
2097
3122
  user: config.user,
@@ -2102,16 +3127,16 @@ var MSSQLStore = class extends MastraStorage {
2102
3127
  const legacyEvals = new LegacyEvalsMSSQL({ pool: this.pool, schema: this.schema });
2103
3128
  const operations = new StoreOperationsMSSQL({ pool: this.pool, schemaName: this.schema });
2104
3129
  const scores = new ScoresMSSQL({ pool: this.pool, operations, schema: this.schema });
2105
- const traces = new TracesMSSQL({ pool: this.pool, operations, schema: this.schema });
2106
3130
  const workflows = new WorkflowsMSSQL({ pool: this.pool, operations, schema: this.schema });
2107
3131
  const memory = new MemoryMSSQL({ pool: this.pool, schema: this.schema, operations });
3132
+ const observability = new ObservabilityMSSQL({ pool: this.pool, operations, schema: this.schema });
2108
3133
  this.stores = {
2109
3134
  operations,
2110
3135
  scores,
2111
- traces,
2112
3136
  workflows,
2113
3137
  legacyEvals,
2114
- memory
3138
+ memory,
3139
+ observability
2115
3140
  };
2116
3141
  } catch (e) {
2117
3142
  throw new MastraError(
@@ -2131,6 +3156,11 @@ var MSSQLStore = class extends MastraStorage {
2131
3156
  try {
2132
3157
  await this.isConnected;
2133
3158
  await super.init();
3159
+ try {
3160
+ await this.stores.operations.createAutomaticIndexes();
3161
+ } catch (indexError) {
3162
+ this.logger?.warn?.("Failed to create indexes:", indexError);
3163
+ }
2134
3164
  } catch (error) {
2135
3165
  this.isConnected = null;
2136
3166
  throw new MastraError(
@@ -2157,7 +3187,10 @@ var MSSQLStore = class extends MastraStorage {
2157
3187
  resourceWorkingMemory: true,
2158
3188
  hasColumn: true,
2159
3189
  createTable: true,
2160
- deleteMessages: true
3190
+ deleteMessages: true,
3191
+ getScoresBySpan: true,
3192
+ aiTracing: true,
3193
+ indexManagement: true
2161
3194
  };
2162
3195
  }
2163
3196
  /** @deprecated use getEvals instead */
@@ -2167,18 +3200,6 @@ var MSSQLStore = class extends MastraStorage {
2167
3200
  async getEvals(options = {}) {
2168
3201
  return this.stores.legacyEvals.getEvals(options);
2169
3202
  }
2170
- /**
2171
- * @deprecated use getTracesPaginated instead
2172
- */
2173
- async getTraces(args) {
2174
- return this.stores.traces.getTraces(args);
2175
- }
2176
- async getTracesPaginated(args) {
2177
- return this.stores.traces.getTracesPaginated(args);
2178
- }
2179
- async batchTraceInsert({ records }) {
2180
- return this.stores.traces.batchTraceInsert({ records });
2181
- }
2182
3203
  async createTable({
2183
3204
  tableName,
2184
3205
  schema
@@ -2293,9 +3314,10 @@ var MSSQLStore = class extends MastraStorage {
2293
3314
  async persistWorkflowSnapshot({
2294
3315
  workflowName,
2295
3316
  runId,
3317
+ resourceId,
2296
3318
  snapshot
2297
3319
  }) {
2298
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
3320
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
2299
3321
  }
2300
3322
  async loadWorkflowSnapshot({
2301
3323
  workflowName,
@@ -2322,6 +3344,60 @@ var MSSQLStore = class extends MastraStorage {
2322
3344
  async close() {
2323
3345
  await this.pool.close();
2324
3346
  }
3347
+ /**
3348
+ * Index Management
3349
+ */
3350
+ async createIndex(options) {
3351
+ return this.stores.operations.createIndex(options);
3352
+ }
3353
+ async listIndexes(tableName) {
3354
+ return this.stores.operations.listIndexes(tableName);
3355
+ }
3356
+ async describeIndex(indexName) {
3357
+ return this.stores.operations.describeIndex(indexName);
3358
+ }
3359
+ async dropIndex(indexName) {
3360
+ return this.stores.operations.dropIndex(indexName);
3361
+ }
3362
+ /**
3363
+ * AI Tracing / Observability
3364
+ */
3365
+ getObservabilityStore() {
3366
+ if (!this.stores.observability) {
3367
+ throw new MastraError({
3368
+ id: "MSSQL_STORE_OBSERVABILITY_NOT_INITIALIZED",
3369
+ domain: ErrorDomain.STORAGE,
3370
+ category: ErrorCategory.SYSTEM,
3371
+ text: "Observability storage is not initialized"
3372
+ });
3373
+ }
3374
+ return this.stores.observability;
3375
+ }
3376
+ async createAISpan(span) {
3377
+ return this.getObservabilityStore().createAISpan(span);
3378
+ }
3379
+ async updateAISpan({
3380
+ spanId,
3381
+ traceId,
3382
+ updates
3383
+ }) {
3384
+ return this.getObservabilityStore().updateAISpan({ spanId, traceId, updates });
3385
+ }
3386
+ async getAITrace(traceId) {
3387
+ return this.getObservabilityStore().getAITrace(traceId);
3388
+ }
3389
+ async getAITracesPaginated(args) {
3390
+ return this.getObservabilityStore().getAITracesPaginated(args);
3391
+ }
3392
+ async batchCreateAISpans(args) {
3393
+ return this.getObservabilityStore().batchCreateAISpans(args);
3394
+ }
3395
+ async batchUpdateAISpans(args) {
3396
+ return this.getObservabilityStore().batchUpdateAISpans(args);
3397
+ }
3398
+ async batchDeleteAITraces(args) {
3399
+ return this.getObservabilityStore().batchDeleteAITraces(args);
3400
+ }
2325
3401
  /**
2326
3402
  * Scorers
2327
3403
  */
@@ -2330,9 +3406,18 @@ var MSSQLStore = class extends MastraStorage {
2330
3406
  }
2331
3407
  async getScoresByScorerId({
2332
3408
  scorerId: _scorerId,
2333
- pagination: _pagination
3409
+ pagination: _pagination,
3410
+ entityId: _entityId,
3411
+ entityType: _entityType,
3412
+ source: _source
2334
3413
  }) {
2335
- return this.stores.scores.getScoresByScorerId({ scorerId: _scorerId, pagination: _pagination });
3414
+ return this.stores.scores.getScoresByScorerId({
3415
+ scorerId: _scorerId,
3416
+ pagination: _pagination,
3417
+ entityId: _entityId,
3418
+ entityType: _entityType,
3419
+ source: _source
3420
+ });
2336
3421
  }
2337
3422
  async saveScore(_score) {
2338
3423
  return this.stores.scores.saveScore(_score);
@@ -2354,6 +3439,13 @@ var MSSQLStore = class extends MastraStorage {
2354
3439
  pagination: _pagination
2355
3440
  });
2356
3441
  }
3442
+ async getScoresBySpan({
3443
+ traceId,
3444
+ spanId,
3445
+ pagination: _pagination
3446
+ }) {
3447
+ return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination: _pagination });
3448
+ }
2357
3449
  };
2358
3450
 
2359
3451
  export { MSSQLStore };