@mastra/mssql 0.5.1 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
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';
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';
5
4
  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/scores';
7
+ import { saveScorePayloadSchema } from '@mastra/core/evals';
8
8
 
9
9
  // src/storage/index.ts
10
10
  function getSchemaName(schema) {
@@ -80,153 +80,7 @@ function transformFromSqlRow({
80
80
  return result;
81
81
  }
82
82
 
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
- };
83
+ // src/storage/domains/memory/index.ts
230
84
  var MemoryMSSQL = class extends MemoryStorage {
231
85
  pool;
232
86
  schema;
@@ -244,7 +98,7 @@ var MemoryMSSQL = class extends MemoryStorage {
244
98
  });
245
99
  const cleanMessages = messagesWithParsedContent.map(({ seq_id, ...rest }) => rest);
246
100
  const list = new MessageList().add(cleanMessages, "memory");
247
- return format === "v2" ? list.get.all.v2() : list.get.all.v1();
101
+ return format === "v2" ? list.get.all.db() : list.get.all.v1();
248
102
  }
249
103
  constructor({
250
104
  pool,
@@ -258,7 +112,7 @@ var MemoryMSSQL = class extends MemoryStorage {
258
112
  }
259
113
  async getThreadById({ threadId }) {
260
114
  try {
261
- const sql7 = `SELECT
115
+ const sql5 = `SELECT
262
116
  id,
263
117
  [resourceId],
264
118
  title,
@@ -269,7 +123,7 @@ var MemoryMSSQL = class extends MemoryStorage {
269
123
  WHERE id = @threadId`;
270
124
  const request = this.pool.request();
271
125
  request.input("threadId", threadId);
272
- const resultSet = await request.query(sql7);
126
+ const resultSet = await request.query(sql5);
273
127
  const thread = resultSet.recordset[0] || null;
274
128
  if (!thread) {
275
129
  return null;
@@ -294,11 +148,24 @@ var MemoryMSSQL = class extends MemoryStorage {
294
148
  );
295
149
  }
296
150
  }
297
- async getThreadsByResourceIdPaginated(args) {
298
- const { resourceId, page = 0, perPage: perPageInput, orderBy = "createdAt", sortDirection = "DESC" } = args;
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);
299
168
  try {
300
- const perPage = perPageInput !== void 0 ? perPageInput : 100;
301
- const currentOffset = page * perPage;
302
169
  const baseQuery = `FROM ${getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) })} WHERE [resourceId] = @resourceId`;
303
170
  const countQuery = `SELECT COUNT(*) as count ${baseQuery}`;
304
171
  const countRequest = this.pool.request();
@@ -310,17 +177,22 @@ var MemoryMSSQL = class extends MemoryStorage {
310
177
  threads: [],
311
178
  total: 0,
312
179
  page,
313
- perPage,
180
+ perPage: perPageForResponse,
314
181
  hasMore: false
315
182
  };
316
183
  }
317
- const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
318
- const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
184
+ const orderByField = field === "createdAt" ? "[createdAt]" : "[updatedAt]";
185
+ const dir = (direction || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
186
+ const limitValue = perPageInput === false ? total : perPage;
319
187
  const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir} OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
320
188
  const dataRequest = this.pool.request();
321
189
  dataRequest.input("resourceId", resourceId);
322
- dataRequest.input("perPage", perPage);
323
- dataRequest.input("offset", currentOffset);
190
+ dataRequest.input("offset", offset);
191
+ if (limitValue > 2147483647) {
192
+ dataRequest.input("perPage", sql2.BigInt, limitValue);
193
+ } else {
194
+ dataRequest.input("perPage", limitValue);
195
+ }
324
196
  const rowsResult = await dataRequest.query(dataQuery);
325
197
  const rows = rowsResult.recordset || [];
326
198
  const threads = rows.map((thread) => ({
@@ -333,13 +205,13 @@ var MemoryMSSQL = class extends MemoryStorage {
333
205
  threads,
334
206
  total,
335
207
  page,
336
- perPage,
337
- hasMore: currentOffset + threads.length < total
208
+ perPage: perPageForResponse,
209
+ hasMore: perPageInput === false ? false : offset + perPage < total
338
210
  };
339
211
  } catch (error) {
340
212
  const mastraError = new MastraError(
341
213
  {
342
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
214
+ id: "MASTRA_STORAGE_MSSQL_STORE_LIST_THREADS_BY_RESOURCE_ID_FAILED",
343
215
  domain: ErrorDomain.STORAGE,
344
216
  category: ErrorCategory.THIRD_PARTY,
345
217
  details: {
@@ -351,7 +223,13 @@ var MemoryMSSQL = class extends MemoryStorage {
351
223
  );
352
224
  this.logger?.error?.(mastraError.toString());
353
225
  this.logger?.trackException?.(mastraError);
354
- return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
226
+ return {
227
+ threads: [],
228
+ total: 0,
229
+ page,
230
+ perPage: perPageForResponse,
231
+ hasMore: false
232
+ };
355
233
  }
356
234
  }
357
235
  async saveThread({ thread }) {
@@ -375,12 +253,12 @@ var MemoryMSSQL = class extends MemoryStorage {
375
253
  req.input("title", thread.title);
376
254
  const metadata = thread.metadata ? JSON.stringify(thread.metadata) : null;
377
255
  if (metadata === null) {
378
- req.input("metadata", sql3.NVarChar, null);
256
+ req.input("metadata", sql2.NVarChar, null);
379
257
  } else {
380
258
  req.input("metadata", metadata);
381
259
  }
382
- req.input("createdAt", sql3.DateTime2, thread.createdAt);
383
- req.input("updatedAt", sql3.DateTime2, thread.updatedAt);
260
+ req.input("createdAt", sql2.DateTime2, thread.createdAt);
261
+ req.input("updatedAt", sql2.DateTime2, thread.updatedAt);
384
262
  await req.query(mergeSql);
385
263
  return thread;
386
264
  } catch (error) {
@@ -397,31 +275,6 @@ var MemoryMSSQL = class extends MemoryStorage {
397
275
  );
398
276
  }
399
277
  }
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
- }
425
278
  /**
426
279
  * Updates a thread's title and metadata, merging with existing metadata. Returns the updated thread.
427
280
  */
@@ -449,7 +302,7 @@ var MemoryMSSQL = class extends MemoryStorage {
449
302
  };
450
303
  try {
451
304
  const table = getTableName({ indexName: TABLE_THREADS, schemaName: getSchemaName(this.schema) });
452
- const sql7 = `UPDATE ${table}
305
+ const sql5 = `UPDATE ${table}
453
306
  SET title = @title,
454
307
  metadata = @metadata,
455
308
  [updatedAt] = @updatedAt
@@ -460,7 +313,7 @@ var MemoryMSSQL = class extends MemoryStorage {
460
313
  req.input("title", title);
461
314
  req.input("metadata", JSON.stringify(mergedMetadata));
462
315
  req.input("updatedAt", /* @__PURE__ */ new Date());
463
- const result = await req.query(sql7);
316
+ const result = await req.query(sql5);
464
317
  let thread = result.recordset && result.recordset[0];
465
318
  if (thread && "seq_id" in thread) {
466
319
  const { seq_id, ...rest } = thread;
@@ -530,11 +383,9 @@ var MemoryMSSQL = class extends MemoryStorage {
530
383
  }
531
384
  async _getIncludedMessages({
532
385
  threadId,
533
- selectBy,
534
- orderByStatement
386
+ include
535
387
  }) {
536
388
  if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
537
- const include = selectBy?.include;
538
389
  if (!include) return null;
539
390
  const unionQueries = [];
540
391
  const paramValues = [];
@@ -559,7 +410,7 @@ var MemoryMSSQL = class extends MemoryStorage {
559
410
  m.[resourceId],
560
411
  m.seq_id
561
412
  FROM (
562
- SELECT *, ROW_NUMBER() OVER (${orderByStatement}) as row_num
413
+ SELECT *, ROW_NUMBER() OVER (ORDER BY [createdAt] ASC) as row_num
563
414
  FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })}
564
415
  WHERE [thread_id] = ${pThreadId}
565
416
  ) AS m
@@ -567,15 +418,17 @@ var MemoryMSSQL = class extends MemoryStorage {
567
418
  OR EXISTS (
568
419
  SELECT 1
569
420
  FROM (
570
- SELECT *, ROW_NUMBER() OVER (${orderByStatement}) as row_num
421
+ SELECT *, ROW_NUMBER() OVER (ORDER BY [createdAt] ASC) as row_num
571
422
  FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })}
572
423
  WHERE [thread_id] = ${pThreadId}
573
424
  ) AS target
574
425
  WHERE target.id = ${pId}
575
426
  AND (
576
- (m.row_num <= target.row_num + ${pPrev} AND m.row_num > target.row_num)
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})
577
429
  OR
578
- (m.row_num >= target.row_num - ${pNext} AND m.row_num < target.row_num)
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})
579
432
  )
580
433
  )
581
434
  `
@@ -604,34 +457,16 @@ var MemoryMSSQL = class extends MemoryStorage {
604
457
  });
605
458
  return dedupedRows;
606
459
  }
