@mastra/libsql 0.10.3 → 0.10.4-alpha.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 +24 -0
- package/dist/_tsup-dts-rollup.d.cts +10 -0
- package/dist/_tsup-dts-rollup.d.ts +10 -0
- package/dist/index.cjs +548 -149
- package/dist/index.js +537 -138
- package/package.json +4 -4
- package/src/storage/index.test.ts +165 -0
- package/src/storage/index.ts +452 -136
- package/src/vector/index.ts +126 -14
package/src/storage/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createClient } from '@libsql/client';
|
|
2
2
|
import type { Client, InValue } from '@libsql/client';
|
|
3
3
|
import { MessageList } from '@mastra/core/agent';
|
|
4
|
-
import type { MastraMessageV2 } from '@mastra/core/agent';
|
|
4
|
+
import type { MastraMessageContentV2, MastraMessageV2 } from '@mastra/core/agent';
|
|
5
|
+
import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
|
|
5
6
|
import type { MetricResult, TestInfo } from '@mastra/core/eval';
|
|
6
7
|
import type { MastraMessageV1, StorageThreadType } from '@mastra/core/memory';
|
|
7
8
|
import {
|
|
@@ -128,8 +129,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
128
129
|
const sql = this.getCreateTableSQL(tableName, schema);
|
|
129
130
|
await this.client.execute(sql);
|
|
130
131
|
} catch (error) {
|
|
131
|
-
this.logger.error(`Error creating table ${tableName}: ${error}`);
|
|
132
|
-
throw error;
|
|
132
|
+
// this.logger.error(`Error creating table ${tableName}: ${error}`);
|
|
133
|
+
// throw error;
|
|
134
|
+
throw new MastraError(
|
|
135
|
+
{
|
|
136
|
+
id: 'LIBSQL_STORE_CREATE_TABLE_FAILED',
|
|
137
|
+
domain: ErrorDomain.STORAGE,
|
|
138
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
139
|
+
details: {
|
|
140
|
+
tableName,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
error,
|
|
144
|
+
);
|
|
133
145
|
}
|
|
134
146
|
}
|
|
135
147
|
|
|
@@ -183,10 +195,17 @@ export class LibSQLStore extends MastraStorage {
|
|
|
183
195
|
}
|
|
184
196
|
}
|
|
185
197
|
} catch (error) {
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
throw new MastraError(
|
|
199
|
+
{
|
|
200
|
+
id: 'LIBSQL_STORE_ALTER_TABLE_FAILED',
|
|
201
|
+
domain: ErrorDomain.STORAGE,
|
|
202
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
203
|
+
details: {
|
|
204
|
+
tableName,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
error,
|
|
188
208
|
);
|
|
189
|
-
throw new Error(`Failed to alter table ${tableName}: ${error}`);
|
|
190
209
|
}
|
|
191
210
|
}
|
|
192
211
|
|
|
@@ -195,9 +214,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
195
214
|
try {
|
|
196
215
|
await this.client.execute(`DELETE FROM ${parsedTableName}`);
|
|
197
216
|
} catch (e) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
217
|
+
const mastraError = new MastraError(
|
|
218
|
+
{
|
|
219
|
+
id: 'LIBSQL_STORE_CLEAR_TABLE_FAILED',
|
|
220
|
+
domain: ErrorDomain.STORAGE,
|
|
221
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
222
|
+
details: {
|
|
223
|
+
tableName,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
e,
|
|
227
|
+
);
|
|
228
|
+
this.logger?.trackException?.(mastraError);
|
|
229
|
+
this.logger?.error?.(mastraError.toString());
|
|
201
230
|
}
|
|
202
231
|
}
|
|
203
232
|
|
|
@@ -277,7 +306,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
277
306
|
return this.executeWriteOperationWithRetry(
|
|
278
307
|
() => this.doBatchInsert(args),
|
|
279
308
|
`batch insert into table ${args.tableName}`,
|
|
280
|
-
)
|
|
309
|
+
).catch(error => {
|
|
310
|
+
throw new MastraError(
|
|
311
|
+
{
|
|
312
|
+
id: 'LIBSQL_STORE_BATCH_INSERT_FAILED',
|
|
313
|
+
domain: ErrorDomain.STORAGE,
|
|
314
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
315
|
+
details: {
|
|
316
|
+
tableName: args.tableName,
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
error,
|
|
320
|
+
);
|
|
321
|
+
});
|
|
281
322
|
}
|
|
282
323
|
|
|
283
324
|
private async doBatchInsert({
|
|
@@ -327,19 +368,31 @@ export class LibSQLStore extends MastraStorage {
|
|
|
327
368
|
}
|
|
328
369
|
|
|
329
370
|
async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
371
|
+
try {
|
|
372
|
+
const result = await this.load<StorageThreadType>({
|
|
373
|
+
tableName: TABLE_THREADS,
|
|
374
|
+
keys: { id: threadId },
|
|
375
|
+
});
|
|
334
376
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
377
|
+
if (!result) {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
338
380
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
381
|
+
return {
|
|
382
|
+
...result,
|
|
383
|
+
metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
|
|
384
|
+
};
|
|
385
|
+
} catch (error) {
|
|
386
|
+
throw new MastraError(
|
|
387
|
+
{
|
|
388
|
+
id: 'LIBSQL_STORE_GET_THREAD_BY_ID_FAILED',
|
|
389
|
+
domain: ErrorDomain.STORAGE,
|
|
390
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
391
|
+
details: { threadId },
|
|
392
|
+
},
|
|
393
|
+
error,
|
|
394
|
+
);
|
|
395
|
+
}
|
|
343
396
|
}
|
|
344
397
|
|
|
345
398
|
/**
|
|
@@ -372,7 +425,17 @@ export class LibSQLStore extends MastraStorage {
|
|
|
372
425
|
}
|
|
373
426
|
return result.rows.map(mapRowToStorageThreadType);
|
|
374
427
|
} catch (error) {
|
|
375
|
-
|
|
428
|
+
const mastraError = new MastraError(
|
|
429
|
+
{
|
|
430
|
+
id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
|
|
431
|
+
domain: ErrorDomain.STORAGE,
|
|
432
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
433
|
+
details: { resourceId },
|
|
434
|
+
},
|
|
435
|
+
error,
|
|
436
|
+
);
|
|
437
|
+
this.logger?.trackException?.(mastraError);
|
|
438
|
+
this.logger?.error?.(mastraError.toString());
|
|
376
439
|
return [];
|
|
377
440
|
}
|
|
378
441
|
}
|
|
@@ -430,21 +493,46 @@ export class LibSQLStore extends MastraStorage {
|
|
|
430
493
|
hasMore: currentOffset + threads.length < total,
|
|
431
494
|
};
|
|
432
495
|
} catch (error) {
|
|
433
|
-
|
|
496
|
+
const mastraError = new MastraError(
|
|
497
|
+
{
|
|
498
|
+
id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
|
|
499
|
+
domain: ErrorDomain.STORAGE,
|
|
500
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
501
|
+
details: { resourceId },
|
|
502
|
+
},
|
|
503
|
+
error,
|
|
504
|
+
);
|
|
505
|
+
this.logger?.trackException?.(mastraError);
|
|
506
|
+
this.logger?.error?.(mastraError.toString());
|
|
434
507
|
return { threads: [], total: 0, page, perPage, hasMore: false };
|
|
435
508
|
}
|
|
436
509
|
}
|
|
437
510
|
|
|
438
511
|
async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
512
|
+
try {
|
|
513
|
+
await this.insert({
|
|
514
|
+
tableName: TABLE_THREADS,
|
|
515
|
+
record: {
|
|
516
|
+
...thread,
|
|
517
|
+
metadata: JSON.stringify(thread.metadata),
|
|
518
|
+
},
|
|
519
|
+
});
|
|
446
520
|
|
|
447
|
-
|
|
521
|
+
return thread;
|
|
522
|
+
} catch (error) {
|
|
523
|
+
const mastraError = new MastraError(
|
|
524
|
+
{
|
|
525
|
+
id: 'LIBSQL_STORE_SAVE_THREAD_FAILED',
|
|
526
|
+
domain: ErrorDomain.STORAGE,
|
|
527
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
528
|
+
details: { threadId: thread.id },
|
|
529
|
+
},
|
|
530
|
+
error,
|
|
531
|
+
);
|
|
532
|
+
this.logger?.trackException?.(mastraError);
|
|
533
|
+
this.logger?.error?.(mastraError.toString());
|
|
534
|
+
throw mastraError;
|
|
535
|
+
}
|
|
448
536
|
}
|
|
449
537
|
|
|
450
538
|
async updateThread({
|
|
@@ -458,7 +546,13 @@ export class LibSQLStore extends MastraStorage {
|
|
|
458
546
|
}): Promise<StorageThreadType> {
|
|
459
547
|
const thread = await this.getThreadById({ threadId: id });
|
|
460
548
|
if (!thread) {
|
|
461
|
-
throw new
|
|
549
|
+
throw new MastraError({
|
|
550
|
+
id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED_THREAD_NOT_FOUND',
|
|
551
|
+
domain: ErrorDomain.STORAGE,
|
|
552
|
+
category: ErrorCategory.USER,
|
|
553
|
+
text: `Thread ${id} not found`,
|
|
554
|
+
details: { threadId: id },
|
|
555
|
+
});
|
|
462
556
|
}
|
|
463
557
|
|
|
464
558
|
const updatedThread = {
|
|
@@ -470,24 +564,49 @@ export class LibSQLStore extends MastraStorage {
|
|
|
470
564
|
},
|
|
471
565
|
};
|
|
472
566
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
567
|
+
try {
|
|
568
|
+
await this.client.execute({
|
|
569
|
+
sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
|
|
570
|
+
args: [title, JSON.stringify(updatedThread.metadata), id],
|
|
571
|
+
});
|
|
477
572
|
|
|
478
|
-
|
|
573
|
+
return updatedThread;
|
|
574
|
+
} catch (error) {
|
|
575
|
+
throw new MastraError(
|
|
576
|
+
{
|
|
577
|
+
id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED',
|
|
578
|
+
domain: ErrorDomain.STORAGE,
|
|
579
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
580
|
+
text: `Failed to update thread ${id}`,
|
|
581
|
+
details: { threadId: id },
|
|
582
|
+
},
|
|
583
|
+
error,
|
|
584
|
+
);
|
|
585
|
+
}
|
|
479
586
|
}
|
|
480
587
|
|
|
481
588
|
async deleteThread({ threadId }: { threadId: string }): Promise<void> {
|
|
482
589
|
// Delete messages for this thread (manual step)
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
590
|
+
try {
|
|
591
|
+
await this.client.execute({
|
|
592
|
+
sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
|
|
593
|
+
args: [threadId],
|
|
594
|
+
});
|
|
595
|
+
await this.client.execute({
|
|
596
|
+
sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
|
|
597
|
+
args: [threadId],
|
|
598
|
+
});
|
|
599
|
+
} catch (error) {
|
|
600
|
+
throw new MastraError(
|
|
601
|
+
{
|
|
602
|
+
id: 'LIBSQL_STORE_DELETE_THREAD_FAILED',
|
|
603
|
+
domain: ErrorDomain.STORAGE,
|
|
604
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
605
|
+
details: { threadId },
|
|
606
|
+
},
|
|
607
|
+
error,
|
|
608
|
+
);
|
|
609
|
+
}
|
|
491
610
|
// TODO: Need to check if CASCADE is enabled so that messages will be automatically deleted due to CASCADE constraint
|
|
492
611
|
}
|
|
493
612
|
|
|
@@ -577,8 +696,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
577
696
|
}): Promise<MastraMessageV1[] | MastraMessageV2[]> {
|
|
578
697
|
try {
|
|
579
698
|
const messages: MastraMessageV2[] = [];
|
|
580
|
-
const limit =
|
|
581
|
-
|
|
699
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
582
700
|
if (selectBy?.include?.length) {
|
|
583
701
|
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
584
702
|
if (includeMessages) {
|
|
@@ -612,8 +730,15 @@ export class LibSQLStore extends MastraStorage {
|
|
|
612
730
|
if (format === `v2`) return list.get.all.v2();
|
|
613
731
|
return list.get.all.v1();
|
|
614
732
|
} catch (error) {
|
|
615
|
-
|
|
616
|
-
|
|
733
|
+
throw new MastraError(
|
|
734
|
+
{
|
|
735
|
+
id: 'LIBSQL_STORE_GET_MESSAGES_FAILED',
|
|
736
|
+
domain: ErrorDomain.STORAGE,
|
|
737
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
738
|
+
details: { threadId },
|
|
739
|
+
},
|
|
740
|
+
error,
|
|
741
|
+
);
|
|
617
742
|
}
|
|
618
743
|
}
|
|
619
744
|
|
|
@@ -630,9 +755,21 @@ export class LibSQLStore extends MastraStorage {
|
|
|
630
755
|
const messages: MastraMessageV2[] = [];
|
|
631
756
|
|
|
632
757
|
if (selectBy?.include?.length) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
758
|
+
try {
|
|
759
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
760
|
+
if (includeMessages) {
|
|
761
|
+
messages.push(...includeMessages);
|
|
762
|
+
}
|
|
763
|
+
} catch (error) {
|
|
764
|
+
throw new MastraError(
|
|
765
|
+
{
|
|
766
|
+
id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_GET_INCLUDE_MESSAGES_FAILED',
|
|
767
|
+
domain: ErrorDomain.STORAGE,
|
|
768
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
769
|
+
details: { threadId },
|
|
770
|
+
},
|
|
771
|
+
error,
|
|
772
|
+
);
|
|
636
773
|
}
|
|
637
774
|
}
|
|
638
775
|
|
|
@@ -688,7 +825,17 @@ export class LibSQLStore extends MastraStorage {
|
|
|
688
825
|
hasMore: currentOffset + messages.length < total,
|
|
689
826
|
};
|
|
690
827
|
} catch (error) {
|
|
691
|
-
|
|
828
|
+
const mastraError = new MastraError(
|
|
829
|
+
{
|
|
830
|
+
id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_FAILED',
|
|
831
|
+
domain: ErrorDomain.STORAGE,
|
|
832
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
833
|
+
details: { threadId },
|
|
834
|
+
},
|
|
835
|
+
error,
|
|
836
|
+
);
|
|
837
|
+
this.logger?.trackException?.(mastraError);
|
|
838
|
+
this.logger?.error?.(mastraError.toString());
|
|
692
839
|
return { messages: [], total: 0, page, perPage, hasMore: false };
|
|
693
840
|
}
|
|
694
841
|
}
|
|
@@ -750,11 +897,123 @@ export class LibSQLStore extends MastraStorage {
|
|
|
750
897
|
if (format === `v2`) return list.get.all.v2();
|
|
751
898
|
return list.get.all.v1();
|
|
752
899
|
} catch (error) {
|
|
753
|
-
|
|
754
|
-
|
|
900
|
+
throw new MastraError(
|
|
901
|
+
{
|
|
902
|
+
id: 'LIBSQL_STORE_SAVE_MESSAGES_FAILED',
|
|
903
|
+
domain: ErrorDomain.STORAGE,
|
|
904
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
905
|
+
},
|
|
906
|
+
error,
|
|
907
|
+
);
|
|
755
908
|
}
|
|
756
909
|
}
|
|
757
910
|
|
|
911
|
+
async updateMessages({
|
|
912
|
+
messages,
|
|
913
|
+
}: {
|
|
914
|
+
messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {
|
|
915
|
+
id: string;
|
|
916
|
+
content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
|
|
917
|
+
})[];
|
|
918
|
+
}): Promise<MastraMessageV2[]> {
|
|
919
|
+
if (messages.length === 0) {
|
|
920
|
+
return [];
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
const messageIds = messages.map(m => m.id);
|
|
924
|
+
const placeholders = messageIds.map(() => '?').join(',');
|
|
925
|
+
|
|
926
|
+
const selectSql = `SELECT * FROM ${TABLE_MESSAGES} WHERE id IN (${placeholders})`;
|
|
927
|
+
const existingResult = await this.client.execute({ sql: selectSql, args: messageIds });
|
|
928
|
+
const existingMessages: MastraMessageV2[] = existingResult.rows.map(row => this.parseRow(row));
|
|
929
|
+
|
|
930
|
+
if (existingMessages.length === 0) {
|
|
931
|
+
return [];
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
const batchStatements = [];
|
|
935
|
+
const threadIdsToUpdate = new Set<string>();
|
|
936
|
+
const columnMapping: Record<string, string> = {
|
|
937
|
+
threadId: 'thread_id',
|
|
938
|
+
};
|
|
939
|
+
|
|
940
|
+
for (const existingMessage of existingMessages) {
|
|
941
|
+
const updatePayload = messages.find(m => m.id === existingMessage.id);
|
|
942
|
+
if (!updatePayload) continue;
|
|
943
|
+
|
|
944
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
945
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
946
|
+
|
|
947
|
+
threadIdsToUpdate.add(existingMessage.threadId!);
|
|
948
|
+
if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
|
|
949
|
+
threadIdsToUpdate.add(updatePayload.threadId);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const setClauses = [];
|
|
953
|
+
const args: InValue[] = [];
|
|
954
|
+
const updatableFields = { ...fieldsToUpdate };
|
|
955
|
+
|
|
956
|
+
// Special handling for the 'content' field to merge instead of overwrite
|
|
957
|
+
if (updatableFields.content) {
|
|
958
|
+
const newContent = {
|
|
959
|
+
...existingMessage.content,
|
|
960
|
+
...updatableFields.content,
|
|
961
|
+
// Deep merge metadata if it exists on both
|
|
962
|
+
...(existingMessage.content?.metadata && updatableFields.content.metadata
|
|
963
|
+
? {
|
|
964
|
+
metadata: {
|
|
965
|
+
...existingMessage.content.metadata,
|
|
966
|
+
...updatableFields.content.metadata,
|
|
967
|
+
},
|
|
968
|
+
}
|
|
969
|
+
: {}),
|
|
970
|
+
};
|
|
971
|
+
setClauses.push(`${parseSqlIdentifier('content', 'column name')} = ?`);
|
|
972
|
+
args.push(JSON.stringify(newContent));
|
|
973
|
+
delete updatableFields.content;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
for (const key in updatableFields) {
|
|
977
|
+
if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
|
|
978
|
+
const dbKey = columnMapping[key] || key;
|
|
979
|
+
setClauses.push(`${parseSqlIdentifier(dbKey, 'column name')} = ?`);
|
|
980
|
+
let value = updatableFields[key as keyof typeof updatableFields];
|
|
981
|
+
|
|
982
|
+
if (typeof value === 'object' && value !== null) {
|
|
983
|
+
value = JSON.stringify(value);
|
|
984
|
+
}
|
|
985
|
+
args.push(value as InValue);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
if (setClauses.length === 0) continue;
|
|
990
|
+
|
|
991
|
+
args.push(id);
|
|
992
|
+
|
|
993
|
+
const sql = `UPDATE ${TABLE_MESSAGES} SET ${setClauses.join(', ')} WHERE id = ?`;
|
|
994
|
+
batchStatements.push({ sql, args });
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
if (batchStatements.length === 0) {
|
|
998
|
+
return existingMessages;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const now = new Date().toISOString();
|
|
1002
|
+
for (const threadId of threadIdsToUpdate) {
|
|
1003
|
+
if (threadId) {
|
|
1004
|
+
batchStatements.push({
|
|
1005
|
+
sql: `UPDATE ${TABLE_THREADS} SET updatedAt = ? WHERE id = ?`,
|
|
1006
|
+
args: [now, threadId],
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
await this.client.batch(batchStatements, 'write');
|
|
1012
|
+
|
|
1013
|
+
const updatedResult = await this.client.execute({ sql: selectSql, args: messageIds });
|
|
1014
|
+
return updatedResult.rows.map(row => this.parseRow(row));
|
|
1015
|
+
}
|
|
1016
|
+
|
|
758
1017
|
private transformEvalRow(row: Record<string, any>): EvalRow {
|
|
759
1018
|
const resultValue = JSON.parse(row.result as string);
|
|
760
1019
|
const testInfoValue = row.test_info ? JSON.parse(row.test_info as string) : undefined;
|
|
@@ -799,8 +1058,15 @@ export class LibSQLStore extends MastraStorage {
|
|
|
799
1058
|
if (error instanceof Error && error.message.includes('no such table')) {
|
|
800
1059
|
return [];
|
|
801
1060
|
}
|
|
802
|
-
|
|
803
|
-
|
|
1061
|
+
throw new MastraError(
|
|
1062
|
+
{
|
|
1063
|
+
id: 'LIBSQL_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
|
|
1064
|
+
domain: ErrorDomain.STORAGE,
|
|
1065
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1066
|
+
details: { agentName },
|
|
1067
|
+
},
|
|
1068
|
+
error,
|
|
1069
|
+
);
|
|
804
1070
|
}
|
|
805
1071
|
}
|
|
806
1072
|
|
|
@@ -840,37 +1106,48 @@ export class LibSQLStore extends MastraStorage {
|
|
|
840
1106
|
|
|
841
1107
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
842
1108
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1109
|
+
try {
|
|
1110
|
+
const countResult = await this.client.execute({
|
|
1111
|
+
sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
|
|
1112
|
+
args: queryParams,
|
|
1113
|
+
});
|
|
1114
|
+
const total = Number(countResult.rows?.[0]?.count ?? 0);
|
|
848
1115
|
|
|
849
|
-
|
|
850
|
-
|
|
1116
|
+
const currentOffset = page * perPage;
|
|
1117
|
+
const hasMore = currentOffset + perPage < total;
|
|
1118
|
+
|
|
1119
|
+
if (total === 0) {
|
|
1120
|
+
return {
|
|
1121
|
+
evals: [],
|
|
1122
|
+
total: 0,
|
|
1123
|
+
page,
|
|
1124
|
+
perPage,
|
|
1125
|
+
hasMore: false,
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
const dataResult = await this.client.execute({
|
|
1130
|
+
sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
|
|
1131
|
+
args: [...queryParams, perPage, currentOffset],
|
|
1132
|
+
});
|
|
851
1133
|
|
|
852
|
-
if (total === 0) {
|
|
853
1134
|
return {
|
|
854
|
-
evals: [],
|
|
855
|
-
total
|
|
1135
|
+
evals: dataResult.rows?.map(row => this.transformEvalRow(row)) ?? [],
|
|
1136
|
+
total,
|
|
856
1137
|
page,
|
|
857
1138
|
perPage,
|
|
858
|
-
hasMore
|
|
1139
|
+
hasMore,
|
|
859
1140
|
};
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
throw new MastraError(
|
|
1143
|
+
{
|
|
1144
|
+
id: 'LIBSQL_STORE_GET_EVALS_FAILED',
|
|
1145
|
+
domain: ErrorDomain.STORAGE,
|
|
1146
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1147
|
+
},
|
|
1148
|
+
error,
|
|
1149
|
+
);
|
|
860
1150
|
}
|
|
861
|
-
|
|
862
|
-
const dataResult = await this.client.execute({
|
|
863
|
-
sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
|
|
864
|
-
args: [...queryParams, perPage, currentOffset],
|
|
865
|
-
});
|
|
866
|
-
|
|
867
|
-
return {
|
|
868
|
-
evals: dataResult.rows?.map(row => this.transformEvalRow(row)) ?? [],
|
|
869
|
-
total,
|
|
870
|
-
page,
|
|
871
|
-
perPage,
|
|
872
|
-
hasMore,
|
|
873
|
-
};
|
|
874
1151
|
}
|
|
875
1152
|
|
|
876
1153
|
/**
|
|
@@ -892,8 +1169,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
892
1169
|
end: args.toDate,
|
|
893
1170
|
};
|
|
894
1171
|
}
|
|
895
|
-
|
|
896
|
-
|
|
1172
|
+
try {
|
|
1173
|
+
const result = await this.getTracesPaginated(args);
|
|
1174
|
+
return result.traces;
|
|
1175
|
+
} catch (error) {
|
|
1176
|
+
throw new MastraError(
|
|
1177
|
+
{
|
|
1178
|
+
id: 'LIBSQL_STORE_GET_TRACES_FAILED',
|
|
1179
|
+
domain: ErrorDomain.STORAGE,
|
|
1180
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1181
|
+
},
|
|
1182
|
+
error,
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
897
1185
|
}
|
|
898
1186
|
|
|
899
1187
|
public async getTracesPaginated(
|
|
@@ -943,55 +1231,66 @@ export class LibSQLStore extends MastraStorage {
|
|
|
943
1231
|
|
|
944
1232
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
945
1233
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1234
|
+
try {
|
|
1235
|
+
const countResult = await this.client.execute({
|
|
1236
|
+
sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
|
|
1237
|
+
args: queryArgs,
|
|
1238
|
+
});
|
|
1239
|
+
const total = Number(countResult.rows?.[0]?.count ?? 0);
|
|
1240
|
+
|
|
1241
|
+
if (total === 0) {
|
|
1242
|
+
return {
|
|
1243
|
+
traces: [],
|
|
1244
|
+
total: 0,
|
|
1245
|
+
page,
|
|
1246
|
+
perPage,
|
|
1247
|
+
hasMore: false,
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
const dataResult = await this.client.execute({
|
|
1252
|
+
sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
|
|
1253
|
+
args: [...queryArgs, perPage, currentOffset],
|
|
1254
|
+
});
|
|
1255
|
+
|
|
1256
|
+
const traces =
|
|
1257
|
+
dataResult.rows?.map(
|
|
1258
|
+
row =>
|
|
1259
|
+
({
|
|
1260
|
+
id: row.id,
|
|
1261
|
+
parentSpanId: row.parentSpanId,
|
|
1262
|
+
traceId: row.traceId,
|
|
1263
|
+
name: row.name,
|
|
1264
|
+
scope: row.scope,
|
|
1265
|
+
kind: row.kind,
|
|
1266
|
+
status: safelyParseJSON(row.status as string),
|
|
1267
|
+
events: safelyParseJSON(row.events as string),
|
|
1268
|
+
links: safelyParseJSON(row.links as string),
|
|
1269
|
+
attributes: safelyParseJSON(row.attributes as string),
|
|
1270
|
+
startTime: row.startTime,
|
|
1271
|
+
endTime: row.endTime,
|
|
1272
|
+
other: safelyParseJSON(row.other as string),
|
|
1273
|
+
createdAt: row.createdAt,
|
|
1274
|
+
}) as Trace,
|
|
1275
|
+
) ?? [];
|
|
951
1276
|
|
|
952
|
-
if (total === 0) {
|
|
953
1277
|
return {
|
|
954
|
-
traces
|
|
955
|
-
total
|
|
1278
|
+
traces,
|
|
1279
|
+
total,
|
|
956
1280
|
page,
|
|
957
1281
|
perPage,
|
|
958
|
-
hasMore:
|
|
1282
|
+
hasMore: currentOffset + traces.length < total,
|
|
959
1283
|
};
|
|
1284
|
+
} catch (error) {
|
|
1285
|
+
throw new MastraError(
|
|
1286
|
+
{
|
|
1287
|
+
id: 'LIBSQL_STORE_GET_TRACES_PAGINATED_FAILED',
|
|
1288
|
+
domain: ErrorDomain.STORAGE,
|
|
1289
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1290
|
+
},
|
|
1291
|
+
error,
|
|
1292
|
+
);
|
|
960
1293
|
}
|
|
961
|
-
|
|
962
|
-
const dataResult = await this.client.execute({
|
|
963
|
-
sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
|
|
964
|
-
args: [...queryArgs, perPage, currentOffset],
|
|
965
|
-
});
|
|
966
|
-
|
|
967
|
-
const traces =
|
|
968
|
-
dataResult.rows?.map(
|
|
969
|
-
row =>
|
|
970
|
-
({
|
|
971
|
-
id: row.id,
|
|
972
|
-
parentSpanId: row.parentSpanId,
|
|
973
|
-
traceId: row.traceId,
|
|
974
|
-
name: row.name,
|
|
975
|
-
scope: row.scope,
|
|
976
|
-
kind: row.kind,
|
|
977
|
-
status: safelyParseJSON(row.status as string),
|
|
978
|
-
events: safelyParseJSON(row.events as string),
|
|
979
|
-
links: safelyParseJSON(row.links as string),
|
|
980
|
-
attributes: safelyParseJSON(row.attributes as string),
|
|
981
|
-
startTime: row.startTime,
|
|
982
|
-
endTime: row.endTime,
|
|
983
|
-
other: safelyParseJSON(row.other as string),
|
|
984
|
-
createdAt: row.createdAt,
|
|
985
|
-
}) as Trace,
|
|
986
|
-
) ?? [];
|
|
987
|
-
|
|
988
|
-
return {
|
|
989
|
-
traces,
|
|
990
|
-
total,
|
|
991
|
-
page,
|
|
992
|
-
perPage,
|
|
993
|
-
hasMore: currentOffset + traces.length < total,
|
|
994
|
-
};
|
|
995
1294
|
}
|
|
996
1295
|
|
|
997
1296
|
async getWorkflowRuns({
|
|
@@ -1061,8 +1360,14 @@ export class LibSQLStore extends MastraStorage {
|
|
|
1061
1360
|
// Use runs.length as total when not paginating
|
|
1062
1361
|
return { runs, total: total || runs.length };
|
|
1063
1362
|
} catch (error) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1363
|
+
throw new MastraError(
|
|
1364
|
+
{
|
|
1365
|
+
id: 'LIBSQL_STORE_GET_WORKFLOW_RUNS_FAILED',
|
|
1366
|
+
domain: ErrorDomain.STORAGE,
|
|
1367
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1368
|
+
},
|
|
1369
|
+
error,
|
|
1370
|
+
);
|
|
1066
1371
|
}
|
|
1067
1372
|
}
|
|
1068
1373
|
|
|
@@ -1088,16 +1393,27 @@ export class LibSQLStore extends MastraStorage {
|
|
|
1088
1393
|
|
|
1089
1394
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
1090
1395
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1396
|
+
try {
|
|
1397
|
+
const result = await this.client.execute({
|
|
1398
|
+
sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
|
|
1399
|
+
args,
|
|
1400
|
+
});
|
|
1095
1401
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1402
|
+
if (!result.rows?.[0]) {
|
|
1403
|
+
return null;
|
|
1404
|
+
}
|
|
1099
1405
|
|
|
1100
|
-
|
|
1406
|
+
return this.parseWorkflowRun(result.rows[0]);
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
throw new MastraError(
|
|
1409
|
+
{
|
|
1410
|
+
id: 'LIBSQL_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',
|
|
1411
|
+
domain: ErrorDomain.STORAGE,
|
|
1412
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1413
|
+
},
|
|
1414
|
+
error,
|
|
1415
|
+
);
|
|
1416
|
+
}
|
|
1101
1417
|
}
|
|
1102
1418
|
|
|
1103
1419
|
private async hasColumn(table: string, column: string): Promise<boolean> {
|