@mastra/mssql 1.0.0-beta.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +921 -0
- package/dist/docs/README.md +31 -0
- package/dist/docs/SKILL.md +32 -0
- package/dist/docs/SOURCE_MAP.json +6 -0
- package/dist/docs/storage/01-reference.md +141 -0
- package/dist/index.cjs +293 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +291 -37
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +45 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +2 -2
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +23 -0
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/utils.d.ts.map +1 -1
- package/dist/storage/index.d.ts +9 -4
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
2
|
-
import {
|
|
2
|
+
import { MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, TABLE_SCHEMAS, createStorageErrorId, normalizePerPage, calculatePagination, ObservabilityStorage, TABLE_SPANS, SPAN_SCHEMA, listTracesArgsSchema, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, MastraCompositeStore, TraceStatus, getDefaultValue, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
|
|
3
3
|
import sql from 'mssql';
|
|
4
4
|
import { MessageList } from '@mastra/core/agent';
|
|
5
5
|
import { MastraBase } from '@mastra/core/base';
|
|
@@ -334,15 +334,49 @@ ${columns}
|
|
|
334
334
|
);
|
|
335
335
|
const pkExists = Array.isArray(pkResult.recordset) && pkResult.recordset.length > 0;
|
|
336
336
|
if (!pkExists) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
337
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
338
|
+
if (duplicateInfo.hasDuplicates) {
|
|
339
|
+
const errorMessage = `
|
|
340
|
+
===========================================================================
|
|
341
|
+
MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}
|
|
342
|
+
===========================================================================
|
|
343
|
+
|
|
344
|
+
Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations.
|
|
345
|
+
|
|
346
|
+
The spans table requires a unique constraint on (traceId, spanId), but your
|
|
347
|
+
database contains duplicate entries that must be resolved first.
|
|
348
|
+
|
|
349
|
+
To fix this, run the manual migration command:
|
|
350
|
+
|
|
351
|
+
npx mastra migrate
|
|
352
|
+
|
|
353
|
+
This command will:
|
|
354
|
+
1. Remove duplicate spans (keeping the most complete/recent version)
|
|
355
|
+
2. Add the required unique constraint
|
|
356
|
+
|
|
357
|
+
Note: This migration may take some time for large tables.
|
|
358
|
+
===========================================================================
|
|
359
|
+
`;
|
|
360
|
+
throw new MastraError({
|
|
361
|
+
id: createStorageErrorId("MSSQL", "MIGRATION_REQUIRED", "DUPLICATE_SPANS"),
|
|
362
|
+
domain: ErrorDomain.STORAGE,
|
|
363
|
+
category: ErrorCategory.USER,
|
|
364
|
+
text: errorMessage
|
|
365
|
+
});
|
|
366
|
+
} else {
|
|
367
|
+
try {
|
|
368
|
+
const addPkSql = `ALTER TABLE ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} ADD CONSTRAINT [${pkConstraintName}] PRIMARY KEY ([traceId], [spanId])`;
|
|
369
|
+
await this.pool.request().query(addPkSql);
|
|
370
|
+
} catch (pkError) {
|
|
371
|
+
this.logger?.warn?.(`Failed to add composite primary key to spans table:`, pkError);
|
|
372
|
+
}
|
|
342
373
|
}
|
|
343
374
|
}
|
|
344
375
|
}
|
|
345
376
|
} catch (error) {
|
|
377
|
+
if (error instanceof MastraError) {
|
|
378
|
+
throw error;
|
|
379
|
+
}
|
|
346
380
|
throw new MastraError(
|
|
347
381
|
{
|
|
348
382
|
id: createStorageErrorId("MSSQL", "CREATE_TABLE", "FAILED"),
|
|
@@ -384,6 +418,154 @@ ${columns}
|
|
|
384
418
|
this.logger?.warn?.(`Failed to migrate spans table ${fullTableName}:`, error);
|
|
385
419
|
}
|
|
386
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Deduplicates spans with the same (traceId, spanId) combination.
|
|
423
|
+
* This is needed for databases that existed before the unique constraint was added.
|
|
424
|
+
*
|
|
425
|
+
* Priority for keeping spans:
|
|
426
|
+
* 1. Completed spans (endedAt IS NOT NULL) over incomplete spans
|
|
427
|
+
* 2. Most recent updatedAt
|
|
428
|
+
* 3. Most recent createdAt (as tiebreaker)
|
|
429
|
+
*
|
|
430
|
+
* Note: This prioritizes migration completion over perfect data preservation.
|
|
431
|
+
* Old trace data may be lost, which is acceptable for this use case.
|
|
432
|
+
*/
|
|
433
|
+
async deduplicateSpans() {
|
|
434
|
+
const fullTableName = getTableName({ indexName: TABLE_SPANS, schemaName: getSchemaName(this.schemaName) });
|
|
435
|
+
try {
|
|
436
|
+
const duplicateCheck = await this.pool.request().query(`
|
|
437
|
+
SELECT TOP 1 1 as has_duplicates
|
|
438
|
+
FROM ${fullTableName}
|
|
439
|
+
GROUP BY [traceId], [spanId]
|
|
440
|
+
HAVING COUNT(*) > 1
|
|
441
|
+
`);
|
|
442
|
+
if (!duplicateCheck.recordset || duplicateCheck.recordset.length === 0) {
|
|
443
|
+
this.logger?.debug?.(`No duplicate spans found in ${fullTableName}`);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
this.logger?.info?.(`Duplicate spans detected in ${fullTableName}, starting deduplication...`);
|
|
447
|
+
const result = await this.pool.request().query(`
|
|
448
|
+
WITH RankedSpans AS (
|
|
449
|
+
SELECT *, ROW_NUMBER() OVER (
|
|
450
|
+
PARTITION BY [traceId], [spanId]
|
|
451
|
+
ORDER BY
|
|
452
|
+
CASE WHEN [endedAt] IS NOT NULL THEN 0 ELSE 1 END,
|
|
453
|
+
[updatedAt] DESC,
|
|
454
|
+
[createdAt] DESC
|
|
455
|
+
) as rn
|
|
456
|
+
FROM ${fullTableName}
|
|
457
|
+
)
|
|
458
|
+
DELETE FROM RankedSpans WHERE rn > 1
|
|
459
|
+
`);
|
|
460
|
+
this.logger?.info?.(
|
|
461
|
+
`Deduplication complete: removed ${result.rowsAffected?.[0] ?? 0} duplicate spans from ${fullTableName}`
|
|
462
|
+
);
|
|
463
|
+
} catch (error) {
|
|
464
|
+
this.logger?.warn?.("Failed to deduplicate spans:", error);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Checks for duplicate (traceId, spanId) combinations in the spans table.
|
|
469
|
+
* Returns information about duplicates for logging/CLI purposes.
|
|
470
|
+
*/
|
|
471
|
+
async checkForDuplicateSpans() {
|
|
472
|
+
const fullTableName = getTableName({ indexName: TABLE_SPANS, schemaName: getSchemaName(this.schemaName) });
|
|
473
|
+
try {
|
|
474
|
+
const result = await this.pool.request().query(`
|
|
475
|
+
SELECT COUNT(*) as duplicate_count
|
|
476
|
+
FROM (
|
|
477
|
+
SELECT [traceId], [spanId]
|
|
478
|
+
FROM ${fullTableName}
|
|
479
|
+
GROUP BY [traceId], [spanId]
|
|
480
|
+
HAVING COUNT(*) > 1
|
|
481
|
+
) duplicates
|
|
482
|
+
`);
|
|
483
|
+
const duplicateCount = result.recordset?.[0]?.duplicate_count ?? 0;
|
|
484
|
+
return {
|
|
485
|
+
hasDuplicates: duplicateCount > 0,
|
|
486
|
+
duplicateCount,
|
|
487
|
+
tableName: fullTableName
|
|
488
|
+
};
|
|
489
|
+
} catch (error) {
|
|
490
|
+
this.logger?.debug?.(`Could not check for duplicates: ${error}`);
|
|
491
|
+
return { hasDuplicates: false, duplicateCount: 0, tableName: fullTableName };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Checks if the PRIMARY KEY constraint on (traceId, spanId) already exists on the spans table.
|
|
496
|
+
*/
|
|
497
|
+
async spansPrimaryKeyExists() {
|
|
498
|
+
const schemaPrefix = this.schemaName ? `${parseSqlIdentifier(this.schemaName, "schema name")}_` : "";
|
|
499
|
+
const pkConstraintName = `${schemaPrefix}mastra_ai_spans_traceid_spanid_pk`;
|
|
500
|
+
const checkPkRequest = this.pool.request();
|
|
501
|
+
checkPkRequest.input("constraintName", pkConstraintName);
|
|
502
|
+
const pkResult = await checkPkRequest.query(
|
|
503
|
+
`SELECT 1 AS found FROM sys.key_constraints WHERE name = @constraintName`
|
|
504
|
+
);
|
|
505
|
+
return Array.isArray(pkResult.recordset) && pkResult.recordset.length > 0;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Manually run the spans migration to deduplicate and add the unique constraint.
|
|
509
|
+
* This is intended to be called from the CLI when duplicates are detected.
|
|
510
|
+
*
|
|
511
|
+
* @returns Migration result with status and details
|
|
512
|
+
*/
|
|
513
|
+
async migrateSpans() {
|
|
514
|
+
const fullTableName = getTableName({ indexName: TABLE_SPANS, schemaName: getSchemaName(this.schemaName) });
|
|
515
|
+
const pkExists = await this.spansPrimaryKeyExists();
|
|
516
|
+
if (pkExists) {
|
|
517
|
+
return {
|
|
518
|
+
success: true,
|
|
519
|
+
alreadyMigrated: true,
|
|
520
|
+
duplicatesRemoved: 0,
|
|
521
|
+
message: `Migration already complete. PRIMARY KEY constraint exists on ${fullTableName}.`
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
525
|
+
if (duplicateInfo.hasDuplicates) {
|
|
526
|
+
this.logger?.info?.(
|
|
527
|
+
`Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations. Starting deduplication...`
|
|
528
|
+
);
|
|
529
|
+
await this.deduplicateSpans();
|
|
530
|
+
} else {
|
|
531
|
+
this.logger?.info?.(`No duplicate spans found.`);
|
|
532
|
+
}
|
|
533
|
+
const schemaPrefix = this.schemaName ? `${parseSqlIdentifier(this.schemaName, "schema name")}_` : "";
|
|
534
|
+
const pkConstraintName = `${schemaPrefix}mastra_ai_spans_traceid_spanid_pk`;
|
|
535
|
+
const addPkSql = `ALTER TABLE ${fullTableName} ADD CONSTRAINT [${pkConstraintName}] PRIMARY KEY ([traceId], [spanId])`;
|
|
536
|
+
await this.pool.request().query(addPkSql);
|
|
537
|
+
return {
|
|
538
|
+
success: true,
|
|
539
|
+
alreadyMigrated: false,
|
|
540
|
+
duplicatesRemoved: duplicateInfo.duplicateCount,
|
|
541
|
+
message: duplicateInfo.hasDuplicates ? `Migration complete. Removed duplicates and added PRIMARY KEY constraint to ${fullTableName}.` : `Migration complete. Added PRIMARY KEY constraint to ${fullTableName}.`
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Check migration status for the spans table.
|
|
546
|
+
* Returns information about whether migration is needed.
|
|
547
|
+
*/
|
|
548
|
+
async checkSpansMigrationStatus() {
|
|
549
|
+
const fullTableName = getTableName({ indexName: TABLE_SPANS, schemaName: getSchemaName(this.schemaName) });
|
|
550
|
+
const pkExists = await this.spansPrimaryKeyExists();
|
|
551
|
+
if (pkExists) {
|
|
552
|
+
return {
|
|
553
|
+
needsMigration: false,
|
|
554
|
+
hasDuplicates: false,
|
|
555
|
+
duplicateCount: 0,
|
|
556
|
+
constraintExists: true,
|
|
557
|
+
tableName: fullTableName
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
561
|
+
return {
|
|
562
|
+
needsMigration: true,
|
|
563
|
+
hasDuplicates: duplicateInfo.hasDuplicates,
|
|
564
|
+
duplicateCount: duplicateInfo.duplicateCount,
|
|
565
|
+
constraintExists: false,
|
|
566
|
+
tableName: fullTableName
|
|
567
|
+
};
|
|
568
|
+
}
|
|
387
569
|
/**
|
|
388
570
|
* Alters table schema to add columns if they don't exist
|
|
389
571
|
* @param tableName Name of the table
|
|
@@ -1010,10 +1192,12 @@ function getTableName2({ indexName, schemaName }) {
|
|
|
1010
1192
|
function buildDateRangeFilter(dateRange, fieldName) {
|
|
1011
1193
|
const filters = {};
|
|
1012
1194
|
if (dateRange?.start) {
|
|
1013
|
-
|
|
1195
|
+
const suffix = dateRange.startExclusive ? "_gt" : "_gte";
|
|
1196
|
+
filters[`${fieldName}${suffix}`] = dateRange.start;
|
|
1014
1197
|
}
|
|
1015
1198
|
if (dateRange?.end) {
|
|
1016
|
-
|
|
1199
|
+
const suffix = dateRange.endExclusive ? "_lt" : "_lte";
|
|
1200
|
+
filters[`${fieldName}${suffix}`] = dateRange.end;
|
|
1017
1201
|
}
|
|
1018
1202
|
return filters;
|
|
1019
1203
|
}
|
|
@@ -1031,11 +1215,21 @@ function prepareWhereClause(filters, _schema) {
|
|
|
1031
1215
|
const fieldName = key.slice(0, -4);
|
|
1032
1216
|
conditions.push(`[${parseSqlIdentifier(fieldName, "field name")}] >= @${paramName}`);
|
|
1033
1217
|
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
1218
|
+
} else if (key.endsWith("_gt")) {
|
|
1219
|
+
const paramName = `p${paramIndex++}`;
|
|
1220
|
+
const fieldName = key.slice(0, -3);
|
|
1221
|
+
conditions.push(`[${parseSqlIdentifier(fieldName, "field name")}] > @${paramName}`);
|
|
1222
|
+
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
1034
1223
|
} else if (key.endsWith("_lte")) {
|
|
1035
1224
|
const paramName = `p${paramIndex++}`;
|
|
1036
1225
|
const fieldName = key.slice(0, -4);
|
|
1037
1226
|
conditions.push(`[${parseSqlIdentifier(fieldName, "field name")}] <= @${paramName}`);
|
|
1038
1227
|
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
1228
|
+
} else if (key.endsWith("_lt")) {
|
|
1229
|
+
const paramName = `p${paramIndex++}`;
|
|
1230
|
+
const fieldName = key.slice(0, -3);
|
|
1231
|
+
conditions.push(`[${parseSqlIdentifier(fieldName, "field name")}] < @${paramName}`);
|
|
1232
|
+
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
1039
1233
|
} else if (value === null) {
|
|
1040
1234
|
conditions.push(`[${parseSqlIdentifier(key, "field name")}] IS NULL`);
|
|
1041
1235
|
} else if (isInOperator(value)) {
|
|
@@ -1247,28 +1441,76 @@ var MemoryMSSQL = class _MemoryMSSQL extends MemoryStorage {
|
|
|
1247
1441
|
);
|
|
1248
1442
|
}
|
|
1249
1443
|
}
|
|
1250
|
-
async
|
|
1251
|
-
const {
|
|
1252
|
-
|
|
1444
|
+
async listThreads(args) {
|
|
1445
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
1446
|
+
try {
|
|
1447
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
1448
|
+
} catch (error) {
|
|
1253
1449
|
throw new MastraError({
|
|
1254
|
-
id: createStorageErrorId("MSSQL", "
|
|
1450
|
+
id: createStorageErrorId("MSSQL", "LIST_THREADS", "INVALID_PAGE"),
|
|
1255
1451
|
domain: ErrorDomain.STORAGE,
|
|
1256
1452
|
category: ErrorCategory.USER,
|
|
1257
|
-
text:
|
|
1258
|
-
details: {
|
|
1259
|
-
resourceId,
|
|
1260
|
-
page
|
|
1261
|
-
}
|
|
1453
|
+
text: error instanceof Error ? error.message : "Invalid pagination parameters",
|
|
1454
|
+
details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
|
|
1262
1455
|
});
|
|
1263
1456
|
}
|
|
1264
1457
|
const perPage = normalizePerPage(perPageInput, 100);
|
|
1458
|
+
try {
|
|
1459
|
+
this.validateMetadataKeys(filter?.metadata);
|
|
1460
|
+
} catch (error) {
|
|
1461
|
+
throw new MastraError({
|
|
1462
|
+
id: createStorageErrorId("MSSQL", "LIST_THREADS", "INVALID_METADATA_KEY"),
|
|
1463
|
+
domain: ErrorDomain.STORAGE,
|
|
1464
|
+
category: ErrorCategory.USER,
|
|
1465
|
+
text: error instanceof Error ? error.message : "Invalid metadata key",
|
|
1466
|
+
details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1265
1469
|
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1266
1470
|
const { field, direction } = this.parseOrderBy(orderBy);
|
|
1267
1471
|
try {
|
|
1268
|
-
const
|
|
1472
|
+
const tableName = getTableName2({ indexName: TABLE_THREADS, schemaName: getSchemaName2(this.schema) });
|
|
1473
|
+
const whereClauses = [];
|
|
1474
|
+
const params = {};
|
|
1475
|
+
if (filter?.resourceId) {
|
|
1476
|
+
whereClauses.push("[resourceId] = @resourceId");
|
|
1477
|
+
params.resourceId = filter.resourceId;
|
|
1478
|
+
}
|
|
1479
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
|
|
1480
|
+
let metadataIndex = 0;
|
|
1481
|
+
for (const [key, value] of Object.entries(filter.metadata)) {
|
|
1482
|
+
if (value !== null && typeof value === "object") {
|
|
1483
|
+
throw new MastraError({
|
|
1484
|
+
id: createStorageErrorId("MSSQL", "LIST_THREADS", "INVALID_METADATA_VALUE"),
|
|
1485
|
+
domain: ErrorDomain.STORAGE,
|
|
1486
|
+
category: ErrorCategory.USER,
|
|
1487
|
+
text: `Metadata filter value for key "${key}" must be a scalar type (string, number, boolean, or null), got ${Array.isArray(value) ? "array" : "object"}`,
|
|
1488
|
+
details: { key, valueType: Array.isArray(value) ? "array" : "object" }
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1491
|
+
if (value === null) {
|
|
1492
|
+
whereClauses.push(`JSON_VALUE(metadata, '$.${key}') IS NULL`);
|
|
1493
|
+
} else {
|
|
1494
|
+
const paramName = `metadata${metadataIndex}`;
|
|
1495
|
+
whereClauses.push(`JSON_VALUE(metadata, '$.${key}') = @${paramName}`);
|
|
1496
|
+
if (typeof value === "string") {
|
|
1497
|
+
params[paramName] = value;
|
|
1498
|
+
} else if (typeof value === "boolean") {
|
|
1499
|
+
params[paramName] = value ? "true" : "false";
|
|
1500
|
+
} else {
|
|
1501
|
+
params[paramName] = String(value);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
metadataIndex++;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
|
|
1508
|
+
const baseQuery = `FROM ${tableName} ${whereClause}`;
|
|
1269
1509
|
const countQuery = `SELECT COUNT(*) as count ${baseQuery}`;
|
|
1270
1510
|
const countRequest = this.pool.request();
|
|
1271
|
-
|
|
1511
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1512
|
+
countRequest.input(key, value);
|
|
1513
|
+
}
|
|
1272
1514
|
const countResult = await countRequest.query(countQuery);
|
|
1273
1515
|
const total = parseInt(countResult.recordset[0]?.count ?? "0", 10);
|
|
1274
1516
|
if (total === 0) {
|
|
@@ -1285,7 +1527,9 @@ var MemoryMSSQL = class _MemoryMSSQL extends MemoryStorage {
|
|
|
1285
1527
|
const limitValue = perPageInput === false ? total : perPage;
|
|
1286
1528
|
const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir} OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
|
|
1287
1529
|
const dataRequest = this.pool.request();
|
|
1288
|
-
|
|
1530
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1531
|
+
dataRequest.input(key, value);
|
|
1532
|
+
}
|
|
1289
1533
|
dataRequest.input("offset", offset);
|
|
1290
1534
|
if (limitValue > 2147483647) {
|
|
1291
1535
|
dataRequest.input("perPage", sql.BigInt, limitValue);
|
|
@@ -1308,13 +1552,17 @@ var MemoryMSSQL = class _MemoryMSSQL extends MemoryStorage {
|
|
|
1308
1552
|
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
1309
1553
|
};
|
|
1310
1554
|
} catch (error) {
|
|
1555
|
+
if (error instanceof MastraError && error.category === ErrorCategory.USER) {
|
|
1556
|
+
throw error;
|
|
1557
|
+
}
|
|
1311
1558
|
const mastraError = new MastraError(
|
|
1312
1559
|
{
|
|
1313
|
-
id: createStorageErrorId("MSSQL", "
|
|
1560
|
+
id: createStorageErrorId("MSSQL", "LIST_THREADS", "FAILED"),
|
|
1314
1561
|
domain: ErrorDomain.STORAGE,
|
|
1315
1562
|
category: ErrorCategory.THIRD_PARTY,
|
|
1316
1563
|
details: {
|
|
1317
|
-
resourceId,
|
|
1564
|
+
...filter?.resourceId && { resourceId: filter.resourceId },
|
|
1565
|
+
hasMetadataFilter: !!filter?.metadata,
|
|
1318
1566
|
page
|
|
1319
1567
|
}
|
|
1320
1568
|
},
|
|
@@ -2196,6 +2444,22 @@ var ObservabilityMSSQL = class _ObservabilityMSSQL extends ObservabilityStorage
|
|
|
2196
2444
|
async dangerouslyClearAll() {
|
|
2197
2445
|
await this.db.clearTable({ tableName: TABLE_SPANS });
|
|
2198
2446
|
}
|
|
2447
|
+
/**
|
|
2448
|
+
* Manually run the spans migration to deduplicate and add the unique constraint.
|
|
2449
|
+
* This is intended to be called from the CLI when duplicates are detected.
|
|
2450
|
+
*
|
|
2451
|
+
* @returns Migration result with status and details
|
|
2452
|
+
*/
|
|
2453
|
+
async migrateSpans() {
|
|
2454
|
+
return this.db.migrateSpans();
|
|
2455
|
+
}
|
|
2456
|
+
/**
|
|
2457
|
+
* Check migration status for the spans table.
|
|
2458
|
+
* Returns information about whether migration is needed.
|
|
2459
|
+
*/
|
|
2460
|
+
async checkSpansMigrationStatus() {
|
|
2461
|
+
return this.db.checkSpansMigrationStatus();
|
|
2462
|
+
}
|
|
2199
2463
|
get tracingStrategy() {
|
|
2200
2464
|
return {
|
|
2201
2465
|
preferred: "batch-with-updates",
|
|
@@ -3595,7 +3859,7 @@ var WorkflowsMSSQL = class _WorkflowsMSSQL extends WorkflowsStorage {
|
|
|
3595
3859
|
var isPoolConfig = (config) => {
|
|
3596
3860
|
return "pool" in config;
|
|
3597
3861
|
};
|
|
3598
|
-
var MSSQLStore = class extends
|
|
3862
|
+
var MSSQLStore = class extends MastraCompositeStore {
|
|
3599
3863
|
pool;
|
|
3600
3864
|
schema;
|
|
3601
3865
|
isConnected = null;
|
|
@@ -3666,6 +3930,9 @@ var MSSQLStore = class extends MastraStorage {
|
|
|
3666
3930
|
await super.init();
|
|
3667
3931
|
} catch (error) {
|
|
3668
3932
|
this.isConnected = null;
|
|
3933
|
+
if (error instanceof MastraError) {
|
|
3934
|
+
throw error;
|
|
3935
|
+
}
|
|
3669
3936
|
throw new MastraError(
|
|
3670
3937
|
{
|
|
3671
3938
|
id: createStorageErrorId("MSSQL", "INIT", "FAILED"),
|
|
@@ -3684,19 +3951,6 @@ var MSSQLStore = class extends MastraStorage {
|
|
|
3684
3951
|
throw err;
|
|
3685
3952
|
}
|
|
3686
3953
|
}
|
|
3687
|
-
get supports() {
|
|
3688
|
-
return {
|
|
3689
|
-
selectByIncludeResourceScope: true,
|
|
3690
|
-
resourceWorkingMemory: true,
|
|
3691
|
-
hasColumn: true,
|
|
3692
|
-
createTable: true,
|
|
3693
|
-
deleteMessages: true,
|
|
3694
|
-
observability: true,
|
|
3695
|
-
indexManagement: true,
|
|
3696
|
-
listScoresBySpan: true,
|
|
3697
|
-
agents: false
|
|
3698
|
-
};
|
|
3699
|
-
}
|
|
3700
3954
|
/**
|
|
3701
3955
|
* Closes the MSSQL connection pool.
|
|
3702
3956
|
*
|
|
@@ -3707,6 +3961,6 @@ var MSSQLStore = class extends MastraStorage {
|
|
|
3707
3961
|
}
|
|
3708
3962
|
};
|
|
3709
3963
|
|
|
3710
|
-
export { MSSQLStore };
|
|
3964
|
+
export { MSSQLStore, MemoryMSSQL, ObservabilityMSSQL, ScoresMSSQL, WorkflowsMSSQL };
|
|
3711
3965
|
//# sourceMappingURL=index.js.map
|
|
3712
3966
|
//# sourceMappingURL=index.js.map
|