607
- async getMessages(args) {
608
- const { threadId, resourceId, format, selectBy } = args;
460
+ async listMessagesById({ messageIds }) {
461
+ if (messageIds.length === 0) return { messages: [] };
609
462
  const selectStatement = `SELECT seq_id, id, content, role, type, [createdAt], thread_id AS threadId, resourceId`;
610
463
  const orderByStatement = `ORDER BY [seq_id] DESC`;
611
- const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
612
464
  try {
613
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
614
465
  let rows = [];
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`;
466
+ let query = `${selectStatement} FROM ${getTableName({ indexName: TABLE_MESSAGES, schemaName: getSchemaName(this.schema) })} WHERE [id] IN (${messageIds.map((_, i) => `@id${i}`).join(", ")})`;
624
467
  const request = this.pool.request();
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);
468
+ messageIds.forEach((id, i) => request.input(`id${i}`, id));
469
+ query += ` ${orderByStatement}`;
635
470
  const result = await request.query(query);
636
471
  const remainingRows = result.recordset || [];
637
472
  rows.push(...remainingRows);
@@ -639,153 +474,171 @@ var MemoryMSSQL = class extends MemoryStorage {
639
474
  const timeDiff = a.seq_id - b.seq_id;
640
475
  return timeDiff;
641
476
  });
642
- rows = rows.map(({ seq_id, ...rest }) => rest);
643
- return this._parseAndFormatMessages(rows, format);
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() };
644
490
  } catch (error) {
645
491
  const mastraError = new MastraError(
646
492
  {
647
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_MESSAGES_FAILED",
493
+ id: "MASTRA_STORAGE_MSSQL_STORE_LIST_MESSAGES_BY_ID_FAILED",
648
494
  domain: ErrorDomain.STORAGE,
649
495
  category: ErrorCategory.THIRD_PARTY,
650
496
  details: {
651
- threadId,
652
- resourceId: resourceId ?? ""
497
+ messageIds: JSON.stringify(messageIds)
653
498
  }
654
499
  },
655
500
  error
656
501
  );
657
502
  this.logger?.error?.(mastraError.toString());
658
503
  this.logger?.trackException?.(mastraError);
659
- return [];
504
+ return { messages: [] };
660
505
  }
661
506
  }
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(
507
+ async listMessages(args) {
508
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
509
+ if (!threadId.trim()) {
510
+ throw new MastraError(
687
511
  {
688
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_MESSAGES_BY_ID_FAILED",
512
+ id: "STORAGE_MSSQL_LIST_MESSAGES_INVALID_THREAD_ID",
689
513
  domain: ErrorDomain.STORAGE,
690
514
  category: ErrorCategory.THIRD_PARTY,
691
- details: {
692
- messageIds: JSON.stringify(messageIds)
693
- }
515
+ details: { threadId }
694
516
  },
695
- error
517
+ new Error("threadId must be a non-empty string")
696
518
  );
697
- this.logger?.error?.(mastraError.toString());
698
- this.logger?.trackException?.(mastraError);
699
- return [];
700
519
  }
701
- }
702
- async getMessagesPaginated(args) {
703
- const { threadId, resourceId, format, selectBy } = args;
704
- const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
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);
705
534
  try {
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);
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}`);
732
552
  const total = parseInt(countResult.recordset[0]?.total, 10) || 0;
733
- if (total === 0 && messages.length > 0) {
734
- const parsedIncluded = this._parseAndFormatMessages(messages, format);
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)) {
735
574
  return {
736
- messages: parsedIncluded,
737
- total: parsedIncluded.length,
575
+ messages: [],
576
+ total: 0,
738
577
  page,
739
- perPage,
578
+ perPage: perPageForResponse,
740
579
  hasMore: false
741
580
  };
742
581
  }
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
- const parsed = this._parseAndFormatMessages(messages, format);
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;
758
609
  return {
759
- messages: parsed,
610
+ messages: finalMessages,
760
611
  total,
761
612
  page,
762
- perPage,
763
- hasMore: currentOffset + rows.length < total
613
+ perPage: perPageForResponse,
614
+ hasMore
764
615
  };
765
616
  } catch (error) {
766
617
  const mastraError = new MastraError(
767
618
  {
768
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_MESSAGES_PAGINATED_FAILED",
619
+ id: "MASTRA_STORAGE_MSSQL_STORE_LIST_MESSAGES_FAILED",
769
620
  domain: ErrorDomain.STORAGE,
770
621
  category: ErrorCategory.THIRD_PARTY,
771
622
  details: {
772
623
  threadId,
773
- resourceId: resourceId ?? "",
774
- page
624
+ resourceId: resourceId ?? ""
775
625
  }
776
626
  },
777
627
  error
778
628
  );
779
629
  this.logger?.error?.(mastraError.toString());
780
630
  this.logger?.trackException?.(mastraError);
781
- return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
631
+ return {
632
+ messages: [],
633
+ total: 0,
634
+ page,
635
+ perPage: perPageForResponse,
636
+ hasMore: false
637
+ };
782
638
  }
783
639
  }
