@mastra/mssql 0.0.0-pgvector-index-fix-20250905222058 → 0.0.0-playground-studio-cloud-20251031080052
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +167 -10
- package/README.md +315 -36
- package/dist/index.cjs +1412 -320
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1413 -321
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +44 -0
- package/dist/storage/domains/observability/index.d.ts.map +1 -0
- package/dist/storage/domains/operations/index.d.ts +67 -4
- package/dist/storage/domains/operations/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +11 -2
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/utils.d.ts +19 -0
- package/dist/storage/domains/utils.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +5 -3
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +54 -15
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/storage/domains/traces/index.d.ts +0 -37
- package/dist/storage/domains/traces/index.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
var error = require('@mastra/core/error');
|
|
4
4
|
var storage = require('@mastra/core/storage');
|
|
5
|
-
var
|
|
5
|
+
var sql3 = require('mssql');
|
|
6
6
|
var utils = require('@mastra/core/utils');
|
|
7
7
|
var agent = require('@mastra/core/agent');
|
|
8
|
+
var crypto = require('crypto');
|
|
9
|
+
var scores = require('@mastra/core/scores');
|
|
8
10
|
|
|
9
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
12
|
|
|
11
|
-
var
|
|
13
|
+
var sql3__default = /*#__PURE__*/_interopDefault(sql3);
|
|
12
14
|
|
|
13
15
|
// src/storage/index.ts
|
|
14
16
|
function getSchemaName(schema) {
|
|
@@ -20,6 +22,69 @@ function getTableName({ indexName, schemaName }) {
|
|
|
20
22
|
const quotedSchemaName = schemaName;
|
|
21
23
|
return quotedSchemaName ? `${quotedSchemaName}.${quotedIndexName}` : quotedIndexName;
|
|
22
24
|
}
|
|
25
|
+
function buildDateRangeFilter(dateRange, fieldName) {
|
|
26
|
+
const filters = {};
|
|
27
|
+
if (dateRange?.start) {
|
|
28
|
+
filters[`${fieldName}_gte`] = dateRange.start;
|
|
29
|
+
}
|
|
30
|
+
if (dateRange?.end) {
|
|
31
|
+
filters[`${fieldName}_lte`] = dateRange.end;
|
|
32
|
+
}
|
|
33
|
+
return filters;
|
|
34
|
+
}
|
|
35
|
+
function prepareWhereClause(filters, _schema) {
|
|
36
|
+
const conditions = [];
|
|
37
|
+
const params = {};
|
|
38
|
+
let paramIndex = 1;
|
|
39
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
40
|
+
if (value === void 0) return;
|
|
41
|
+
const paramName = `p${paramIndex++}`;
|
|
42
|
+
if (key.endsWith("_gte")) {
|
|
43
|
+
const fieldName = key.slice(0, -4);
|
|
44
|
+
conditions.push(`[${utils.parseSqlIdentifier(fieldName, "field name")}] >= @${paramName}`);
|
|
45
|
+
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
46
|
+
} else if (key.endsWith("_lte")) {
|
|
47
|
+
const fieldName = key.slice(0, -4);
|
|
48
|
+
conditions.push(`[${utils.parseSqlIdentifier(fieldName, "field name")}] <= @${paramName}`);
|
|
49
|
+
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
50
|
+
} else if (value === null) {
|
|
51
|
+
conditions.push(`[${utils.parseSqlIdentifier(key, "field name")}] IS NULL`);
|
|
52
|
+
} else {
|
|
53
|
+
conditions.push(`[${utils.parseSqlIdentifier(key, "field name")}] = @${paramName}`);
|
|
54
|
+
params[paramName] = value instanceof Date ? value.toISOString() : value;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
sql: conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "",
|
|
59
|
+
params
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function transformFromSqlRow({
|
|
63
|
+
tableName,
|
|
64
|
+
sqlRow
|
|
65
|
+
}) {
|
|
66
|
+
const schema = storage.TABLE_SCHEMAS[tableName];
|
|
67
|
+
const result = {};
|
|
68
|
+
Object.entries(sqlRow).forEach(([key, value]) => {
|
|
69
|
+
const columnSchema = schema?.[key];
|
|
70
|
+
if (columnSchema?.type === "jsonb" && typeof value === "string") {
|
|
71
|
+
try {
|
|
72
|
+
result[key] = JSON.parse(value);
|
|
73
|
+
} catch {
|
|
74
|
+
result[key] = value;
|
|
75
|
+
}
|
|
76
|
+
} else if (columnSchema?.type === "timestamp" && value && typeof value === "string") {
|
|
77
|
+
result[key] = new Date(value);
|
|
78
|
+
} else if (columnSchema?.type === "timestamp" && value instanceof Date) {
|
|
79
|
+
result[key] = value;
|
|
80
|
+
} else if (columnSchema?.type === "boolean") {
|
|
81
|
+
result[key] = Boolean(value);
|
|
82
|
+
} else {
|
|
83
|
+
result[key] = value;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
23
88
|
|
|
24
89
|
// src/storage/domains/legacy-evals/index.ts
|
|
25
90
|
function transformEvalRow(row) {
|
|
@@ -30,7 +95,7 @@ function transformEvalRow(row) {
|
|
|
30
95
|
} catch {
|
|
31
96
|
}
|
|
32
97
|
}
|
|
33
|
-
if (row.
|
|
98
|
+
if (row.result) {
|
|
34
99
|
try {
|
|
35
100
|
resultValue = typeof row.result === "string" ? JSON.parse(row.result) : row.result;
|
|
36
101
|
} catch {
|
|
@@ -76,7 +141,7 @@ var LegacyEvalsMSSQL = class extends storage.LegacyEvalsStorage {
|
|
|
76
141
|
if (error && error.number === 208 && error.message && error.message.includes("Invalid object name")) {
|
|
77
142
|
return [];
|
|
78
143
|
}
|
|
79
|
-
|
|
144
|
+
this.logger?.error?.("Failed to get evals for the specified agent:", error);
|
|
80
145
|
throw error;
|
|
81
146
|
}
|
|
82
147
|
}
|
|
@@ -112,7 +177,7 @@ var LegacyEvalsMSSQL = class extends storage.LegacyEvalsStorage {
|
|
|
112
177
|
const countReq = this.pool.request();
|
|
113
178
|
Object.entries(params).forEach(([key, value]) => {
|
|
114
179
|
if (value instanceof Date) {
|
|
115
|
-
countReq.input(key,
|
|
180
|
+
countReq.input(key, sql3__default.default.DateTime, value);
|
|
116
181
|
} else {
|
|
117
182
|
countReq.input(key, value);
|
|
118
183
|
}
|
|
@@ -131,7 +196,7 @@ var LegacyEvalsMSSQL = class extends storage.LegacyEvalsStorage {
|
|
|
131
196
|
const req = this.pool.request();
|
|
132
197
|
Object.entries(params).forEach(([key, value]) => {
|
|
133
198
|
if (value instanceof Date) {
|
|
134
|
-
req.input(key,
|
|
199
|
+
req.input(key, sql3__default.default.DateTime, value);
|
|
135
200
|
} else {
|
|
136
201
|
req.input(key, value);
|
|
137
202
|
}
|
|
@@ -163,7 +228,7 @@ var LegacyEvalsMSSQL = class extends storage.LegacyEvalsStorage {
|
|
|
163
228
|
error$1
|
|
164
229
|
);
|
|
165
230
|
this.logger?.error?.(mastraError.toString());
|
|
166
|
-
this.logger?.trackException(mastraError);
|
|
231
|
+
this.logger?.trackException?.(mastraError);
|
|
167
232
|
throw mastraError;
|
|
168
233
|
}
|
|
169
234
|
}
|
|
@@ -199,7 +264,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
199
264
|
}
|
|
200
265
|
async getThreadById({ threadId }) {
|
|
201
266
|
try {
|
|
202
|
-
const
|
|
267
|
+
const sql6 = `SELECT
|
|
203
268
|
id,
|
|
204
269
|
[resourceId],
|
|
205
270
|
title,
|
|
@@ -210,7 +275,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
210
275
|
WHERE id = @threadId`;
|
|
211
276
|
const request = this.pool.request();
|
|
212
277
|
request.input("threadId", threadId);
|
|
213
|
-
const resultSet = await request.query(
|
|
278
|
+
const resultSet = await request.query(sql6);
|
|
214
279
|
const thread = resultSet.recordset[0] || null;
|
|
215
280
|
if (!thread) {
|
|
216
281
|
return null;
|
|
@@ -256,7 +321,8 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
256
321
|
};
|
|
257
322
|
}
|
|
258
323
|
const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
|
|
259
|
-
const
|
|
324
|
+
const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
|
|
325
|
+
const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir} OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
|
|
260
326
|
const dataRequest = this.pool.request();
|
|
261
327
|
dataRequest.input("resourceId", resourceId);
|
|
262
328
|
dataRequest.input("perPage", perPage);
|
|
@@ -313,9 +379,14 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
313
379
|
req.input("id", thread.id);
|
|
314
380
|
req.input("resourceId", thread.resourceId);
|
|
315
381
|
req.input("title", thread.title);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
382
|
+
const metadata = thread.metadata ? JSON.stringify(thread.metadata) : null;
|
|
383
|
+
if (metadata === null) {
|
|
384
|
+
req.input("metadata", sql3__default.default.NVarChar, null);
|
|
385
|
+
} else {
|
|
386
|
+
req.input("metadata", metadata);
|
|
387
|
+
}
|
|
388
|
+
req.input("createdAt", sql3__default.default.DateTime2, thread.createdAt);
|
|
389
|
+
req.input("updatedAt", sql3__default.default.DateTime2, thread.updatedAt);
|
|
319
390
|
await req.query(mergeSql);
|
|
320
391
|
return thread;
|
|
321
392
|
} catch (error$1) {
|
|
@@ -340,7 +411,8 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
340
411
|
try {
|
|
341
412
|
const baseQuery = `FROM ${getTableName({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName(this.schema) })} WHERE [resourceId] = @resourceId`;
|
|
342
413
|
const orderByField = orderBy === "createdAt" ? "[createdAt]" : "[updatedAt]";
|
|
343
|
-
const
|
|
414
|
+
const dir = (sortDirection || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC";
|
|
415
|
+
const dataQuery = `SELECT id, [resourceId], title, metadata, [createdAt], [updatedAt] ${baseQuery} ORDER BY ${orderByField} ${dir}`;
|
|
344
416
|
const request = this.pool.request();
|
|
345
417
|
request.input("resourceId", resourceId);
|
|
346
418
|
const resultSet = await request.query(dataQuery);
|
|
@@ -383,7 +455,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
383
455
|
};
|
|
384
456
|
try {
|
|
385
457
|
const table = getTableName({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName(this.schema) });
|
|
386
|
-
const
|
|
458
|
+
const sql6 = `UPDATE ${table}
|
|
387
459
|
SET title = @title,
|
|
388
460
|
metadata = @metadata,
|
|
389
461
|
[updatedAt] = @updatedAt
|
|
@@ -394,7 +466,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
394
466
|
req.input("title", title);
|
|
395
467
|
req.input("metadata", JSON.stringify(mergedMetadata));
|
|
396
468
|
req.input("updatedAt", /* @__PURE__ */ new Date());
|
|
397
|
-
const result = await req.query(
|
|
469
|
+
const result = await req.query(sql6);
|
|
398
470
|
let thread = result.recordset && result.recordset[0];
|
|
399
471
|
if (thread && "seq_id" in thread) {
|
|
400
472
|
const { seq_id, ...rest } = thread;
|
|
@@ -589,7 +661,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
589
661
|
error$1
|
|
590
662
|
);
|
|
591
663
|
this.logger?.error?.(mastraError.toString());
|
|
592
|
-
this.logger?.trackException(mastraError);
|
|
664
|
+
this.logger?.trackException?.(mastraError);
|
|
593
665
|
return [];
|
|
594
666
|
}
|
|
595
667
|
}
|
|
@@ -629,7 +701,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
629
701
|
error$1
|
|
630
702
|
);
|
|
631
703
|
this.logger?.error?.(mastraError.toString());
|
|
632
|
-
this.logger?.trackException(mastraError);
|
|
704
|
+
this.logger?.trackException?.(mastraError);
|
|
633
705
|
return [];
|
|
634
706
|
}
|
|
635
707
|
}
|
|
@@ -691,7 +763,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
691
763
|
const parsed = this._parseAndFormatMessages(messages, format);
|
|
692
764
|
return {
|
|
693
765
|
messages: parsed,
|
|
694
|
-
total
|
|
766
|
+
total,
|
|
695
767
|
page,
|
|
696
768
|
perPage,
|
|
697
769
|
hasMore: currentOffset + rows.length < total
|
|
@@ -711,7 +783,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
711
783
|
error$1
|
|
712
784
|
);
|
|
713
785
|
this.logger?.error?.(mastraError.toString());
|
|
714
|
-
this.logger?.trackException(mastraError);
|
|
786
|
+
this.logger?.trackException?.(mastraError);
|
|
715
787
|
return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
|
|
716
788
|
}
|
|
717
789
|
}
|
|
@@ -763,7 +835,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
763
835
|
"content",
|
|
764
836
|
typeof message.content === "string" ? message.content : JSON.stringify(message.content)
|
|
765
837
|
);
|
|
766
|
-
request.input("createdAt",
|
|
838
|
+
request.input("createdAt", sql3__default.default.DateTime2, message.createdAt);
|
|
767
839
|
request.input("role", message.role);
|
|
768
840
|
request.input("type", message.type || "v2");
|
|
769
841
|
request.input("resourceId", message.resourceId);
|
|
@@ -782,7 +854,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
782
854
|
await request.query(mergeSql);
|
|
783
855
|
}
|
|
784
856
|
const threadReq = transaction.request();
|
|
785
|
-
threadReq.input("updatedAt",
|
|
857
|
+
threadReq.input("updatedAt", sql3__default.default.DateTime2, /* @__PURE__ */ new Date());
|
|
786
858
|
threadReq.input("id", threadId);
|
|
787
859
|
await threadReq.query(`UPDATE ${tableThreads} SET [updatedAt] = @updatedAt WHERE id = @id`);
|
|
788
860
|
await transaction.commit();
|
|
@@ -978,8 +1050,10 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
978
1050
|
return null;
|
|
979
1051
|
}
|
|
980
1052
|
return {
|
|
981
|
-
|
|
982
|
-
|
|
1053
|
+
id: result.id,
|
|
1054
|
+
createdAt: result.createdAt,
|
|
1055
|
+
updatedAt: result.updatedAt,
|
|
1056
|
+
workingMemory: result.workingMemory,
|
|
983
1057
|
metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
|
|
984
1058
|
};
|
|
985
1059
|
} catch (error$1) {
|
|
@@ -993,7 +1067,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
993
1067
|
error$1
|
|
994
1068
|
);
|
|
995
1069
|
this.logger?.error?.(mastraError.toString());
|
|
996
|
-
this.logger?.trackException(mastraError);
|
|
1070
|
+
this.logger?.trackException?.(mastraError);
|
|
997
1071
|
throw mastraError;
|
|
998
1072
|
}
|
|
999
1073
|
}
|
|
@@ -1002,7 +1076,7 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
1002
1076
|
tableName: storage.TABLE_RESOURCES,
|
|
1003
1077
|
record: {
|
|
1004
1078
|
...resource,
|
|
1005
|
-
metadata:
|
|
1079
|
+
metadata: resource.metadata
|
|
1006
1080
|
}
|
|
1007
1081
|
});
|
|
1008
1082
|
return resource;
|
|
@@ -1060,20 +1134,337 @@ var MemoryMSSQL = class extends storage.MemoryStorage {
|
|
|
1060
1134
|
error$1
|
|
1061
1135
|
);
|
|
1062
1136
|
this.logger?.error?.(mastraError.toString());
|
|
1063
|
-
this.logger?.trackException(mastraError);
|
|
1137
|
+
this.logger?.trackException?.(mastraError);
|
|
1064
1138
|
throw mastraError;
|
|
1065
1139
|
}
|
|
1066
1140
|
}
|
|
1067
1141
|
};
|
|
1142
|
+
var ObservabilityMSSQL = class extends storage.ObservabilityStorage {
|
|
1143
|
+
pool;
|
|
1144
|
+
operations;
|
|
1145
|
+
schema;
|
|
1146
|
+
constructor({
|
|
1147
|
+
pool,
|
|
1148
|
+
operations,
|
|
1149
|
+
schema
|
|
1150
|
+
}) {
|
|
1151
|
+
super();
|
|
1152
|
+
this.pool = pool;
|
|
1153
|
+
this.operations = operations;
|
|
1154
|
+
this.schema = schema;
|
|
1155
|
+
}
|
|
1156
|
+
get aiTracingStrategy() {
|
|
1157
|
+
return {
|
|
1158
|
+
preferred: "batch-with-updates",
|
|
1159
|
+
supported: ["batch-with-updates", "insert-only"]
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
async createAISpan(span) {
|
|
1163
|
+
try {
|
|
1164
|
+
const startedAt = span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt;
|
|
1165
|
+
const endedAt = span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt;
|
|
1166
|
+
const record = {
|
|
1167
|
+
...span,
|
|
1168
|
+
startedAt,
|
|
1169
|
+
endedAt
|
|
1170
|
+
// Note: createdAt/updatedAt will be set by default values
|
|
1171
|
+
};
|
|
1172
|
+
return this.operations.insert({ tableName: storage.TABLE_AI_SPANS, record });
|
|
1173
|
+
} catch (error$1) {
|
|
1174
|
+
throw new error.MastraError(
|
|
1175
|
+
{
|
|
1176
|
+
id: "MSSQL_STORE_CREATE_AI_SPAN_FAILED",
|
|
1177
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1178
|
+
category: error.ErrorCategory.USER,
|
|
1179
|
+
details: {
|
|
1180
|
+
spanId: span.spanId,
|
|
1181
|
+
traceId: span.traceId,
|
|
1182
|
+
spanType: span.spanType,
|
|
1183
|
+
spanName: span.name
|
|
1184
|
+
}
|
|
1185
|
+
},
|
|
1186
|
+
error$1
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
async getAITrace(traceId) {
|
|
1191
|
+
try {
|
|
1192
|
+
const tableName = getTableName({
|
|
1193
|
+
indexName: storage.TABLE_AI_SPANS,
|
|
1194
|
+
schemaName: getSchemaName(this.schema)
|
|
1195
|
+
});
|
|
1196
|
+
const request = this.pool.request();
|
|
1197
|
+
request.input("traceId", traceId);
|
|
1198
|
+
const result = await request.query(
|
|
1199
|
+
`SELECT
|
|
1200
|
+
[traceId], [spanId], [parentSpanId], [name], [scope], [spanType],
|
|
1201
|
+
[attributes], [metadata], [links], [input], [output], [error], [isEvent],
|
|
1202
|
+
[startedAt], [endedAt], [createdAt], [updatedAt]
|
|
1203
|
+
FROM ${tableName}
|
|
1204
|
+
WHERE [traceId] = @traceId
|
|
1205
|
+
ORDER BY [startedAt] DESC`
|
|
1206
|
+
);
|
|
1207
|
+
if (!result.recordset || result.recordset.length === 0) {
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1210
|
+
return {
|
|
1211
|
+
traceId,
|
|
1212
|
+
spans: result.recordset.map(
|
|
1213
|
+
(span) => transformFromSqlRow({
|
|
1214
|
+
tableName: storage.TABLE_AI_SPANS,
|
|
1215
|
+
sqlRow: span
|
|
1216
|
+
})
|
|
1217
|
+
)
|
|
1218
|
+
};
|
|
1219
|
+
} catch (error$1) {
|
|
1220
|
+
throw new error.MastraError(
|
|
1221
|
+
{
|
|
1222
|
+
id: "MSSQL_STORE_GET_AI_TRACE_FAILED",
|
|
1223
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1224
|
+
category: error.ErrorCategory.USER,
|
|
1225
|
+
details: {
|
|
1226
|
+
traceId
|
|
1227
|
+
}
|
|
1228
|
+
},
|
|
1229
|
+
error$1
|
|
1230
|
+
);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
async updateAISpan({
|
|
1234
|
+
spanId,
|
|
1235
|
+
traceId,
|
|
1236
|
+
updates
|
|
1237
|
+
}) {
|
|
1238
|
+
try {
|
|
1239
|
+
const data = { ...updates };
|
|
1240
|
+
if (data.endedAt instanceof Date) {
|
|
1241
|
+
data.endedAt = data.endedAt.toISOString();
|
|
1242
|
+
}
|
|
1243
|
+
if (data.startedAt instanceof Date) {
|
|
1244
|
+
data.startedAt = data.startedAt.toISOString();
|
|
1245
|
+
}
|
|
1246
|
+
await this.operations.update({
|
|
1247
|
+
tableName: storage.TABLE_AI_SPANS,
|
|
1248
|
+
keys: { spanId, traceId },
|
|
1249
|
+
data
|
|
1250
|
+
});
|
|
1251
|
+
} catch (error$1) {
|
|
1252
|
+
throw new error.MastraError(
|
|
1253
|
+
{
|
|
1254
|
+
id: "MSSQL_STORE_UPDATE_AI_SPAN_FAILED",
|
|
1255
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1256
|
+
category: error.ErrorCategory.USER,
|
|
1257
|
+
details: {
|
|
1258
|
+
spanId,
|
|
1259
|
+
traceId
|
|
1260
|
+
}
|
|
1261
|
+
},
|
|
1262
|
+
error$1
|
|
1263
|
+
);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
async getAITracesPaginated({
|
|
1267
|
+
filters,
|
|
1268
|
+
pagination
|
|
1269
|
+
}) {
|
|
1270
|
+
const page = pagination?.page ?? 0;
|
|
1271
|
+
const perPage = pagination?.perPage ?? 10;
|
|
1272
|
+
const { entityId, entityType, ...actualFilters } = filters || {};
|
|
1273
|
+
const filtersWithDateRange = {
|
|
1274
|
+
...actualFilters,
|
|
1275
|
+
...buildDateRangeFilter(pagination?.dateRange, "startedAt"),
|
|
1276
|
+
parentSpanId: null
|
|
1277
|
+
// Only get root spans for traces
|
|
1278
|
+
};
|
|
1279
|
+
const whereClause = prepareWhereClause(filtersWithDateRange);
|
|
1280
|
+
let actualWhereClause = whereClause.sql;
|
|
1281
|
+
const params = { ...whereClause.params };
|
|
1282
|
+
let currentParamIndex = Object.keys(params).length + 1;
|
|
1283
|
+
if (entityId && entityType) {
|
|
1284
|
+
let name = "";
|
|
1285
|
+
if (entityType === "workflow") {
|
|
1286
|
+
name = `workflow run: '${entityId}'`;
|
|
1287
|
+
} else if (entityType === "agent") {
|
|
1288
|
+
name = `agent run: '${entityId}'`;
|
|
1289
|
+
} else {
|
|
1290
|
+
const error$1 = new error.MastraError({
|
|
1291
|
+
id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
|
|
1292
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1293
|
+
category: error.ErrorCategory.USER,
|
|
1294
|
+
details: {
|
|
1295
|
+
entityType
|
|
1296
|
+
},
|
|
1297
|
+
text: `Cannot filter by entity type: ${entityType}`
|
|
1298
|
+
});
|
|
1299
|
+
throw error$1;
|
|
1300
|
+
}
|
|
1301
|
+
const entityParam = `p${currentParamIndex++}`;
|
|
1302
|
+
if (actualWhereClause) {
|
|
1303
|
+
actualWhereClause += ` AND [name] = @${entityParam}`;
|
|
1304
|
+
} else {
|
|
1305
|
+
actualWhereClause = ` WHERE [name] = @${entityParam}`;
|
|
1306
|
+
}
|
|
1307
|
+
params[entityParam] = name;
|
|
1308
|
+
}
|
|
1309
|
+
const tableName = getTableName({
|
|
1310
|
+
indexName: storage.TABLE_AI_SPANS,
|
|
1311
|
+
schemaName: getSchemaName(this.schema)
|
|
1312
|
+
});
|
|
1313
|
+
try {
|
|
1314
|
+
const countRequest = this.pool.request();
|
|
1315
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
1316
|
+
countRequest.input(key, value);
|
|
1317
|
+
});
|
|
1318
|
+
const countResult = await countRequest.query(
|
|
1319
|
+
`SELECT COUNT(*) as count FROM ${tableName}${actualWhereClause}`
|
|
1320
|
+
);
|
|
1321
|
+
const total = countResult.recordset[0]?.count ?? 0;
|
|
1322
|
+
if (total === 0) {
|
|
1323
|
+
return {
|
|
1324
|
+
pagination: {
|
|
1325
|
+
total: 0,
|
|
1326
|
+
page,
|
|
1327
|
+
perPage,
|
|
1328
|
+
hasMore: false
|
|
1329
|
+
},
|
|
1330
|
+
spans: []
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
const dataRequest = this.pool.request();
|
|
1334
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
1335
|
+
dataRequest.input(key, value);
|
|
1336
|
+
});
|
|
1337
|
+
dataRequest.input("offset", page * perPage);
|
|
1338
|
+
dataRequest.input("limit", perPage);
|
|
1339
|
+
const dataResult = await dataRequest.query(
|
|
1340
|
+
`SELECT * FROM ${tableName}${actualWhereClause} ORDER BY [startedAt] DESC OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`
|
|
1341
|
+
);
|
|
1342
|
+
const spans = dataResult.recordset.map(
|
|
1343
|
+
(row) => transformFromSqlRow({
|
|
1344
|
+
tableName: storage.TABLE_AI_SPANS,
|
|
1345
|
+
sqlRow: row
|
|
1346
|
+
})
|
|
1347
|
+
);
|
|
1348
|
+
return {
|
|
1349
|
+
pagination: {
|
|
1350
|
+
total,
|
|
1351
|
+
page,
|
|
1352
|
+
perPage,
|
|
1353
|
+
hasMore: (page + 1) * perPage < total
|
|
1354
|
+
},
|
|
1355
|
+
spans
|
|
1356
|
+
};
|
|
1357
|
+
} catch (error$1) {
|
|
1358
|
+
throw new error.MastraError(
|
|
1359
|
+
{
|
|
1360
|
+
id: "MSSQL_STORE_GET_AI_TRACES_PAGINATED_FAILED",
|
|
1361
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1362
|
+
category: error.ErrorCategory.USER
|
|
1363
|
+
},
|
|
1364
|
+
error$1
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
async batchCreateAISpans(args) {
|
|
1369
|
+
if (!args.records || args.records.length === 0) {
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
try {
|
|
1373
|
+
await this.operations.batchInsert({
|
|
1374
|
+
tableName: storage.TABLE_AI_SPANS,
|
|
1375
|
+
records: args.records.map((span) => ({
|
|
1376
|
+
...span,
|
|
1377
|
+
startedAt: span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt,
|
|
1378
|
+
endedAt: span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt
|
|
1379
|
+
}))
|
|
1380
|
+
});
|
|
1381
|
+
} catch (error$1) {
|
|
1382
|
+
throw new error.MastraError(
|
|
1383
|
+
{
|
|
1384
|
+
id: "MSSQL_STORE_BATCH_CREATE_AI_SPANS_FAILED",
|
|
1385
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1386
|
+
category: error.ErrorCategory.USER,
|
|
1387
|
+
details: {
|
|
1388
|
+
count: args.records.length
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
error$1
|
|
1392
|
+
);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
async batchUpdateAISpans(args) {
|
|
1396
|
+
if (!args.records || args.records.length === 0) {
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
try {
|
|
1400
|
+
const updates = args.records.map(({ traceId, spanId, updates: data }) => {
|
|
1401
|
+
const processedData = { ...data };
|
|
1402
|
+
if (processedData.endedAt instanceof Date) {
|
|
1403
|
+
processedData.endedAt = processedData.endedAt.toISOString();
|
|
1404
|
+
}
|
|
1405
|
+
if (processedData.startedAt instanceof Date) {
|
|
1406
|
+
processedData.startedAt = processedData.startedAt.toISOString();
|
|
1407
|
+
}
|
|
1408
|
+
return {
|
|
1409
|
+
keys: { spanId, traceId },
|
|
1410
|
+
data: processedData
|
|
1411
|
+
};
|
|
1412
|
+
});
|
|
1413
|
+
await this.operations.batchUpdate({
|
|
1414
|
+
tableName: storage.TABLE_AI_SPANS,
|
|
1415
|
+
updates
|
|
1416
|
+
});
|
|
1417
|
+
} catch (error$1) {
|
|
1418
|
+
throw new error.MastraError(
|
|
1419
|
+
{
|
|
1420
|
+
id: "MSSQL_STORE_BATCH_UPDATE_AI_SPANS_FAILED",
|
|
1421
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1422
|
+
category: error.ErrorCategory.USER,
|
|
1423
|
+
details: {
|
|
1424
|
+
count: args.records.length
|
|
1425
|
+
}
|
|
1426
|
+
},
|
|
1427
|
+
error$1
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
async batchDeleteAITraces(args) {
|
|
1432
|
+
if (!args.traceIds || args.traceIds.length === 0) {
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
try {
|
|
1436
|
+
const keys = args.traceIds.map((traceId) => ({ traceId }));
|
|
1437
|
+
await this.operations.batchDelete({
|
|
1438
|
+
tableName: storage.TABLE_AI_SPANS,
|
|
1439
|
+
keys
|
|
1440
|
+
});
|
|
1441
|
+
} catch (error$1) {
|
|
1442
|
+
throw new error.MastraError(
|
|
1443
|
+
{
|
|
1444
|
+
id: "MSSQL_STORE_BATCH_DELETE_AI_TRACES_FAILED",
|
|
1445
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1446
|
+
category: error.ErrorCategory.USER,
|
|
1447
|
+
details: {
|
|
1448
|
+
count: args.traceIds.length
|
|
1449
|
+
}
|
|
1450
|
+
},
|
|
1451
|
+
error$1
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1068
1456
|
var StoreOperationsMSSQL = class extends storage.StoreOperations {
|
|
1069
1457
|
pool;
|
|
1070
1458
|
schemaName;
|
|
1071
1459
|
setupSchemaPromise = null;
|
|
1072
1460
|
schemaSetupComplete = void 0;
|
|
1073
|
-
getSqlType(type, isPrimaryKey = false) {
|
|
1461
|
+
getSqlType(type, isPrimaryKey = false, useLargeStorage = false) {
|
|
1074
1462
|
switch (type) {
|
|
1075
1463
|
case "text":
|
|
1076
|
-
|
|
1464
|
+
if (useLargeStorage) {
|
|
1465
|
+
return "NVARCHAR(MAX)";
|
|
1466
|
+
}
|
|
1467
|
+
return isPrimaryKey ? "NVARCHAR(255)" : "NVARCHAR(400)";
|
|
1077
1468
|
case "timestamp":
|
|
1078
1469
|
return "DATETIME2(7)";
|
|
1079
1470
|
case "uuid":
|
|
@@ -1086,6 +1477,8 @@ var StoreOperationsMSSQL = class extends storage.StoreOperations {
|
|
|
1086
1477
|
return "BIGINT";
|
|
1087
1478
|
case "float":
|
|
1088
1479
|
return "FLOAT";
|
|
1480
|
+
case "boolean":
|
|
1481
|
+
return "BIT";
|
|
1089
1482
|
default:
|
|
1090
1483
|
throw new error.MastraError({
|
|
1091
1484
|
id: "MASTRA_STORAGE_MSSQL_STORE_TYPE_NOT_SUPPORTED",
|
|
@@ -1148,20 +1541,26 @@ var StoreOperationsMSSQL = class extends storage.StoreOperations {
|
|
|
1148
1541
|
}
|
|
1149
1542
|
await this.setupSchemaPromise;
|
|
1150
1543
|
}
|
|
1151
|
-
async insert({
|
|
1544
|
+
async insert({
|
|
1545
|
+
tableName,
|
|
1546
|
+
record,
|
|
1547
|
+
transaction
|
|
1548
|
+
}) {
|
|
1152
1549
|
try {
|
|
1153
|
-
const columns = Object.keys(record)
|
|
1154
|
-
const
|
|
1155
|
-
const paramNames =
|
|
1156
|
-
const insertSql = `INSERT INTO ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} (${
|
|
1157
|
-
const request = this.pool.request();
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
request.input(`param${i}`,
|
|
1550
|
+
const columns = Object.keys(record);
|
|
1551
|
+
const parsedColumns = columns.map((col) => utils.parseSqlIdentifier(col, "column name"));
|
|
1552
|
+
const paramNames = columns.map((_, i) => `@param${i}`);
|
|
1553
|
+
const insertSql = `INSERT INTO ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} (${parsedColumns.map((c) => `[${c}]`).join(", ")}) VALUES (${paramNames.join(", ")})`;
|
|
1554
|
+
const request = transaction ? transaction.request() : this.pool.request();
|
|
1555
|
+
columns.forEach((col, i) => {
|
|
1556
|
+
const value = record[col];
|
|
1557
|
+
const preparedValue = this.prepareValue(value, col, tableName);
|
|
1558
|
+
if (preparedValue instanceof Date) {
|
|
1559
|
+
request.input(`param${i}`, sql3__default.default.DateTime2, preparedValue);
|
|
1560
|
+
} else if (preparedValue === null || preparedValue === void 0) {
|
|
1561
|
+
request.input(`param${i}`, this.getMssqlType(tableName, col), null);
|
|
1163
1562
|
} else {
|
|
1164
|
-
request.input(`param${i}`,
|
|
1563
|
+
request.input(`param${i}`, preparedValue);
|
|
1165
1564
|
}
|
|
1166
1565
|
});
|
|
1167
1566
|
await request.query(insertSql);
|
|
@@ -1185,7 +1584,7 @@ var StoreOperationsMSSQL = class extends storage.StoreOperations {
|
|
|
1185
1584
|
try {
|
|
1186
1585
|
await this.pool.request().query(`TRUNCATE TABLE ${fullTableName}`);
|
|
1187
1586
|
} catch (truncateError) {
|
|
1188
|
-
if (truncateError
|
|
1587
|
+
if (truncateError?.number === 4712) {
|
|
1189
1588
|
await this.pool.request().query(`DELETE FROM ${fullTableName}`);
|
|
1190
1589
|
} else {
|
|
1191
1590
|
throw truncateError;
|
|
@@ -1208,9 +1607,11 @@ var StoreOperationsMSSQL = class extends storage.StoreOperations {
|
|
|
1208
1607
|
getDefaultValue(type) {
|
|
1209
1608
|
switch (type) {
|
|
1210
1609
|
case "timestamp":
|
|
1211
|
-
return "DEFAULT
|
|
1610
|
+
return "DEFAULT SYSUTCDATETIME()";
|
|
1212
1611
|
case "jsonb":
|
|
1213
1612
|
return "DEFAULT N'{}'";
|
|
1613
|
+
case "boolean":
|
|
1614
|
+
return "DEFAULT 0";
|
|
1214
1615
|
default:
|
|
1215
1616
|
return super.getDefaultValue(type);
|
|
1216
1617
|
}
|
|
@@ -1221,13 +1622,29 @@ var StoreOperationsMSSQL = class extends storage.StoreOperations {
|
|
|
1221
1622
|
}) {
|
|
1222
1623
|
try {
|
|
1223
1624
|
const uniqueConstraintColumns = tableName === storage.TABLE_WORKFLOW_SNAPSHOT ? ["workflow_name", "run_id"] : [];
|
|
1625
|
+
const largeDataColumns = [
|
|
1626
|
+
"workingMemory",
|
|
1627
|
+
"snapshot",
|
|
1628
|
+
"metadata",
|
|
1629
|
+
"content",
|
|
1630
|
+
// messages.content - can be very long conversation content
|
|
1631
|
+
"input",
|
|
1632
|
+
// evals.input - test input data
|
|
1633
|
+
"output",
|
|
1634
|
+
// evals.output - test output data
|
|
1635
|
+
"instructions",
|
|
1636
|
+
// evals.instructions - evaluation instructions
|
|
1637
|
+
"other"
|
|
1638
|
+
// traces.other - additional trace data
|
|
1639
|
+
];
|
|
1224
1640
|
const columns = Object.entries(schema).map(([name, def]) => {
|
|
1225
1641
|
const parsedName = utils.parseSqlIdentifier(name, "column name");
|
|
1226
1642
|
const constraints = [];
|
|
1227
1643
|
if (def.primaryKey) constraints.push("PRIMARY KEY");
|
|
1228
1644
|
if (!def.nullable) constraints.push("NOT NULL");
|
|
1229
1645
|
const isIndexed = !!def.primaryKey || uniqueConstraintColumns.includes(name);
|
|
1230
|
-
|
|
1646
|
+
const useLargeStorage = largeDataColumns.includes(name);
|
|
1647
|
+
return `[${parsedName}] ${this.getSqlType(def.type, isIndexed, useLargeStorage)} ${constraints.join(" ")}`.trim();
|
|
1231
1648
|
}).join(",\n");
|
|
1232
1649
|
if (this.schemaName) {
|
|
1233
1650
|
await this.setupSchema();
|
|
@@ -1314,7 +1731,19 @@ ${columns}
|
|
|
1314
1731
|
const columnExists = Array.isArray(checkResult.recordset) && checkResult.recordset.length > 0;
|
|
1315
1732
|
if (!columnExists) {
|
|
1316
1733
|
const columnDef = schema[columnName];
|
|
1317
|
-
const
|
|
1734
|
+
const largeDataColumns = [
|
|
1735
|
+
"workingMemory",
|
|
1736
|
+
"snapshot",
|
|
1737
|
+
"metadata",
|
|
1738
|
+
"content",
|
|
1739
|
+
"input",
|
|
1740
|
+
"output",
|
|
1741
|
+
"instructions",
|
|
1742
|
+
"other"
|
|
1743
|
+
];
|
|
1744
|
+
const useLargeStorage = largeDataColumns.includes(columnName);
|
|
1745
|
+
const isIndexed = !!columnDef.primaryKey;
|
|
1746
|
+
const sqlType = this.getSqlType(columnDef.type, isIndexed, useLargeStorage);
|
|
1318
1747
|
const nullable = columnDef.nullable === false ? "NOT NULL" : "";
|
|
1319
1748
|
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
1320
1749
|
const parsedColumnName = utils.parseSqlIdentifier(columnName, "column name");
|
|
@@ -1342,13 +1771,17 @@ ${columns}
|
|
|
1342
1771
|
try {
|
|
1343
1772
|
const keyEntries = Object.entries(keys).map(([key, value]) => [utils.parseSqlIdentifier(key, "column name"), value]);
|
|
1344
1773
|
const conditions = keyEntries.map(([key], i) => `[${key}] = @param${i}`).join(" AND ");
|
|
1345
|
-
const
|
|
1346
|
-
const sql7 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
|
|
1774
|
+
const sql6 = `SELECT * FROM ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} WHERE ${conditions}`;
|
|
1347
1775
|
const request = this.pool.request();
|
|
1348
|
-
|
|
1349
|
-
|
|
1776
|
+
keyEntries.forEach(([key, value], i) => {
|
|
1777
|
+
const preparedValue = this.prepareValue(value, key, tableName);
|
|
1778
|
+
if (preparedValue === null || preparedValue === void 0) {
|
|
1779
|
+
request.input(`param${i}`, this.getMssqlType(tableName, key), null);
|
|
1780
|
+
} else {
|
|
1781
|
+
request.input(`param${i}`, preparedValue);
|
|
1782
|
+
}
|
|
1350
1783
|
});
|
|
1351
|
-
const resultSet = await request.query(
|
|
1784
|
+
const resultSet = await request.query(sql6);
|
|
1352
1785
|
const result = resultSet.recordset[0] || null;
|
|
1353
1786
|
if (!result) {
|
|
1354
1787
|
return null;
|
|
@@ -1380,7 +1813,7 @@ ${columns}
|
|
|
1380
1813
|
try {
|
|
1381
1814
|
await transaction.begin();
|
|
1382
1815
|
for (const record of records) {
|
|
1383
|
-
await this.insert({ tableName, record });
|
|
1816
|
+
await this.insert({ tableName, record, transaction });
|
|
1384
1817
|
}
|
|
1385
1818
|
await transaction.commit();
|
|
1386
1819
|
} catch (error$1) {
|
|
@@ -1417,53 +1850,594 @@ ${columns}
|
|
|
1417
1850
|
);
|
|
1418
1851
|
}
|
|
1419
1852
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1853
|
+
/**
|
|
1854
|
+
* Prepares a value for database operations, handling Date objects and JSON serialization
|
|
1855
|
+
*/
|
|
1856
|
+
prepareValue(value, columnName, tableName) {
|
|
1857
|
+
if (value === null || value === void 0) {
|
|
1858
|
+
return value;
|
|
1859
|
+
}
|
|
1860
|
+
if (value instanceof Date) {
|
|
1861
|
+
return value;
|
|
1862
|
+
}
|
|
1863
|
+
const schema = storage.TABLE_SCHEMAS[tableName];
|
|
1864
|
+
const columnSchema = schema?.[columnName];
|
|
1865
|
+
if (columnSchema?.type === "boolean") {
|
|
1866
|
+
return value ? 1 : 0;
|
|
1867
|
+
}
|
|
1868
|
+
if (columnSchema?.type === "jsonb") {
|
|
1869
|
+
return JSON.stringify(value);
|
|
1870
|
+
}
|
|
1871
|
+
if (typeof value === "object") {
|
|
1872
|
+
return JSON.stringify(value);
|
|
1873
|
+
}
|
|
1874
|
+
return value;
|
|
1426
1875
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
}) {
|
|
1453
|
-
super();
|
|
1454
|
-
this.pool = pool;
|
|
1455
|
-
this.operations = operations;
|
|
1456
|
-
this.schema = schema;
|
|
1876
|
+
/**
|
|
1877
|
+
* Maps TABLE_SCHEMAS types to mssql param types (used when value is null)
|
|
1878
|
+
*/
|
|
1879
|
+
getMssqlType(tableName, columnName) {
|
|
1880
|
+
const col = storage.TABLE_SCHEMAS[tableName]?.[columnName];
|
|
1881
|
+
switch (col?.type) {
|
|
1882
|
+
case "text":
|
|
1883
|
+
return sql3__default.default.NVarChar;
|
|
1884
|
+
case "timestamp":
|
|
1885
|
+
return sql3__default.default.DateTime2;
|
|
1886
|
+
case "uuid":
|
|
1887
|
+
return sql3__default.default.UniqueIdentifier;
|
|
1888
|
+
case "jsonb":
|
|
1889
|
+
return sql3__default.default.NVarChar;
|
|
1890
|
+
case "integer":
|
|
1891
|
+
return sql3__default.default.Int;
|
|
1892
|
+
case "bigint":
|
|
1893
|
+
return sql3__default.default.BigInt;
|
|
1894
|
+
case "float":
|
|
1895
|
+
return sql3__default.default.Float;
|
|
1896
|
+
case "boolean":
|
|
1897
|
+
return sql3__default.default.Bit;
|
|
1898
|
+
default:
|
|
1899
|
+
return sql3__default.default.NVarChar;
|
|
1900
|
+
}
|
|
1457
1901
|
}
|
|
1458
|
-
|
|
1902
|
+
/**
|
|
1903
|
+
* Update a single record in the database
|
|
1904
|
+
*/
|
|
1905
|
+
async update({
|
|
1906
|
+
tableName,
|
|
1907
|
+
keys,
|
|
1908
|
+
data,
|
|
1909
|
+
transaction
|
|
1910
|
+
}) {
|
|
1459
1911
|
try {
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1912
|
+
if (!data || Object.keys(data).length === 0) {
|
|
1913
|
+
throw new error.MastraError({
|
|
1914
|
+
id: "MASTRA_STORAGE_MSSQL_UPDATE_EMPTY_DATA",
|
|
1915
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1916
|
+
category: error.ErrorCategory.USER,
|
|
1917
|
+
text: "Cannot update with empty data payload"
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
if (!keys || Object.keys(keys).length === 0) {
|
|
1921
|
+
throw new error.MastraError({
|
|
1922
|
+
id: "MASTRA_STORAGE_MSSQL_UPDATE_EMPTY_KEYS",
|
|
1923
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1924
|
+
category: error.ErrorCategory.USER,
|
|
1925
|
+
text: "Cannot update without keys to identify records"
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
const setClauses = [];
|
|
1929
|
+
const request = transaction ? transaction.request() : this.pool.request();
|
|
1930
|
+
let paramIndex = 0;
|
|
1931
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
1932
|
+
const parsedKey = utils.parseSqlIdentifier(key, "column name");
|
|
1933
|
+
const paramName = `set${paramIndex++}`;
|
|
1934
|
+
setClauses.push(`[${parsedKey}] = @${paramName}`);
|
|
1935
|
+
const preparedValue = this.prepareValue(value, key, tableName);
|
|
1936
|
+
if (preparedValue === null || preparedValue === void 0) {
|
|
1937
|
+
request.input(paramName, this.getMssqlType(tableName, key), null);
|
|
1938
|
+
} else {
|
|
1939
|
+
request.input(paramName, preparedValue);
|
|
1940
|
+
}
|
|
1941
|
+
});
|
|
1942
|
+
const whereConditions = [];
|
|
1943
|
+
Object.entries(keys).forEach(([key, value]) => {
|
|
1944
|
+
const parsedKey = utils.parseSqlIdentifier(key, "column name");
|
|
1945
|
+
const paramName = `where${paramIndex++}`;
|
|
1946
|
+
whereConditions.push(`[${parsedKey}] = @${paramName}`);
|
|
1947
|
+
const preparedValue = this.prepareValue(value, key, tableName);
|
|
1948
|
+
if (preparedValue === null || preparedValue === void 0) {
|
|
1949
|
+
request.input(paramName, this.getMssqlType(tableName, key), null);
|
|
1950
|
+
} else {
|
|
1951
|
+
request.input(paramName, preparedValue);
|
|
1952
|
+
}
|
|
1953
|
+
});
|
|
1954
|
+
const tableName_ = getTableName({
|
|
1955
|
+
indexName: tableName,
|
|
1956
|
+
schemaName: getSchemaName(this.schemaName)
|
|
1957
|
+
});
|
|
1958
|
+
const updateSql = `UPDATE ${tableName_} SET ${setClauses.join(", ")} WHERE ${whereConditions.join(" AND ")}`;
|
|
1959
|
+
await request.query(updateSql);
|
|
1960
|
+
} catch (error$1) {
|
|
1961
|
+
throw new error.MastraError(
|
|
1962
|
+
{
|
|
1963
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_FAILED",
|
|
1964
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1965
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1966
|
+
details: {
|
|
1967
|
+
tableName
|
|
1968
|
+
}
|
|
1969
|
+
},
|
|
1970
|
+
error$1
|
|
1971
|
+
);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Update multiple records in a single batch transaction
|
|
1976
|
+
*/
|
|
1977
|
+
async batchUpdate({
|
|
1978
|
+
tableName,
|
|
1979
|
+
updates
|
|
1980
|
+
}) {
|
|
1981
|
+
const transaction = this.pool.transaction();
|
|
1982
|
+
try {
|
|
1983
|
+
await transaction.begin();
|
|
1984
|
+
for (const { keys, data } of updates) {
|
|
1985
|
+
await this.update({ tableName, keys, data, transaction });
|
|
1986
|
+
}
|
|
1987
|
+
await transaction.commit();
|
|
1988
|
+
} catch (error$1) {
|
|
1989
|
+
await transaction.rollback();
|
|
1990
|
+
throw new error.MastraError(
|
|
1991
|
+
{
|
|
1992
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_BATCH_UPDATE_FAILED",
|
|
1993
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1994
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1995
|
+
details: {
|
|
1996
|
+
tableName,
|
|
1997
|
+
numberOfRecords: updates.length
|
|
1998
|
+
}
|
|
1999
|
+
},
|
|
2000
|
+
error$1
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
/**
|
|
2005
|
+
* Delete multiple records by keys
|
|
2006
|
+
*/
|
|
2007
|
+
async batchDelete({ tableName, keys }) {
|
|
2008
|
+
if (keys.length === 0) {
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
const tableName_ = getTableName({
|
|
2012
|
+
indexName: tableName,
|
|
2013
|
+
schemaName: getSchemaName(this.schemaName)
|
|
2014
|
+
});
|
|
2015
|
+
const transaction = this.pool.transaction();
|
|
2016
|
+
try {
|
|
2017
|
+
await transaction.begin();
|
|
2018
|
+
for (const keySet of keys) {
|
|
2019
|
+
const conditions = [];
|
|
2020
|
+
const request = transaction.request();
|
|
2021
|
+
let paramIndex = 0;
|
|
2022
|
+
Object.entries(keySet).forEach(([key, value]) => {
|
|
2023
|
+
const parsedKey = utils.parseSqlIdentifier(key, "column name");
|
|
2024
|
+
const paramName = `p${paramIndex++}`;
|
|
2025
|
+
conditions.push(`[${parsedKey}] = @${paramName}`);
|
|
2026
|
+
const preparedValue = this.prepareValue(value, key, tableName);
|
|
2027
|
+
if (preparedValue === null || preparedValue === void 0) {
|
|
2028
|
+
request.input(paramName, this.getMssqlType(tableName, key), null);
|
|
2029
|
+
} else {
|
|
2030
|
+
request.input(paramName, preparedValue);
|
|
2031
|
+
}
|
|
2032
|
+
});
|
|
2033
|
+
const deleteSql = `DELETE FROM ${tableName_} WHERE ${conditions.join(" AND ")}`;
|
|
2034
|
+
await request.query(deleteSql);
|
|
2035
|
+
}
|
|
2036
|
+
await transaction.commit();
|
|
2037
|
+
} catch (error$1) {
|
|
2038
|
+
await transaction.rollback();
|
|
2039
|
+
throw new error.MastraError(
|
|
2040
|
+
{
|
|
2041
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_BATCH_DELETE_FAILED",
|
|
2042
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2043
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2044
|
+
details: {
|
|
2045
|
+
tableName,
|
|
2046
|
+
numberOfRecords: keys.length
|
|
2047
|
+
}
|
|
2048
|
+
},
|
|
2049
|
+
error$1
|
|
2050
|
+
);
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Create a new index on a table
|
|
2055
|
+
*/
|
|
2056
|
+
async createIndex(options) {
|
|
2057
|
+
try {
|
|
2058
|
+
const { name, table, columns, unique = false, where } = options;
|
|
2059
|
+
const schemaName = this.schemaName || "dbo";
|
|
2060
|
+
const fullTableName = getTableName({
|
|
2061
|
+
indexName: table,
|
|
2062
|
+
schemaName: getSchemaName(this.schemaName)
|
|
2063
|
+
});
|
|
2064
|
+
const indexNameSafe = utils.parseSqlIdentifier(name, "index name");
|
|
2065
|
+
const checkRequest = this.pool.request();
|
|
2066
|
+
checkRequest.input("indexName", indexNameSafe);
|
|
2067
|
+
checkRequest.input("schemaName", schemaName);
|
|
2068
|
+
checkRequest.input("tableName", table);
|
|
2069
|
+
const indexExists = await checkRequest.query(`
|
|
2070
|
+
SELECT 1 as found
|
|
2071
|
+
FROM sys.indexes i
|
|
2072
|
+
INNER JOIN sys.tables t ON i.object_id = t.object_id
|
|
2073
|
+
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
2074
|
+
WHERE i.name = @indexName
|
|
2075
|
+
AND s.name = @schemaName
|
|
2076
|
+
AND t.name = @tableName
|
|
2077
|
+
`);
|
|
2078
|
+
if (indexExists.recordset && indexExists.recordset.length > 0) {
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
const uniqueStr = unique ? "UNIQUE " : "";
|
|
2082
|
+
const columnsStr = columns.map((col) => {
|
|
2083
|
+
if (col.includes(" DESC") || col.includes(" ASC")) {
|
|
2084
|
+
const [colName, ...modifiers] = col.split(" ");
|
|
2085
|
+
if (!colName) {
|
|
2086
|
+
throw new Error(`Invalid column specification: ${col}`);
|
|
2087
|
+
}
|
|
2088
|
+
return `[${utils.parseSqlIdentifier(colName, "column name")}] ${modifiers.join(" ")}`;
|
|
2089
|
+
}
|
|
2090
|
+
return `[${utils.parseSqlIdentifier(col, "column name")}]`;
|
|
2091
|
+
}).join(", ");
|
|
2092
|
+
const whereStr = where ? ` WHERE ${where}` : "";
|
|
2093
|
+
const createIndexSql = `CREATE ${uniqueStr}INDEX [${indexNameSafe}] ON ${fullTableName} (${columnsStr})${whereStr}`;
|
|
2094
|
+
await this.pool.request().query(createIndexSql);
|
|
2095
|
+
} catch (error$1) {
|
|
2096
|
+
throw new error.MastraError(
|
|
2097
|
+
{
|
|
2098
|
+
id: "MASTRA_STORAGE_MSSQL_INDEX_CREATE_FAILED",
|
|
2099
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2100
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2101
|
+
details: {
|
|
2102
|
+
indexName: options.name,
|
|
2103
|
+
tableName: options.table
|
|
2104
|
+
}
|
|
2105
|
+
},
|
|
2106
|
+
error$1
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Drop an existing index
|
|
2112
|
+
*/
|
|
2113
|
+
async dropIndex(indexName) {
|
|
2114
|
+
try {
|
|
2115
|
+
const schemaName = this.schemaName || "dbo";
|
|
2116
|
+
const indexNameSafe = utils.parseSqlIdentifier(indexName, "index name");
|
|
2117
|
+
const checkRequest = this.pool.request();
|
|
2118
|
+
checkRequest.input("indexName", indexNameSafe);
|
|
2119
|
+
checkRequest.input("schemaName", schemaName);
|
|
2120
|
+
const result = await checkRequest.query(`
|
|
2121
|
+
SELECT t.name as table_name
|
|
2122
|
+
FROM sys.indexes i
|
|
2123
|
+
INNER JOIN sys.tables t ON i.object_id = t.object_id
|
|
2124
|
+
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
|
|
2125
|
+
WHERE i.name = @indexName
|
|
2126
|
+
AND s.name = @schemaName
|
|
2127
|
+
`);
|
|
2128
|
+
if (!result.recordset || result.recordset.length === 0) {
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
if (result.recordset.length > 1) {
|
|
2132
|
+
const tables = result.recordset.map((r) => r.table_name).join(", ");
|
|
2133
|
+
throw new error.MastraError({
|
|
2134
|
+
id: "MASTRA_STORAGE_MSSQL_INDEX_AMBIGUOUS",
|
|
2135
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2136
|
+
category: error.ErrorCategory.USER,
|
|
2137
|
+
text: `Index "${indexNameSafe}" exists on multiple tables (${tables}) in schema "${schemaName}". Please drop indexes manually or ensure unique index names.`
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
const tableName = result.recordset[0].table_name;
|
|
2141
|
+
const fullTableName = getTableName({
|
|
2142
|
+
indexName: tableName,
|
|
2143
|
+
schemaName: getSchemaName(this.schemaName)
|
|
2144
|
+
});
|
|
2145
|
+
const dropSql = `DROP INDEX [${indexNameSafe}] ON ${fullTableName}`;
|
|
2146
|
+
await this.pool.request().query(dropSql);
|
|
2147
|
+
} catch (error$1) {
|
|
2148
|
+
throw new error.MastraError(
|
|
2149
|
+
{
|
|
2150
|
+
id: "MASTRA_STORAGE_MSSQL_INDEX_DROP_FAILED",
|
|
2151
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2152
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2153
|
+
details: {
|
|
2154
|
+
indexName
|
|
2155
|
+
}
|
|
2156
|
+
},
|
|
2157
|
+
error$1
|
|
2158
|
+
);
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* List indexes for a specific table or all tables
|
|
2163
|
+
*/
|
|
2164
|
+
async listIndexes(tableName) {
|
|
2165
|
+
try {
|
|
2166
|
+
const schemaName = this.schemaName || "dbo";
|
|
2167
|
+
let query;
|
|
2168
|
+
const request = this.pool.request();
|
|
2169
|
+
request.input("schemaName", schemaName);
|
|
2170
|
+
if (tableName) {
|
|
2171
|
+
query = `
|
|
2172
|
+
SELECT
|
|
2173
|
+
i.name as name,
|
|
2174
|
+
o.name as [table],
|
|
2175
|
+
i.is_unique as is_unique,
|
|
2176
|
+
CAST(SUM(s.used_page_count) * 8 / 1024.0 AS VARCHAR(50)) + ' MB' as size
|
|
2177
|
+
FROM sys.indexes i
|
|
2178
|
+
INNER JOIN sys.objects o ON i.object_id = o.object_id
|
|
2179
|
+
INNER JOIN sys.schemas sch ON o.schema_id = sch.schema_id
|
|
2180
|
+
LEFT JOIN sys.dm_db_partition_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
|
|
2181
|
+
WHERE sch.name = @schemaName
|
|
2182
|
+
AND o.name = @tableName
|
|
2183
|
+
AND i.name IS NOT NULL
|
|
2184
|
+
GROUP BY i.name, o.name, i.is_unique
|
|
2185
|
+
`;
|
|
2186
|
+
request.input("tableName", tableName);
|
|
2187
|
+
} else {
|
|
2188
|
+
query = `
|
|
2189
|
+
SELECT
|
|
2190
|
+
i.name as name,
|
|
2191
|
+
o.name as [table],
|
|
2192
|
+
i.is_unique as is_unique,
|
|
2193
|
+
CAST(SUM(s.used_page_count) * 8 / 1024.0 AS VARCHAR(50)) + ' MB' as size
|
|
2194
|
+
FROM sys.indexes i
|
|
2195
|
+
INNER JOIN sys.objects o ON i.object_id = o.object_id
|
|
2196
|
+
INNER JOIN sys.schemas sch ON o.schema_id = sch.schema_id
|
|
2197
|
+
LEFT JOIN sys.dm_db_partition_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
|
|
2198
|
+
WHERE sch.name = @schemaName
|
|
2199
|
+
AND i.name IS NOT NULL
|
|
2200
|
+
GROUP BY i.name, o.name, i.is_unique
|
|
2201
|
+
`;
|
|
2202
|
+
}
|
|
2203
|
+
const result = await request.query(query);
|
|
2204
|
+
const indexes = [];
|
|
2205
|
+
for (const row of result.recordset) {
|
|
2206
|
+
const colRequest = this.pool.request();
|
|
2207
|
+
colRequest.input("indexName", row.name);
|
|
2208
|
+
colRequest.input("schemaName", schemaName);
|
|
2209
|
+
const colResult = await colRequest.query(`
|
|
2210
|
+
SELECT c.name as column_name
|
|
2211
|
+
FROM sys.indexes i
|
|
2212
|
+
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
|
2213
|
+
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
|
|
2214
|
+
INNER JOIN sys.objects o ON i.object_id = o.object_id
|
|
2215
|
+
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
|
|
2216
|
+
WHERE i.name = @indexName
|
|
2217
|
+
AND s.name = @schemaName
|
|
2218
|
+
ORDER BY ic.key_ordinal
|
|
2219
|
+
`);
|
|
2220
|
+
indexes.push({
|
|
2221
|
+
name: row.name,
|
|
2222
|
+
table: row.table,
|
|
2223
|
+
columns: colResult.recordset.map((c) => c.column_name),
|
|
2224
|
+
unique: row.is_unique || false,
|
|
2225
|
+
size: row.size || "0 MB",
|
|
2226
|
+
definition: ""
|
|
2227
|
+
// MSSQL doesn't store definition like PG
|
|
2228
|
+
});
|
|
2229
|
+
}
|
|
2230
|
+
return indexes;
|
|
2231
|
+
} catch (error$1) {
|
|
2232
|
+
throw new error.MastraError(
|
|
2233
|
+
{
|
|
2234
|
+
id: "MASTRA_STORAGE_MSSQL_INDEX_LIST_FAILED",
|
|
2235
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2236
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2237
|
+
details: tableName ? {
|
|
2238
|
+
tableName
|
|
2239
|
+
} : {}
|
|
2240
|
+
},
|
|
2241
|
+
error$1
|
|
2242
|
+
);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* Get detailed statistics for a specific index
|
|
2247
|
+
*/
|
|
2248
|
+
async describeIndex(indexName) {
|
|
2249
|
+
try {
|
|
2250
|
+
const schemaName = this.schemaName || "dbo";
|
|
2251
|
+
const request = this.pool.request();
|
|
2252
|
+
request.input("indexName", indexName);
|
|
2253
|
+
request.input("schemaName", schemaName);
|
|
2254
|
+
const query = `
|
|
2255
|
+
SELECT
|
|
2256
|
+
i.name as name,
|
|
2257
|
+
o.name as [table],
|
|
2258
|
+
i.is_unique as is_unique,
|
|
2259
|
+
CAST(SUM(s.used_page_count) * 8 / 1024.0 AS VARCHAR(50)) + ' MB' as size,
|
|
2260
|
+
i.type_desc as method,
|
|
2261
|
+
ISNULL(us.user_scans, 0) as scans,
|
|
2262
|
+
ISNULL(us.user_seeks + us.user_scans, 0) as tuples_read,
|
|
2263
|
+
ISNULL(us.user_lookups, 0) as tuples_fetched
|
|
2264
|
+
FROM sys.indexes i
|
|
2265
|
+
INNER JOIN sys.objects o ON i.object_id = o.object_id
|
|
2266
|
+
INNER JOIN sys.schemas sch ON o.schema_id = sch.schema_id
|
|
2267
|
+
LEFT JOIN sys.dm_db_partition_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
|
|
2268
|
+
LEFT JOIN sys.dm_db_index_usage_stats us ON i.object_id = us.object_id AND i.index_id = us.index_id
|
|
2269
|
+
WHERE i.name = @indexName
|
|
2270
|
+
AND sch.name = @schemaName
|
|
2271
|
+
GROUP BY i.name, o.name, i.is_unique, i.type_desc, us.user_seeks, us.user_scans, us.user_lookups
|
|
2272
|
+
`;
|
|
2273
|
+
const result = await request.query(query);
|
|
2274
|
+
if (!result.recordset || result.recordset.length === 0) {
|
|
2275
|
+
throw new Error(`Index "${indexName}" not found in schema "${schemaName}"`);
|
|
2276
|
+
}
|
|
2277
|
+
const row = result.recordset[0];
|
|
2278
|
+
const colRequest = this.pool.request();
|
|
2279
|
+
colRequest.input("indexName", indexName);
|
|
2280
|
+
colRequest.input("schemaName", schemaName);
|
|
2281
|
+
const colResult = await colRequest.query(`
|
|
2282
|
+
SELECT c.name as column_name
|
|
2283
|
+
FROM sys.indexes i
|
|
2284
|
+
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
|
2285
|
+
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
|
|
2286
|
+
INNER JOIN sys.objects o ON i.object_id = o.object_id
|
|
2287
|
+
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
|
|
2288
|
+
WHERE i.name = @indexName
|
|
2289
|
+
AND s.name = @schemaName
|
|
2290
|
+
ORDER BY ic.key_ordinal
|
|
2291
|
+
`);
|
|
2292
|
+
return {
|
|
2293
|
+
name: row.name,
|
|
2294
|
+
table: row.table,
|
|
2295
|
+
columns: colResult.recordset.map((c) => c.column_name),
|
|
2296
|
+
unique: row.is_unique || false,
|
|
2297
|
+
size: row.size || "0 MB",
|
|
2298
|
+
definition: "",
|
|
2299
|
+
method: row.method?.toLowerCase() || "nonclustered",
|
|
2300
|
+
scans: Number(row.scans) || 0,
|
|
2301
|
+
tuples_read: Number(row.tuples_read) || 0,
|
|
2302
|
+
tuples_fetched: Number(row.tuples_fetched) || 0
|
|
2303
|
+
};
|
|
2304
|
+
} catch (error$1) {
|
|
2305
|
+
throw new error.MastraError(
|
|
2306
|
+
{
|
|
2307
|
+
id: "MASTRA_STORAGE_MSSQL_INDEX_DESCRIBE_FAILED",
|
|
2308
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2309
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2310
|
+
details: {
|
|
2311
|
+
indexName
|
|
2312
|
+
}
|
|
2313
|
+
},
|
|
2314
|
+
error$1
|
|
2315
|
+
);
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
/**
|
|
2319
|
+
* Returns definitions for automatic performance indexes
|
|
2320
|
+
* IMPORTANT: Uses seq_id DESC instead of createdAt DESC for MSSQL due to millisecond accuracy limitations
|
|
2321
|
+
* NOTE: Using NVARCHAR(400) for text columns (800 bytes) leaves room for composite indexes
|
|
2322
|
+
*/
|
|
2323
|
+
getAutomaticIndexDefinitions() {
|
|
2324
|
+
const schemaPrefix = this.schemaName ? `${this.schemaName}_` : "";
|
|
2325
|
+
return [
|
|
2326
|
+
// Composite indexes for optimal filtering + sorting performance
|
|
2327
|
+
// NVARCHAR(400) = 800 bytes, plus BIGINT (8 bytes) = 808 bytes total (under 900-byte limit)
|
|
2328
|
+
{
|
|
2329
|
+
name: `${schemaPrefix}mastra_threads_resourceid_seqid_idx`,
|
|
2330
|
+
table: storage.TABLE_THREADS,
|
|
2331
|
+
columns: ["resourceId", "seq_id DESC"]
|
|
2332
|
+
},
|
|
2333
|
+
{
|
|
2334
|
+
name: `${schemaPrefix}mastra_messages_thread_id_seqid_idx`,
|
|
2335
|
+
table: storage.TABLE_MESSAGES,
|
|
2336
|
+
columns: ["thread_id", "seq_id DESC"]
|
|
2337
|
+
},
|
|
2338
|
+
{
|
|
2339
|
+
name: `${schemaPrefix}mastra_traces_name_seqid_idx`,
|
|
2340
|
+
table: storage.TABLE_TRACES,
|
|
2341
|
+
columns: ["name", "seq_id DESC"]
|
|
2342
|
+
},
|
|
2343
|
+
{
|
|
2344
|
+
name: `${schemaPrefix}mastra_evals_agent_name_seqid_idx`,
|
|
2345
|
+
table: storage.TABLE_EVALS,
|
|
2346
|
+
columns: ["agent_name", "seq_id DESC"]
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
name: `${schemaPrefix}mastra_scores_trace_id_span_id_seqid_idx`,
|
|
2350
|
+
table: storage.TABLE_SCORERS,
|
|
2351
|
+
columns: ["traceId", "spanId", "seq_id DESC"]
|
|
2352
|
+
},
|
|
2353
|
+
// AI Spans indexes for optimal trace querying
|
|
2354
|
+
{
|
|
2355
|
+
name: `${schemaPrefix}mastra_ai_spans_traceid_startedat_idx`,
|
|
2356
|
+
table: storage.TABLE_AI_SPANS,
|
|
2357
|
+
columns: ["traceId", "startedAt DESC"]
|
|
2358
|
+
},
|
|
2359
|
+
{
|
|
2360
|
+
name: `${schemaPrefix}mastra_ai_spans_parentspanid_startedat_idx`,
|
|
2361
|
+
table: storage.TABLE_AI_SPANS,
|
|
2362
|
+
columns: ["parentSpanId", "startedAt DESC"]
|
|
2363
|
+
},
|
|
2364
|
+
{
|
|
2365
|
+
name: `${schemaPrefix}mastra_ai_spans_name_idx`,
|
|
2366
|
+
table: storage.TABLE_AI_SPANS,
|
|
2367
|
+
columns: ["name"]
|
|
2368
|
+
},
|
|
2369
|
+
{
|
|
2370
|
+
name: `${schemaPrefix}mastra_ai_spans_spantype_startedat_idx`,
|
|
2371
|
+
table: storage.TABLE_AI_SPANS,
|
|
2372
|
+
columns: ["spanType", "startedAt DESC"]
|
|
2373
|
+
}
|
|
2374
|
+
];
|
|
2375
|
+
}
|
|
2376
|
+
/**
|
|
2377
|
+
* Creates automatic indexes for optimal query performance
|
|
2378
|
+
* Uses getAutomaticIndexDefinitions() to determine which indexes to create
|
|
2379
|
+
*/
|
|
2380
|
+
async createAutomaticIndexes() {
|
|
2381
|
+
try {
|
|
2382
|
+
const indexes = this.getAutomaticIndexDefinitions();
|
|
2383
|
+
for (const indexOptions of indexes) {
|
|
2384
|
+
try {
|
|
2385
|
+
await this.createIndex(indexOptions);
|
|
2386
|
+
} catch (error) {
|
|
2387
|
+
this.logger?.warn?.(`Failed to create index ${indexOptions.name}:`, error);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
} catch (error$1) {
|
|
2391
|
+
throw new error.MastraError(
|
|
2392
|
+
{
|
|
2393
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_CREATE_PERFORMANCE_INDEXES_FAILED",
|
|
2394
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2395
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
2396
|
+
},
|
|
2397
|
+
error$1
|
|
2398
|
+
);
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
};
|
|
2402
|
+
function transformScoreRow(row) {
|
|
2403
|
+
return {
|
|
2404
|
+
...row,
|
|
2405
|
+
input: storage.safelyParseJSON(row.input),
|
|
2406
|
+
scorer: storage.safelyParseJSON(row.scorer),
|
|
2407
|
+
preprocessStepResult: storage.safelyParseJSON(row.preprocessStepResult),
|
|
2408
|
+
analyzeStepResult: storage.safelyParseJSON(row.analyzeStepResult),
|
|
2409
|
+
metadata: storage.safelyParseJSON(row.metadata),
|
|
2410
|
+
output: storage.safelyParseJSON(row.output),
|
|
2411
|
+
additionalContext: storage.safelyParseJSON(row.additionalContext),
|
|
2412
|
+
runtimeContext: storage.safelyParseJSON(row.runtimeContext),
|
|
2413
|
+
entity: storage.safelyParseJSON(row.entity),
|
|
2414
|
+
createdAt: row.createdAt,
|
|
2415
|
+
updatedAt: row.updatedAt
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
var ScoresMSSQL = class extends storage.ScoresStorage {
|
|
2419
|
+
pool;
|
|
2420
|
+
operations;
|
|
2421
|
+
schema;
|
|
2422
|
+
constructor({
|
|
2423
|
+
pool,
|
|
2424
|
+
operations,
|
|
2425
|
+
schema
|
|
2426
|
+
}) {
|
|
2427
|
+
super();
|
|
2428
|
+
this.pool = pool;
|
|
2429
|
+
this.operations = operations;
|
|
2430
|
+
this.schema = schema;
|
|
2431
|
+
}
|
|
2432
|
+
async getScoreById({ id }) {
|
|
2433
|
+
try {
|
|
2434
|
+
const request = this.pool.request();
|
|
2435
|
+
request.input("p1", id);
|
|
2436
|
+
const result = await request.query(
|
|
2437
|
+
`SELECT * FROM ${getTableName({ indexName: storage.TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE id = @p1`
|
|
2438
|
+
);
|
|
2439
|
+
if (result.recordset.length === 0) {
|
|
2440
|
+
return null;
|
|
1467
2441
|
}
|
|
1468
2442
|
return transformScoreRow(result.recordset[0]);
|
|
1469
2443
|
} catch (error$1) {
|
|
@@ -1479,6 +2453,19 @@ var ScoresMSSQL = class extends storage.ScoresStorage {
|
|
|
1479
2453
|
}
|
|
1480
2454
|
}
|
|
1481
2455
|
async saveScore(score) {
|
|
2456
|
+
let validatedScore;
|
|
2457
|
+
try {
|
|
2458
|
+
validatedScore = scores.saveScorePayloadSchema.parse(score);
|
|
2459
|
+
} catch (error$1) {
|
|
2460
|
+
throw new error.MastraError(
|
|
2461
|
+
{
|
|
2462
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_SAVE_SCORE_VALIDATION_FAILED",
|
|
2463
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2464
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
2465
|
+
},
|
|
2466
|
+
error$1
|
|
2467
|
+
);
|
|
2468
|
+
}
|
|
1482
2469
|
try {
|
|
1483
2470
|
const scoreId = crypto.randomUUID();
|
|
1484
2471
|
const {
|
|
@@ -1492,21 +2479,21 @@ var ScoresMSSQL = class extends storage.ScoresStorage {
|
|
|
1492
2479
|
runtimeContext,
|
|
1493
2480
|
entity,
|
|
1494
2481
|
...rest
|
|
1495
|
-
} =
|
|
2482
|
+
} = validatedScore;
|
|
1496
2483
|
await this.operations.insert({
|
|
1497
2484
|
tableName: storage.TABLE_SCORERS,
|
|
1498
2485
|
record: {
|
|
1499
2486
|
id: scoreId,
|
|
1500
2487
|
...rest,
|
|
1501
|
-
input:
|
|
1502
|
-
output:
|
|
1503
|
-
preprocessStepResult: preprocessStepResult
|
|
1504
|
-
analyzeStepResult: analyzeStepResult
|
|
1505
|
-
metadata: metadata
|
|
1506
|
-
additionalContext: additionalContext
|
|
1507
|
-
runtimeContext: runtimeContext
|
|
1508
|
-
entity: entity
|
|
1509
|
-
scorer: scorer
|
|
2488
|
+
input: input || "",
|
|
2489
|
+
output: output || "",
|
|
2490
|
+
preprocessStepResult: preprocessStepResult || null,
|
|
2491
|
+
analyzeStepResult: analyzeStepResult || null,
|
|
2492
|
+
metadata: metadata || null,
|
|
2493
|
+
additionalContext: additionalContext || null,
|
|
2494
|
+
runtimeContext: runtimeContext || null,
|
|
2495
|
+
entity: entity || null,
|
|
2496
|
+
scorer: scorer || null,
|
|
1510
2497
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1511
2498
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1512
2499
|
}
|
|
@@ -1526,14 +2513,37 @@ var ScoresMSSQL = class extends storage.ScoresStorage {
|
|
|
1526
2513
|
}
|
|
1527
2514
|
async getScoresByScorerId({
|
|
1528
2515
|
scorerId,
|
|
1529
|
-
pagination
|
|
2516
|
+
pagination,
|
|
2517
|
+
entityId,
|
|
2518
|
+
entityType,
|
|
2519
|
+
source
|
|
1530
2520
|
}) {
|
|
1531
2521
|
try {
|
|
1532
|
-
const
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
2522
|
+
const conditions = ["[scorerId] = @p1"];
|
|
2523
|
+
const params = { p1: scorerId };
|
|
2524
|
+
let paramIndex = 2;
|
|
2525
|
+
if (entityId) {
|
|
2526
|
+
conditions.push(`[entityId] = @p${paramIndex}`);
|
|
2527
|
+
params[`p${paramIndex}`] = entityId;
|
|
2528
|
+
paramIndex++;
|
|
2529
|
+
}
|
|
2530
|
+
if (entityType) {
|
|
2531
|
+
conditions.push(`[entityType] = @p${paramIndex}`);
|
|
2532
|
+
params[`p${paramIndex}`] = entityType;
|
|
2533
|
+
paramIndex++;
|
|
2534
|
+
}
|
|
2535
|
+
if (source) {
|
|
2536
|
+
conditions.push(`[source] = @p${paramIndex}`);
|
|
2537
|
+
params[`p${paramIndex}`] = source;
|
|
2538
|
+
paramIndex++;
|
|
2539
|
+
}
|
|
2540
|
+
const whereClause = conditions.join(" AND ");
|
|
2541
|
+
const tableName = getTableName({ indexName: storage.TABLE_SCORERS, schemaName: getSchemaName(this.schema) });
|
|
2542
|
+
const countRequest = this.pool.request();
|
|
2543
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
2544
|
+
countRequest.input(key, value);
|
|
2545
|
+
});
|
|
2546
|
+
const totalResult = await countRequest.query(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`);
|
|
1537
2547
|
const total = totalResult.recordset[0]?.count || 0;
|
|
1538
2548
|
if (total === 0) {
|
|
1539
2549
|
return {
|
|
@@ -1547,12 +2557,13 @@ var ScoresMSSQL = class extends storage.ScoresStorage {
|
|
|
1547
2557
|
};
|
|
1548
2558
|
}
|
|
1549
2559
|
const dataRequest = this.pool.request();
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
2560
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
2561
|
+
dataRequest.input(key, value);
|
|
2562
|
+
});
|
|
2563
|
+
dataRequest.input("perPage", pagination.perPage);
|
|
2564
|
+
dataRequest.input("offset", pagination.page * pagination.perPage);
|
|
2565
|
+
const dataQuery = `SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY [createdAt] DESC OFFSET @offset ROWS FETCH NEXT @perPage ROWS ONLY`;
|
|
2566
|
+
const result = await dataRequest.query(dataQuery);
|
|
1556
2567
|
return {
|
|
1557
2568
|
pagination: {
|
|
1558
2569
|
total: Number(total),
|
|
@@ -1677,8 +2688,62 @@ var ScoresMSSQL = class extends storage.ScoresStorage {
|
|
|
1677
2688
|
);
|
|
1678
2689
|
}
|
|
1679
2690
|
}
|
|
2691
|
+
async getScoresBySpan({
|
|
2692
|
+
traceId,
|
|
2693
|
+
spanId,
|
|
2694
|
+
pagination
|
|
2695
|
+
}) {
|
|
2696
|
+
try {
|
|
2697
|
+
const request = this.pool.request();
|
|
2698
|
+
request.input("p1", traceId);
|
|
2699
|
+
request.input("p2", spanId);
|
|
2700
|
+
const totalResult = await request.query(
|
|
2701
|
+
`SELECT COUNT(*) as count FROM ${getTableName({ indexName: storage.TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [traceId] = @p1 AND [spanId] = @p2`
|
|
2702
|
+
);
|
|
2703
|
+
const total = totalResult.recordset[0]?.count || 0;
|
|
2704
|
+
if (total === 0) {
|
|
2705
|
+
return {
|
|
2706
|
+
pagination: {
|
|
2707
|
+
total: 0,
|
|
2708
|
+
page: pagination.page,
|
|
2709
|
+
perPage: pagination.perPage,
|
|
2710
|
+
hasMore: false
|
|
2711
|
+
},
|
|
2712
|
+
scores: []
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
const limit = pagination.perPage + 1;
|
|
2716
|
+
const dataRequest = this.pool.request();
|
|
2717
|
+
dataRequest.input("p1", traceId);
|
|
2718
|
+
dataRequest.input("p2", spanId);
|
|
2719
|
+
dataRequest.input("p3", limit);
|
|
2720
|
+
dataRequest.input("p4", pagination.page * pagination.perPage);
|
|
2721
|
+
const result = await dataRequest.query(
|
|
2722
|
+
`SELECT * FROM ${getTableName({ indexName: storage.TABLE_SCORERS, schemaName: getSchemaName(this.schema) })} WHERE [traceId] = @p1 AND [spanId] = @p2 ORDER BY [createdAt] DESC OFFSET @p4 ROWS FETCH NEXT @p3 ROWS ONLY`
|
|
2723
|
+
);
|
|
2724
|
+
return {
|
|
2725
|
+
pagination: {
|
|
2726
|
+
total: Number(total),
|
|
2727
|
+
page: pagination.page,
|
|
2728
|
+
perPage: pagination.perPage,
|
|
2729
|
+
hasMore: result.recordset.length > pagination.perPage
|
|
2730
|
+
},
|
|
2731
|
+
scores: result.recordset.slice(0, pagination.perPage).map((row) => transformScoreRow(row))
|
|
2732
|
+
};
|
|
2733
|
+
} catch (error$1) {
|
|
2734
|
+
throw new error.MastraError(
|
|
2735
|
+
{
|
|
2736
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_GET_SCORES_BY_SPAN_FAILED",
|
|
2737
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2738
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2739
|
+
details: { traceId, spanId }
|
|
2740
|
+
},
|
|
2741
|
+
error$1
|
|
2742
|
+
);
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
1680
2745
|
};
|
|
1681
|
-
var
|
|
2746
|
+
var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
1682
2747
|
pool;
|
|
1683
2748
|
operations;
|
|
1684
2749
|
schema;
|
|
@@ -1692,210 +2757,168 @@ var TracesMSSQL = class extends storage.TracesStorage {
|
|
|
1692
2757
|
this.operations = operations;
|
|
1693
2758
|
this.schema = schema;
|
|
1694
2759
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
if (
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
2760
|
+
parseWorkflowRun(row) {
|
|
2761
|
+
let parsedSnapshot = row.snapshot;
|
|
2762
|
+
if (typeof parsedSnapshot === "string") {
|
|
2763
|
+
try {
|
|
2764
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
2765
|
+
} catch (e) {
|
|
2766
|
+
this.logger?.warn?.(`Failed to parse snapshot for workflow ${row.workflow_name}:`, e);
|
|
2767
|
+
}
|
|
1702
2768
|
}
|
|
1703
|
-
|
|
1704
|
-
|
|
2769
|
+
return {
|
|
2770
|
+
workflowName: row.workflow_name,
|
|
2771
|
+
runId: row.run_id,
|
|
2772
|
+
snapshot: parsedSnapshot,
|
|
2773
|
+
createdAt: row.createdAt,
|
|
2774
|
+
updatedAt: row.updatedAt,
|
|
2775
|
+
resourceId: row.resourceId
|
|
2776
|
+
};
|
|
1705
2777
|
}
|
|
1706
|
-
async
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
const
|
|
1714
|
-
|
|
1715
|
-
if (name) {
|
|
1716
|
-
const paramName = `p${paramIndex++}`;
|
|
1717
|
-
conditions.push(`[name] LIKE @${paramName}`);
|
|
1718
|
-
paramMap[paramName] = `${name}%`;
|
|
1719
|
-
}
|
|
1720
|
-
if (scope) {
|
|
1721
|
-
const paramName = `p${paramIndex++}`;
|
|
1722
|
-
conditions.push(`[scope] = @${paramName}`);
|
|
1723
|
-
paramMap[paramName] = scope;
|
|
1724
|
-
}
|
|
1725
|
-
if (attributes) {
|
|
1726
|
-
Object.entries(attributes).forEach(([key, value]) => {
|
|
1727
|
-
const parsedKey = utils.parseFieldKey(key);
|
|
1728
|
-
const paramName = `p${paramIndex++}`;
|
|
1729
|
-
conditions.push(`JSON_VALUE([attributes], '$.${parsedKey}') = @${paramName}`);
|
|
1730
|
-
paramMap[paramName] = value;
|
|
1731
|
-
});
|
|
1732
|
-
}
|
|
1733
|
-
if (filters) {
|
|
1734
|
-
Object.entries(filters).forEach(([key, value]) => {
|
|
1735
|
-
const parsedKey = utils.parseFieldKey(key);
|
|
1736
|
-
const paramName = `p${paramIndex++}`;
|
|
1737
|
-
conditions.push(`[${parsedKey}] = @${paramName}`);
|
|
1738
|
-
paramMap[paramName] = value;
|
|
1739
|
-
});
|
|
1740
|
-
}
|
|
1741
|
-
if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
|
|
1742
|
-
const paramName = `p${paramIndex++}`;
|
|
1743
|
-
conditions.push(`[createdAt] >= @${paramName}`);
|
|
1744
|
-
paramMap[paramName] = fromDate.toISOString();
|
|
1745
|
-
}
|
|
1746
|
-
if (toDate instanceof Date && !isNaN(toDate.getTime())) {
|
|
1747
|
-
const paramName = `p${paramIndex++}`;
|
|
1748
|
-
conditions.push(`[createdAt] <= @${paramName}`);
|
|
1749
|
-
paramMap[paramName] = toDate.toISOString();
|
|
1750
|
-
}
|
|
1751
|
-
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1752
|
-
const countQuery = `SELECT COUNT(*) as total FROM ${getTableName({ indexName: storage.TABLE_TRACES, schemaName: getSchemaName(this.schema) })} ${whereClause}`;
|
|
1753
|
-
let total = 0;
|
|
2778
|
+
async updateWorkflowResults({
|
|
2779
|
+
workflowName,
|
|
2780
|
+
runId,
|
|
2781
|
+
stepId,
|
|
2782
|
+
result,
|
|
2783
|
+
runtimeContext
|
|
2784
|
+
}) {
|
|
2785
|
+
const table = getTableName({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
|
|
2786
|
+
const transaction = this.pool.transaction();
|
|
1754
2787
|
try {
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
2788
|
+
await transaction.begin();
|
|
2789
|
+
const selectRequest = new sql3__default.default.Request(transaction);
|
|
2790
|
+
selectRequest.input("workflow_name", workflowName);
|
|
2791
|
+
selectRequest.input("run_id", runId);
|
|
2792
|
+
const existingSnapshotResult = await selectRequest.query(
|
|
2793
|
+
`SELECT snapshot FROM ${table} WITH (UPDLOCK, HOLDLOCK) WHERE workflow_name = @workflow_name AND run_id = @run_id`
|
|
2794
|
+
);
|
|
2795
|
+
let snapshot;
|
|
2796
|
+
if (!existingSnapshotResult.recordset || existingSnapshotResult.recordset.length === 0) {
|
|
2797
|
+
snapshot = {
|
|
2798
|
+
context: {},
|
|
2799
|
+
activePaths: [],
|
|
2800
|
+
timestamp: Date.now(),
|
|
2801
|
+
suspendedPaths: {},
|
|
2802
|
+
resumeLabels: {},
|
|
2803
|
+
serializedStepGraph: [],
|
|
2804
|
+
value: {},
|
|
2805
|
+
waitingPaths: {},
|
|
2806
|
+
status: "pending",
|
|
2807
|
+
runId,
|
|
2808
|
+
runtimeContext: {}
|
|
2809
|
+
};
|
|
2810
|
+
} else {
|
|
2811
|
+
const existingSnapshot = existingSnapshotResult.recordset[0].snapshot;
|
|
2812
|
+
snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
|
|
2813
|
+
}
|
|
2814
|
+
snapshot.context[stepId] = result;
|
|
2815
|
+
snapshot.runtimeContext = { ...snapshot.runtimeContext, ...runtimeContext };
|
|
2816
|
+
const upsertReq = new sql3__default.default.Request(transaction);
|
|
2817
|
+
upsertReq.input("workflow_name", workflowName);
|
|
2818
|
+
upsertReq.input("run_id", runId);
|
|
2819
|
+
upsertReq.input("snapshot", JSON.stringify(snapshot));
|
|
2820
|
+
upsertReq.input("createdAt", sql3__default.default.DateTime2, /* @__PURE__ */ new Date());
|
|
2821
|
+
upsertReq.input("updatedAt", sql3__default.default.DateTime2, /* @__PURE__ */ new Date());
|
|
2822
|
+
await upsertReq.query(
|
|
2823
|
+
`MERGE ${table} AS target
|
|
2824
|
+
USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
|
|
2825
|
+
ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
|
|
2826
|
+
WHEN MATCHED THEN UPDATE SET snapshot = @snapshot, [updatedAt] = @updatedAt
|
|
2827
|
+
WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, snapshot, [createdAt], [updatedAt])
|
|
2828
|
+
VALUES (@workflow_name, @run_id, @snapshot, @createdAt, @updatedAt);`
|
|
2829
|
+
);
|
|
2830
|
+
await transaction.commit();
|
|
2831
|
+
return snapshot.context;
|
|
1765
2832
|
} catch (error$1) {
|
|
2833
|
+
try {
|
|
2834
|
+
await transaction.rollback();
|
|
2835
|
+
} catch {
|
|
2836
|
+
}
|
|
1766
2837
|
throw new error.MastraError(
|
|
1767
2838
|
{
|
|
1768
|
-
id: "
|
|
2839
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_WORKFLOW_RESULTS_FAILED",
|
|
1769
2840
|
domain: error.ErrorDomain.STORAGE,
|
|
1770
2841
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1771
2842
|
details: {
|
|
1772
|
-
|
|
1773
|
-
|
|
2843
|
+
workflowName,
|
|
2844
|
+
runId,
|
|
2845
|
+
stepId
|
|
1774
2846
|
}
|
|
1775
2847
|
},
|
|
1776
2848
|
error$1
|
|
1777
2849
|
);
|
|
1778
2850
|
}
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
}
|
|
1788
|
-
const dataQuery = `SELECT * FROM ${getTableName({ indexName: storage.TABLE_TRACES, schemaName: getSchemaName(this.schema) })} ${whereClause} ORDER BY [seq_id] DESC OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY`;
|
|
1789
|
-
const dataRequest = this.pool.request();
|
|
1790
|
-
Object.entries(paramMap).forEach(([key, value]) => {
|
|
1791
|
-
if (value instanceof Date) {
|
|
1792
|
-
dataRequest.input(key, sql2__default.default.DateTime, value);
|
|
1793
|
-
} else {
|
|
1794
|
-
dataRequest.input(key, value);
|
|
1795
|
-
}
|
|
1796
|
-
});
|
|
1797
|
-
dataRequest.input("offset", currentOffset);
|
|
1798
|
-
dataRequest.input("limit", perPage);
|
|
2851
|
+
}
|
|
2852
|
+
async updateWorkflowState({
|
|
2853
|
+
workflowName,
|
|
2854
|
+
runId,
|
|
2855
|
+
opts
|
|
2856
|
+
}) {
|
|
2857
|
+
const table = getTableName({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
|
|
2858
|
+
const transaction = this.pool.transaction();
|
|
1799
2859
|
try {
|
|
1800
|
-
|
|
1801
|
-
const
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
2860
|
+
await transaction.begin();
|
|
2861
|
+
const selectRequest = new sql3__default.default.Request(transaction);
|
|
2862
|
+
selectRequest.input("workflow_name", workflowName);
|
|
2863
|
+
selectRequest.input("run_id", runId);
|
|
2864
|
+
const existingSnapshotResult = await selectRequest.query(
|
|
2865
|
+
`SELECT snapshot FROM ${table} WITH (UPDLOCK, HOLDLOCK) WHERE workflow_name = @workflow_name AND run_id = @run_id`
|
|
2866
|
+
);
|
|
2867
|
+
if (!existingSnapshotResult.recordset || existingSnapshotResult.recordset.length === 0) {
|
|
2868
|
+
await transaction.rollback();
|
|
2869
|
+
return void 0;
|
|
2870
|
+
}
|
|
2871
|
+
const existingSnapshot = existingSnapshotResult.recordset[0].snapshot;
|
|
2872
|
+
const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
|
|
2873
|
+
if (!snapshot || !snapshot?.context) {
|
|
2874
|
+
await transaction.rollback();
|
|
2875
|
+
throw new error.MastraError(
|
|
2876
|
+
{
|
|
2877
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_WORKFLOW_STATE_SNAPSHOT_NOT_FOUND",
|
|
2878
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2879
|
+
category: error.ErrorCategory.SYSTEM,
|
|
2880
|
+
details: {
|
|
2881
|
+
workflowName,
|
|
2882
|
+
runId
|
|
2883
|
+
}
|
|
2884
|
+
},
|
|
2885
|
+
new Error(`Snapshot not found for runId ${runId}`)
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
const updatedSnapshot = { ...snapshot, ...opts };
|
|
2889
|
+
const updateRequest = new sql3__default.default.Request(transaction);
|
|
2890
|
+
updateRequest.input("snapshot", JSON.stringify(updatedSnapshot));
|
|
2891
|
+
updateRequest.input("workflow_name", workflowName);
|
|
2892
|
+
updateRequest.input("run_id", runId);
|
|
2893
|
+
updateRequest.input("updatedAt", sql3__default.default.DateTime2, /* @__PURE__ */ new Date());
|
|
2894
|
+
await updateRequest.query(
|
|
2895
|
+
`UPDATE ${table} SET snapshot = @snapshot, [updatedAt] = @updatedAt WHERE workflow_name = @workflow_name AND run_id = @run_id`
|
|
2896
|
+
);
|
|
2897
|
+
await transaction.commit();
|
|
2898
|
+
return updatedSnapshot;
|
|
1825
2899
|
} catch (error$1) {
|
|
2900
|
+
try {
|
|
2901
|
+
await transaction.rollback();
|
|
2902
|
+
} catch {
|
|
2903
|
+
}
|
|
1826
2904
|
throw new error.MastraError(
|
|
1827
2905
|
{
|
|
1828
|
-
id: "
|
|
2906
|
+
id: "MASTRA_STORAGE_MSSQL_STORE_UPDATE_WORKFLOW_STATE_FAILED",
|
|
1829
2907
|
domain: error.ErrorDomain.STORAGE,
|
|
1830
2908
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1831
2909
|
details: {
|
|
1832
|
-
|
|
1833
|
-
|
|
2910
|
+
workflowName,
|
|
2911
|
+
runId
|
|
1834
2912
|
}
|
|
1835
2913
|
},
|
|
1836
2914
|
error$1
|
|
1837
2915
|
);
|
|
1838
2916
|
}
|
|
1839
2917
|
}
|
|
1840
|
-
async batchTraceInsert({ records }) {
|
|
1841
|
-
this.logger.debug("Batch inserting traces", { count: records.length });
|
|
1842
|
-
await this.operations.batchInsert({
|
|
1843
|
-
tableName: storage.TABLE_TRACES,
|
|
1844
|
-
records
|
|
1845
|
-
});
|
|
1846
|
-
}
|
|
1847
|
-
};
|
|
1848
|
-
function parseWorkflowRun(row) {
|
|
1849
|
-
let parsedSnapshot = row.snapshot;
|
|
1850
|
-
if (typeof parsedSnapshot === "string") {
|
|
1851
|
-
try {
|
|
1852
|
-
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1853
|
-
} catch (e) {
|
|
1854
|
-
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
return {
|
|
1858
|
-
workflowName: row.workflow_name,
|
|
1859
|
-
runId: row.run_id,
|
|
1860
|
-
snapshot: parsedSnapshot,
|
|
1861
|
-
createdAt: row.createdAt,
|
|
1862
|
-
updatedAt: row.updatedAt,
|
|
1863
|
-
resourceId: row.resourceId
|
|
1864
|
-
};
|
|
1865
|
-
}
|
|
1866
|
-
var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
1867
|
-
pool;
|
|
1868
|
-
operations;
|
|
1869
|
-
schema;
|
|
1870
|
-
constructor({
|
|
1871
|
-
pool,
|
|
1872
|
-
operations,
|
|
1873
|
-
schema
|
|
1874
|
-
}) {
|
|
1875
|
-
super();
|
|
1876
|
-
this.pool = pool;
|
|
1877
|
-
this.operations = operations;
|
|
1878
|
-
this.schema = schema;
|
|
1879
|
-
}
|
|
1880
|
-
updateWorkflowResults({
|
|
1881
|
-
// workflowName,
|
|
1882
|
-
// runId,
|
|
1883
|
-
// stepId,
|
|
1884
|
-
// result,
|
|
1885
|
-
// runtimeContext,
|
|
1886
|
-
}) {
|
|
1887
|
-
throw new Error("Method not implemented.");
|
|
1888
|
-
}
|
|
1889
|
-
updateWorkflowState({
|
|
1890
|
-
// workflowName,
|
|
1891
|
-
// runId,
|
|
1892
|
-
// opts,
|
|
1893
|
-
}) {
|
|
1894
|
-
throw new Error("Method not implemented.");
|
|
1895
|
-
}
|
|
1896
2918
|
async persistWorkflowSnapshot({
|
|
1897
2919
|
workflowName,
|
|
1898
2920
|
runId,
|
|
2921
|
+
resourceId,
|
|
1899
2922
|
snapshot
|
|
1900
2923
|
}) {
|
|
1901
2924
|
const table = getTableName({ indexName: storage.TABLE_WORKFLOW_SNAPSHOT, schemaName: getSchemaName(this.schema) });
|
|
@@ -1904,17 +2927,19 @@ var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
|
1904
2927
|
const request = this.pool.request();
|
|
1905
2928
|
request.input("workflow_name", workflowName);
|
|
1906
2929
|
request.input("run_id", runId);
|
|
2930
|
+
request.input("resourceId", resourceId);
|
|
1907
2931
|
request.input("snapshot", JSON.stringify(snapshot));
|
|
1908
|
-
request.input("createdAt",
|
|
1909
|
-
request.input("updatedAt",
|
|
2932
|
+
request.input("createdAt", sql3__default.default.DateTime2, new Date(now));
|
|
2933
|
+
request.input("updatedAt", sql3__default.default.DateTime2, new Date(now));
|
|
1910
2934
|
const mergeSql = `MERGE INTO ${table} AS target
|
|
1911
2935
|
USING (SELECT @workflow_name AS workflow_name, @run_id AS run_id) AS src
|
|
1912
2936
|
ON target.workflow_name = src.workflow_name AND target.run_id = src.run_id
|
|
1913
2937
|
WHEN MATCHED THEN UPDATE SET
|
|
2938
|
+
resourceId = @resourceId,
|
|
1914
2939
|
snapshot = @snapshot,
|
|
1915
2940
|
[updatedAt] = @updatedAt
|
|
1916
|
-
WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, snapshot, [createdAt], [updatedAt])
|
|
1917
|
-
VALUES (@workflow_name, @run_id, @snapshot, @createdAt, @updatedAt);`;
|
|
2941
|
+
WHEN NOT MATCHED THEN INSERT (workflow_name, run_id, resourceId, snapshot, [createdAt], [updatedAt])
|
|
2942
|
+
VALUES (@workflow_name, @run_id, @resourceId, @snapshot, @createdAt, @updatedAt);`;
|
|
1918
2943
|
await request.query(mergeSql);
|
|
1919
2944
|
} catch (error$1) {
|
|
1920
2945
|
throw new error.MastraError(
|
|
@@ -1986,7 +3011,7 @@ var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
|
1986
3011
|
if (!result.recordset || result.recordset.length === 0) {
|
|
1987
3012
|
return null;
|
|
1988
3013
|
}
|
|
1989
|
-
return parseWorkflowRun(result.recordset[0]);
|
|
3014
|
+
return this.parseWorkflowRun(result.recordset[0]);
|
|
1990
3015
|
} catch (error$1) {
|
|
1991
3016
|
throw new error.MastraError(
|
|
1992
3017
|
{
|
|
@@ -2023,7 +3048,7 @@ var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
|
2023
3048
|
conditions.push(`[resourceId] = @resourceId`);
|
|
2024
3049
|
paramMap["resourceId"] = resourceId;
|
|
2025
3050
|
} else {
|
|
2026
|
-
|
|
3051
|
+
this.logger?.warn?.(`[${storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
|
|
2027
3052
|
}
|
|
2028
3053
|
}
|
|
2029
3054
|
if (fromDate instanceof Date && !isNaN(fromDate.getTime())) {
|
|
@@ -2040,7 +3065,7 @@ var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
|
2040
3065
|
const request = this.pool.request();
|
|
2041
3066
|
Object.entries(paramMap).forEach(([key, value]) => {
|
|
2042
3067
|
if (value instanceof Date) {
|
|
2043
|
-
request.input(key,
|
|
3068
|
+
request.input(key, sql3__default.default.DateTime, value);
|
|
2044
3069
|
} else {
|
|
2045
3070
|
request.input(key, value);
|
|
2046
3071
|
}
|
|
@@ -2057,7 +3082,7 @@ var WorkflowsMSSQL = class extends storage.WorkflowsStorage {
|
|
|
2057
3082
|
request.input("offset", offset);
|
|
2058
3083
|
}
|
|
2059
3084
|
const result = await request.query(query);
|
|
2060
|
-
const runs = (result.recordset || []).map((row) => parseWorkflowRun(row));
|
|
3085
|
+
const runs = (result.recordset || []).map((row) => this.parseWorkflowRun(row));
|
|
2061
3086
|
return { runs, total: total || runs.length };
|
|
2062
3087
|
} catch (error$1) {
|
|
2063
3088
|
throw new error.MastraError(
|
|
@@ -2097,7 +3122,7 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2097
3122
|
}
|
|
2098
3123
|
}
|
|
2099
3124
|
this.schema = config.schemaName || "dbo";
|
|
2100
|
-
this.pool = "connectionString" in config ? new
|
|
3125
|
+
this.pool = "connectionString" in config ? new sql3__default.default.ConnectionPool(config.connectionString) : new sql3__default.default.ConnectionPool({
|
|
2101
3126
|
server: config.server,
|
|
2102
3127
|
database: config.database,
|
|
2103
3128
|
user: config.user,
|
|
@@ -2108,16 +3133,16 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2108
3133
|
const legacyEvals = new LegacyEvalsMSSQL({ pool: this.pool, schema: this.schema });
|
|
2109
3134
|
const operations = new StoreOperationsMSSQL({ pool: this.pool, schemaName: this.schema });
|
|
2110
3135
|
const scores = new ScoresMSSQL({ pool: this.pool, operations, schema: this.schema });
|
|
2111
|
-
const traces = new TracesMSSQL({ pool: this.pool, operations, schema: this.schema });
|
|
2112
3136
|
const workflows = new WorkflowsMSSQL({ pool: this.pool, operations, schema: this.schema });
|
|
2113
3137
|
const memory = new MemoryMSSQL({ pool: this.pool, schema: this.schema, operations });
|
|
3138
|
+
const observability = new ObservabilityMSSQL({ pool: this.pool, operations, schema: this.schema });
|
|
2114
3139
|
this.stores = {
|
|
2115
3140
|
operations,
|
|
2116
3141
|
scores,
|
|
2117
|
-
traces,
|
|
2118
3142
|
workflows,
|
|
2119
3143
|
legacyEvals,
|
|
2120
|
-
memory
|
|
3144
|
+
memory,
|
|
3145
|
+
observability
|
|
2121
3146
|
};
|
|
2122
3147
|
} catch (e) {
|
|
2123
3148
|
throw new error.MastraError(
|
|
@@ -2137,6 +3162,11 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2137
3162
|
try {
|
|
2138
3163
|
await this.isConnected;
|
|
2139
3164
|
await super.init();
|
|
3165
|
+
try {
|
|
3166
|
+
await this.stores.operations.createAutomaticIndexes();
|
|
3167
|
+
} catch (indexError) {
|
|
3168
|
+
this.logger?.warn?.("Failed to create indexes:", indexError);
|
|
3169
|
+
}
|
|
2140
3170
|
} catch (error$1) {
|
|
2141
3171
|
this.isConnected = null;
|
|
2142
3172
|
throw new error.MastraError(
|
|
@@ -2163,7 +3193,10 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2163
3193
|
resourceWorkingMemory: true,
|
|
2164
3194
|
hasColumn: true,
|
|
2165
3195
|
createTable: true,
|
|
2166
|
-
deleteMessages: true
|
|
3196
|
+
deleteMessages: true,
|
|
3197
|
+
getScoresBySpan: true,
|
|
3198
|
+
aiTracing: true,
|
|
3199
|
+
indexManagement: true
|
|
2167
3200
|
};
|
|
2168
3201
|
}
|
|
2169
3202
|
/** @deprecated use getEvals instead */
|
|
@@ -2173,18 +3206,6 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2173
3206
|
async getEvals(options = {}) {
|
|
2174
3207
|
return this.stores.legacyEvals.getEvals(options);
|
|
2175
3208
|
}
|
|
2176
|
-
/**
|
|
2177
|
-
* @deprecated use getTracesPaginated instead
|
|
2178
|
-
*/
|
|
2179
|
-
async getTraces(args) {
|
|
2180
|
-
return this.stores.traces.getTraces(args);
|
|
2181
|
-
}
|
|
2182
|
-
async getTracesPaginated(args) {
|
|
2183
|
-
return this.stores.traces.getTracesPaginated(args);
|
|
2184
|
-
}
|
|
2185
|
-
async batchTraceInsert({ records }) {
|
|
2186
|
-
return this.stores.traces.batchTraceInsert({ records });
|
|
2187
|
-
}
|
|
2188
3209
|
async createTable({
|
|
2189
3210
|
tableName,
|
|
2190
3211
|
schema
|
|
@@ -2299,9 +3320,10 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2299
3320
|
async persistWorkflowSnapshot({
|
|
2300
3321
|
workflowName,
|
|
2301
3322
|
runId,
|
|
3323
|
+
resourceId,
|
|
2302
3324
|
snapshot
|
|
2303
3325
|
}) {
|
|
2304
|
-
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
|
|
3326
|
+
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
2305
3327
|
}
|
|
2306
3328
|
async loadWorkflowSnapshot({
|
|
2307
3329
|
workflowName,
|
|
@@ -2328,6 +3350,60 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2328
3350
|
async close() {
|
|
2329
3351
|
await this.pool.close();
|
|
2330
3352
|
}
|
|
3353
|
+
/**
|
|
3354
|
+
* Index Management
|
|
3355
|
+
*/
|
|
3356
|
+
async createIndex(options) {
|
|
3357
|
+
return this.stores.operations.createIndex(options);
|
|
3358
|
+
}
|
|
3359
|
+
async listIndexes(tableName) {
|
|
3360
|
+
return this.stores.operations.listIndexes(tableName);
|
|
3361
|
+
}
|
|
3362
|
+
async describeIndex(indexName) {
|
|
3363
|
+
return this.stores.operations.describeIndex(indexName);
|
|
3364
|
+
}
|
|
3365
|
+
async dropIndex(indexName) {
|
|
3366
|
+
return this.stores.operations.dropIndex(indexName);
|
|
3367
|
+
}
|
|
3368
|
+
/**
|
|
3369
|
+
* AI Tracing / Observability
|
|
3370
|
+
*/
|
|
3371
|
+
getObservabilityStore() {
|
|
3372
|
+
if (!this.stores.observability) {
|
|
3373
|
+
throw new error.MastraError({
|
|
3374
|
+
id: "MSSQL_STORE_OBSERVABILITY_NOT_INITIALIZED",
|
|
3375
|
+
domain: error.ErrorDomain.STORAGE,
|
|
3376
|
+
category: error.ErrorCategory.SYSTEM,
|
|
3377
|
+
text: "Observability storage is not initialized"
|
|
3378
|
+
});
|
|
3379
|
+
}
|
|
3380
|
+
return this.stores.observability;
|
|
3381
|
+
}
|
|
3382
|
+
async createAISpan(span) {
|
|
3383
|
+
return this.getObservabilityStore().createAISpan(span);
|
|
3384
|
+
}
|
|
3385
|
+
async updateAISpan({
|
|
3386
|
+
spanId,
|
|
3387
|
+
traceId,
|
|
3388
|
+
updates
|
|
3389
|
+
}) {
|
|
3390
|
+
return this.getObservabilityStore().updateAISpan({ spanId, traceId, updates });
|
|
3391
|
+
}
|
|
3392
|
+
async getAITrace(traceId) {
|
|
3393
|
+
return this.getObservabilityStore().getAITrace(traceId);
|
|
3394
|
+
}
|
|
3395
|
+
async getAITracesPaginated(args) {
|
|
3396
|
+
return this.getObservabilityStore().getAITracesPaginated(args);
|
|
3397
|
+
}
|
|
3398
|
+
async batchCreateAISpans(args) {
|
|
3399
|
+
return this.getObservabilityStore().batchCreateAISpans(args);
|
|
3400
|
+
}
|
|
3401
|
+
async batchUpdateAISpans(args) {
|
|
3402
|
+
return this.getObservabilityStore().batchUpdateAISpans(args);
|
|
3403
|
+
}
|
|
3404
|
+
async batchDeleteAITraces(args) {
|
|
3405
|
+
return this.getObservabilityStore().batchDeleteAITraces(args);
|
|
3406
|
+
}
|
|
2331
3407
|
/**
|
|
2332
3408
|
* Scorers
|
|
2333
3409
|
*/
|
|
@@ -2336,9 +3412,18 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2336
3412
|
}
|
|
2337
3413
|
async getScoresByScorerId({
|
|
2338
3414
|
scorerId: _scorerId,
|
|
2339
|
-
pagination: _pagination
|
|
3415
|
+
pagination: _pagination,
|
|
3416
|
+
entityId: _entityId,
|
|
3417
|
+
entityType: _entityType,
|
|
3418
|
+
source: _source
|
|
2340
3419
|
}) {
|
|
2341
|
-
return this.stores.scores.getScoresByScorerId({
|
|
3420
|
+
return this.stores.scores.getScoresByScorerId({
|
|
3421
|
+
scorerId: _scorerId,
|
|
3422
|
+
pagination: _pagination,
|
|
3423
|
+
entityId: _entityId,
|
|
3424
|
+
entityType: _entityType,
|
|
3425
|
+
source: _source
|
|
3426
|
+
});
|
|
2342
3427
|
}
|
|
2343
3428
|
async saveScore(_score) {
|
|
2344
3429
|
return this.stores.scores.saveScore(_score);
|
|
@@ -2360,6 +3445,13 @@ var MSSQLStore = class extends storage.MastraStorage {
|
|
|
2360
3445
|
pagination: _pagination
|
|
2361
3446
|
});
|
|
2362
3447
|
}
|
|
3448
|
+
async getScoresBySpan({
|
|
3449
|
+
traceId,
|
|
3450
|
+
spanId,
|
|
3451
|
+
pagination: _pagination
|
|
3452
|
+
}) {
|
|
3453
|
+
return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination: _pagination });
|
|
3454
|
+
}
|
|
2363
3455
|
};
|
|
2364
3456
|
|
|
2365
3457
|
exports.MSSQLStore = MSSQLStore;
|