@mastra/mssql 0.0.0-netlify-no-bundle-20251127120354 → 0.0.0-partial-response-backport-20251204204441

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,10 +1,10 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
- import { MastraStorage, StoreOperations, TABLE_WORKFLOW_SNAPSHOT, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_SCORERS, TABLE_SPANS, ScoresStorage, normalizePerPage, calculatePagination, WorkflowsStorage, MemoryStorage, TABLE_RESOURCES, ObservabilityStorage, safelyParseJSON } from '@mastra/core/storage';
3
- import sql2 from 'mssql';
2
+ import { MastraStorage, LegacyEvalsStorage, StoreOperations, TABLE_WORKFLOW_SNAPSHOT, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_EVALS, TABLE_SCORERS, TABLE_AI_SPANS, ScoresStorage, TracesStorage, WorkflowsStorage, MemoryStorage, resolveMessageLimit, TABLE_RESOURCES, ObservabilityStorage, safelyParseJSON } from '@mastra/core/storage';
3
+ import sql3 from 'mssql';
4
+ import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
4
5
  import { MessageList } from '@mastra/core/agent';
5
- import { parseSqlIdentifier } from '@mastra/core/utils';
6
6
  import { randomUUID } from 'crypto';
7
- import { saveScorePayloadSchema } from '@mastra/core/evals';
7
+ import { saveScorePayloadSchema } from '@mastra/core/scores';
8
8
 
9
9
  // src/storage/index.ts