784
- async saveMessages({
785
- messages,
786
- format
787
- }) {
788
- if (messages.length === 0) return messages;
640
+ async saveMessages({ messages }) {
641
+ if (messages.length === 0) return { messages: [] };
789
642
  const threadId = messages[0]?.threadId;
790
643
  if (!threadId) {
791
644
  throw new MastraError({
@@ -829,7 +682,7 @@ var MemoryMSSQL = class extends MemoryStorage {
829
682
  "content",
830
683
  typeof message.content === "string" ? message.content : JSON.stringify(message.content)
831
684
  );
832
- request.input("createdAt", sql3.DateTime2, message.createdAt);
685
+ request.input("createdAt", sql2.DateTime2, message.createdAt);
833
686
  request.input("role", message.role);
834
687
  request.input("type", message.type || "v2");
835
688
  request.input("resourceId", message.resourceId);
@@ -848,7 +701,7 @@ var MemoryMSSQL = class extends MemoryStorage {
848
701
  await request.query(mergeSql);
849
702
  }
850
703
  const threadReq = transaction.request();
851
- threadReq.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
704
+ threadReq.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
852
705
  threadReq.input("id", threadId);
853
706
  await threadReq.query(`UPDATE ${tableThreads} SET [updatedAt] = @updatedAt WHERE id = @id`);
854
707
  await transaction.commit();
@@ -867,8 +720,7 @@ var MemoryMSSQL = class extends MemoryStorage {
867
720
  return message;
868
721
  });
869
722
  const list = new MessageList().add(messagesWithParsedContent, "memory");
870
- if (format === "v2") return list.get.all.v2();
871
- return list.get.all.v1();
723
+ return { messages: list.get.all.db() };
872
724
  } catch (error) {
873
725
  throw new MastraError(
874
726
  {
@@ -1147,13 +999,13 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1147
999
  this.operations = operations;
1148
1000
  this.schema = schema;
1149
1001
  }
1150
- get aiTracingStrategy() {
1002
+ get tracingStrategy() {
1151
1003
  return {
1152
1004
  preferred: "batch-with-updates",
1153
1005
  supported: ["batch-with-updates", "insert-only"]
1154
1006
  };
1155
1007
  }
1156
- async createAISpan(span) {
1008
+ async createSpan(span) {
1157
1009
  try {
1158
1010
  const startedAt = span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt;
1159
1011
  const endedAt = span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt;
@@ -1163,11 +1015,11 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1163
1015
  endedAt
1164
1016
  // Note: createdAt/updatedAt will be set by default values
1165
1017
  };
1166
- return this.operations.insert({ tableName: TABLE_AI_SPANS, record });
1018
+ return this.operations.insert({ tableName: TABLE_SPANS, record });
1167
1019
  } catch (error) {
1168
1020
  throw new MastraError(
1169
1021
  {
1170
- id: "MSSQL_STORE_CREATE_AI_SPAN_FAILED",
1022
+ id: "MSSQL_STORE_CREATE_SPAN_FAILED",
1171
1023
  domain: ErrorDomain.STORAGE,
1172
1024
  category: ErrorCategory.USER,
1173
1025
  details: {
@@ -1181,10 +1033,10 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1181
1033
  );
1182
1034
  }
1183
1035
  }
1184
- async getAITrace(traceId) {
1036
+ async getTrace(traceId) {
1185
1037
  try {
1186
1038
  const tableName = getTableName({
1187
- indexName: TABLE_AI_SPANS,
1039
+ indexName: TABLE_SPANS,
1188
1040
  schemaName: getSchemaName(this.schema)
1189
1041
  });
1190
1042
  const request = this.pool.request();
@@ -1205,7 +1057,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1205
1057
  traceId,
1206
1058
  spans: result.recordset.map(
1207
1059
  (span) => transformFromSqlRow({
1208
- tableName: TABLE_AI_SPANS,
1060
+ tableName: TABLE_SPANS,
1209
1061
  sqlRow: span
1210
1062
  })
1211
1063
  )
@@ -1213,7 +1065,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1213
1065
  } catch (error) {
1214
1066
  throw new MastraError(
1215
1067
  {
1216
- id: "MSSQL_STORE_GET_AI_TRACE_FAILED",
1068
+ id: "MSSQL_STORE_GET_TRACE_FAILED",
1217
1069
  domain: ErrorDomain.STORAGE,
1218
1070
  category: ErrorCategory.USER,
1219
1071
  details: {
@@ -1224,7 +1076,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1224
1076
  );
1225
1077
  }
1226
1078
  }
1227
- async updateAISpan({
1079
+ async updateSpan({
1228
1080
  spanId,
1229
1081
  traceId,
1230
1082
  updates
@@ -1238,14 +1090,14 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1238
1090
  data.startedAt = data.startedAt.toISOString();
1239
1091
  }
1240
1092
  await this.operations.update({
1241
- tableName: TABLE_AI_SPANS,
1093
+ tableName: TABLE_SPANS,
1242
1094
  keys: { spanId, traceId },
1243
1095
  data
1244
1096
  });
1245
1097
  } catch (error) {
1246
1098
  throw new MastraError(
1247
1099
  {
1248
- id: "MSSQL_STORE_UPDATE_AI_SPAN_FAILED",
1100
+ id: "MSSQL_STORE_UPDATE_SPAN_FAILED",
1249
1101
  domain: ErrorDomain.STORAGE,
1250
1102
  category: ErrorCategory.USER,
1251
1103
  details: {
@@ -1257,7 +1109,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1257
1109
  );
1258
1110
  }
1259
1111
  }
1260
- async getAITracesPaginated({
1112
+ async getTracesPaginated({
1261
1113
  filters,
1262
1114
  pagination
1263
1115
  }) {
@@ -1282,7 +1134,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1282
1134
  name = `agent run: '${entityId}'`;
1283
1135
  } else {
1284
1136
  const error = new MastraError({
1285
- id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
1137
+ id: "MSSQL_STORE_GET_TRACES_PAGINATED_FAILED",
1286
1138
  domain: ErrorDomain.STORAGE,
1287
1139
  category: ErrorCategory.USER,
1288
1140
  details: {
@@ -1301,7 +1153,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1301
1153
  params[entityParam] = name;
1302
1154
  }
1303
1155
  const tableName = getTableName({
1304
- indexName: TABLE_AI_SPANS,
1156
+ indexName: TABLE_SPANS,
1305
1157
  schemaName: getSchemaName(this.schema)
1306
1158
  });
1307
1159
  try {
@@ -1335,7 +1187,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1335
1187
  );
1336
1188
  const spans = dataResult.recordset.map(
1337
1189
  (row) => transformFromSqlRow({
1338
- tableName: TABLE_AI_SPANS,
1190
+ tableName: TABLE_SPANS,
1339
1191
  sqlRow: row
1340
1192
  })
1341
1193
  );
@@ -1351,7 +1203,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1351
1203
  } catch (error) {
1352
1204
  throw new MastraError(
1353
1205
  {
1354
- id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
1206
+ id: "MSSQL_STORE_GET_TRACES_PAGINATED_FAILED",
1355
1207
  domain: ErrorDomain.STORAGE,
1356
1208
  category: ErrorCategory.USER
1357
1209
  },
@@ -1359,13 +1211,13 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1359
1211
  );
1360
1212
  }
1361
1213
  }
1362
- async batchCreateAISpans(args) {
1214
+ async batchCreateSpans(args) {
1363
1215
  if (!args.records || args.records.length === 0) {
1364
1216
  return;
1365
1217
  }
1366
1218
  try {
1367
1219
  await this.operations.batchInsert({
1368
- tableName: TABLE_AI_SPANS,
1220
+ tableName: TABLE_SPANS,
1369
1221
  records: args.records.map((span) => ({
1370
1222
  ...span,
1371
1223
  startedAt: span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt,
@@ -1375,7 +1227,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1375
1227
  } catch (error) {
1376
1228
  throw new MastraError(
1377
1229
  {
1378
- id: "MSSQL_STORE_BATCH_CREATE_AI_SPANS_FAILED",
1230
+ id: "MSSQL_STORE_BATCH_CREATE_SPANS_FAILED",
1379
1231
  domain: ErrorDomain.STORAGE,
1380
1232
  category: ErrorCategory.USER,
1381
1233
  details: {
@@ -1386,7 +1238,7 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1386
1238
  );
1387
1239
  }
1388
1240
  }
1389
- async batchUpdateAISpans(args) {
1241
+ async batchUpdateSpans(args) {
1390
1242
  if (!args.records || args.records.length === 0) {
1391
1243
  return;
1392
1244
  }
@@ -1405,13 +1257,13 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1405
1257
  };
1406
1258
  });
1407
1259
  await this.operations.batchUpdate({
1408
- tableName: TABLE_AI_SPANS,
1260
+ tableName: TABLE_SPANS,
1409
1261
  updates
1410
1262
  });
1411
1263
  } catch (error) {
1412
1264
  throw new MastraError(
1413
1265
  {
1414
- id: "MSSQL_STORE_BATCH_UPDATE_AI_SPANS_FAILED",
1266
+ id: "MSSQL_STORE_BATCH_UPDATE_SPANS_FAILED",
1415
1267
  domain: ErrorDomain.STORAGE,
1416
1268
  category: ErrorCategory.USER,
1417
1269
  details: {
@@ -1422,20 +1274,20 @@ var ObservabilityMSSQL = class extends ObservabilityStorage {
1422
1274
  );
1423
1275
  }
1424
1276
  }
1425
- async batchDeleteAITraces(args) {
1277
+ async batchDeleteTraces(args) {
1426
1278
  if (!args.traceIds || args.traceIds.length === 0) {
1427
1279
  return;
1428
1280
  }
1429
1281
  try {
1430
1282
  const keys = args.traceIds.map((traceId) => ({ traceId }));
1431
1283
  await this.operations.batchDelete({
1432
- tableName: TABLE_AI_SPANS,
1284
+ tableName: TABLE_SPANS,
1433
1285
  keys
1434
1286
  });
1435
1287
  } catch (error) {
1436
1288
  throw new MastraError(
1437
1289
  {
1438
- id: "MSSQL_STORE_BATCH_DELETE_AI_TRACES_FAILED",
1290
+ id: "MSSQL_STORE_BATCH_DELETE_TRACES_FAILED",
1439
1291
  domain: ErrorDomain.STORAGE,
1440
1292
  category: ErrorCategory.USER,
1441
1293
  details: {
@@ -1550,7 +1402,7 @@ var StoreOperationsMSSQL = class extends StoreOperations {
1550
1402
  const value = record[col];
1551
1403
  const preparedValue = this.prepareValue(value, col, tableName);
1552
1404
  if (preparedValue instanceof Date) {
1553
- request.input(`param${i}`, sql3.DateTime2, preparedValue);
1405
+ request.input(`param${i}`, sql2.DateTime2, preparedValue);
1554
1406
  } else if (preparedValue === null || preparedValue === void 0) {
1555
1407
  request.input(`param${i}`, this.getMssqlType(tableName, col), null);
1556
1408
  } else {
@@ -1765,7 +1617,7 @@ ${columns}
1765
1617
  try {
1766
1618
  const keyEntries = Object.entries(keys).map(([key, value]) => [parseSqlIdentifier(key, "column name"), value]);
1767
1619
  const conditions = keyEntries.map(([key], i) => `[${key}] = @param${i}`).join(" AND ");
1768
- const sql7 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
1620
+ const sql5 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
1769
1621
  const request = this.pool.request();
1770
1622
  keyEntries.forEach(([key, value], i) => {
1771
1623
  const preparedValue = this.prepareValue(value, key, tableName);
@@ -1775,7 +1627,7 @@ ${columns}
1775
1627
  request.input(`param${i}`, preparedValue);
1776
1628
  }
1777
1629
  });
1778
- const resultSet = await request.query(sql7);
1630
+ const resultSet = await request.query(sql5);
1779
1631
  const result = resultSet.recordset[0] || null;
1780
1632
  if (!result) {
1781
1633
  return null;
@@ -1860,6 +1712,20 @@ ${columns}
1860
1712
  return value ? 1 : 0;
1861
1713
  }
1862
1714
  if (columnSchema?.type === "jsonb") {
1715
+ if (typeof value === "string") {
1716
+ const trimmed = value.trim();
1717
+ if (trimmed.length > 0) {
1718
+ try {
1719
+ JSON.parse(trimmed);
1720
+ return trimmed;
1721
+ } catch {
1722
+ }
1723
+ }
1724
+ return JSON.stringify(value);
1725
+ }
1726
+ if (typeof value === "bigint") {
1727
+ return value.toString();
1728
+ }
1863
1729
  return JSON.stringify(value);
1864
1730
  }
1865
1731
  if (typeof value === "object") {
@@ -1874,23 +1740,23 @@ ${columns}
1874
1740
  const col = TABLE_SCHEMAS[tableName]?.[columnName];
1875
1741
  switch (col?.type) {
1876
1742
  case "text":
1877
- return sql3.NVarChar;
1743
+ return sql2.NVarChar;
1878
1744
  case "timestamp":
1879
- return sql3.DateTime2;
1745
+ return sql2.DateTime2;
1880
1746
  case "uuid":
1881
- return sql3.UniqueIdentifier;
1747
+ return sql2.UniqueIdentifier;
1882
1748
  case "jsonb":
1883
- return sql3.NVarChar;
1749
+ return sql2.NVarChar;
1884
1750
  case "integer":
1885
- return sql3.Int;
1751
+ return sql2.Int;
1886
1752
  case "bigint":
1887
- return sql3.BigInt;
1753
+ return sql2.BigInt;
1888
1754
  case "float":
1889
- return sql3.Float;
1755
+ return sql2.Float;
1890
1756
  case "boolean":
1891
- return sql3.Bit;
1757
+ return sql2.Bit;
1892
1758
  default:
1893
- return sql3.NVarChar;
1759
+ return sql2.NVarChar;
1894
1760
  }
1895
1761
  }
1896
1762
  /**
@@ -2334,35 +2200,30 @@ ${columns}
2334
2200
  table: TABLE_TRACES,
2335
2201
  columns: ["name", "seq_id DESC"]
2336
2202
  },
2337
- {
2338
- name: `${schemaPrefix}mastra_evals_agent_name_seqid_idx`,
2339
- table: TABLE_EVALS,
2340
- columns: ["agent_name", "seq_id DESC"]
2341
- },
2342
2203
  {
2343
2204
  name: `${schemaPrefix}mastra_scores_trace_id_span_id_seqid_idx`,
2344
2205
  table: TABLE_SCORERS,
2345
2206
  columns: ["traceId", "spanId", "seq_id DESC"]
2346
2207
  },
2347
- // AI Spans indexes for optimal trace querying
2208
+ // Spans indexes for optimal trace querying
2348
2209
  {
2349
2210
  name: `${schemaPrefix}mastra_ai_spans_traceid_startedat_idx`,
2350
- table: TABLE_AI_SPANS,
2211
+ table: TABLE_SPANS,
2351
2212
  columns: ["traceId", "startedAt DESC"]
2352
2213
  },
2353
2214
  {
2354
2215
  name: `${schemaPrefix}mastra_ai_spans_parentspanid_startedat_idx`,
2355
- table: TABLE_AI_SPANS,
2216
+ table: TABLE_SPANS,
2356
2217
  columns: ["parentSpanId", "startedAt DESC"]
2357
2218
  },
2358
2219
  {
2359
2220
  name: `${schemaPrefix}mastra_ai_spans_name_idx`,
2360
- table: TABLE_AI_SPANS,
2221
+ table: TABLE_SPANS,
2361
2222
  columns: ["name"]
2362
2223
  },
2363
2224
  {
2364
2225
  name: `${schemaPrefix}mastra_ai_spans_spantype_startedat_idx`,
2365
- table: TABLE_AI_SPANS,
2226
+ table: TABLE_SPANS,
2366
2227
  columns: ["spanType", "startedAt DESC"]
2367
2228
  }
2368
2229
  ];
@@ -2403,7 +2264,7 @@ function transformScoreRow(row) {
2403
2264
  metadata: safelyParseJSON(row.metadata),
2404
2265
  output: safelyParseJSON(row.output),
2405
2266
  additionalContext: safelyParseJSON(row.additionalContext),
2406
- runtimeContext: safelyParseJSON(row.runtimeContext),
2267
+ requestContext: safelyParseJSON(row.requestContext),
2407
2268
  entity: safelyParseJSON(row.entity),
2408
2269
  createdAt: row.createdAt,
2409
2270
  updatedAt: row.updatedAt
@@ -2470,7 +2331,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2470
2331
  input,
2471
2332
  output,
2472
2333
  additionalContext,
2473
- runtimeContext,
2334
+ requestContext,
2474
2335
  entity,
2475
2336
  ...rest
2476
2337
  } = validatedScore;
@@ -2485,7 +2346,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2485
2346
  analyzeStepResult: analyzeStepResult || null,
2486
2347
  metadata: metadata || null,
2487
2348
  additionalContext: additionalContext || null,
2488
- runtimeContext: runtimeContext || null,
2349
+ requestContext: requestContext || null,
2489
2350
  entity: entity || null,
2490
2351
  scorer: scorer || null,
2491
2352
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2505,7 +2366,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2505
2366
  );
2506
2367
  }
2507
2368
  }
2508
- async getScoresByScorerId({
2369
+ async listScoresByScorerId({
2509
2370
  scorerId,
2510
2371
  pagination,
2511
2372
  entityId,
@@ -2539,31 +2400,36 @@ var ScoresMSSQL = class extends ScoresStorage {
2539
2400
  });
2540
2401
  const totalResult = await countRequest.query(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`);
2541
2402
  const total = totalResult.recordset[0]?.count || 0;
2403
+ const { page, perPage: perPageInput } = pagination;
2542
2404
  if (total === 0) {
2543
2405
  return {
2544
2406
  pagination: {
2545
2407
  total: 0,
2546
- page: pagination.page,
2547
- perPage: pagination.perPage,
2408
+ page,
2409
+ perPage: perPageInput,
2548
2410
  hasMore: false
2549
2411
  },
2550
2412
  scores: []
2551
2413
  };
2552
2414
  }
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;
2553
2419
  const dataRequest = this.pool.request();
2554
2420
  Object.entries(params).forEach(([key, value]) => {
2555
2421
  dataRequest.input(key, value);
2556
2422
  });
2557
- dataRequest.input("perPage", pagination.perPage);
2558
- dataRequest.input("offset", pagination.page * pagination.perPage);
2423
+ dataRequest.input("perPage", limitValue);
2424
+ dataRequest.input("offset", start);
2559
2425
  const dataQuery = `SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY [createdAt] DESC OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
2560
2426
  const result = await dataRequest.query(dataQuery);
2561
2427
  return {
2562
2428
  pagination: {
2563
2429
  total: Number(total),
2564
- page: pagination.page,
2565
- perPage: pagination.perPage,
2566
- hasMore: Number(total) > (pagination.page + 1) * pagination.perPage
2430
+ page,
2431
+ perPage: perPageForResponse,
2432
+ hasMore: end < total
2567
2433
  },
2568
2434
  scores: result.recordset.map((row) => transformScoreRow(row))
2569
2435
  };
@@ -2579,7 +2445,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2579
2445
  );
2580
2446
  }
2581
2447
  }
2582
- async getScoresByRunId({
2448
+ async listScoresByRunId({
2583
2449
  runId,
2584
2450
  pagination
2585
2451
  }) {
@@ -2590,30 +2456,35 @@ var ScoresMSSQL = class extends ScoresStorage {
2590
2456
  `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [runId] = @p1`
2591
2457
  );
2592
2458
  const total = totalResult.recordset[0]?.count || 0;
2459
+ const { page, perPage: perPageInput } = pagination;
2593
2460
  if (total === 0) {
2594
2461
  return {
2595
2462
  pagination: {
2596
2463
  total: 0,
2597
- page: pagination.page,
2598
- perPage: pagination.perPage,
2464
+ page,
2465
+ perPage: perPageInput,
2599
2466
  hasMore: false
2600
2467
  },
2601
2468
  scores: []
2602
2469
  };
2603
2470
  }
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;
2604
2475
  const dataRequest = this.pool.request();
2605
2476
  dataRequest.input("p1", runId);
2606
- dataRequest.input("p2", pagination.perPage);
2607
- dataRequest.input("p3", pagination.page * pagination.perPage);
2477
+ dataRequest.input("p2", limitValue);
2478
+ dataRequest.input("p3", start);
2608
2479
  const result = await dataRequest.query(
2609
2480
  `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`
2610
2481
  );
2611
2482
  return {
2612
2483
  pagination: {
2613
2484
  total: Number(total),
2614
- page: pagination.page,
2615
- perPage: pagination.perPage,
2616
- hasMore: Number(total) > (pagination.page + 1) * pagination.perPage
2485
+ page,
2486
+ perPage: perPageForResponse,
2487
+ hasMore: end < total
2617
2488
  },
2618
2489
  scores: result.recordset.map((row) => transformScoreRow(row))
2619
2490
  };
@@ -2629,7 +2500,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2629
2500
  );
2630
2501
  }
2631
2502
  }
2632
- async getScoresByEntityId({
2503
+ async listScoresByEntityId({
2633
2504
  entityId,
2634
2505
  entityType,
2635
2506
  pagination
@@ -2642,31 +2513,36 @@ var ScoresMSSQL = class extends ScoresStorage {
2642
2513
  `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [entityId] = @p1 AND [entityType] = @p2`
2643
2514
  );
2644
2515
  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);
2645
2519
  if (total === 0) {
2646
2520
  return {
2647
2521
  pagination: {
2648
2522
  total: 0,
2649
- page: pagination.page,
2650
- perPage: pagination.perPage,
2523
+ page,
2524
+ perPage: perPageForResponse,
2651
2525
  hasMore: false
2652
2526
  },
2653
2527
  scores: []
2654
2528
  };
2655
2529
  }
2530
+ const limitValue = perPageInput === false ? total : perPage;
2531
+ const end = perPageInput === false ? total : start + perPage;
2656
2532
  const dataRequest = this.pool.request();
2657
2533
  dataRequest.input("p1", entityId);
2658
2534
  dataRequest.input("p2", entityType);
2659
- dataRequest.input("p3", pagination.perPage);
2660
- dataRequest.input("p4", pagination.page * pagination.perPage);
2535
+ dataRequest.input("p3", limitValue);
2536
+ dataRequest.input("p4", start);
2661
2537
  const result = await dataRequest.query(
2662
2538
  `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`
2663
2539
  );
2664
2540
  return {
2665
2541
  pagination: {
2666
2542
  total: Number(total),
2667
- page: pagination.page,
2668
- perPage: pagination.perPage,
2669
- hasMore: Number(total) > (pagination.page + 1) * pagination.perPage
2543
+ page,
2544
+ perPage: perPageForResponse,
2545
+ hasMore: end < total
2670
2546
  },
2671
2547
  scores: result.recordset.map((row) => transformScoreRow(row))
2672
2548
  };
@@ -2682,7 +2558,7 @@ var ScoresMSSQL = class extends ScoresStorage {
2682
2558
  );
2683
2559
  }
2684
2560
  }
2685
- async getScoresBySpan({
2561
+ async listScoresBySpan({
2686
2562
  traceId,
2687
2563
  spanId,
2688
2564
  pagination
@@ -2695,34 +2571,38 @@ var ScoresMSSQL = class extends ScoresStorage {
2695
2571
  `SELECT COUNT(*) as count FROM ${getTableName({ indexName: TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [traceId] = @p1 AND [spanId] = @p2`
2696
2572
  );
2697
2573
  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);
2698
2577
  if (total === 0) {
2699
2578
  return {
2700
2579
  pagination: {
2701
2580
  total: 0,
2702
- page: pagination.page,
2703
- perPage: pagination.perPage,
2581
+ page,
2582
+ perPage: perPageForResponse,
2704
2583
  hasMore: false
2705
2584
  },
2706
2585
  scores: []
2707
2586
  };
2708
2587
  }
2709
- const limit = pagination.perPage + 1;
2588
+ const limitValue = perPageInput === false ? total : perPage;
2589
+ const end = perPageInput === false ? total : start + perPage;
2710
2590
  const dataRequest = this.pool.request();
2711
2591
  dataRequest.input("p1", traceId);
2712
2592
  dataRequest.input("p2", spanId);
2713
- dataRequest.input("p3", limit);
2714
- dataRequest.input("p4", pagination.page * pagination.perPage);
2593
+ dataRequest.input("p3", limitValue);
2594
+ dataRequest.input("p4", start);
2715
2595
  const result = await dataRequest.query(
2716
2596
  `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
2597
  );
2718
2598
  return {
2719
2599
  pagination: {
2720
2600
  total: Number(total),
2721
- page: pagination.page,
2722
- perPage: pagination.perPage,
2723
- hasMore: result.recordset.length > pagination.perPage
2601
+ page,
2602
+ perPage: perPageForResponse,
2603
+ hasMore: end < total
2724
2604
  },
2725
- scores: result.recordset.slice(0, pagination.perPage).map((row) => transformScoreRow(row))
2605
+ scores: result.recordset.map((row) => transformScoreRow(row))
2726
2606
  };
2727
2607
  } catch (error) {
2728
2608
  throw new MastraError(
@@ -2737,173 +2617,6 @@ var ScoresMSSQL = class extends ScoresStorage {
2737
2617
  }
2738
2618
  }
2739
2619
  };
2740
- var TracesMSSQL = class extends TracesStorage {
2741
- pool;
2742
- operations;
2743
- schema;
2744
- constructor({
2745
- pool,
2746
- operations,
2747
- schema
2748
- }) {
2749
- super();
2750
- this.pool = pool;
2751
- this.operations = operations;
2752
- this.schema = schema;
2753
- }
2754
- /** @deprecated use getTracesPaginated instead*/
2755
- async getTraces(args) {
2756
- if (args.fromDate || args.toDate) {
2757
- args.dateRange = {
2758
- start: args.fromDate,
2759
- end: args.toDate
2760
- };
2761
- }
2762
- const result = await this.getTracesPaginated(args);
2763
- return result.traces;
2764
- }
2765
- async getTracesPaginated(args) {
2766
- const { name, scope, page = 0, perPage: perPageInput, attributes, filters, dateRange } = args;
2767
- const fromDate = dateRange?.start;
2768
- const toDate = dateRange?.end;
2769
- const perPage = perPageInput !== void 0 ? perPageInput : 100;
2770
- const currentOffset = page * perPage;
2771
- const paramMap = {};
2772
- const conditions = [];
2773
- let paramIndex = 1;
2774
- if (name) {
2775
- const paramName = `p${paramIndex++}`;
2776
- conditions.push(`[name] LIKE @${paramName}`);
2777
- paramMap[paramName] = `${name}%`;
2778
- }
2779
- if (scope) {
2780
- const paramName = `p${paramIndex++}`;
2781
- conditions.push(`[scope] = @${paramName}`);
2782
- paramMap[paramName] = scope;
2783
- }
2784
- if (attributes) {
2785
- Object.entries(attributes).forEach(([key, value]) => {
2786
- const parsedKey = parseFieldKey(key);
2787
- const paramName = `p${paramIndex++}`;
2788
- conditions.push(`JSON_VALUE([attributes], '$.${parsedKey}') = @${paramName}`);
2789
- paramMap[paramName] = value;
2790
- });
2791
- }
2792
- if (filters) {
2793
- Object.entries(filters).forEach(([key, value]) => {
2794
- const parsedKey = parseFieldKey(key);
2795
- const paramName = `p${paramIndex++}`;
2796
- conditions.push(`[${parsedKey}] = @${paramName}`);
2797
- paramMap[paramName] = value;
2798
- });
2799
- }
2800
- if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
2801
- const paramName = `p${paramIndex++}`;
2802
- conditions.push(`[createdAt] >= @${paramName}`);
2803
- paramMap[paramName] = fromDate.toISOString();
2804
- }
2805
- if (toDate instanceof Date && !isNaN(toDate.getTime())) {
2806
- const paramName = `p${paramIndex++}`;
2807
- conditions.push(`[createdAt] <= @${paramName}`);
2808
- paramMap[paramName] = toDate.toISOString();
2809
- }
2810
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2811
- const countQuery = `SELECT COUNT(*) as total FROM ${getTableName({ indexName: TABLE_TRACES, schemaName: getSchemaName(this.schema) })} ${whereClause}`;
2812
- let total = 0;
2813
- try {
2814
- const countRequest = this.pool.request();
2815
- Object.entries(paramMap).forEach(([key, value]) => {
2816
- if (value instanceof Date) {
2817
- countRequest.input(key, sql3.DateTime, value);
2818
- } else {
2819
- countRequest.input(key, value);
2820
- }
2821
- });
2822
- const countResult = await countRequest.query(countQuery);
2823
- total = parseInt(countResult.recordset[0].total, 10);
2824
- } catch (error) {
2825
- throw new MastraError(
2826
- {
2827
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TOTAL_COUNT",
2828
- domain: ErrorDomain.STORAGE,
2829
- category: ErrorCategory.THIRD_PARTY,
2830
- details: {
2831
- name: args.name ?? "",
2832
- scope: args.scope ?? ""
2833
- }
2834
- },
2835
- error
2836
- );
2837
- }
2838
- if (total === 0) {
2839
- return {
2840
- traces: [],
2841
- total: 0,
2842
- page,
2843
- perPage,
2844
- hasMore: false
2845
- };
2846
- }
2847
- 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`;
2848
- const dataRequest = this.pool.request();
2849
- Object.entries(paramMap).forEach(([key, value]) => {
2850
- if (value instanceof Date) {
2851
- dataRequest.input(key, sql3.DateTime, value);
2852
- } else {
2853
- dataRequest.input(key, value);
2854
- }
2855
- });
2856
- dataRequest.input("offset", currentOffset);
2857
- dataRequest.input("limit", perPage);
2858
- try {
2859
- const rowsResult = await dataRequest.query(dataQuery);
2860
- const rows = rowsResult.recordset;
2861
- const traces = rows.map((row) => ({
2862
- id: row.id,
2863
- parentSpanId: row.parentSpanId,
2864
- traceId: row.traceId,
2865
- name: row.name,
2866
- scope: row.scope,
2867
- kind: row.kind,
2868
- status: JSON.parse(row.status),
2869
- events: JSON.parse(row.events),
2870
- links: JSON.parse(row.links),
2871
- attributes: JSON.parse(row.attributes),
2872
- startTime: row.startTime,
2873
- endTime: row.endTime,
2874
- other: row.other,
2875
- createdAt: row.createdAt
2876
- }));
2877
- return {
2878
- traces,
2879
- total,
2880
- page,
2881
- perPage,
2882
- hasMore: currentOffset + traces.length < total
2883
- };
2884
- } catch (error) {
2885
- throw new MastraError(
2886
- {
2887
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TRACES",
2888
- domain: ErrorDomain.STORAGE,
2889
- category: ErrorCategory.THIRD_PARTY,
2890
- details: {
2891
- name: args.name ?? "",
2892
- scope: args.scope ?? ""
2893
- }
2894
- },
2895
- error
2896
- );
2897
- }
2898
- }
2899
- async batchTraceInsert({ records }) {
2900
- this.logger.debug("Batch inserting traces", { count: records.length });
2901
- await this.operations.batchInsert({
2902
- tableName: TABLE_TRACES,
2903
- records
2904
- });
2905
- }
2906
- };
2907
2620
  var WorkflowsMSSQL = class extends WorkflowsStorage {
2908
2621
  pool;
2909
2622
  operations;
@@ -2941,13 +2654,13 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2941
2654
  runId,
2942
2655
  stepId,
2943
2656
  result,
2944
- runtimeContext
2657
+ requestContext
2945
2658
  }) {
2946
2659
  const table = getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
2947
2660
  const transaction = this.pool.transaction();
2948
2661
  try {
2949
2662
  await transaction.begin();
2950
- const selectRequest = new sql3.Request(transaction);
2663
+ const selectRequest = new sql2.Request(transaction);
2951
2664
  selectRequest.input("workflow_name", workflowName);
2952
2665
  selectRequest.input("run_id", runId);
2953
2666
  const existingSnapshotResult = await selectRequest.query(
@@ -2966,20 +2679,20 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
2966
2679
  waitingPaths: {},
2967
2680
  status: "pending",
2968
2681
  runId,
2969
- runtimeContext: {}
2682
+ requestContext: {}
2970
2683
  };
2971
2684
  } else {
2972
2685
  const existingSnapshot = existingSnapshotResult.recordset[0].snapshot;
2973
2686
  snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
2974
2687
  }
2975
2688
  snapshot.context[stepId] = result;
2976
- snapshot.runtimeContext = { ...snapshot.runtimeContext, ...runtimeContext };
2977
- const upsertReq = new sql3.Request(transaction);
2689
+ snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
2690
+ const upsertReq = new sql2.Request(transaction);
2978
2691
  upsertReq.input("workflow_name", workflowName);
2979
2692
  upsertReq.input("run_id", runId);
2980
2693
  upsertReq.input("snapshot", JSON.stringify(snapshot));
2981
- upsertReq.input("createdAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2982
- upsertReq.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2694
+ upsertReq.input("createdAt", sql2.DateTime2, /* @__PURE__ */ new Date());
2695
+ upsertReq.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
2983
2696
  await upsertReq.query(
2984
2697
  `MERGE ${table} AS target
2985
2698
  USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
@@ -3019,7 +2732,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
3019
2732
  const transaction = this.pool.transaction();
3020
2733
  try {
3021
2734
  await transaction.begin();
3022
- const selectRequest = new sql3.Request(transaction);
2735
+ const selectRequest = new sql2.Request(transaction);
3023
2736
  selectRequest.input("workflow_name", workflowName);
3024
2737
  selectRequest.input("run_id", runId);
3025
2738
  const existingSnapshotResult = await selectRequest.query(
@@ -3047,11 +2760,11 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
3047
2760
  );
3048
2761
  }
3049
2762
  const updatedSnapshot = { ...snapshot, ...opts };
3050
- const updateRequest = new sql3.Request(transaction);
2763
+ const updateRequest = new sql2.Request(transaction);
3051
2764
  updateRequest.input("snapshot", JSON.stringify(updatedSnapshot));
3052
2765
  updateRequest.input("workflow_name", workflowName);
3053
2766
  updateRequest.input("run_id", runId);
3054
- updateRequest.input("updatedAt", sql3.DateTime2, /* @__PURE__ */ new Date());
2767
+ updateRequest.input("updatedAt", sql2.DateTime2, /* @__PURE__ */ new Date());
3055
2768
  await updateRequest.query(
3056
2769
  `UPDATE ${table} SET snapshot = @snapshot, [updatedAt] = @updatedAt WHERE workflow_name = @workflow_name AND run_id = @run_id`
3057
2770
  );
@@ -3090,8 +2803,8 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
3090
2803
  request.input("run_id", runId);
3091
2804
  request.input("resourceId", resourceId);
3092
2805
  request.input("snapshot", JSON.stringify(snapshot));
3093
- request.input("createdAt", sql3.DateTime2, new Date(now));
3094
- request.input("updatedAt", sql3.DateTime2, new Date(now));
2806
+ request.input("createdAt", sql2.DateTime2, new Date(now));
2807
+ request.input("updatedAt", sql2.DateTime2, new Date(now));
3095
2808
  const mergeSql = `MERGE INTO ${table} AS target
3096
2809
  USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
3097
2810
  ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
@@ -3188,12 +2901,12 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
3188
2901
  );
3189
2902
  }
3190
2903
  }
3191
- async getWorkflowRuns({
2904
+ async listWorkflowRuns({
3192
2905
  workflowName,
3193
2906
  fromDate,
3194
2907
  toDate,
3195
- limit,
3196
- offset,
2908
+ page,
2909
+ perPage,
3197
2910
  resourceId
3198
2911
  } = {}) {
3199
2912
  try {
@@ -3226,20 +2939,23 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
3226
2939
  const request = this.pool.request();
3227
2940
  Object.entries(paramMap).forEach(([key, value]) => {
3228
2941
  if (value instanceof Date) {
3229
- request.input(key, sql3.DateTime, value);
2942
+ request.input(key, sql2.DateTime, value);
3230
2943
  } else {
3231
2944
  request.input(key, value);
3232
2945
  }
3233
2946
  });
3234
- if (limit !== void 0 && offset !== void 0) {
2947
+ const usePagination = typeof perPage === "number" && typeof page === "number";
2948
+ if (usePagination) {
3235
2949
  const countQuery = `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`;
3236
2950
  const countResult = await request.query(countQuery);
3237
2951
  total = Number(countResult.recordset[0]?.count || 0);
3238
2952
  }
3239
2953
  let query = `SELECT * FROM ${tableName} ${whereClause} ORDER BY [seq_id] DESC`;
3240
- if (limit !== void 0 && offset !== void 0) {
3241
- query += ` OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`;
3242
- request.input("limit", limit);
2954
+ if (usePagination) {
2955
+ const normalizedPerPage = normalizePerPage(perPage, Number.MAX_SAFE_INTEGER);
2956
+ const offset = page * normalizedPerPage;
2957
+ query += ` OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
2958
+ request.input("perPage", normalizedPerPage);
3243
2959
  request.input("offset", offset);
3244
2960
  }
3245
2961
  const result = await request.query(query);
@@ -3248,7 +2964,7 @@ var WorkflowsMSSQL = class extends WorkflowsStorage {
3248
2964
  } catch (error) {
3249
2965
  throw new MastraError(
3250
2966
  {
3251
- id: "MASTRA_STORAGE_MSSQL_STORE_GET_WORKFLOW_RUNS_FAILED",
2967
+ id: "MASTRA_STORAGE_MSSQL_STORE_LIST_WORKFLOW_RUNS_FAILED",
3252
2968
  domain: ErrorDomain.STORAGE,
3253
2969
  category: ErrorCategory.THIRD_PARTY,
3254
2970
  details: {
@@ -3268,7 +2984,10 @@ var MSSQLStore = class extends MastraStorage {
3268
2984
  isConnected = null;
3269
2985
  stores;
3270
2986
  constructor(config) {
3271
- super({ name: "MSSQLStore" });
2987
+ if (!config.id || typeof config.id !== "string" || config.id.trim() === "") {
2988
+ throw new Error("MSSQLStore: id must be provided and cannot be empty.");
2989
+ }
2990
+ super({ id: config.id, name: "MSSQLStore" });
3272
2991
  try {
3273
2992
  if ("connectionString" in config) {
3274
2993
  if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") {
@@ -3283,7 +3002,7 @@ var MSSQLStore = class extends MastraStorage {
3283
3002
  }
3284
3003
  }
3285
3004
  this.schema = config.schemaName || "dbo";
3286
- this.pool = "connectionString" in config ? new sql3.ConnectionPool(config.connectionString) : new sql3.ConnectionPool({
3005
+ this.pool = "connectionString" in config ? new sql2.ConnectionPool(config.connectionString) : new sql2.ConnectionPool({
3287
3006
  server: config.server,
3288
3007
  database: config.database,
3289
3008
  user: config.user,
@@ -3291,19 +3010,15 @@ var MSSQLStore = class extends MastraStorage {
3291
3010
  port: config.port,
3292
3011
  options: config.options || { encrypt: true, trustServerCertificate: true }
3293
3012
  });
3294
- const legacyEvals = new LegacyEvalsMSSQL({ pool: this.pool, schema: this.schema });
3295
3013
  const operations = new StoreOperationsMSSQL({ pool: this.pool, schemaName: this.schema });
3296
3014
  const scores = new ScoresMSSQL({ pool: this.pool, operations, schema: this.schema });
3297
- const traces = new TracesMSSQL({ pool: this.pool, operations, schema: this.schema });
3298
3015
  const workflows = new WorkflowsMSSQL({ pool: this.pool, operations, schema: this.schema });
3299
3016
  const memory = new MemoryMSSQL({ pool: this.pool, schema: this.schema, operations });
3300
3017
  const observability = new ObservabilityMSSQL({ pool: this.pool, operations, schema: this.schema });
3301
3018
  this.stores = {
3302
3019
  operations,
3303
3020
  scores,
3304
- traces,
3305
3021
  workflows,
3306
- legacyEvals,
3307
3022
  memory,
3308
3023
  observability
3309
3024
  };
@@ -3357,30 +3072,11 @@ var MSSQLStore = class extends MastraStorage {
3357
3072
  hasColumn: true,
3358
3073
  createTable: true,
3359
3074
  deleteMessages: true,
3360
- getScoresBySpan: true,
3361
- aiTracing: true,
3075
+ listScoresBySpan: true,
3076
+ observabilityInstance: true,
3362
3077
  indexManagement: true
3363
3078
  };
3364
3079
  }
3365
- /** @deprecated use getEvals instead */
3366
- async getEvalsByAgentName(agentName, type) {
3367
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
3368
- }
3369
- async getEvals(options = {}) {
3370
- return this.stores.legacyEvals.getEvals(options);
3371
- }
3372
- /**
3373
- * @deprecated use getTracesPaginated instead
3374
- */
3375
- async getTraces(args) {
3376
- return this.stores.traces.getTraces(args);
3377
- }
3378
- async getTracesPaginated(args) {
3379
- return this.stores.traces.getTracesPaginated(args);
3380
- }
3381
- async batchTraceInsert({ records }) {
3382
- return this.stores.traces.batchTraceInsert({ records });
3383
- }
3384
3080
  async createTable({
3385
3081
  tableName,
3386
3082
  schema
@@ -3415,15 +3111,6 @@ var MSSQLStore = class extends MastraStorage {
3415
3111
  async getThreadById({ threadId }) {
3416
3112
  return this.stores.memory.getThreadById({ threadId });
3417
3113
  }
3418
- /**
3419
- * @deprecated use getThreadsByResourceIdPaginated instead
3420
- */
3421
- async getThreadsByResourceId(args) {
3422
- return this.stores.memory.getThreadsByResourceId(args);
3423
- }
3424
- async getThreadsByResourceIdPaginated(args) {
3425
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
3426
- }
3427
3114
  async saveThread({ thread }) {
3428
3115
  return this.stores.memory.saveThread({ thread });
3429
3116
  }
@@ -3437,17 +3124,8 @@ var MSSQLStore = class extends MastraStorage {
3437
3124
  async deleteThread({ threadId }) {
3438
3125
  return this.stores.memory.deleteThread({ threadId });
3439
3126
  }
3440
- async getMessages(args) {
3441
- return this.stores.memory.getMessages(args);
3442
- }
3443
- async getMessagesById({
3444
- messageIds,
3445
- format
3446
- }) {
3447
- return this.stores.memory.getMessagesById({ messageIds, format });
3448
- }
3449
- async getMessagesPaginated(args) {
3450
- return this.stores.memory.getMessagesPaginated(args);
3127
+ async listMessagesById({ messageIds }) {
3128
+ return this.stores.memory.listMessagesById({ messageIds });
3451
3129
  }
3452
3130
  async saveMessages(args) {
3453
3131
  return this.stores.memory.saveMessages(args);
@@ -3481,9 +3159,9 @@ var MSSQLStore = class extends MastraStorage {
3481
3159
  runId,
3482
3160
  stepId,
3483
3161
  result,
3484
- runtimeContext
3162
+ requestContext
3485
3163
  }) {
3486
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
3164
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
3487
3165
  }
3488
3166
  async updateWorkflowState({
3489
3167
  workflowName,
@@ -3506,15 +3184,15 @@ var MSSQLStore = class extends MastraStorage {
3506
3184
  }) {
3507
3185
  return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
3508
3186
  }
3509
- async getWorkflowRuns({
3187
+ async listWorkflowRuns({
3510
3188
  workflowName,
3511
3189
  fromDate,
3512
3190
  toDate,
3513
- limit,
3514
- offset,
3191
+ perPage,
3192
+ page,
3515
3193
  resourceId
3516
3194
  } = {}) {
3517
- return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
3195
+ return this.stores.workflows.listWorkflowRuns({ workflowName, fromDate, toDate, perPage, page, resourceId });
3518
3196
  }
3519
3197
  async getWorkflowRunById({
3520
3198
  runId,
@@ -3541,7 +3219,7 @@ var MSSQLStore = class extends MastraStorage {
3541
3219
  return this.stores.operations.dropIndex(indexName);
3542
3220
  }
3543
3221
  /**
3544
- * AI Tracing / Observability
3222
+ * Tracing / Observability
3545
3223
  */
3546
3224
  getObservabilityStore() {
3547
3225
  if (!this.stores.observability) {
@@ -3554,30 +3232,30 @@ var MSSQLStore = class extends MastraStorage {
3554
3232
  }
3555
3233
  return this.stores.observability;
3556
3234
  }
3557
- async createAISpan(span) {
3558
- return this.getObservabilityStore().createAISpan(span);
3235
+ async createSpan(span) {
3236
+ return this.getObservabilityStore().createSpan(span);
3559
3237
  }
3560
- async updateAISpan({
3238
+ async updateSpan({
3561
3239
  spanId,
3562
3240
  traceId,
3563
3241
  updates
3564
3242
  }) {
3565
- return this.getObservabilityStore().updateAISpan({ spanId, traceId, updates });
3243
+ return this.getObservabilityStore().updateSpan({ spanId, traceId, updates });
3566
3244
  }
3567
- async getAITrace(traceId) {
3568
- return this.getObservabilityStore().getAITrace(traceId);
3245
+ async getTrace(traceId) {
3246
+ return this.getObservabilityStore().getTrace(traceId);
3569
3247
  }
3570
- async getAITracesPaginated(args) {
3571
- return this.getObservabilityStore().getAITracesPaginated(args);
3248
+ async getTracesPaginated(args) {
3249
+ return this.getObservabilityStore().getTracesPaginated(args);
3572
3250
  }
3573
- async batchCreateAISpans(args) {
3574
- return this.getObservabilityStore().batchCreateAISpans(args);
3251
+ async batchCreateSpans(args) {
3252
+ return this.getObservabilityStore().batchCreateSpans(args);
3575
3253
  }
3576
- async batchUpdateAISpans(args) {
3577
- return this.getObservabilityStore().batchUpdateAISpans(args);
3254
+ async batchUpdateSpans(args) {
3255
+ return this.getObservabilityStore().batchUpdateSpans(args);
3578
3256
  }
3579
- async batchDeleteAITraces(args) {
3580
- return this.getObservabilityStore().batchDeleteAITraces(args);
3257
+ async batchDeleteTraces(args) {
3258
+ return this.getObservabilityStore().batchDeleteTraces(args);
3581
3259
  }
3582
3260
  /**
3583
3261
  * Scorers
@@ -3585,14 +3263,14 @@ var MSSQLStore = class extends MastraStorage {
3585
3263
  async getScoreById({ id: _id }) {
3586
3264
  return this.stores.scores.getScoreById({ id: _id });
3587
3265
  }
3588
- async getScoresByScorerId({
3266
+ async listScoresByScorerId({
3589
3267
  scorerId: _scorerId,
3590
3268
  pagination: _pagination,
3591
3269
  entityId: _entityId,
3592
3270
  entityType: _entityType,
3593
3271
  source: _source
3594
3272
  }) {
3595
- return this.stores.scores.getScoresByScorerId({
3273
+ return this.stores.scores.listScoresByScorerId({
3596
3274
  scorerId: _scorerId,
3597
3275
  pagination: _pagination,
3598
3276
  entityId: _entityId,
@@ -3603,29 +3281,29 @@ var MSSQLStore = class extends MastraStorage {
3603
3281
  async saveScore(_score) {
3604
3282
  return this.stores.scores.saveScore(_score);
3605
3283
  }
3606
- async getScoresByRunId({
3284
+ async listScoresByRunId({
3607
3285
  runId: _runId,
3608
3286
  pagination: _pagination
3609
3287
  }) {
3610
- return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
3288
+ return this.stores.scores.listScoresByRunId({ runId: _runId, pagination: _pagination });
3611
3289
  }
3612
- async getScoresByEntityId({
3290
+ async listScoresByEntityId({
3613
3291
  entityId: _entityId,
3614
3292
  entityType: _entityType,
3615
3293
  pagination: _pagination
3616
3294
  }) {
3617
- return this.stores.scores.getScoresByEntityId({
3295
+ return this.stores.scores.listScoresByEntityId({
3618
3296
  entityId: _entityId,
3619
3297
  entityType: _entityType,
3620
3298
  pagination: _pagination
3621
3299
  });
3622
3300
  }
3623
- async getScoresBySpan({
3301
+ async listScoresBySpan({
3624
3302
  traceId,
3625
3303
  spanId,
3626
3304
  pagination: _pagination
3627
3305
  }) {
3628
- return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination: _pagination });
3306
+ return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination: _pagination });
3629
3307
  }
3630
3308
  };
3631
3309