@mastra/mongodb 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +57 -0
- package/LICENSE.md +11 -42
- package/dist/_tsup-dts-rollup.d.cts +376 -54
- package/dist/_tsup-dts-rollup.d.ts +376 -54
- package/dist/index.cjs +1420 -424
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1414 -418
- package/docker-compose.yaml +1 -1
- package/package.json +6 -6
- package/src/storage/ConnectorHandler.ts +7 -0
- package/src/storage/MongoDBConnector.ts +93 -0
- package/src/storage/connectors/MongoDBConnector.ts +93 -0
- package/src/storage/connectors/base.ts +7 -0
- package/src/storage/domains/legacy-evals/index.ts +193 -0
- package/src/storage/domains/memory/index.ts +741 -0
- package/src/storage/domains/operations/index.ts +152 -0
- package/src/storage/domains/scores/index.ts +379 -0
- package/src/storage/domains/traces/index.ts +142 -0
- package/src/storage/domains/utils.ts +43 -0
- package/src/storage/domains/workflows/index.ts +196 -0
- package/src/storage/index.test.ts +24 -1226
- package/src/storage/index.ts +218 -776
- package/src/storage/types.ts +14 -0
- package/src/vector/index.test.ts +16 -1
- package/src/vector/index.ts +34 -11
package/src/storage/index.ts
CHANGED
|
@@ -1,272 +1,175 @@
|
|
|
1
|
-
import { MessageList } from '@mastra/core/agent';
|
|
2
1
|
import type { MastraMessageContentV2 } from '@mastra/core/agent';
|
|
3
2
|
import { ErrorDomain, ErrorCategory, MastraError } from '@mastra/core/error';
|
|
4
|
-
import type { MetricResult, TestInfo } from '@mastra/core/eval';
|
|
5
3
|
import type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';
|
|
4
|
+
import type { ScoreRowData } from '@mastra/core/scores';
|
|
6
5
|
import type {
|
|
7
6
|
EvalRow,
|
|
7
|
+
PaginationArgs,
|
|
8
8
|
PaginationInfo,
|
|
9
9
|
StorageColumn,
|
|
10
10
|
StorageGetMessagesArg,
|
|
11
11
|
StorageGetTracesArg,
|
|
12
12
|
TABLE_NAMES,
|
|
13
13
|
WorkflowRun,
|
|
14
|
+
WorkflowRuns,
|
|
15
|
+
StorageResourceType,
|
|
16
|
+
StorageDomains,
|
|
17
|
+
StoragePagination,
|
|
18
|
+
StorageGetTracesPaginatedArg,
|
|
14
19
|
} from '@mastra/core/storage';
|
|
15
|
-
import {
|
|
16
|
-
MastraStorage,
|
|
17
|
-
TABLE_EVALS,
|
|
18
|
-
TABLE_MESSAGES,
|
|
19
|
-
TABLE_THREADS,
|
|
20
|
-
TABLE_TRACES,
|
|
21
|
-
TABLE_WORKFLOW_SNAPSHOT,
|
|
22
|
-
} from '@mastra/core/storage';
|
|
20
|
+
import { MastraStorage } from '@mastra/core/storage';
|
|
23
21
|
import type { Trace } from '@mastra/core/telemetry';
|
|
24
22
|
import type { WorkflowRunState } from '@mastra/core/workflows';
|
|
25
|
-
import
|
|
26
|
-
import {
|
|
23
|
+
import { MongoDBConnector } from './connectors/MongoDBConnector';
|
|
24
|
+
import { LegacyEvalsMongoDB } from './domains/legacy-evals';
|
|
25
|
+
import { MemoryStorageMongoDB } from './domains/memory';
|
|
26
|
+
import { StoreOperationsMongoDB } from './domains/operations';
|
|
27
|
+
import { ScoresStorageMongoDB } from './domains/scores';
|
|
28
|
+
import { TracesStorageMongoDB } from './domains/traces';
|
|
29
|
+
import { WorkflowsStorageMongoDB } from './domains/workflows';
|
|
30
|
+
import type { MongoDBConfig } from './types';
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return JSON.parse(jsonString);
|
|
31
|
-
} catch {
|
|
32
|
-
return {};
|
|
33
|
-
}
|
|
34
|
-
}
|
|
32
|
+
export class MongoDBStore extends MastraStorage {
|
|
33
|
+
#connector: MongoDBConnector;
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
url: string;
|
|
38
|
-
dbName: string;
|
|
39
|
-
options?: MongoClientOptions;
|
|
40
|
-
}
|
|
35
|
+
stores: StorageDomains;
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
public get supports(): {
|
|
38
|
+
selectByIncludeResourceScope: boolean;
|
|
39
|
+
resourceWorkingMemory: boolean;
|
|
40
|
+
hasColumn: boolean;
|
|
41
|
+
createTable: boolean;
|
|
42
|
+
} {
|
|
43
|
+
return {
|
|
44
|
+
selectByIncludeResourceScope: true,
|
|
45
|
+
resourceWorkingMemory: true,
|
|
46
|
+
hasColumn: false,
|
|
47
|
+
createTable: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
47
50
|
|
|
48
51
|
constructor(config: MongoDBConfig) {
|
|
49
52
|
super({ name: 'MongoDBStore' });
|
|
50
|
-
|
|
53
|
+
|
|
54
|
+
this.stores = {} as StorageDomains;
|
|
51
55
|
|
|
52
56
|
try {
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
);
|
|
57
|
+
if ('connectorHandler' in config) {
|
|
58
|
+
this.#connector = MongoDBConnector.fromConnectionHandler(config.connectorHandler);
|
|
59
|
+
return;
|
|
57
60
|
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw new MastraError(
|
|
63
|
+
{
|
|
64
|
+
id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
|
|
65
|
+
domain: ErrorDomain.STORAGE,
|
|
66
|
+
category: ErrorCategory.USER,
|
|
67
|
+
details: { connectionHandler: true },
|
|
68
|
+
},
|
|
69
|
+
error,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
58
72
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
73
|
+
try {
|
|
74
|
+
this.#connector = MongoDBConnector.fromDatabaseConfig({
|
|
75
|
+
options: config.options,
|
|
76
|
+
url: config.url,
|
|
77
|
+
dbName: config.dbName,
|
|
78
|
+
});
|
|
64
79
|
} catch (error) {
|
|
65
80
|
throw new MastraError(
|
|
66
81
|
{
|
|
67
82
|
id: 'STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED',
|
|
68
83
|
domain: ErrorDomain.STORAGE,
|
|
69
84
|
category: ErrorCategory.USER,
|
|
70
|
-
details: { url: config
|
|
85
|
+
details: { url: config?.url, dbName: config?.dbName },
|
|
71
86
|
},
|
|
72
87
|
error,
|
|
73
88
|
);
|
|
74
89
|
}
|
|
75
90
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
91
|
+
const operations = new StoreOperationsMongoDB({
|
|
92
|
+
connector: this.#connector,
|
|
93
|
+
});
|
|
79
94
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
95
|
+
const memory = new MemoryStorageMongoDB({
|
|
96
|
+
operations,
|
|
97
|
+
});
|
|
84
98
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
const traces = new TracesStorageMongoDB({
|
|
100
|
+
operations,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const legacyEvals = new LegacyEvalsMongoDB({
|
|
104
|
+
operations,
|
|
105
|
+
});
|
|
90
106
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
107
|
+
const scores = new ScoresStorageMongoDB({
|
|
108
|
+
operations,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const workflows = new WorkflowsStorageMongoDB({
|
|
112
|
+
operations,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
this.stores = {
|
|
116
|
+
operations,
|
|
117
|
+
memory,
|
|
118
|
+
traces,
|
|
119
|
+
legacyEvals,
|
|
120
|
+
scores,
|
|
121
|
+
workflows,
|
|
122
|
+
};
|
|
94
123
|
}
|
|
95
124
|
|
|
96
|
-
async createTable(
|
|
97
|
-
|
|
125
|
+
async createTable({
|
|
126
|
+
tableName,
|
|
127
|
+
schema,
|
|
128
|
+
}: {
|
|
129
|
+
tableName: TABLE_NAMES;
|
|
130
|
+
schema: Record<string, StorageColumn>;
|
|
131
|
+
}): Promise<void> {
|
|
132
|
+
return this.stores.operations.createTable({ tableName, schema });
|
|
98
133
|
}
|
|
99
134
|
|
|
100
|
-
/**
|
|
101
|
-
* No-op: This backend is schemaless and does not require schema changes.
|
|
102
|
-
* @param tableName Name of the table
|
|
103
|
-
* @param schema Schema of the table
|
|
104
|
-
* @param ifNotExists Array of column names to add if they don't exist
|
|
105
|
-
*/
|
|
106
135
|
async alterTable(_args: {
|
|
107
136
|
tableName: TABLE_NAMES;
|
|
108
137
|
schema: Record<string, StorageColumn>;
|
|
109
138
|
ifNotExists: string[];
|
|
110
139
|
}): Promise<void> {
|
|
111
|
-
|
|
140
|
+
return this.stores.operations.alterTable(_args);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
|
|
144
|
+
return this.stores.operations.dropTable({ tableName });
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
|
|
115
|
-
|
|
116
|
-
const collection = await this.getCollection(tableName);
|
|
117
|
-
await collection.deleteMany({});
|
|
118
|
-
} catch (error) {
|
|
119
|
-
if (error instanceof Error) {
|
|
120
|
-
const matstraError = new MastraError(
|
|
121
|
-
{
|
|
122
|
-
id: 'STORAGE_MONGODB_STORE_CLEAR_TABLE_FAILED',
|
|
123
|
-
domain: ErrorDomain.STORAGE,
|
|
124
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
125
|
-
details: { tableName },
|
|
126
|
-
},
|
|
127
|
-
error,
|
|
128
|
-
);
|
|
129
|
-
this.logger.error(matstraError.message);
|
|
130
|
-
this.logger?.trackException(matstraError);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
148
|
+
return this.stores.operations.clearTable({ tableName });
|
|
133
149
|
}
|
|
134
150
|
|
|
135
151
|
async insert({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {
|
|
136
|
-
|
|
137
|
-
const collection = await this.getCollection(tableName);
|
|
138
|
-
await collection.insertOne(record);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
if (error instanceof Error) {
|
|
141
|
-
const matstraError = new MastraError(
|
|
142
|
-
{
|
|
143
|
-
id: 'STORAGE_MONGODB_STORE_INSERT_FAILED',
|
|
144
|
-
domain: ErrorDomain.STORAGE,
|
|
145
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
146
|
-
details: { tableName },
|
|
147
|
-
},
|
|
148
|
-
error,
|
|
149
|
-
);
|
|
150
|
-
this.logger.error(matstraError.message);
|
|
151
|
-
this.logger?.trackException(matstraError);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
152
|
+
return this.stores.operations.insert({ tableName, record });
|
|
154
153
|
}
|
|
155
154
|
|
|
156
155
|
async batchInsert({ tableName, records }: { tableName: TABLE_NAMES; records: Record<string, any>[] }): Promise<void> {
|
|
157
|
-
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
const collection = await this.getCollection(tableName);
|
|
163
|
-
await collection.insertMany(records);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
throw new MastraError(
|
|
166
|
-
{
|
|
167
|
-
id: 'STORAGE_MONGODB_STORE_BATCH_INSERT_FAILED',
|
|
168
|
-
domain: ErrorDomain.STORAGE,
|
|
169
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
170
|
-
details: { tableName },
|
|
171
|
-
},
|
|
172
|
-
error,
|
|
173
|
-
);
|
|
174
|
-
}
|
|
156
|
+
return this.stores.operations.batchInsert({ tableName, records });
|
|
175
157
|
}
|
|
176
158
|
|
|
177
159
|
async load<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {
|
|
178
|
-
this.
|
|
179
|
-
try {
|
|
180
|
-
const collection = await this.getCollection(tableName);
|
|
181
|
-
return (await collection.find(keys).toArray()) as R;
|
|
182
|
-
} catch (error) {
|
|
183
|
-
throw new MastraError(
|
|
184
|
-
{
|
|
185
|
-
id: 'STORAGE_MONGODB_STORE_LOAD_FAILED',
|
|
186
|
-
domain: ErrorDomain.STORAGE,
|
|
187
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
188
|
-
details: { tableName },
|
|
189
|
-
},
|
|
190
|
-
error,
|
|
191
|
-
);
|
|
192
|
-
}
|
|
160
|
+
return this.stores.operations.load({ tableName, keys });
|
|
193
161
|
}
|
|
194
162
|
|
|
195
163
|
async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
|
|
196
|
-
|
|
197
|
-
const collection = await this.getCollection(TABLE_THREADS);
|
|
198
|
-
const result = await collection.findOne<any>({ id: threadId });
|
|
199
|
-
if (!result) {
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return {
|
|
204
|
-
...result,
|
|
205
|
-
metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
|
|
206
|
-
};
|
|
207
|
-
} catch (error) {
|
|
208
|
-
throw new MastraError(
|
|
209
|
-
{
|
|
210
|
-
id: 'STORAGE_MONGODB_STORE_GET_THREAD_BY_ID_FAILED',
|
|
211
|
-
domain: ErrorDomain.STORAGE,
|
|
212
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
213
|
-
details: { threadId },
|
|
214
|
-
},
|
|
215
|
-
error,
|
|
216
|
-
);
|
|
217
|
-
}
|
|
164
|
+
return this.stores.memory.getThreadById({ threadId });
|
|
218
165
|
}
|
|
219
166
|
|
|
220
167
|
async getThreadsByResourceId({ resourceId }: { resourceId: string }): Promise<StorageThreadType[]> {
|
|
221
|
-
|
|
222
|
-
const collection = await this.getCollection(TABLE_THREADS);
|
|
223
|
-
const results = await collection.find<any>({ resourceId }).toArray();
|
|
224
|
-
if (!results.length) {
|
|
225
|
-
return [];
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return results.map(result => ({
|
|
229
|
-
...result,
|
|
230
|
-
metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
|
|
231
|
-
}));
|
|
232
|
-
} catch (error) {
|
|
233
|
-
throw new MastraError(
|
|
234
|
-
{
|
|
235
|
-
id: 'STORAGE_MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
|
|
236
|
-
domain: ErrorDomain.STORAGE,
|
|
237
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
238
|
-
details: { resourceId },
|
|
239
|
-
},
|
|
240
|
-
error,
|
|
241
|
-
);
|
|
242
|
-
}
|
|
168
|
+
return this.stores.memory.getThreadsByResourceId({ resourceId });
|
|
243
169
|
}
|
|
244
170
|
|
|
245
171
|
async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
|
|
246
|
-
|
|
247
|
-
const collection = await this.getCollection(TABLE_THREADS);
|
|
248
|
-
await collection.updateOne(
|
|
249
|
-
{ id: thread.id },
|
|
250
|
-
{
|
|
251
|
-
$set: {
|
|
252
|
-
...thread,
|
|
253
|
-
metadata: JSON.stringify(thread.metadata),
|
|
254
|
-
},
|
|
255
|
-
},
|
|
256
|
-
{ upsert: true },
|
|
257
|
-
);
|
|
258
|
-
return thread;
|
|
259
|
-
} catch (error) {
|
|
260
|
-
throw new MastraError(
|
|
261
|
-
{
|
|
262
|
-
id: 'STORAGE_MONGODB_STORE_SAVE_THREAD_FAILED',
|
|
263
|
-
domain: ErrorDomain.STORAGE,
|
|
264
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
265
|
-
details: { threadId: thread.id },
|
|
266
|
-
},
|
|
267
|
-
error,
|
|
268
|
-
);
|
|
269
|
-
}
|
|
172
|
+
return this.stores.memory.saveThread({ thread });
|
|
270
173
|
}
|
|
271
174
|
|
|
272
175
|
async updateThread({
|
|
@@ -278,71 +181,11 @@ export class MongoDBStore extends MastraStorage {
|
|
|
278
181
|
title: string;
|
|
279
182
|
metadata: Record<string, unknown>;
|
|
280
183
|
}): Promise<StorageThreadType> {
|
|
281
|
-
|
|
282
|
-
if (!thread) {
|
|
283
|
-
throw new MastraError({
|
|
284
|
-
id: 'STORAGE_MONGODB_STORE_UPDATE_THREAD_NOT_FOUND',
|
|
285
|
-
domain: ErrorDomain.STORAGE,
|
|
286
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
287
|
-
details: { threadId: id },
|
|
288
|
-
text: `Thread ${id} not found`,
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const updatedThread = {
|
|
293
|
-
...thread,
|
|
294
|
-
title,
|
|
295
|
-
metadata: {
|
|
296
|
-
...thread.metadata,
|
|
297
|
-
...metadata,
|
|
298
|
-
},
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
try {
|
|
302
|
-
const collection = await this.getCollection(TABLE_THREADS);
|
|
303
|
-
await collection.updateOne(
|
|
304
|
-
{ id },
|
|
305
|
-
{
|
|
306
|
-
$set: {
|
|
307
|
-
title,
|
|
308
|
-
metadata: JSON.stringify(updatedThread.metadata),
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
);
|
|
312
|
-
} catch (error) {
|
|
313
|
-
throw new MastraError(
|
|
314
|
-
{
|
|
315
|
-
id: 'STORAGE_MONGODB_STORE_UPDATE_THREAD_FAILED',
|
|
316
|
-
domain: ErrorDomain.STORAGE,
|
|
317
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
318
|
-
details: { threadId: id },
|
|
319
|
-
},
|
|
320
|
-
error,
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return updatedThread;
|
|
184
|
+
return this.stores.memory.updateThread({ id, title, metadata });
|
|
325
185
|
}
|
|
326
186
|
|
|
327
187
|
async deleteThread({ threadId }: { threadId: string }): Promise<void> {
|
|
328
|
-
|
|
329
|
-
// First, delete all messages associated with the thread
|
|
330
|
-
const collectionMessages = await this.getCollection(TABLE_MESSAGES);
|
|
331
|
-
await collectionMessages.deleteMany({ thread_id: threadId });
|
|
332
|
-
// Then delete the thread itself
|
|
333
|
-
const collectionThreads = await this.getCollection(TABLE_THREADS);
|
|
334
|
-
await collectionThreads.deleteOne({ id: threadId });
|
|
335
|
-
} catch (error) {
|
|
336
|
-
throw new MastraError(
|
|
337
|
-
{
|
|
338
|
-
id: 'STORAGE_MONGODB_STORE_DELETE_THREAD_FAILED',
|
|
339
|
-
domain: ErrorDomain.STORAGE,
|
|
340
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
341
|
-
details: { threadId },
|
|
342
|
-
},
|
|
343
|
-
error,
|
|
344
|
-
);
|
|
345
|
-
}
|
|
188
|
+
return this.stores.memory.deleteThread({ threadId });
|
|
346
189
|
}
|
|
347
190
|
|
|
348
191
|
public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;
|
|
@@ -354,353 +197,71 @@ export class MongoDBStore extends MastraStorage {
|
|
|
354
197
|
}: StorageGetMessagesArg & {
|
|
355
198
|
format?: 'v1' | 'v2';
|
|
356
199
|
}): Promise<MastraMessageV1[] | MastraMessageV2[]> {
|
|
357
|
-
|
|
358
|
-
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
359
|
-
const include = selectBy?.include || [];
|
|
360
|
-
let messages: MastraMessageV2[] = [];
|
|
361
|
-
let allMessages: MastraMessageV2[] = [];
|
|
362
|
-
const collection = await this.getCollection(TABLE_MESSAGES);
|
|
363
|
-
// Get all messages from the thread ordered by creation date descending
|
|
364
|
-
allMessages = (await collection.find({ thread_id: threadId }).sort({ createdAt: -1 }).toArray()).map((row: any) =>
|
|
365
|
-
this.parseRow(row),
|
|
366
|
-
);
|
|
367
|
-
|
|
368
|
-
// If there are messages to include, select the messages around the included IDs
|
|
369
|
-
if (include.length) {
|
|
370
|
-
// Map IDs to their position in the ordered array
|
|
371
|
-
const idToIndex = new Map<string, number>();
|
|
372
|
-
allMessages.forEach((msg, idx) => {
|
|
373
|
-
idToIndex.set(msg.id, idx);
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
const selectedIndexes = new Set<number>();
|
|
377
|
-
for (const inc of include) {
|
|
378
|
-
const idx = idToIndex.get(inc.id);
|
|
379
|
-
if (idx === undefined) continue;
|
|
380
|
-
// Previous messages
|
|
381
|
-
for (let i = 1; i <= (inc.withPreviousMessages || 0); i++) {
|
|
382
|
-
if (idx + i < allMessages.length) selectedIndexes.add(idx + i);
|
|
383
|
-
}
|
|
384
|
-
// Included message
|
|
385
|
-
selectedIndexes.add(idx);
|
|
386
|
-
// Next messages
|
|
387
|
-
for (let i = 1; i <= (inc.withNextMessages || 0); i++) {
|
|
388
|
-
if (idx - i >= 0) selectedIndexes.add(idx - i);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
// Add the selected messages, filtering out undefined
|
|
392
|
-
messages.push(
|
|
393
|
-
...Array.from(selectedIndexes)
|
|
394
|
-
.map(i => allMessages[i])
|
|
395
|
-
.filter((m): m is MastraMessageV2 => !!m),
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// Get the remaining messages, excluding those already selected
|
|
400
|
-
const excludeIds = new Set(messages.map(m => m.id));
|
|
401
|
-
for (const msg of allMessages) {
|
|
402
|
-
if (messages.length >= limit) break;
|
|
403
|
-
if (!excludeIds.has(msg.id)) {
|
|
404
|
-
messages.push(msg);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Sort all messages by creation date ascending
|
|
409
|
-
messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
410
|
-
|
|
411
|
-
const list = new MessageList().add(messages.slice(0, limit), 'memory');
|
|
412
|
-
if (format === `v2`) return list.get.all.v2();
|
|
413
|
-
return list.get.all.v1();
|
|
414
|
-
} catch (error) {
|
|
415
|
-
throw new MastraError(
|
|
416
|
-
{
|
|
417
|
-
id: 'STORAGE_MONGODB_STORE_GET_MESSAGES_FAILED',
|
|
418
|
-
domain: ErrorDomain.STORAGE,
|
|
419
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
420
|
-
details: { threadId },
|
|
421
|
-
},
|
|
422
|
-
error,
|
|
423
|
-
);
|
|
424
|
-
}
|
|
200
|
+
return this.stores.memory.getMessages({ threadId, selectBy, format });
|
|
425
201
|
}
|
|
426
202
|
|
|
427
203
|
async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;
|
|
428
204
|
async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;
|
|
429
|
-
async saveMessages(
|
|
430
|
-
messages,
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
| { messages: MastraMessageV1[]; format?: undefined | 'v1' }
|
|
434
|
-
| { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[] | MastraMessageV1[]> {
|
|
435
|
-
if (!messages.length) {
|
|
436
|
-
return messages;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
const threadId = messages[0]?.threadId;
|
|
440
|
-
if (!threadId) {
|
|
441
|
-
this.logger.error('Thread ID is required to save messages');
|
|
442
|
-
throw new Error('Thread ID is required');
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
try {
|
|
446
|
-
// Prepare batch statements for all messages
|
|
447
|
-
const messagesToInsert = messages.map(message => {
|
|
448
|
-
const time = message.createdAt || new Date();
|
|
449
|
-
return {
|
|
450
|
-
id: message.id,
|
|
451
|
-
thread_id: threadId,
|
|
452
|
-
content: typeof message.content === 'string' ? message.content : JSON.stringify(message.content),
|
|
453
|
-
role: message.role,
|
|
454
|
-
type: message.type,
|
|
455
|
-
resourceId: message.resourceId,
|
|
456
|
-
createdAt: time instanceof Date ? time.toISOString() : time,
|
|
457
|
-
};
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
// Execute message inserts and thread update in parallel for better performance
|
|
461
|
-
const collection = await this.getCollection(TABLE_MESSAGES);
|
|
462
|
-
const threadsCollection = await this.getCollection(TABLE_THREADS);
|
|
463
|
-
|
|
464
|
-
await Promise.all([
|
|
465
|
-
collection.bulkWrite(
|
|
466
|
-
messagesToInsert.map(msg => ({
|
|
467
|
-
updateOne: {
|
|
468
|
-
filter: { id: msg.id },
|
|
469
|
-
update: { $set: msg },
|
|
470
|
-
upsert: true,
|
|
471
|
-
},
|
|
472
|
-
})),
|
|
473
|
-
),
|
|
474
|
-
threadsCollection.updateOne({ id: threadId }, { $set: { updatedAt: new Date() } }),
|
|
475
|
-
]);
|
|
476
|
-
|
|
477
|
-
const list = new MessageList().add(messages, 'memory');
|
|
478
|
-
if (format === `v2`) return list.get.all.v2();
|
|
479
|
-
return list.get.all.v1();
|
|
480
|
-
} catch (error) {
|
|
481
|
-
this.logger.error('Failed to save messages in database: ' + (error as { message: string })?.message);
|
|
482
|
-
throw error;
|
|
483
|
-
}
|
|
205
|
+
async saveMessages(
|
|
206
|
+
args: { messages: MastraMessageV1[]; format?: undefined | 'v1' } | { messages: MastraMessageV2[]; format: 'v2' },
|
|
207
|
+
): Promise<MastraMessageV2[] | MastraMessageV1[]> {
|
|
208
|
+
return this.stores.memory.saveMessages(args);
|
|
484
209
|
}
|
|
485
210
|
|
|
486
|
-
async
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
filters,
|
|
494
|
-
}: {
|
|
495
|
-
name?: string;
|
|
496
|
-
scope?: string;
|
|
497
|
-
page: number;
|
|
498
|
-
perPage: number;
|
|
499
|
-
attributes?: Record<string, string>;
|
|
500
|
-
filters?: Record<string, any>;
|
|
501
|
-
} = {
|
|
502
|
-
page: 0,
|
|
503
|
-
perPage: 100,
|
|
504
|
-
},
|
|
505
|
-
): Promise<any[]> {
|
|
506
|
-
const limit = perPage;
|
|
507
|
-
const offset = page * perPage;
|
|
508
|
-
|
|
509
|
-
const query: any = {};
|
|
510
|
-
if (name) {
|
|
511
|
-
query['name'] = new RegExp(name);
|
|
512
|
-
}
|
|
211
|
+
async getThreadsByResourceIdPaginated(_args: {
|
|
212
|
+
resourceId: string;
|
|
213
|
+
page: number;
|
|
214
|
+
perPage: number;
|
|
215
|
+
}): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
|
|
216
|
+
return this.stores.memory.getThreadsByResourceIdPaginated(_args);
|
|
217
|
+
}
|
|
513
218
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
219
|
+
async getMessagesPaginated(
|
|
220
|
+
_args: StorageGetMessagesArg,
|
|
221
|
+
): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
|
|
222
|
+
return this.stores.memory.getMessagesPaginated(_args);
|
|
223
|
+
}
|
|
517
224
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
225
|
+
async updateMessages(_args: {
|
|
226
|
+
messages: Partial<Omit<MastraMessageV2, 'createdAt'>> &
|
|
227
|
+
{
|
|
228
|
+
id: string;
|
|
229
|
+
content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
|
|
230
|
+
}[];
|
|
231
|
+
}): Promise<MastraMessageV2[]> {
|
|
232
|
+
return this.stores.memory.updateMessages(_args);
|
|
233
|
+
}
|
|
523
234
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
});
|
|
528
|
-
}
|
|
235
|
+
async getTraces(args: StorageGetTracesArg): Promise<Trace[]> {
|
|
236
|
+
return this.stores.traces.getTraces(args);
|
|
237
|
+
}
|
|
529
238
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const result = await collection
|
|
533
|
-
.find(query, {
|
|
534
|
-
sort: { startTime: -1 },
|
|
535
|
-
})
|
|
536
|
-
.limit(limit)
|
|
537
|
-
.skip(offset)
|
|
538
|
-
.toArray();
|
|
539
|
-
|
|
540
|
-
return result.map(row => ({
|
|
541
|
-
id: row.id,
|
|
542
|
-
parentSpanId: row.parentSpanId,
|
|
543
|
-
traceId: row.traceId,
|
|
544
|
-
name: row.name,
|
|
545
|
-
scope: row.scope,
|
|
546
|
-
kind: row.kind,
|
|
547
|
-
status: safelyParseJSON(row.status as string),
|
|
548
|
-
events: safelyParseJSON(row.events as string),
|
|
549
|
-
links: safelyParseJSON(row.links as string),
|
|
550
|
-
attributes: safelyParseJSON(row.attributes as string),
|
|
551
|
-
startTime: row.startTime,
|
|
552
|
-
endTime: row.endTime,
|
|
553
|
-
other: safelyParseJSON(row.other as string),
|
|
554
|
-
createdAt: row.createdAt,
|
|
555
|
-
})) as any;
|
|
556
|
-
} catch (error) {
|
|
557
|
-
throw new MastraError(
|
|
558
|
-
{
|
|
559
|
-
id: 'STORAGE_MONGODB_STORE_GET_TRACES_FAILED',
|
|
560
|
-
domain: ErrorDomain.STORAGE,
|
|
561
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
562
|
-
},
|
|
563
|
-
error,
|
|
564
|
-
);
|
|
565
|
-
}
|
|
239
|
+
async getTracesPaginated(args: StorageGetTracesPaginatedArg): Promise<PaginationInfo & { traces: Trace[] }> {
|
|
240
|
+
return this.stores.traces.getTracesPaginated(args);
|
|
566
241
|
}
|
|
567
242
|
|
|
568
|
-
async getWorkflowRuns({
|
|
569
|
-
workflowName,
|
|
570
|
-
fromDate,
|
|
571
|
-
toDate,
|
|
572
|
-
limit,
|
|
573
|
-
offset,
|
|
574
|
-
}: {
|
|
243
|
+
async getWorkflowRuns(args?: {
|
|
575
244
|
workflowName?: string;
|
|
576
245
|
fromDate?: Date;
|
|
577
246
|
toDate?: Date;
|
|
578
247
|
limit?: number;
|
|
579
248
|
offset?: number;
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
snapshot: WorkflowRunState | string;
|
|
585
|
-
createdAt: Date;
|
|
586
|
-
updatedAt: Date;
|
|
587
|
-
}>;
|
|
588
|
-
total: number;
|
|
589
|
-
}> {
|
|
590
|
-
const query: any = {};
|
|
591
|
-
if (workflowName) {
|
|
592
|
-
query['workflow_name'] = workflowName;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
if (fromDate || toDate) {
|
|
596
|
-
query['createdAt'] = {};
|
|
597
|
-
if (fromDate) {
|
|
598
|
-
query['createdAt']['$gte'] = fromDate;
|
|
599
|
-
}
|
|
600
|
-
if (toDate) {
|
|
601
|
-
query['createdAt']['$lte'] = toDate;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
try {
|
|
606
|
-
const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
|
|
607
|
-
let total = 0;
|
|
608
|
-
// Only get total count when using pagination
|
|
609
|
-
if (limit !== undefined && offset !== undefined) {
|
|
610
|
-
total = await collection.countDocuments(query);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// Get results
|
|
614
|
-
const request = collection.find(query).sort({ createdAt: 'desc' });
|
|
615
|
-
if (limit) {
|
|
616
|
-
request.limit(limit);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
if (offset) {
|
|
620
|
-
request.skip(offset);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
const result = await request.toArray();
|
|
624
|
-
const runs = result.map(row => {
|
|
625
|
-
let parsedSnapshot: WorkflowRunState | string = row.snapshot;
|
|
626
|
-
if (typeof parsedSnapshot === 'string') {
|
|
627
|
-
try {
|
|
628
|
-
parsedSnapshot = JSON.parse(row.snapshot as string) as WorkflowRunState;
|
|
629
|
-
} catch (e) {
|
|
630
|
-
// If parsing fails, return the raw snapshot string
|
|
631
|
-
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
return {
|
|
636
|
-
workflowName: row.workflow_name as string,
|
|
637
|
-
runId: row.run_id as string,
|
|
638
|
-
snapshot: parsedSnapshot,
|
|
639
|
-
createdAt: new Date(row.createdAt as string),
|
|
640
|
-
updatedAt: new Date(row.updatedAt as string),
|
|
641
|
-
};
|
|
642
|
-
});
|
|
249
|
+
resourceId?: string;
|
|
250
|
+
}): Promise<WorkflowRuns> {
|
|
251
|
+
return this.stores.workflows.getWorkflowRuns(args);
|
|
252
|
+
}
|
|
643
253
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
652
|
-
},
|
|
653
|
-
error,
|
|
654
|
-
);
|
|
655
|
-
}
|
|
254
|
+
async getEvals(
|
|
255
|
+
options: {
|
|
256
|
+
agentName?: string;
|
|
257
|
+
type?: 'test' | 'live';
|
|
258
|
+
} & PaginationArgs = {},
|
|
259
|
+
): Promise<PaginationInfo & { evals: EvalRow[] }> {
|
|
260
|
+
return this.stores.legacyEvals.getEvals(options);
|
|
656
261
|
}
|
|
657
262
|
|
|
658
263
|
async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {
|
|
659
|
-
|
|
660
|
-
const query: any = {
|
|
661
|
-
agent_name: agentName,
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
if (type === 'test') {
|
|
665
|
-
query['test_info'] = { $ne: null };
|
|
666
|
-
// is not possible to filter by test_info.testPath because it is not a json field
|
|
667
|
-
// query['test_info.testPath'] = { $ne: null };
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
if (type === 'live') {
|
|
671
|
-
// is not possible to filter by test_info.testPath because it is not a json field
|
|
672
|
-
query['test_info'] = null;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
const collection = await this.getCollection(TABLE_EVALS);
|
|
676
|
-
const documents = await collection.find(query).sort({ created_at: 'desc' }).toArray();
|
|
677
|
-
const result = documents.map(row => this.transformEvalRow(row));
|
|
678
|
-
// Post filter to remove if test_info.testPath is null
|
|
679
|
-
return result.filter(row => {
|
|
680
|
-
if (type === 'live') {
|
|
681
|
-
return !Boolean(row.testInfo?.testPath);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
if (type === 'test') {
|
|
685
|
-
return row.testInfo?.testPath !== null;
|
|
686
|
-
}
|
|
687
|
-
return true;
|
|
688
|
-
});
|
|
689
|
-
} catch (error) {
|
|
690
|
-
// Handle case where table doesn't exist yet
|
|
691
|
-
if (error instanceof Error && error.message.includes('no such table')) {
|
|
692
|
-
return [];
|
|
693
|
-
}
|
|
694
|
-
throw new MastraError(
|
|
695
|
-
{
|
|
696
|
-
id: 'STORAGE_MONGODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
|
|
697
|
-
domain: ErrorDomain.STORAGE,
|
|
698
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
699
|
-
details: { agentName },
|
|
700
|
-
},
|
|
701
|
-
error,
|
|
702
|
-
);
|
|
703
|
-
}
|
|
264
|
+
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
704
265
|
}
|
|
705
266
|
|
|
706
267
|
async persistWorkflowSnapshot({
|
|
@@ -712,33 +273,7 @@ export class MongoDBStore extends MastraStorage {
|
|
|
712
273
|
runId: string;
|
|
713
274
|
snapshot: WorkflowRunState;
|
|
714
275
|
}): Promise<void> {
|
|
715
|
-
|
|
716
|
-
const now = new Date().toISOString();
|
|
717
|
-
const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
|
|
718
|
-
await collection.updateOne(
|
|
719
|
-
{ workflow_name: workflowName, run_id: runId },
|
|
720
|
-
{
|
|
721
|
-
$set: {
|
|
722
|
-
snapshot: JSON.stringify(snapshot),
|
|
723
|
-
updatedAt: now,
|
|
724
|
-
},
|
|
725
|
-
$setOnInsert: {
|
|
726
|
-
createdAt: now,
|
|
727
|
-
},
|
|
728
|
-
},
|
|
729
|
-
{ upsert: true },
|
|
730
|
-
);
|
|
731
|
-
} catch (error) {
|
|
732
|
-
throw new MastraError(
|
|
733
|
-
{
|
|
734
|
-
id: 'STORAGE_MONGODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED',
|
|
735
|
-
domain: ErrorDomain.STORAGE,
|
|
736
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
737
|
-
details: { workflowName, runId },
|
|
738
|
-
},
|
|
739
|
-
error,
|
|
740
|
-
);
|
|
741
|
-
}
|
|
276
|
+
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
|
|
742
277
|
}
|
|
743
278
|
|
|
744
279
|
async loadWorkflowSnapshot({
|
|
@@ -748,31 +283,7 @@ export class MongoDBStore extends MastraStorage {
|
|
|
748
283
|
workflowName: string;
|
|
749
284
|
runId: string;
|
|
750
285
|
}): Promise<WorkflowRunState | null> {
|
|
751
|
-
|
|
752
|
-
const result = await this.load<any[]>({
|
|
753
|
-
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
754
|
-
keys: {
|
|
755
|
-
workflow_name: workflowName,
|
|
756
|
-
run_id: runId,
|
|
757
|
-
},
|
|
758
|
-
});
|
|
759
|
-
|
|
760
|
-
if (!result?.length) {
|
|
761
|
-
return null;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
return JSON.parse(result[0].snapshot);
|
|
765
|
-
} catch (error) {
|
|
766
|
-
throw new MastraError(
|
|
767
|
-
{
|
|
768
|
-
id: 'STORAGE_MONGODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED',
|
|
769
|
-
domain: ErrorDomain.STORAGE,
|
|
770
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
771
|
-
details: { workflowName, runId },
|
|
772
|
-
},
|
|
773
|
-
error,
|
|
774
|
-
);
|
|
775
|
-
}
|
|
286
|
+
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
776
287
|
}
|
|
777
288
|
|
|
778
289
|
async getWorkflowRunById({
|
|
@@ -782,164 +293,95 @@ export class MongoDBStore extends MastraStorage {
|
|
|
782
293
|
runId: string;
|
|
783
294
|
workflowName?: string;
|
|
784
295
|
}): Promise<WorkflowRun | null> {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
if (runId) {
|
|
788
|
-
query['run_id'] = runId;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
if (workflowName) {
|
|
792
|
-
query['workflow_name'] = workflowName;
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
|
|
796
|
-
const result = await collection.findOne(query);
|
|
797
|
-
if (!result) {
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
296
|
+
return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
|
|
297
|
+
}
|
|
800
298
|
|
|
801
|
-
|
|
299
|
+
async close(): Promise<void> {
|
|
300
|
+
try {
|
|
301
|
+
await this.#connector.close();
|
|
802
302
|
} catch (error) {
|
|
803
303
|
throw new MastraError(
|
|
804
304
|
{
|
|
805
|
-
id: '
|
|
305
|
+
id: 'STORAGE_MONGODB_STORE_CLOSE_FAILED',
|
|
806
306
|
domain: ErrorDomain.STORAGE,
|
|
807
|
-
category: ErrorCategory.
|
|
808
|
-
details: { runId },
|
|
307
|
+
category: ErrorCategory.USER,
|
|
809
308
|
},
|
|
810
309
|
error,
|
|
811
310
|
);
|
|
812
311
|
}
|
|
813
312
|
}
|
|
814
313
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
} catch (e) {
|
|
821
|
-
// If parsing fails, return the raw snapshot string
|
|
822
|
-
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
return {
|
|
827
|
-
workflowName: row.workflow_name,
|
|
828
|
-
runId: row.run_id,
|
|
829
|
-
snapshot: parsedSnapshot,
|
|
830
|
-
createdAt: row.createdAt,
|
|
831
|
-
updatedAt: row.updatedAt,
|
|
832
|
-
resourceId: row.resourceId,
|
|
833
|
-
};
|
|
314
|
+
/**
|
|
315
|
+
* SCORERS
|
|
316
|
+
*/
|
|
317
|
+
async getScoreById({ id }: { id: string }): Promise<ScoreRowData | null> {
|
|
318
|
+
return this.stores.scores.getScoreById({ id });
|
|
834
319
|
}
|
|
835
320
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
content = JSON.parse(row.content);
|
|
840
|
-
} catch {
|
|
841
|
-
// use content as is if it's not JSON
|
|
842
|
-
}
|
|
843
|
-
return {
|
|
844
|
-
id: row.id,
|
|
845
|
-
content,
|
|
846
|
-
role: row.role,
|
|
847
|
-
type: row.type,
|
|
848
|
-
createdAt: new Date(row.createdAt as string),
|
|
849
|
-
threadId: row.thread_id,
|
|
850
|
-
resourceId: row.resourceId,
|
|
851
|
-
} as MastraMessageV2;
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
private transformEvalRow(row: Record<string, any>): EvalRow {
|
|
855
|
-
let testInfoValue = null;
|
|
856
|
-
if (row.test_info) {
|
|
857
|
-
try {
|
|
858
|
-
testInfoValue = typeof row.test_info === 'string' ? JSON.parse(row.test_info) : row.test_info;
|
|
859
|
-
} catch (e) {
|
|
860
|
-
console.warn('Failed to parse test_info:', e);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
const resultValue = JSON.parse(row.result as string);
|
|
864
|
-
if (!resultValue || typeof resultValue !== 'object' || !('score' in resultValue)) {
|
|
865
|
-
throw new MastraError({
|
|
866
|
-
id: 'STORAGE_MONGODB_STORE_INVALID_METRIC_FORMAT',
|
|
867
|
-
text: `Invalid MetricResult format: ${JSON.stringify(resultValue)}`,
|
|
868
|
-
domain: ErrorDomain.STORAGE,
|
|
869
|
-
category: ErrorCategory.USER,
|
|
870
|
-
});
|
|
871
|
-
}
|
|
321
|
+
async saveScore(score: Omit<ScoreRowData, 'id' | 'createdAt' | 'updatedAt'>): Promise<{ score: ScoreRowData }> {
|
|
322
|
+
return this.stores.scores.saveScore(score);
|
|
323
|
+
}
|
|
872
324
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
globalRunId: row.global_run_id as string,
|
|
882
|
-
runId: row.run_id as string,
|
|
883
|
-
createdAt: row.created_at as string,
|
|
884
|
-
};
|
|
325
|
+
async getScoresByRunId({
|
|
326
|
+
runId,
|
|
327
|
+
pagination,
|
|
328
|
+
}: {
|
|
329
|
+
runId: string;
|
|
330
|
+
pagination: StoragePagination;
|
|
331
|
+
}): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
|
|
332
|
+
return this.stores.scores.getScoresByRunId({ runId, pagination });
|
|
885
333
|
}
|
|
886
334
|
|
|
887
|
-
async
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
335
|
+
async getScoresByEntityId({
|
|
336
|
+
entityId,
|
|
337
|
+
entityType,
|
|
338
|
+
pagination,
|
|
339
|
+
}: {
|
|
340
|
+
pagination: StoragePagination;
|
|
341
|
+
entityId: string;
|
|
342
|
+
entityType: string;
|
|
343
|
+
}): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
|
|
344
|
+
return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
|
|
894
345
|
}
|
|
895
346
|
|
|
896
|
-
async
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
347
|
+
async getScoresByScorerId({
|
|
348
|
+
scorerId,
|
|
349
|
+
pagination,
|
|
350
|
+
entityId,
|
|
351
|
+
entityType,
|
|
352
|
+
}: {
|
|
353
|
+
scorerId: string;
|
|
354
|
+
pagination: StoragePagination;
|
|
355
|
+
entityId?: string;
|
|
356
|
+
entityType?: string;
|
|
357
|
+
}): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
|
|
358
|
+
return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType });
|
|
907
359
|
}
|
|
908
360
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
domain: ErrorDomain.STORAGE,
|
|
915
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
916
|
-
text: 'Method not implemented.',
|
|
917
|
-
});
|
|
361
|
+
/**
|
|
362
|
+
* RESOURCES
|
|
363
|
+
*/
|
|
364
|
+
async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {
|
|
365
|
+
return this.stores.memory.getResourceById({ resourceId });
|
|
918
366
|
}
|
|
919
367
|
|
|
920
|
-
async
|
|
921
|
-
|
|
922
|
-
await this.#client.close();
|
|
923
|
-
} catch (error) {
|
|
924
|
-
throw new MastraError(
|
|
925
|
-
{
|
|
926
|
-
id: 'STORAGE_MONGODB_STORE_CLOSE_FAILED',
|
|
927
|
-
domain: ErrorDomain.STORAGE,
|
|
928
|
-
category: ErrorCategory.USER,
|
|
929
|
-
},
|
|
930
|
-
error,
|
|
931
|
-
);
|
|
932
|
-
}
|
|
368
|
+
async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {
|
|
369
|
+
return this.stores.memory.saveResource({ resource });
|
|
933
370
|
}
|
|
934
371
|
|
|
935
|
-
async
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
372
|
+
async updateResource({
|
|
373
|
+
resourceId,
|
|
374
|
+
workingMemory,
|
|
375
|
+
metadata,
|
|
376
|
+
}: {
|
|
377
|
+
resourceId: string;
|
|
378
|
+
workingMemory?: string;
|
|
379
|
+
metadata?: Record<string, unknown>;
|
|
380
|
+
}): Promise<StorageResourceType> {
|
|
381
|
+
return this.stores.memory.updateResource({
|
|
382
|
+
resourceId,
|
|
383
|
+
workingMemory,
|
|
384
|
+
metadata,
|
|
385
|
+
});
|
|
944
386
|
}
|
|
945
387
|
}
|