10
10
  function getSchemaName(schema) {
@@ -80,7 +80,153 @@ function transformFromSqlRow({
80
80
  return result;
81
81
  }
82
82
 
83
- // src/storage/domains/memory/index.ts
83
+ // src/storage/domains/legacy-evals/index.ts
84
+ function transformEvalRow(row) {
85
+ let testInfoValue = null, resultValue = null;
86
+ if (row.test_info) {
87
+ try {
88
+ testInfoValue = typeof row.test_info === "string" ? JSON.parse(row.test_info) : row.test_info;
89
+ } catch {
90
+ }
91
+ }
92
+ if (row.result) {
93
+ try {
94
+ resultValue = typeof row.result === "string" ? JSON.parse(row.result) : row.result;
95
+ } catch {
96
+ }
97
+ }
98
+ return {
99
+ agentName: row.agent_name,
100
+ input: row.input,
101
+ output: row.output,
102
+ result: resultValue,
103
+ metricName: row.metric_name,
104
+ instructions: row.instructions,
105
+ testInfo: testInfoValue,
106
+ globalRunId: row.global_run_id,
107
+ runId: row.run_id,
108
+ createdAt: row.created_at
109
+ };
110
+ }
111
+ var LegacyEvalsMSSQL = class extends LegacyEvalsStorage {
112
+ pool;
113
+ schema;
114
+ constructor({ pool, schema }) {
115
+ super();
116
+ this.pool = pool;
117
+ this.schema = schema;
118
+ }
119
+ /** @deprecated use getEvals instead */
120
+ async getEvalsByAgentName(agentName, type) {
121
+ try {
122
+ let query = `SELECT * FROM ${getTableName({ indexName: TABLE_EVALS, schemaName: getSchemaName(this.schema) })} WHERE agent_name = @p1`;
123
+ if (type === "test") {
124
+ query += " AND test_info IS NOT NULL AND JSON_VALUE(test_info, '$.testPath') IS NOT NULL";
125
+ } else if (type === "live") {
126
+ query += " AND (test_info IS NULL OR JSON_VALUE(test_info, '$.testPath') IS NULL)";
127
+ }
128
+ query += " ORDER BY created_at DESC";
129
+ const request = this.pool.request();
130
+ request.input("p1", agentName);
131
+ const result = await request.query(query);
132
+ const rows = result.recordset;
133
+ return typeof transformEvalRow === "function" ? rows?.map((row) => transformEvalRow(row)) ?? [] : rows ?? [];
134
+ } catch (error) {
135
+ if (error && error.number === 208 && error.message && error.message.includes("Invalid object name")) {
136
+ return [];
137
+ }
138
+ this.logger?.error?.("Failed to get evals for the specified agent:", error);
139
+ throw error;
140
+ }
141
+ }
142
+ async getEvals(options = {}) {
143
+ const { agentName, type, page = 0, perPage = 100, dateRange } = options;
144
+ const fromDate = dateRange?.start;
145
+ const toDate = dateRange?.end;
146
+ const where = [];
147
+ const params = {};
148
+ if (agentName) {
149
+ where.push("agent_name = @agentName");
150
+ params["agentName"] = agentName;
151
+ }
152
+ if (type === "test") {
153
+ where.push("test_info IS NOT NULL AND JSON_VALUE(test_info, '$.testPath') IS NOT NULL");
154
+ } else if (type === "live") {
155
+ where.push("(test_info IS NULL OR JSON_VALUE(test_info, '$.testPath') IS NULL)");
156
+ }
157
+ if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
158
+ where.push(`[created_at] >= @fromDate`);
159
+ params[`fromDate`] = fromDate.toISOString();
160
+ }
161
+ if (toDate instanceof Date && !isNaN(toDate.getTime())) {
162
+ where.push(`[created_at] <= @toDate`);
163
+ params[`toDate`] = toDate.toISOString();
164
+ }
165
+ const whereClause = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
166
+ const tableName = getTableName({ indexName: TABLE_EVALS, schemaName: getSchemaName(this.schema) });
167
+ const offset = page * perPage;
168
+ const countQuery = `SELECT COUNT(*) as total FROM ${tableName} ${whereClause}`;
169
+ const dataQuery = `SELECT * FROM ${tableName} ${whereClause} ORDER BY seq_id DESC OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
170
+ try {
171
+ const countReq = this.pool.request();
172
+ Object.entries(params).forEach(([key, value]) => {
173
+ if (value instanceof Date) {
174
+ countReq.input(key, sql3.DateTime, value);
175
+ } else {
176
+ countReq.input(key, value);
177
+ }
178
+ });
179
+ const countResult = await countReq.query(countQuery);
180
+ const total = countResult.recordset[0]?.total || 0;
181
+ if (total === 0) {
182
+ return {
183
+ evals: [],
184
+ total: 0,
185
+ page,
186
+ perPage,
187
+ hasMore: false
188
+ };
189
+ }
190
+ const req = this.pool.request();
191
+ Object.entries(params).forEach(([key, value]) => {
192
+ if (value instanceof Date) {
193
+ req.input(key, sql3.DateTime, value);
194
+ } else {
195
+ req.input(key, value);
196
+ }
197
+ });
198
+ req.input("offset", offset);
199
+ req.input("perPage", perPage);
200
+ const result = await req.query(dataQuery);
201
+ const rows = result.recordset;
202
+ return {
203
+ evals: rows?.map((row) => transformEvalRow(row)) ?? [],
204
+ total,
205
+ page,
206
+ perPage,
207
+ hasMore: offset + (rows?.length ?? 0) < total
208
+ };
209
+ } catch (error) {
210
+ const mastraError = new MastraError(
211
+ {
212
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_EVALS_FAILED",
213
+ domain: ErrorDomain.STORAGE,
214
+ category: ErrorCategory.THIRD_PARTY,
215
+ details: {
216
+ agentName: agentName || "all",
217
+ type: type || "all",
218
+ page,
219
+ perPage
220
+ }
221
+ },
222
+ error
223
+ );
224
+ this.logger?.error?.(mastraError.toString());
225
+ this.logger?.trackException?.(mastraError);
226
+ throw mastraError;
227
+ }
228
+ }
229
+ };
84
230
  var MemoryMSSQL = class extends MemoryStorage {
85
231
  pool;
86
232
  schema;
@@ -98,7 +244,7 @@ var MemoryMSSQL = class extends MemoryStorage {
98
244
  });
99
245
  const cleanMessages = messagesWithParsedContent.map(({ seq_id, ...rest }) => rest);
100
246
  const list = new MessageList().add(cleanMessages, "memory");
101
- return format === "v2" ? list.get.all.db() : list.get.all.v1();
247
+ return format === "v2" ? list.get.all.v2() : list.get.all.v1();
102
248
  }
103
249
  constructor({
104
250
  pool,
@@ -112,7 +258,7 @@ var MemoryMSSQL = class extends MemoryStorage {
112
258
  }
113
259
  async getThreadById({ threadId }) {
114
260
  try {
115
- const sql5 = `SELECT
261
+ const sql7 = `SELECT
116
262
  id,
117
263
  [resourceId],
118
264
  title,
@@ -123,7 +269,7 @@ var MemoryMSSQL = class extends MemoryStorage {
123
269
  WHERE id = @threadId`;
124
270
  const request = this.pool.request();
125
271
  request.input("threadId", threadId);
126
- const resultSet = await request.query(sql5);
272
+ const resultSet = await request.query(sql7);
127
273
  const thread = resultSet.recordset[0] || null;
128
274
  if (!thread) {
129
275
  return null;
@@ -148,24 +294,11 @@ var MemoryMSSQL = class extends MemoryStorage {
148
294
  );
149
295
  }
150
296
  }
151
- async listThreadsByResourceId(args) {
152
- const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
153
- if (page < 0) {
154
- throw new MastraError({
155
- id: "MASTRA_STORAGE_MSSQL_STORE_INVALID_PAGE",
156
- domain: ErrorDomain.STORAGE,
157
- category: ErrorCategory.USER,
158
- text: "Page number must be non-negative",
159
- details: {
160
- resourceId,
161
- page
162
- }
163
- });
164
- }
165
- const perPage = normalizePerPage(perPageInput, 100);
166
- const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
167
- const { field, direction } = this.parseOrderBy(orderBy);
297
+ async getThreadsByResourceIdPaginated(args) {
298
+ const { resourceId, page = 0, perPage: perPageInput, orderBy = "createdAt", sortDirection = "DESC" } = args;
168
299
  try {
300
+ const perPage = perPageInput !== void 0 ? perPageInput : 100;
301
+ const currentOffset = page * perPage;
169
302
  const baseQuery = `FROM ${getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) })} WHERE [resourceId] = @resourceId`;
170
303
  const countQuery = `SELECT COUNT(*) as count ${baseQuery}`;
171
304
  const countRequest = this.pool.request();
@@ -177,22 +310,17 @@ var MemoryMSSQL = class extends MemoryStorage {
177
310
  threads: [],
178
311
  total: 0,
179
312
  page,
180
- perPage: perPageForResponse,
313
+ perPage,
181
314
  hasMore: false
182
315
  };
183
316
  }
184
- const orderByField = field === "createdAt" ? "[createdAt]" : "[updatedAt]";
185
- const dir = (direction || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
186
- const limitValue = perPageInput === false ? total : perPage;
317
+ const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
318
+ const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
187
319
  const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir} OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
188
320
  const dataRequest = this.pool.request();
189
321
  dataRequest.input("resourceId", resourceId);
190
- dataRequest.input("offset", offset);
191
- if (limitValue > 2147483647) {
192
- dataRequest.input("perPage", sql2.BigInt, limitValue);
193
- } else {
194
- dataRequest.input("perPage", limitValue);
195
- }
322
+ dataRequest.input("perPage", perPage);
323
+ dataRequest.input("offset", currentOffset);
196
324
  const rowsResult = await dataRequest.query(dataQuery);
197
325
  const rows = rowsResult.recordset || [];
198
326
  const threads = rows.map((thread) => ({
@@ -205,13 +333,13 @@ var MemoryMSSQL = class extends MemoryStorage {
205
333
  threads,
206
334
  total,
207
335
  page,
208
- perPage: perPageForResponse,
209
- hasMore: perPageInput === false ? false : offset + perPage < total
336
+ perPage,
337
+ hasMore: currentOffset + threads.length < total
210
338
  };
211
339
  } catch (error) {
212
340
  const mastraError = new MastraError(
213
341
  {
214
- id: "MASTRA_STORAGE_MSSQL_STORE_LIST_THREADS_BY_RESOURCE_ID_FAILED",
342
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
215
343
  domain: ErrorDomain.STORAGE,
216
344
  category: ErrorCategory.THIRD_PARTY,
217
345
  details: {
@@ -223,13 +351,7 @@ var MemoryMSSQL = class extends MemoryStorage {
223
351
  );
224
352
  this.logger?.error?.(mastraError.toString());
225
353
  this.logger?.trackException?.(mastraError);
226
- return {
227
- threads: [],
228
- total: 0,
229
- page,
230
- perPage: perPageForResponse,
231
- hasMore: false
232
- };
354
+ return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
233
355
  }
234
356
  }
235
357
  async saveThread({ thread }) {
@@ -253,12 +375,12 @@ var MemoryMSSQL = class extends MemoryStorage {
253
375
  req.input("title", thread.title);
254
376
  const metadata = thread.metadata ? JSON.stringify(thread.metadata) : null;
255
377
  if (metadata === null) {
256
- req.input("metadata", sql2.NVarChar, null);
378
+ req.input("metadata", sql3.NVarChar, null);
257
379
  } else {
258
380
  req.input("metadata", metadata);
259
381
  }
260
- req.input("createdAt", sql2.DateTime2, thread.createdAt);
261
- req.input("updatedAt", sql2.DateTime2, thread.updatedAt);
382
+ req.input("createdAt", sql3.DateTime2, thread.createdAt);
383
+ req.input("updatedAt", sql3.DateTime2, thread.updatedAt);
262
384
  await req.query(mergeSql);
263
385
  return thread;
264
386
  } catch (error) {
@@ -275,6 +397,31 @@ var MemoryMSSQL = class extends MemoryStorage {
275
397
  );
276
398
  }
277
399
  }
400
+ /**
401
+ * @deprecated use getThreadsByResourceIdPaginated instead
402
+ */
403
+ async getThreadsByResourceId(args) {
404
+ const { resourceId, orderBy = "createdAt", sortDirection = "DESC" } = args;
405
+ try {
406
+ const baseQuery = `FROM ${getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) })} WHERE [resourceId] = @resourceId`;
407
+ const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
408
+ const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
409
+ const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir}`;
410
+ const request = this.pool.request();
411
+ request.input("resourceId", resourceId);
412
+ const resultSet = await request.query(dataQuery);
413
+ const rows = resultSet.recordset || [];
414
+ return rows.map((thread) => ({
415
+ ...thread,
416
+ metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
417
+ createdAt: thread.createdAt,
418
+ updatedAt: thread.updatedAt
419
+ }));
420
+ } catch (error) {
421
+ this.logger?.error?.(`Error getting threads for resource ${resourceId}:`, error);
422
+ return [];
423
+ }
424
+ }
278
425
  /**
279
426
  * Updates a thread's title and metadata, merging with existing metadata. Returns the updated thread.
280
427
  */
@@ -302,7 +449,7 @@ var MemoryMSSQL = class extends MemoryStorage {
302
449
  };
303
450
  try {
304
451
  const table = getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) });
305
- const sql5 = `UPDATE ${table}
452
+ const sql7 = `UPDATE ${table}
306
453
  SET title = @title,
307
454
  metadata = @metadata,
308
455
  [updatedAt] = @updatedAt
@@ -313,7 +460,7 @@ var MemoryMSSQL = class extends MemoryStorage {
313
460
  req.input("title", title);
314
461
  req.input("metadata", JSON.stringify(mergedMetadata));
315
462
  req.input("updatedAt", /* @__PURE__ */ new Date());
316
- const result = await req.query(sql5);
463
+ const result = await req.query(sql7);
317
464
  let thread = result.recordset && result.recordset[0];
318
465
  if (thread && "seq_id" in thread) {
319
466
  const { seq_id, ...rest } = thread;
@@ -383,9 +530,11 @@ var MemoryMSSQL = class extends MemoryStorage {
383
530
  }
384
531
  async _getIncludedMessages({
385
532
  threadId,
386
- include
533
+ selectBy,
534
+ orderByStatement
387
535
  }) {
388
536
  if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
537
+ const include = selectBy?.include;
389
538
  if (!include) return null;
390
539
  const unionQueries = [];
391
540
  const paramValues = [];
@@ -410,7 +559,7 @@ var MemoryMSSQL = class extends MemoryStorage {
410
559
  m.[resourceId],
411
560
  m.seq_id
412
561
  FROM (
413
- SELECT *, ROW_NUMBER() OVER (ORDER BY [createdAt] ASC) as row_num
562
+ SELECT *, ROW_NUMBER() OVER (${orderByStatement}) as row_num
414
563
  FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })}
415
564
  WHERE [thread_id] = ${pThreadId}
416
565
  ) AS m
@@ -418,17 +567,15 @@ var MemoryMSSQL = class extends MemoryStorage {
418
567
  OR EXISTS (
419
568
  SELECT 1
420
569
  FROM (
421
- SELECT *, ROW_NUMBER() OVER (ORDER BY [createdAt] ASC) as row_num
570
+ SELECT *, ROW_NUMBER() OVER (${orderByStatement}) as row_num
422
571
  FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })}
423
572
  WHERE [thread_id] = ${pThreadId}
424
573
  ) AS target
425
574
  WHERE target.id = ${pId}
426
575
  AND (
427
- -- Get previous messages (messages that come BEFORE the target)
428
- (m.row_num < target.row_num AND m.row_num >= target.row_num - ${pPrev})
576
+ (m.row_num <= target.row_num + ${pPrev} AND m.row_num > target.row_num)
429
577
  OR
430
- -- Get next messages (messages that come AFTER the target)
431
- (m.row_num > target.row_num AND m.row_num <= target.row_num + ${pNext})
578
+ (m.row_num >= target.row_num - ${pNext} AND m.row_num < target.row_num)
432
579
  )
433
580
  )
434
581
  `
@@ -457,16 +604,34 @@ var MemoryMSSQL = class extends MemoryStorage {
457
604
  });
458
605
  return dedupedRows;
459
606
  }
460
- async listMessagesById({ messageIds }) {
461
- if (messageIds.length === 0) return { messages: [] };
607
+ async getMessages(args) {
608
+ const { threadId, resourceId, format, selectBy } = args;
462
609
  const selectStatement = `SELECT seq_id, id, content, role, type, [createdAt], thread_id AS threadId, resourceId`;
463
610
  const orderByStatement = `ORDER BY [seq_id] DESC`;
611
+ const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
464
612
  try {
613
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
465
614
  let rows = [];
466
- let query = `${selectStatement} FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })} WHERE [id] IN (${messageIds.map((_, i) => `@id${i}`).join(", ")})`;
615
+ const include = selectBy?.include || [];
616
+ if (include?.length) {
617
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy, orderByStatement });
618
+ if (includeMessages) {
619
+ rows.push(...includeMessages);
620
+ }
621
+ }
622
+ const excludeIds = rows.map((m) => m.id).filter(Boolean);
623
+ let query = `${selectStatement} FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })} WHERE [thread_id] = @threadId`;
467
624
  const request = this.pool.request();
468
- messageIds.forEach((id, i) => request.input(`id${i}`, id));
469
- query += ` ${orderByStatement}`;
625
+ request.input("threadId", threadId);
626
+ if (excludeIds.length > 0) {
627
+ const excludeParams = excludeIds.map((_, idx) => `@id${idx}`);
628
+ query += ` AND id NOT IN (${excludeParams.join(", ")})`;
629
+ excludeIds.forEach((id, idx) => {
630
+ request.input(`id${idx}`, id);
631
+ });
632
+ }
633
+ query += ` ${orderByStatement} OFFSET 0 ROWS FETCH NEXT @limit ROWS ONLY`;
634
+ request.input("limit", limit);
470
635
  const result = await request.query(query);
471
636
  const remainingRows = result.recordset || [];
472
637
  rows.push(...remainingRows);
@@ -474,171 +639,154 @@ var MemoryMSSQL = class extends MemoryStorage {
474
639
  const timeDiff = a.seq_id - b.seq_id;
475
640
  return timeDiff;
476
641
  });
477
- const messagesWithParsedContent = rows.map((row) => {
478
- if (typeof row.content === "string") {
479
- try {
480
- return { ...row, content: JSON.parse(row.content) };
481
- } catch {
482
- return row;
483
- }
484
- }
485
- return row;
486
- });
487
- const cleanMessages = messagesWithParsedContent.map(({ seq_id, ...rest }) => rest);
488
- const list = new MessageList().add(cleanMessages, "memory");
489
- return { messages: list.get.all.db() };
642
+ rows = rows.map(({ seq_id, ...rest }) => rest);
643
+ return this._parseAndFormatMessages(rows, format);
490
644
  } catch (error) {
491
645
  const mastraError = new MastraError(
492
646
  {
493
- id: "MASTRA_STORAGE_MSSQL_STORE_LIST_MESSAGES_BY_ID_FAILED",
647
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_MESSAGES_FAILED",
494
648
  domain: ErrorDomain.STORAGE,
495
649
  category: ErrorCategory.THIRD_PARTY,
496
650
  details: {
497
- messageIds: JSON.stringify(messageIds)
651
+ threadId,
652
+ resourceId: resourceId ?? ""
498
653
  }
499
654
  },
500
655
  error
501
656
  );
502
657
  this.logger?.error?.(mastraError.toString());
503
658
  this.logger?.trackException?.(mastraError);
504
- return { messages: [] };
659
+ return [];
505
660
  }
506
661
  }
507
- async listMessages(args) {
508
- const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
509
- if (!threadId.trim()) {
510
- throw new MastraError(
662
+ async getMessagesById({
663
+ messageIds,
664
+ format
665
+ }) {
666
+ if (messageIds.length === 0) return [];
667
+ const selectStatement = `SELECT seq_id, id, content, role, type, [createdAt], thread_id AS threadId, resourceId`;
668
+ const orderByStatement = `ORDER BY [seq_id] DESC`;
669
+ try {
670
+ let rows = [];
671
+ let query = `${selectStatement} FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })} WHERE [id] IN (${messageIds.map((_, i) => `@id${i}`).join(", ")})`;
672
+ const request = this.pool.request();
673
+ messageIds.forEach((id, i) => request.input(`id${i}`, id));
674
+ query += ` ${orderByStatement}`;
675
+ const result = await request.query(query);
676
+ const remainingRows = result.recordset || [];
677
+ rows.push(...remainingRows);
678
+ rows.sort((a, b) => {
679
+ const timeDiff = a.seq_id - b.seq_id;
680
+ return timeDiff;
681
+ });
682
+ rows = rows.map(({ seq_id, ...rest }) => rest);
683
+ if (format === `v1`) return this._parseAndFormatMessages(rows, format);
684
+ return this._parseAndFormatMessages(rows, `v2`);
685
+ } catch (error) {
686
+ const mastraError = new MastraError(
511
687
  {
512
- id: "STORAGE_MSSQL_LIST_MESSAGES_INVALID_THREAD_ID",
688
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_MESSAGES_BY_ID_FAILED",
513
689
  domain: ErrorDomain.STORAGE,
514
690
  category: ErrorCategory.THIRD_PARTY,
515
- details: { threadId }
691
+ details: {
692
+ messageIds: JSON.stringify(messageIds)
693
+ }
516
694
  },
517
- new Error("threadId must be a non-empty string")
695
+ error
518
696
  );
697
+ this.logger?.error?.(mastraError.toString());
698
+ this.logger?.trackException?.(mastraError);
699
+ return [];
519
700
  }
520
- if (page < 0) {
521
- throw new MastraError({
522
- id: "MASTRA_STORAGE_MSSQL_STORE_INVALID_PAGE",
523
- domain: ErrorDomain.STORAGE,
524
- category: ErrorCategory.USER,
525
- text: "Page number must be non-negative",
526
- details: {
527
- threadId,
528
- page
529
- }
530
- });
531
- }
532
- const perPage = normalizePerPage(perPageInput, 40);
533
- const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
701
+ }
702
+ async getMessagesPaginated(args) {
703
+ const { threadId, resourceId, format, selectBy } = args;
704
+ const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
534
705
  try {
535
- const { field, direction } = this.parseOrderBy(orderBy, "ASC");
536
- const orderByStatement = `ORDER BY [${field}] ${direction}, [seq_id] ${direction}`;
537
- const tableName = getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) });
538
- const baseQuery = `SELECT seq_id, id, content, role, type, [createdAt], thread_id AS threadId, resourceId FROM ${tableName}`;
539
- const filters = {
540
- thread_id: threadId,
541
- ...resourceId ? { resourceId } : {},
542
- ...buildDateRangeFilter(filter?.dateRange, "createdAt")
543
- };
544
- const { sql: actualWhereClause = "", params: whereParams } = prepareWhereClause(
545
- filters);
546
- const bindWhereParams = (req) => {
547
- Object.entries(whereParams).forEach(([paramName, paramValue]) => req.input(paramName, paramValue));
548
- };
549
- const countRequest = this.pool.request();
550
- bindWhereParams(countRequest);
551
- const countResult = await countRequest.query(`SELECT COUNT(*) as total FROM ${tableName}${actualWhereClause}`);
706
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
707
+ const fromDate = dateRange?.start;
708
+ const toDate = dateRange?.end;
709
+ const selectStatement = `SELECT seq_id, id, content, role, type, [createdAt], thread_id AS threadId, resourceId`;
710
+ const orderByStatement = `ORDER BY [seq_id] DESC`;
711
+ let messages = [];
712
+ if (selectBy?.include?.length) {
713
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy, orderByStatement });
714
+ if (includeMessages) messages.push(...includeMessages);
715
+ }
716
+ const perPage = perPageInput !== void 0 ? perPageInput : resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
717
+ const currentOffset = page * perPage;
718
+ const conditions = ["[thread_id] = @threadId"];
719
+ const request = this.pool.request();
720
+ request.input("threadId", threadId);
721
+ if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
722
+ conditions.push("[createdAt] >= @fromDate");
723
+ request.input("fromDate", fromDate.toISOString());
724
+ }
725
+ if (toDate instanceof Date && !isNaN(toDate.getTime())) {
726
+ conditions.push("[createdAt] <= @toDate");
727
+ request.input("toDate", toDate.toISOString());
728
+ }
729
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
730
+ const countQuery = `SELECT COUNT(*) as total FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })} ${whereClause}`;
731
+ const countResult = await request.query(countQuery);
552
732
  const total = parseInt(countResult.recordset[0]?.total, 10) || 0;
553
- const fetchBaseMessages = async () => {
554
- const request = this.pool.request();
555
- bindWhereParams(request);
556
- if (perPageInput === false) {
557
- const result2 = await request.query(`${baseQuery}${actualWhereClause} ${orderByStatement}`);
558
- return result2.recordset || [];
559
- }
560
- request.input("offset", offset);
561
- request.input("limit", perPage > 2147483647 ? sql2.BigInt : sql2.Int, perPage);
562
- const result = await request.query(
563
- `${baseQuery}${actualWhereClause} ${orderByStatement} OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`
564
- );
565
- return result.recordset || [];
566
- };
567
- const baseRows = perPage === 0 ? [] : await fetchBaseMessages();
568
- const messages = [...baseRows];
569
- const seqById = /* @__PURE__ */ new Map();
570
- messages.forEach((msg) => {
571
- if (typeof msg.seq_id === "number") seqById.set(msg.id, msg.seq_id);
572
- });
573
- if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
733
+ if (total === 0 && messages.length > 0) {
734
+ const parsedIncluded = this._parseAndFormatMessages(messages, format);
574
735
  return {
575
- messages: [],
576
- total: 0,
736
+ messages: parsedIncluded,
737
+ total: parsedIncluded.length,
577
738
  page,
578
- perPage: perPageForResponse,
739
+ perPage,
579
740
  hasMore: false
580
741
  };
581
742
  }
582
- if (include?.length) {
583
- const messageIds = new Set(messages.map((m) => m.id));
584
- const includeMessages = await this._getIncludedMessages({ threadId, include });
585
- includeMessages?.forEach((msg) => {
586
- if (!messageIds.has(msg.id)) {
587
- messages.push(msg);
588
- messageIds.add(msg.id);
589
- if (typeof msg.seq_id === "number") seqById.set(msg.id, msg.seq_id);
590
- }
591
- });
592
- }
593
- const parsed = this._parseAndFormatMessages(messages, "v2");
594
- const mult = direction === "ASC" ? 1 : -1;
595
- const finalMessages = parsed.sort((a, b) => {
596
- const aVal = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
597
- const bVal = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
598
- if (aVal == null || bVal == null) {
599
- return aVal == null && bVal == null ? a.id.localeCompare(b.id) : aVal == null ? 1 : -1;
600
- }
601
- const diff = (typeof aVal === "number" && typeof bVal === "number" ? aVal - bVal : String(aVal).localeCompare(String(bVal))) * mult;
602
- if (diff !== 0) return diff;
603
- const seqA = seqById.get(a.id);
604
- const seqB = seqById.get(b.id);
605
- return seqA != null && seqB != null ? (seqA - seqB) * mult : a.id.localeCompare(b.id);
606
- });
607
- const returnedThreadMessageCount = finalMessages.filter((m) => m.threadId === threadId).length;
608
- const hasMore = perPageInput !== false && returnedThreadMessageCount < total && offset + perPage < total;
743
+ const excludeIds = messages.map((m) => m.id);
744
+ if (excludeIds.length > 0) {
745
+ const excludeParams = excludeIds.map((_, idx) => `@id${idx}`);
746
+ conditions.push(`id NOT IN (${excludeParams.join(", ")})`);
747
+ excludeIds.forEach((id, idx) => request.input(`id${idx}`, id));
748
+ }
749
+ const finalWhereClause = `WHERE ${conditions.join(" AND ")}`;
750
+ const dataQuery = `${selectStatement} FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })} ${finalWhereClause} ${orderByStatement} OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`;
751
+ request.input("offset", currentOffset);
752
+ request.input("limit", perPage);
753
+ const rowsResult = await request.query(dataQuery);
754
+ const rows = rowsResult.recordset || [];
755
+ rows.sort((a, b) => a.seq_id - b.seq_id);
756
+ messages.push(...rows);
757
+ let parsed = this._parseAndFormatMessages(messages, format);
758
+ parsed = parsed.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
609
759
  return {
610
- messages: finalMessages,
760
+ messages: parsed,
611
761
  total,
612
762
  page,
613
- perPage: perPageForResponse,
614
- hasMore
763
+ perPage,
764
+ hasMore: currentOffset + rows.length < total
615
765
  };
616
766
  } catch (error) {
617
767
  const mastraError = new MastraError(
618
768
  {
619
- id: "MASTRA_STORAGE_MSSQL_STORE_LIST_MESSAGES_FAILED",
769
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_MESSAGES_PAGINATED_FAILED",
620
770
  domain: ErrorDomain.STORAGE,
621
771
  category: ErrorCategory.THIRD_PARTY,
622
772
  details: {
623
773
  threadId,
624
- resourceId: resourceId ?? ""
774
+ resourceId: resourceId ?? "",
775
+ page
625
776
  }
626
777
  },
627
778
  error
628
779
  );
629
780
  this.logger?.error?.(mastraError.toString());
630
781
  this.logger?.trackException?.(mastraError);
631
- return {
632
- messages: [],
633
- total: 0,
634
- page,
635
- perPage: perPageForResponse,
636
- hasMore: false
637
- };
782
+ return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
638
783
  }
639
784
  }
640
- async saveMessages({ messages }) {
641
- if (messages.length === 0) return { messages: [] };
785
+ async saveMessages({
786
+ messages,
787
+ format
788
+ }) {
789
+ if (messages.length === 0) return messages;
642
790
  const threadId = messages[0]?.threadId;
643
791
  if (!threadId) {
644
792
  throw new MastraError({
@@ -682,7 +830,7 @@ var MemoryMSSQL = class extends MemoryStorage {
682
830
  "content",
683
831
  typeof message.content === "string" ? message.content : JSON.stringify(message.content)
684
832
  );
685
- request.input("createdAt", sql2.DateTime2, message.createdAt);
833
+ request.input("createdAt", sql3.DateTime2, message.createdAt);
686
834
  request.input("role", message.role);
687
835
  request.input("type", message.type || "v2");
688
836
  request.input("resourceId", message.resourceId);
@@ -701,7 +849,7 @@ var MemoryMSSQL = class extends MemoryStorage {
701
849
  await request.query(mergeSql);
702
850
  }
703
851
  const threadReq = transaction.request();
704
- threadReq.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
852
+ threadReq.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
705
853
  threadReq.input("id", threadId);
706
854
  await threadReq.query(`UPDATE ${tableThreads} SET [updatedAt] = @updatedAt WHERE id = @id`);
707
855
  await transaction.commit();
@@ -720,7 +868,8 @@ var MemoryMSSQL = class extends MemoryStorage {
720
868
  return message;
721
869
  });
722
870
  const list = new MessageList().add(messagesWithParsedContent, "memory");
723
- return { messages: list.get.all.db() };
871
+ if (format === "v2") return list.get.all.v2();
872
+ return list.get.all.v1();
724
873
  } catch (error) {
725
874
  throw new MastraError(
726
875
  {
@@ -999,13 +1148,13 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
999
1148
  this.operations = operations;
1000
1149
  this.schema = schema;
1001
1150
  }
1002
- get tracingStrategy() {
1151
+ get aiTracingStrategy() {
1003
1152
  return {
1004
1153
  preferred: "batch-with-updates",
1005
1154
  supported: ["batch-with-updates", "insert-only"]
1006
1155
  };
1007
1156
  }
1008
- async createSpan(span) {
1157
+ async createAISpan(span) {
1009
1158
  try {
1010
1159
  const startedAt = span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt;
1011
1160
  const endedAt = span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt;
@@ -1015,11 +1164,11 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1015
1164
  endedAt
1016
1165
  // Note: createdAt/updatedAt will be set by default values
1017
1166
  };
1018
- return this.operations.insert({ tableName: TABLE_SPANS, record });
1167
+ return this.operations.insert({ tableName: TABLE_AI_SPANS, record });
1019
1168
  } catch (error) {
1020
1169
  throw new MastraError(
1021
1170
  {
1022
- id: "MSSQL_STORE_CREATE_SPAN_FAILED",
1171
+ id: "MSSQL_STORE_CREATE_AI_SPAN_FAILED",
1023
1172
  domain: ErrorDomain.STORAGE,
1024
1173
  category: ErrorCategory.USER,
1025
1174
  details: {
@@ -1033,10 +1182,10 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1033
1182
  );
1034
1183
  }
1035
1184
  }
1036
- async getTrace(traceId) {
1185
+ async getAITrace(traceId) {
1037
1186
  try {
1038
1187
  const tableName = getTableName({
1039
- indexName: TABLE_SPANS,
1188
+ indexName: TABLE_AI_SPANS,
1040
1189
  schemaName: getSchemaName(this.schema)
1041
1190
  });
1042
1191
  const request = this.pool.request();
@@ -1057,7 +1206,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1057
1206
  traceId,
1058
1207
  spans: result.recordset.map(
1059
1208
  (span) => transformFromSqlRow({
1060
- tableName: TABLE_SPANS,
1209
+ tableName: TABLE_AI_SPANS,
1061
1210
  sqlRow: span
1062
1211
  })
1063
1212
  )
@@ -1065,7 +1214,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1065
1214
  } catch (error) {
1066
1215
  throw new MastraError(
1067
1216
  {
1068
- id: "MSSQL_STORE_GET_TRACE_FAILED",
1217
+ id: "MSSQL_STORE_GET_AI_TRACE_FAILED",
1069
1218
  domain: ErrorDomain.STORAGE,
1070
1219
  category: ErrorCategory.USER,
1071
1220
  details: {
@@ -1076,7 +1225,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1076
1225
  );
1077
1226
  }
1078
1227
  }
1079
- async updateSpan({
1228
+ async updateAISpan({
1080
1229
  spanId,
1081
1230
  traceId,
1082
1231
  updates
@@ -1090,14 +1239,14 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1090
1239
  data.startedAt = data.startedAt.toISOString();
1091
1240
  }
1092
1241
  await this.operations.update({
1093
- tableName: TABLE_SPANS,
1242
+ tableName: TABLE_AI_SPANS,
1094
1243
  keys: { spanId, traceId },
1095
1244
  data
1096
1245
  });
1097
1246
  } catch (error) {
1098
1247
  throw new MastraError(
1099
1248
  {
1100
- id: "MSSQL_STORE_UPDATE_SPAN_FAILED",
1249
+ id: "MSSQL_STORE_UPDATE_AI_SPAN_FAILED",
1101
1250
  domain: ErrorDomain.STORAGE,
1102
1251
  category: ErrorCategory.USER,
1103
1252
  details: {
@@ -1109,7 +1258,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1109
1258
  );
1110
1259
  }
1111
1260
  }
1112
- async getTracesPaginated({
1261
+ async getAITracesPaginated({
1113
1262
  filters,
1114
1263
  pagination
1115
1264
  }) {
@@ -1134,7 +1283,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1134
1283
  name = `agent run: '${entityId}'`;
1135
1284
  } else {
1136
1285
  const error = new MastraError({
1137
- id: "MSSQL_STORE_GET_TRACES_PAGINATED_FAILED",
1286
+ id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
1138
1287
  domain: ErrorDomain.STORAGE,
1139
1288
  category: ErrorCategory.USER,
1140
1289
  details: {
@@ -1153,7 +1302,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1153
1302
  params[entityParam] = name;
1154
1303
  }
1155
1304
  const tableName = getTableName({
1156
- indexName: TABLE_SPANS,
1305
+ indexName: TABLE_AI_SPANS,
1157
1306
  schemaName: getSchemaName(this.schema)
1158
1307
  });
1159
1308
  try {
@@ -1187,7 +1336,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1187
1336
  );
1188
1337
  const spans = dataResult.recordset.map(
1189
1338
  (row) => transformFromSqlRow({
1190
- tableName: TABLE_SPANS,
1339
+ tableName: TABLE_AI_SPANS,
1191
1340
  sqlRow: row
1192
1341
  })
1193
1342
  );
@@ -1203,7 +1352,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1203
1352
  } catch (error) {
1204
1353
  throw new MastraError(
1205
1354
  {
1206
- id: "MSSQL_STORE_GET_TRACES_PAGINATED_FAILED",
1355
+ id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
1207
1356
  domain: ErrorDomain.STORAGE,
1208
1357
  category: ErrorCategory.USER
1209
1358
  },
@@ -1211,13 +1360,13 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1211
1360
  );
1212
1361
  }
1213
1362
  }
1214
- async batchCreateSpans(args) {
1363
+ async batchCreateAISpans(args) {
1215
1364
  if (!args.records || args.records.length === 0) {
1216
1365
  return;
1217
1366
  }
1218
1367
  try {
1219
1368
  await this.operations.batchInsert({
1220
- tableName: TABLE_SPANS,
1369
+ tableName: TABLE_AI_SPANS,
1221
1370
  records: args.records.map((span) => ({
1222
1371
  ...span,
1223
1372
  startedAt: span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt,
@@ -1227,7 +1376,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1227
1376
  } catch (error) {
1228
1377
  throw new MastraError(
1229
1378
  {
1230
- id: "MSSQL_STORE_BATCH_CREATE_SPANS_FAILED",
1379
+ id: "MSSQL_STORE_BATCH_CREATE_AI_SPANS_FAILED",
1231
1380
  domain: ErrorDomain.STORAGE,
1232
1381
  category: ErrorCategory.USER,
1233
1382
  details: {
@@ -1238,7 +1387,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1238
1387
  );
1239
1388
  }
1240
1389
  }
1241
- async batchUpdateSpans(args) {
1390
+ async batchUpdateAISpans(args) {
1242
1391
  if (!args.records || args.records.length === 0) {
1243
1392
  return;
1244
1393
  }
@@ -1257,13 +1406,13 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1257
1406
  };
1258
1407
  });
1259
1408
  await this.operations.batchUpdate({
1260
- tableName: TABLE_SPANS,
1409
+ tableName: TABLE_AI_SPANS,
1261
1410
  updates
1262
1411
  });
1263
1412
  } catch (error) {
1264
1413
  throw new MastraError(
1265
1414
  {
1266
- id: "MSSQL_STORE_BATCH_UPDATE_SPANS_FAILED",
1415
+ id: "MSSQL_STORE_BATCH_UPDATE_AI_SPANS_FAILED",
1267
1416
  domain: ErrorDomain.STORAGE,
1268
1417
  category: ErrorCategory.USER,
1269
1418
  details: {
@@ -1274,20 +1423,20 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1274
1423
  );
1275
1424
  }
1276
1425
  }
1277
- async batchDeleteTraces(args) {
1426
+ async batchDeleteAITraces(args) {
1278
1427
  if (!args.traceIds || args.traceIds.length === 0) {
1279
1428
  return;
1280
1429
  }
1281
1430
  try {
1282
1431
  const keys = args.traceIds.map((traceId) => ({ traceId }));
1283
1432
  await this.operations.batchDelete({
1284
- tableName: TABLE_SPANS,
1433
+ tableName: TABLE_AI_SPANS,
1285
1434
  keys
1286
1435
  });
1287
1436
  } catch (error) {
1288
1437
  throw new MastraError(
1289
1438
  {
1290
- id: "MSSQL_STORE_BATCH_DELETE_TRACES_FAILED",
1439
+ id: "MSSQL_STORE_BATCH_DELETE_AI_TRACES_FAILED",
1291
1440
  domain: ErrorDomain.STORAGE,
1292
1441
  category: ErrorCategory.USER,
1293
1442
  details: {
@@ -1402,7 +1551,7 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1402
1551
  const value = record[col];
1403
1552
  const preparedValue = this.prepareValue(value, col, tableName);
1404
1553
  if (preparedValue instanceof Date) {
1405
- request.input(`param${i}`, sql2.DateTime2, preparedValue);
1554
+ request.input(`param${i}`, sql3.DateTime2, preparedValue);
1406
1555
  } else if (preparedValue === null || preparedValue === void 0) {
1407
1556
  request.input(`param${i}`, this.getMssqlType(tableName, col), null);
1408
1557
  } else {
@@ -1617,7 +1766,7 @@ ${columns}
1617
1766
  try {
1618
1767
  const keyEntries = Object.entries(keys).map(([key, value]) => [parseSqlIdentifier(key, "column name"), value]);
1619
1768
  const conditions = keyEntries.map(([key], i) => `[${key}] = @param${i}`).join(" AND ");
1620
- const sql5 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
1769
+ const sql7 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
1621
1770
  const request = this.pool.request();
1622
1771
  keyEntries.forEach(([key, value], i) => {
1623
1772
  const preparedValue = this.prepareValue(value, key, tableName);
@@ -1627,7 +1776,7 @@ ${columns}
1627
1776
  request.input(`param${i}`, preparedValue);
1628
1777
  }
1629
1778
  });
1630
- const resultSet = await request.query(sql5);
1779
+ const resultSet = await request.query(sql7);
1631
1780
  const result = resultSet.recordset[0] || null;
1632
1781
  if (!result) {
1633
1782
  return null;
@@ -1740,23 +1889,23 @@ ${columns}
1740
1889
  const col = TABLE_SCHEMAS[tableName]?.[columnName];
1741
1890
  switch (col?.type) {
1742
1891
  case "text":
1743
- return sql2.NVarChar;
1892
+ return sql3.NVarChar;
1744
1893
  case "timestamp":
1745
- return sql2.DateTime2;
1894
+ return sql3.DateTime2;
1746
1895
  case "uuid":
1747
- return sql2.UniqueIdentifier;
1896
+ return sql3.UniqueIdentifier;
1748
1897
  case "jsonb":
1749
- return sql2.NVarChar;
1898
+ return sql3.NVarChar;
1750
1899
  case "integer":
1751
- return sql2.Int;
1900
+ return sql3.Int;
1752
1901
  case "bigint":
1753
- return sql2.BigInt;
1902
+ return sql3.BigInt;
1754
1903
  case "float":
1755
- return sql2.Float;
1904
+ return sql3.Float;
1756
1905
  case "boolean":
1757
- return sql2.Bit;
1906
+ return sql3.Bit;
1758
1907
  default:
1759
- return sql2.NVarChar;
1908
+ return sql3.NVarChar;
1760
1909
  }
1761
1910
  }
1762
1911
  /**
@@ -2200,30 +2349,35 @@ ${columns}
2200
2349
  table: TABLE_TRACES,
2201
2350
  columns: ["name", "seq_id DESC"]
2202
2351
  },
2352
+ {
2353
+ name: `${schemaPrefix}mastra_evals_agent_name_seqid_idx`,
2354
+ table: TABLE_EVALS,
2355
+ columns: ["agent_name", "seq_id DESC"]
2356
+ },
2203
2357
  {
2204
2358
  name: `${schemaPrefix}mastra_scores_trace_id_span_id_seqid_idx`,
2205
2359
  table: TABLE_SCORERS,
2206
2360
  columns: ["traceId", "spanId", "seq_id DESC"]
2207
2361
  },
2208
- // Spans indexes for optimal trace querying
2362
+ // AI Spans indexes for optimal trace querying
2209
2363
  {
2210
2364
  name: `${schemaPrefix}mastra_ai_spans_traceid_startedat_idx`,
2211
- table: TABLE_SPANS,
2365
+ table: TABLE_AI_SPANS,
2212
2366
  columns: ["traceId", "startedAt DESC"]
2213
2367
  },
2214
2368
  {
2215
2369
  name: `${schemaPrefix}mastra_ai_spans_parentspanid_startedat_idx`,
2216
- table: TABLE_SPANS,
2370
+ table: TABLE_AI_SPANS,
2217
2371
  columns: ["parentSpanId", "startedAt DESC"]
2218
2372
  },
2219
2373
  {
2220
2374
  name: `${schemaPrefix}mastra_ai_spans_name_idx`,
2221
- table: TABLE_SPANS,
2375
+ table: TABLE_AI_SPANS,
2222
2376
  columns: ["name"]
2223
2377
  },
2224
2378
  {
2225
2379
  name: `${schemaPrefix}mastra_ai_spans_spantype_startedat_idx`,
2226
- table: TABLE_SPANS,
2380
+ table: TABLE_AI_SPANS,
2227
2381
  columns: ["spanType", "startedAt DESC"]
2228
2382
  }
2229
2383
  ];
@@ -2264,7 +2418,7 @@ function transformScoreRow(row) {
2264
2418
  metadata: safelyParseJSON(row.metadata),
2265
2419
  output: safelyParseJSON(row.output),
2266
2420
  additionalContext: safelyParseJSON(row.additionalContext),
2267
- requestContext: safelyParseJSON(row.requestContext),
2421
+ runtimeContext: safelyParseJSON(row.runtimeContext),
2268
2422
  entity: safelyParseJSON(row.entity),
2269
2423
  createdAt: new Date(row.createdAt),
2270
2424
  updatedAt: new Date(row.updatedAt)
@@ -2331,7 +2485,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2331
2485
  input,
2332
2486
  output,
2333
2487
  additionalContext,
2334
- requestContext,
2488
+ runtimeContext,
2335
2489
  entity,
2336
2490
  ...rest
2337
2491
  } = validatedScore;
@@ -2346,7 +2500,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2346
2500
  analyzeStepResult: analyzeStepResult || null,
2347
2501
  metadata: metadata || null,
2348
2502
  additionalContext: additionalContext || null,
2349
- requestContext: requestContext || null,
2503
+ runtimeContext: runtimeContext || null,
2350
2504
  entity: entity || null,
2351
2505
  scorer: scorer || null,
2352
2506
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2366,7 +2520,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2366
2520
  );
2367
2521
  }
2368
2522
  }
2369
- async listScoresByScorerId({
2523
+ async getScoresByScorerId({
2370
2524
  scorerId,
2371
2525
  pagination,
2372
2526
  entityId,
@@ -2400,36 +2554,31 @@ var ScoresMSSQL = class extends ScoresStorage {
2400
2554
  });
2401
2555
  const totalResult = await countRequest.query(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`);
2402
2556
  const total = totalResult.recordset[0]?.count || 0;
2403
- const { page, perPage: perPageInput } = pagination;
2404
2557
  if (total === 0) {
2405
2558
  return {
2406
2559
  pagination: {
2407
2560
  total: 0,
2408
- page,
2409
- perPage: perPageInput,
2561
+ page: pagination.page,
2562
+ perPage: pagination.perPage,
2410
2563
  hasMore: false
2411
2564
  },
2412
2565
  scores: []
2413
2566
  };
2414
2567
  }
2415
- const perPage = normalizePerPage(perPageInput, 100);
2416
- const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2417
- const limitValue = perPageInput === false ? total : perPage;
2418
- const end = perPageInput === false ? total : start + perPage;
2419
2568
  const dataRequest = this.pool.request();
2420
2569
  Object.entries(params).forEach(([key, value]) => {
2421
2570
  dataRequest.input(key, value);
2422
2571
  });
2423
- dataRequest.input("perPage", limitValue);
2424
- dataRequest.input("offset", start);
2572
+ dataRequest.input("perPage", pagination.perPage);
2573
+ dataRequest.input("offset", pagination.page * pagination.perPage);
2425
2574
  const dataQuery = `SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY [createdAt] DESC OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
2426
2575
  const result = await dataRequest.query(dataQuery);
2427
2576
  return {
2428
2577
  pagination: {
2429
2578
  total: Number(total),
2430
- page,
2431
- perPage: perPageForResponse,
2432
- hasMore: end < total
2579
+ page: pagination.page,
2580
+ perPage: pagination.perPage,
2581
+ hasMore: Number(total) > (pagination.page + 1) * pagination.perPage
2433
2582
  },
2434
2583
  scores: result.recordset.map((row) => transformScoreRow(row))
2435
2584
  };
@@ -2445,7 +2594,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2445
2594
  );
2446
2595
  }
2447
2596
  }
2448
- async listScoresByRunId({
2597
+ async getScoresByRunId({
2449
2598
  runId,
2450
2599
  pagination
2451
2600
  }) {
@@ -2456,35 +2605,30 @@ var ScoresMSSQL = class extends ScoresStorage {
2456
2605
  `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [runId] = @p1`
2457
2606
  );
2458
2607
  const total = totalResult.recordset[0]?.count || 0;
2459
- const { page, perPage: perPageInput } = pagination;
2460
2608
  if (total === 0) {
2461
2609
  return {
2462
2610
  pagination: {
2463
2611
  total: 0,
2464
- page,
2465
- perPage: perPageInput,
2612
+ page: pagination.page,
2613
+ perPage: pagination.perPage,
2466
2614
  hasMore: false
2467
2615
  },
2468
2616
  scores: []
2469
2617
  };
2470
2618
  }
2471
- const perPage = normalizePerPage(perPageInput, 100);
2472
- const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2473
- const limitValue = perPageInput === false ? total : perPage;
2474
- const end = perPageInput === false ? total : start + perPage;
2475
2619
  const dataRequest = this.pool.request();
2476
2620
  dataRequest.input("p1", runId);
2477
- dataRequest.input("p2", limitValue);
2478
- dataRequest.input("p3", start);
2621
+ dataRequest.input("p2", pagination.perPage);
2622
+ dataRequest.input("p3", pagination.page * pagination.perPage);
2479
2623
  const result = await dataRequest.query(
2480
2624
  `SELECT * FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [runId] = @p1 ORDER BY [createdAt] DESC OFFSET @p3 ROWS FETCH NEXT @p2 ROWS ONLY`
2481
2625
  );
2482
2626
  return {
2483
2627
  pagination: {
2484
2628
  total: Number(total),
2485
- page,
2486
- perPage: perPageForResponse,
2487
- hasMore: end < total
2629
+ page: pagination.page,
2630
+ perPage: pagination.perPage,
2631
+ hasMore: Number(total) > (pagination.page + 1) * pagination.perPage
2488
2632
  },
2489
2633
  scores: result.recordset.map((row) => transformScoreRow(row))
2490
2634
  };
@@ -2500,7 +2644,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2500
2644
  );
2501
2645
  }
2502
2646
  }
2503
- async listScoresByEntityId({
2647
+ async getScoresByEntityId({
2504
2648
  entityId,
2505
2649
  entityType,
2506
2650
  pagination
@@ -2513,36 +2657,31 @@ var ScoresMSSQL = class extends ScoresStorage {
2513
2657
  `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [entityId] = @p1 AND [entityType] = @p2`
2514
2658
  );
2515
2659
  const total = totalResult.recordset[0]?.count || 0;
2516
- const { page, perPage: perPageInput } = pagination;
2517
- const perPage = normalizePerPage(perPageInput, 100);
2518
- const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2519
2660
  if (total === 0) {
2520
2661
  return {
2521
2662
  pagination: {
2522
2663
  total: 0,
2523
- page,
2524
- perPage: perPageForResponse,
2664
+ page: pagination.page,
2665
+ perPage: pagination.perPage,
2525
2666
  hasMore: false
2526
2667
  },
2527
2668
  scores: []
2528
2669
  };
2529
2670
  }
2530
- const limitValue = perPageInput === false ? total : perPage;
2531
- const end = perPageInput === false ? total : start + perPage;
2532
2671
  const dataRequest = this.pool.request();
2533
2672
  dataRequest.input("p1", entityId);
2534
2673
  dataRequest.input("p2", entityType);
2535
- dataRequest.input("p3", limitValue);
2536
- dataRequest.input("p4", start);
2674
+ dataRequest.input("p3", pagination.perPage);
2675
+ dataRequest.input("p4", pagination.page * pagination.perPage);
2537
2676
  const result = await dataRequest.query(
2538
2677
  `SELECT * FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [entityId] = @p1 AND [entityType] = @p2 ORDER BY [createdAt] DESC OFFSET @p4 ROWS FETCH NEXT @p3 ROWS ONLY`
2539
2678
  );
2540
2679
  return {
2541
2680
  pagination: {
2542
2681
  total: Number(total),
2543
- page,
2544
- perPage: perPageForResponse,
2545
- hasMore: end < total
2682
+ page: pagination.page,
2683
+ perPage: pagination.perPage,
2684
+ hasMore: Number(total) > (pagination.page + 1) * pagination.perPage
2546
2685
  },
2547
2686
  scores: result.recordset.map((row) => transformScoreRow(row))
2548
2687
  };
@@ -2558,7 +2697,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2558
2697
  );
2559
2698
  }
2560
2699
  }
2561
- async listScoresBySpan({
2700
+ async getScoresBySpan({
2562
2701
  traceId,
2563
2702
  spanId,
2564
2703
  pagination
@@ -2571,38 +2710,34 @@ var ScoresMSSQL = class extends ScoresStorage {
2571
2710
  `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [traceId] = @p1 AND [spanId] = @p2`
2572
2711
  );
2573
2712
  const total = totalResult.recordset[0]?.count || 0;
2574
- const { page, perPage: perPageInput } = pagination;
2575
- const perPage = normalizePerPage(perPageInput, 100);
2576
- const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2577
2713
  if (total === 0) {
2578
2714
  return {
2579
2715
  pagination: {
2580
2716
  total: 0,
2581
- page,
2582
- perPage: perPageForResponse,
2717
+ page: pagination.page,
2718
+ perPage: pagination.perPage,
2583
2719
  hasMore: false
2584
2720
  },
2585
2721
  scores: []
2586
2722
  };
2587
2723
  }
2588
- const limitValue = perPageInput === false ? total : perPage;
2589
- const end = perPageInput === false ? total : start + perPage;
2724
+ const limit = pagination.perPage + 1;
2590
2725
  const dataRequest = this.pool.request();
2591
2726
  dataRequest.input("p1", traceId);
2592
2727
  dataRequest.input("p2", spanId);
2593
- dataRequest.input("p3", limitValue);
2594
- dataRequest.input("p4", start);
2728
+ dataRequest.input("p3", limit);
2729
+ dataRequest.input("p4", pagination.page * pagination.perPage);
2595
2730
  const result = await dataRequest.query(
2596
2731
  `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`
2597
2732
  );
2598
2733
  return {
2599
2734
  pagination: {
2600
2735
  total: Number(total),
2601
- page,
2602
- perPage: perPageForResponse,
2603
- hasMore: end < total
2736
+ page: pagination.page,
2737
+ perPage: pagination.perPage,
2738
+ hasMore: result.recordset.length > pagination.perPage
2604
2739
  },
2605
- scores: result.recordset.map((row) => transformScoreRow(row))
2740
+ scores: result.recordset.slice(0, pagination.perPage).map((row) => transformScoreRow(row))
2606
2741
  };
2607
2742
  } catch (error) {
2608
2743
  throw new MastraError(
@@ -2617,6 +2752,173 @@ var ScoresMSSQL = class extends ScoresStorage {
2617
2752
  }
2618
2753
  }
2619
2754
  };
2755
+ var TracesMSSQL = class extends TracesStorage {
2756
+ pool;
2757
+ operations;
2758
+ schema;
2759
+ constructor({
2760
+ pool,
2761
+ operations,
2762
+ schema
2763
+ }) {
2764
+ super();
2765
+ this.pool = pool;
2766
+ this.operations = operations;
2767
+ this.schema = schema;
2768
+ }
2769
+ /** @deprecated use getTracesPaginated instead*/
2770
+ async getTraces(args) {
2771
+ if (args.fromDate || args.toDate) {
2772
+ args.dateRange = {
2773
+ start: args.fromDate,
2774
+ end: args.toDate
2775
+ };
2776
+ }
2777
+ const result = await this.getTracesPaginated(args);
2778
+ return result.traces;
2779
+ }
2780
+ async getTracesPaginated(args) {
2781
+ const { name, scope, page = 0, perPage: perPageInput, attributes, filters, dateRange } = args;
2782
+ const fromDate = dateRange?.start;
2783
+ const toDate = dateRange?.end;
2784
+ const perPage = perPageInput !== void 0 ? perPageInput : 100;
2785
+ const currentOffset = page * perPage;
2786
+ const paramMap = {};
2787
+ const conditions = [];
2788
+ let paramIndex = 1;
2789
+ if (name) {
2790
+ const paramName = `p${paramIndex++}`;
2791
+ conditions.push(`[name] LIKE @${paramName}`);
2792
+ paramMap[paramName] = `${name}%`;
2793
+ }
2794
+ if (scope) {
2795
+ const paramName = `p${paramIndex++}`;
2796
+ conditions.push(`[scope] = @${paramName}`);
2797
+ paramMap[paramName] = scope;
2798
+ }
2799
+ if (attributes) {
2800
+ Object.entries(attributes).forEach(([key, value]) => {
2801
+ const parsedKey = parseFieldKey(key);
2802
+ const paramName = `p${paramIndex++}`;
2803
+ conditions.push(`JSON_VALUE([attributes], '$.${parsedKey}') = @${paramName}`);
2804
+ paramMap[paramName] = value;
2805
+ });
2806
+ }
2807
+ if (filters) {
2808
+ Object.entries(filters).forEach(([key, value]) => {
2809
+ const parsedKey = parseFieldKey(key);
2810
+ const paramName = `p${paramIndex++}`;
2811
+ conditions.push(`[${parsedKey}] = @${paramName}`);
2812
+ paramMap[paramName] = value;
2813
+ });
2814
+ }
2815
+ if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
2816
+ const paramName = `p${paramIndex++}`;
2817
+ conditions.push(`[createdAt] >= @${paramName}`);
2818
+ paramMap[paramName] = fromDate.toISOString();
2819
+ }
2820
+ if (toDate instanceof Date && !isNaN(toDate.getTime())) {
2821
+ const paramName = `p${paramIndex++}`;
2822
+ conditions.push(`[createdAt] <= @${paramName}`);
2823
+ paramMap[paramName] = toDate.toISOString();
2824
+ }
2825
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2826
+ const countQuery = `SELECT COUNT(*) as total FROM ${getTableName({ indexName: TABLE_TRACES, schemaName: getSchemaName(this.schema) })} ${whereClause}`;
2827
+ let total = 0;
2828
+ try {
2829
+ const countRequest = this.pool.request();
2830
+ Object.entries(paramMap).forEach(([key, value]) => {
2831
+ if (value instanceof Date) {
2832
+ countRequest.input(key, sql3.DateTime, value);
2833
+ } else {
2834
+ countRequest.input(key, value);
2835
+ }
2836
+ });
2837
+ const countResult = await countRequest.query(countQuery);
2838
+ total = parseInt(countResult.recordset[0].total, 10);
2839
+ } catch (error) {
2840
+ throw new MastraError(
2841
+ {
2842
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TOTAL_COUNT",
2843
+ domain: ErrorDomain.STORAGE,
2844
+ category: ErrorCategory.THIRD_PARTY,
2845
+ details: {
2846
+ name: args.name ?? "",
2847
+ scope: args.scope ?? ""
2848
+ }
2849
+ },
2850
+ error
2851
+ );
2852
+ }
2853
+ if (total === 0) {
2854
+ return {
2855
+ traces: [],
2856
+ total: 0,
2857
+ page,
2858
+ perPage,
2859
+ hasMore: false
2860
+ };
2861
+ }
2862
+ 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`;
2863
+ const dataRequest = this.pool.request();
2864
+ Object.entries(paramMap).forEach(([key, value]) => {
2865
+ if (value instanceof Date) {
2866
+ dataRequest.input(key, sql3.DateTime, value);
2867
+ } else {
2868
+ dataRequest.input(key, value);
2869
+ }
2870
+ });
2871
+ dataRequest.input("offset", currentOffset);
2872
+ dataRequest.input("limit", perPage);
2873
+ try {
2874
+ const rowsResult = await dataRequest.query(dataQuery);
2875
+ const rows = rowsResult.recordset;
2876
+ const traces = rows.map((row) => ({
2877
+ id: row.id,
2878
+ parentSpanId: row.parentSpanId,
2879
+ traceId: row.traceId,
2880
+ name: row.name,
2881
+ scope: row.scope,
2882
+ kind: row.kind,
2883
+ status: JSON.parse(row.status),
2884
+ events: JSON.parse(row.events),
2885
+ links: JSON.parse(row.links),
2886
+ attributes: JSON.parse(row.attributes),
2887
+ startTime: row.startTime,
2888
+ endTime: row.endTime,
2889
+ other: row.other,
2890
+ createdAt: row.createdAt
2891
+ }));
2892
+ return {
2893
+ traces,
2894
+ total,
2895
+ page,
2896
+ perPage,
2897
+ hasMore: currentOffset + traces.length < total
2898
+ };
2899
+ } catch (error) {
2900
+ throw new MastraError(
2901
+ {
2902
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TRACES",
2903
+ domain: ErrorDomain.STORAGE,
2904
+ category: ErrorCategory.THIRD_PARTY,
2905
+ details: {
2906
+ name: args.name ?? "",
2907
+ scope: args.scope ?? ""
2908
+ }
2909
+ },
2910
+ error
2911
+ );
2912
+ }
2913
+ }
2914
+ async batchTraceInsert({ records }) {
2915
+ this.logger.debug("Batch inserting traces", { count: records.length });
2916
+ await this.operations.batchInsert({
2917
+ tableName: TABLE_TRACES,
2918
+ records
2919
+ });
2920
+ }
2921
+ };
2620
2922
  var WorkflowsMSSQL = class extends WorkflowsStorage {
2621
2923
  pool;
2622
2924
  operations;
@@ -2654,13 +2956,13 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2654
2956
  runId,
2655
2957
  stepId,
2656
2958
  result,
2657
- requestContext
2959
+ runtimeContext
2658
2960
  }) {
2659
2961
  const table = getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
2660
2962
  const transaction = this.pool.transaction();
2661
2963
  try {
2662
2964
  await transaction.begin();
2663
- const selectRequest = new sql2.Request(transaction);
2965
+ const selectRequest = new sql3.Request(transaction);
2664
2966
  selectRequest.input("workflow_name", workflowName);
2665
2967
  selectRequest.input("run_id", runId);
2666
2968
  const existingSnapshotResult = await selectRequest.query(
@@ -2680,20 +2982,20 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2680
2982
  value: {},
2681
2983
  waitingPaths: {},
2682
2984
  runId,
2683
- requestContext: {}
2985
+ runtimeContext: {}
2684
2986
  };
2685
2987
  } else {
2686
2988
  const existingSnapshot = existingSnapshotResult.recordset[0].snapshot;
2687
2989
  snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
2688
2990
  }
2689
2991
  snapshot.context[stepId] = result;
2690
- snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
2691
- const upsertReq = new sql2.Request(transaction);
2992
+ snapshot.runtimeContext = { ...snapshot.runtimeContext, ...runtimeContext };
2993
+ const upsertReq = new sql3.Request(transaction);
2692
2994
  upsertReq.input("workflow_name", workflowName);
2693
2995
  upsertReq.input("run_id", runId);
2694
2996
  upsertReq.input("snapshot", JSON.stringify(snapshot));
2695
- upsertReq.input("createdAt", sql2.DateTime2, /* @__PURE__ */ new Date());
2696
- upsertReq.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
2997
+ upsertReq.input("createdAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2998
+ upsertReq.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2697
2999
  await upsertReq.query(
2698
3000
  `MERGE ${table} AS target
2699
3001
  USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
@@ -2733,7 +3035,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2733
3035
  const transaction = this.pool.transaction();
2734
3036
  try {
2735
3037
  await transaction.begin();
2736
- const selectRequest = new sql2.Request(transaction);
3038
+ const selectRequest = new sql3.Request(transaction);
2737
3039
  selectRequest.input("workflow_name", workflowName);
2738
3040
  selectRequest.input("run_id", runId);
2739
3041
  const existingSnapshotResult = await selectRequest.query(
@@ -2761,11 +3063,11 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2761
3063
  );
2762
3064
  }
2763
3065
  const updatedSnapshot = { ...snapshot, ...opts };
2764
- const updateRequest = new sql2.Request(transaction);
3066
+ const updateRequest = new sql3.Request(transaction);
2765
3067
  updateRequest.input("snapshot", JSON.stringify(updatedSnapshot));
2766
3068
  updateRequest.input("workflow_name", workflowName);
2767
3069
  updateRequest.input("run_id", runId);
2768
- updateRequest.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
3070
+ updateRequest.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2769
3071
  await updateRequest.query(
2770
3072
  `UPDATE ${table} SET snapshot = @snapshot, [updatedAt] = @updatedAt WHERE workflow_name = @workflow_name AND run_id = @run_id`
2771
3073
  );
@@ -2804,8 +3106,8 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2804
3106
  request.input("run_id", runId);
2805
3107
  request.input("resourceId", resourceId);
2806
3108
  request.input("snapshot", JSON.stringify(snapshot));
2807
- request.input("createdAt", sql2.DateTime2, new Date(now));
2808
- request.input("updatedAt", sql2.DateTime2, new Date(now));
3109
+ request.input("createdAt", sql3.DateTime2, new Date(now));
3110
+ request.input("updatedAt", sql3.DateTime2, new Date(now));
2809
3111
  const mergeSql = `MERGE INTO ${table} AS target
2810
3112
  USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
2811
3113
  ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
@@ -2902,12 +3204,12 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2902
3204
  );
2903
3205
  }
2904
3206
  }
2905
- async listWorkflowRuns({
3207
+ async getWorkflowRuns({
2906
3208
  workflowName,
2907
3209
  fromDate,
2908
3210
  toDate,
2909
- page,
2910
- perPage,
3211
+ limit,
3212
+ offset,
2911
3213
  resourceId,
2912
3214
  status
2913
3215
  } = {}) {
@@ -2945,23 +3247,20 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2945
3247
  const request = this.pool.request();
2946
3248
  Object.entries(paramMap).forEach(([key, value]) => {
2947
3249
  if (value instanceof Date) {
2948
- request.input(key, sql2.DateTime, value);
3250
+ request.input(key, sql3.DateTime, value);
2949
3251
  } else {
2950
3252
  request.input(key, value);
2951
3253
  }
2952
3254
  });
2953
- const usePagination = typeof perPage === "number" && typeof page === "number";
2954
- if (usePagination) {
3255
+ if (limit !== void 0 && offset !== void 0) {
2955
3256
  const countQuery = `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`;
2956
3257
  const countResult = await request.query(countQuery);
2957
3258
  total = Number(countResult.recordset[0]?.count || 0);
2958
3259
  }
2959
3260
  let query = `SELECT * FROM ${tableName} ${whereClause} ORDER BY [seq_id] DESC`;
2960
- if (usePagination) {
2961
- const normalizedPerPage = normalizePerPage(perPage, Number.MAX_SAFE_INTEGER);
2962
- const offset = page * normalizedPerPage;
2963
- query += ` OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
2964
- request.input("perPage", normalizedPerPage);
3261
+ if (limit !== void 0 && offset !== void 0) {
3262
+ query += ` OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`;
3263
+ request.input("limit", limit);
2965
3264
  request.input("offset", offset);
2966
3265
  }
2967
3266
  const result = await request.query(query);
@@ -2970,7 +3269,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2970
3269
  } catch (error) {
2971
3270
  throw new MastraError(
2972
3271
  {
2973
- id: "MASTRA_STORAGE_MSSQL_STORE_LIST_WORKFLOW_RUNS_FAILED",
3272
+ id: "MASTRA_STORAGE_MSSQL_STORE_GET_WORKFLOW_RUNS_FAILED",
2974
3273
  domain: ErrorDomain.STORAGE,
2975
3274
  category: ErrorCategory.THIRD_PARTY,
2976
3275
  details: {
@@ -2990,10 +3289,7 @@ var MSSQLStore = class extends MastraStorage {
2990
3289
  isConnected = null;
2991
3290
  stores;
2992
3291
  constructor(config) {
2993
- if (!config.id || typeof config.id !== "string" || config.id.trim() === "") {
2994
- throw new Error("MSSQLStore: id must be provided and cannot be empty.");
2995
- }
2996
- super({ id: config.id, name: "MSSQLStore" });
3292
+ super({ name: "MSSQLStore" });
2997
3293
  try {
2998
3294
  if ("connectionString" in config) {
2999
3295
  if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") {
@@ -3008,7 +3304,7 @@ var MSSQLStore = class extends MastraStorage {
3008
3304
  }
3009
3305
  }
3010
3306
  this.schema = config.schemaName || "dbo";
3011
- this.pool = "connectionString" in config ? new sql2.ConnectionPool(config.connectionString) : new sql2.ConnectionPool({
3307
+ this.pool = "connectionString" in config ? new sql3.ConnectionPool(config.connectionString) : new sql3.ConnectionPool({
3012
3308
  server: config.server,
3013
3309
  database: config.database,
3014
3310
  user: config.user,
@@ -3016,15 +3312,19 @@ var MSSQLStore = class extends MastraStorage {
3016
3312
  port: config.port,
3017
3313
  options: config.options || { encrypt: true, trustServerCertificate: true }
3018
3314
  });
3315
+ const legacyEvals = new LegacyEvalsMSSQL({ pool: this.pool, schema: this.schema });
3019
3316
  const operations = new StoreOperationsMSSQL({ pool: this.pool, schemaName: this.schema });
3020
3317
  const scores = new ScoresMSSQL({ pool: this.pool, operations, schema: this.schema });
3318
+ const traces = new TracesMSSQL({ pool: this.pool, operations, schema: this.schema });
3021
3319
  const workflows = new WorkflowsMSSQL({ pool: this.pool, operations, schema: this.schema });
3022
3320
  const memory = new MemoryMSSQL({ pool: this.pool, schema: this.schema, operations });
3023
3321
  const observability = new ObservabilityMSSQL({ pool: this.pool, operations, schema: this.schema });
3024
3322
  this.stores = {
3025
3323
  operations,
3026
3324
  scores,
3325
+ traces,
3027
3326
  workflows,
3327
+ legacyEvals,
3028
3328
  memory,
3029
3329
  observability
3030
3330
  };
@@ -3078,11 +3378,30 @@ var MSSQLStore = class extends MastraStorage {
3078
3378
  hasColumn: true,
3079
3379
  createTable: true,
3080
3380
  deleteMessages: true,
3081
- listScoresBySpan: true,
3082
- observabilityInstance: true,
3381
+ getScoresBySpan: true,
3382
+ aiTracing: true,
3083
3383
  indexManagement: true
3084
3384
  };
3085
3385
  }
3386
+ /** @deprecated use getEvals instead */
3387
+ async getEvalsByAgentName(agentName, type) {
3388
+ return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
3389
+ }
3390
+ async getEvals(options = {}) {
3391
+ return this.stores.legacyEvals.getEvals(options);
3392
+ }
3393
+ /**
3394
+ * @deprecated use getTracesPaginated instead
3395
+ */
3396
+ async getTraces(args) {
3397
+ return this.stores.traces.getTraces(args);
3398
+ }
3399
+ async getTracesPaginated(args) {
3400
+ return this.stores.traces.getTracesPaginated(args);
3401
+ }
3402
+ async batchTraceInsert({ records }) {
3403
+ return this.stores.traces.batchTraceInsert({ records });
3404
+ }
3086
3405
  async createTable({
3087
3406
  tableName,
3088
3407
  schema
@@ -3117,6 +3436,15 @@ var MSSQLStore = class extends MastraStorage {
3117
3436
  async getThreadById({ threadId }) {
3118
3437
  return this.stores.memory.getThreadById({ threadId });
3119
3438
  }
3439
+ /**
3440
+ * @deprecated use getThreadsByResourceIdPaginated instead
3441
+ */
3442
+ async getThreadsByResourceId(args) {
3443
+ return this.stores.memory.getThreadsByResourceId(args);
3444
+ }
3445
+ async getThreadsByResourceIdPaginated(args) {
3446
+ return this.stores.memory.getThreadsByResourceIdPaginated(args);
3447
+ }
3120
3448
  async saveThread({ thread }) {
3121
3449
  return this.stores.memory.saveThread({ thread });
3122
3450
  }
@@ -3130,8 +3458,17 @@ var MSSQLStore = class extends MastraStorage {
3130
3458
  async deleteThread({ threadId }) {
3131
3459
  return this.stores.memory.deleteThread({ threadId });
3132
3460
  }
3133
- async listMessagesById({ messageIds }) {
3134
- return this.stores.memory.listMessagesById({ messageIds });
3461
+ async getMessages(args) {
3462
+ return this.stores.memory.getMessages(args);
3463
+ }
3464
+ async getMessagesById({
3465
+ messageIds,
3466
+ format
3467
+ }) {
3468
+ return this.stores.memory.getMessagesById({ messageIds, format });
3469
+ }
3470
+ async getMessagesPaginated(args) {
3471
+ return this.stores.memory.getMessagesPaginated(args);
3135
3472
  }
3136
3473
  async saveMessages(args) {
3137
3474
  return this.stores.memory.saveMessages(args);
@@ -3165,9 +3502,9 @@ var MSSQLStore = class extends MastraStorage {
3165
3502
  runId,
3166
3503
  stepId,
3167
3504
  result,
3168
- requestContext
3505
+ runtimeContext
3169
3506
  }) {
3170
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
3507
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
3171
3508
  }
3172
3509
  async updateWorkflowState({
3173
3510
  workflowName,
@@ -3190,8 +3527,8 @@ var MSSQLStore = class extends MastraStorage {
3190
3527
  }) {
3191
3528
  return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
3192
3529
  }
3193
- async listWorkflowRuns(args = {}) {
3194
- return this.stores.workflows.listWorkflowRuns(args);
3530
+ async getWorkflowRuns(args = {}) {
3531
+ return this.stores.workflows.getWorkflowRuns(args);
3195
3532
  }
3196
3533
  async getWorkflowRunById({
3197
3534
  runId,
@@ -3218,7 +3555,7 @@ var MSSQLStore = class extends MastraStorage {
3218
3555
  return this.stores.operations.dropIndex(indexName);
3219
3556
  }
3220
3557
  /**
3221
- * Tracing / Observability
3558
+ * AI Tracing / Observability
3222
3559
  */
3223
3560
  getObservabilityStore() {
3224
3561
  if (!this.stores.observability) {
@@ -3231,30 +3568,30 @@ var MSSQLStore = class extends MastraStorage {
3231
3568
  }
3232
3569
  return this.stores.observability;
3233
3570
  }
3234
- async createSpan(span) {
3235
- return this.getObservabilityStore().createSpan(span);
3571
+ async createAISpan(span) {
3572
+ return this.getObservabilityStore().createAISpan(span);
3236
3573
  }
3237
- async updateSpan({
3574
+ async updateAISpan({
3238
3575
  spanId,
3239
3576
  traceId,
3240
3577
  updates
3241
3578
  }) {
3242
- return this.getObservabilityStore().updateSpan({ spanId, traceId, updates });
3579
+ return this.getObservabilityStore().updateAISpan({ spanId, traceId, updates });
3243
3580
  }
3244
- async getTrace(traceId) {
3245
- return this.getObservabilityStore().getTrace(traceId);
3581
+ async getAITrace(traceId) {
3582
+ return this.getObservabilityStore().getAITrace(traceId);
3246
3583
  }
3247
- async getTracesPaginated(args) {
3248
- return this.getObservabilityStore().getTracesPaginated(args);
3584
+ async getAITracesPaginated(args) {
3585
+ return this.getObservabilityStore().getAITracesPaginated(args);
3249
3586
  }
3250
- async batchCreateSpans(args) {
3251
- return this.getObservabilityStore().batchCreateSpans(args);
3587
+ async batchCreateAISpans(args) {
3588
+ return this.getObservabilityStore().batchCreateAISpans(args);
3252
3589
  }
3253
- async batchUpdateSpans(args) {
3254
- return this.getObservabilityStore().batchUpdateSpans(args);
3590
+ async batchUpdateAISpans(args) {
3591
+ return this.getObservabilityStore().batchUpdateAISpans(args);
3255
3592
  }
3256
- async batchDeleteTraces(args) {
3257
- return this.getObservabilityStore().batchDeleteTraces(args);
3593
+ async batchDeleteAITraces(args) {
3594
+ return this.getObservabilityStore().batchDeleteAITraces(args);
3258
3595
  }
3259
3596
  /**
3260
3597
  * Scorers
@@ -3262,14 +3599,14 @@ var MSSQLStore = class extends MastraStorage {
3262
3599
  async getScoreById({ id: _id }) {
3263
3600
  return this.stores.scores.getScoreById({ id: _id });
3264
3601
  }
3265
- async listScoresByScorerId({
3602
+ async getScoresByScorerId({
3266
3603
  scorerId: _scorerId,
3267
3604
  pagination: _pagination,
3268
3605
  entityId: _entityId,
3269
3606
  entityType: _entityType,
3270
3607
  source: _source
3271
3608
  }) {
3272
- return this.stores.scores.listScoresByScorerId({
3609
+ return this.stores.scores.getScoresByScorerId({
3273
3610
  scorerId: _scorerId,
3274
3611
  pagination: _pagination,
3275
3612
  entityId: _entityId,
@@ -3280,29 +3617,29 @@ var MSSQLStore = class extends MastraStorage {
3280
3617
  async saveScore(_score) {
3281
3618
  return this.stores.scores.saveScore(_score);
3282
3619
  }
3283
- async listScoresByRunId({
3620
+ async getScoresByRunId({
3284
3621
  runId: _runId,
3285
3622
  pagination: _pagination
3286
3623
  }) {
3287
- return this.stores.scores.listScoresByRunId({ runId: _runId, pagination: _pagination });
3624
+ return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
3288
3625
  }
3289
- async listScoresByEntityId({
3626
+ async getScoresByEntityId({
3290
3627
  entityId: _entityId,
3291
3628
  entityType: _entityType,
3292
3629
  pagination: _pagination
3293
3630
  }) {
3294
- return this.stores.scores.listScoresByEntityId({
3631
+ return this.stores.scores.getScoresByEntityId({
3295
3632
  entityId: _entityId,
3296
3633
  entityType: _entityType,
3297
3634
  pagination: _pagination
3298
3635
  });
3299
3636
  }
3300
- async listScoresBySpan({
3637
+ async getScoresBySpan({
3301
3638
  traceId,
3302
3639
  spanId,
3303
3640
  pagination: _pagination
3304
3641
  }) {
3305
- return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination: _pagination });
3642
+ return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination: _pagination });
3306
3643
  }
3307
3644
  };
3308
3645