@mastra/libsql 0.10.4-alpha.0 → 0.10.4-alpha.2
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 +28 -0
- package/dist/_tsup-dts-rollup.d.cts +33 -6
- package/dist/_tsup-dts-rollup.d.ts +33 -6
- package/dist/index.cjs +555 -155
- package/dist/index.js +545 -145
- package/package.json +4 -4
- package/src/storage/index.test.ts +1 -30
- package/src/storage/index.ts +453 -137
- package/src/vector/filter.test.ts +22 -84
- package/src/vector/filter.ts +19 -5
- package/src/vector/index.test.ts +1 -11
- package/src/vector/index.ts +130 -18
- package/src/vector/sql-builder.ts +5 -5
package/src/storage/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { createClient } from '@libsql/client';
|
|
|
2
2
|
import type { Client, InValue } from '@libsql/client';
|
|
3
3
|
import { MessageList } from '@mastra/core/agent';
|
|
4
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 {
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
TABLE_MESSAGES,
|
|
11
12
|
TABLE_THREADS,
|
|
12
13
|
TABLE_TRACES,
|
|
14
|
+
TABLE_RESOURCES,
|
|
13
15
|
TABLE_WORKFLOW_SNAPSHOT,
|
|
14
16
|
} from '@mastra/core/storage';
|
|
15
17
|
import type {
|
|
@@ -18,6 +20,7 @@ import type {
|
|
|
18
20
|
PaginationInfo,
|
|
19
21
|
StorageColumn,
|
|
20
22
|
StorageGetMessagesArg,
|
|
23
|
+
StorageResourceType,
|
|
21
24
|
TABLE_NAMES,
|
|
22
25
|
WorkflowRun,
|
|
23
26
|
WorkflowRuns,
|
|
@@ -83,9 +86,11 @@ export class LibSQLStore extends MastraStorage {
|
|
|
83
86
|
|
|
84
87
|
public get supports(): {
|
|
85
88
|
selectByIncludeResourceScope: boolean;
|
|
89
|
+
resourceWorkingMemory: boolean;
|
|
86
90
|
} {
|
|
87
91
|
return {
|
|
88
92
|
selectByIncludeResourceScope: true,
|
|
93
|
+
resourceWorkingMemory: true,
|
|
89
94
|
};
|
|
90
95
|
}
|
|
91
96
|
|
|
@@ -128,8 +133,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
128
133
|
const sql = this.getCreateTableSQL(tableName, schema);
|
|
129
134
|
await this.client.execute(sql);
|
|
130
135
|
} catch (error) {
|
|
131
|
-
this.logger.error(`Error creating table ${tableName}: ${error}`);
|
|
132
|
-
throw error;
|
|
136
|
+
// this.logger.error(`Error creating table ${tableName}: ${error}`);
|
|
137
|
+
// throw error;
|
|
138
|
+
throw new MastraError(
|
|
139
|
+
{
|
|
140
|
+
id: 'LIBSQL_STORE_CREATE_TABLE_FAILED',
|
|
141
|
+
domain: ErrorDomain.STORAGE,
|
|
142
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
143
|
+
details: {
|
|
144
|
+
tableName,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
error,
|
|
148
|
+
);
|
|
133
149
|
}
|
|
134
150
|
}
|
|
135
151
|
|
|
@@ -183,10 +199,17 @@ export class LibSQLStore extends MastraStorage {
|
|
|
183
199
|
}
|
|
184
200
|
}
|
|
185
201
|
} catch (error) {
|
|
186
|
-
|
|
187
|
-
|
|
202
|
+
throw new MastraError(
|
|
203
|
+
{
|
|
204
|
+
id: 'LIBSQL_STORE_ALTER_TABLE_FAILED',
|
|
205
|
+
domain: ErrorDomain.STORAGE,
|
|
206
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
207
|
+
details: {
|
|
208
|
+
tableName,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
error,
|
|
188
212
|
);
|
|
189
|
-
throw new Error(`Failed to alter table ${tableName}: ${error}`);
|
|
190
213
|
}
|
|
191
214
|
}
|
|
192
215
|
|
|
@@ -195,9 +218,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
195
218
|
try {
|
|
196
219
|
await this.client.execute(`DELETE FROM ${parsedTableName}`);
|
|
197
220
|
} catch (e) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
221
|
+
const mastraError = new MastraError(
|
|
222
|
+
{
|
|
223
|
+
id: 'LIBSQL_STORE_CLEAR_TABLE_FAILED',
|
|
224
|
+
domain: ErrorDomain.STORAGE,
|
|
225
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
226
|
+
details: {
|
|
227
|
+
tableName,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
e,
|
|
231
|
+
);
|
|
232
|
+
this.logger?.trackException?.(mastraError);
|
|
233
|
+
this.logger?.error?.(mastraError.toString());
|
|
201
234
|
}
|
|
202
235
|
}
|
|
203
236
|
|
|
@@ -277,7 +310,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
277
310
|
return this.executeWriteOperationWithRetry(
|
|
278
311
|
() => this.doBatchInsert(args),
|
|
279
312
|
`batch insert into table ${args.tableName}`,
|
|
280
|
-
)
|
|
313
|
+
).catch(error => {
|
|
314
|
+
throw new MastraError(
|
|
315
|
+
{
|
|
316
|
+
id: 'LIBSQL_STORE_BATCH_INSERT_FAILED',
|
|
317
|
+
domain: ErrorDomain.STORAGE,
|
|
318
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
319
|
+
details: {
|
|
320
|
+
tableName: args.tableName,
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
error,
|
|
324
|
+
);
|
|
325
|
+
});
|
|
281
326
|
}
|
|
282
327
|
|
|
283
328
|
private async doBatchInsert({
|
|
@@ -327,19 +372,31 @@ export class LibSQLStore extends MastraStorage {
|
|
|
327
372
|
}
|
|
328
373
|
|
|
329
374
|
async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
375
|
+
try {
|
|
376
|
+
const result = await this.load<StorageThreadType>({
|
|
377
|
+
tableName: TABLE_THREADS,
|
|
378
|
+
keys: { id: threadId },
|
|
379
|
+
});
|
|
334
380
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
381
|
+
if (!result) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
338
384
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
385
|
+
return {
|
|
386
|
+
...result,
|
|
387
|
+
metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
|
|
388
|
+
};
|
|
389
|
+
} catch (error) {
|
|
390
|
+
throw new MastraError(
|
|
391
|
+
{
|
|
392
|
+
id: 'LIBSQL_STORE_GET_THREAD_BY_ID_FAILED',
|
|
393
|
+
domain: ErrorDomain.STORAGE,
|
|
394
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
395
|
+
details: { threadId },
|
|
396
|
+
},
|
|
397
|
+
error,
|
|
398
|
+
);
|
|
399
|
+
}
|
|
343
400
|
}
|
|
344
401
|
|
|
345
402
|
/**
|
|
@@ -372,7 +429,17 @@ export class LibSQLStore extends MastraStorage {
|
|
|
372
429
|
}
|
|
373
430
|
return result.rows.map(mapRowToStorageThreadType);
|
|
374
431
|
} catch (error) {
|
|
375
|
-
|
|
432
|
+
const mastraError = new MastraError(
|
|
433
|
+
{
|
|
434
|
+
id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
|
|
435
|
+
domain: ErrorDomain.STORAGE,
|
|
436
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
437
|
+
details: { resourceId },
|
|
438
|
+
},
|
|
439
|
+
error,
|
|
440
|
+
);
|
|
441
|
+
this.logger?.trackException?.(mastraError);
|
|
442
|
+
this.logger?.error?.(mastraError.toString());
|
|
376
443
|
return [];
|
|
377
444
|
}
|
|
378
445
|
}
|
|
@@ -430,21 +497,46 @@ export class LibSQLStore extends MastraStorage {
|
|
|
430
497
|
hasMore: currentOffset + threads.length < total,
|
|
431
498
|
};
|
|
432
499
|
} catch (error) {
|
|
433
|
-
|
|
500
|
+
const mastraError = new MastraError(
|
|
501
|
+
{
|
|
502
|
+
id: 'LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED',
|
|
503
|
+
domain: ErrorDomain.STORAGE,
|
|
504
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
505
|
+
details: { resourceId },
|
|
506
|
+
},
|
|
507
|
+
error,
|
|
508
|
+
);
|
|
509
|
+
this.logger?.trackException?.(mastraError);
|
|
510
|
+
this.logger?.error?.(mastraError.toString());
|
|
434
511
|
return { threads: [], total: 0, page, perPage, hasMore: false };
|
|
435
512
|
}
|
|
436
513
|
}
|
|
437
514
|
|
|
438
515
|
async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
516
|
+
try {
|
|
517
|
+
await this.insert({
|
|
518
|
+
tableName: TABLE_THREADS,
|
|
519
|
+
record: {
|
|
520
|
+
...thread,
|
|
521
|
+
metadata: JSON.stringify(thread.metadata),
|
|
522
|
+
},
|
|
523
|
+
});
|
|
446
524
|
|
|
447
|
-
|
|
525
|
+
return thread;
|
|
526
|
+
} catch (error) {
|
|
527
|
+
const mastraError = new MastraError(
|
|
528
|
+
{
|
|
529
|
+
id: 'LIBSQL_STORE_SAVE_THREAD_FAILED',
|
|
530
|
+
domain: ErrorDomain.STORAGE,
|
|
531
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
532
|
+
details: { threadId: thread.id },
|
|
533
|
+
},
|
|
534
|
+
error,
|
|
535
|
+
);
|
|
536
|
+
this.logger?.trackException?.(mastraError);
|
|
537
|
+
this.logger?.error?.(mastraError.toString());
|
|
538
|
+
throw mastraError;
|
|
539
|
+
}
|
|
448
540
|
}
|
|
449
541
|
|
|
450
542
|
async updateThread({
|
|
@@ -458,7 +550,13 @@ export class LibSQLStore extends MastraStorage {
|
|
|
458
550
|
}): Promise<StorageThreadType> {
|
|
459
551
|
const thread = await this.getThreadById({ threadId: id });
|
|
460
552
|
if (!thread) {
|
|
461
|
-
throw new
|
|
553
|
+
throw new MastraError({
|
|
554
|
+
id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED_THREAD_NOT_FOUND',
|
|
555
|
+
domain: ErrorDomain.STORAGE,
|
|
556
|
+
category: ErrorCategory.USER,
|
|
557
|
+
text: `Thread ${id} not found`,
|
|
558
|
+
details: { threadId: id },
|
|
559
|
+
});
|
|
462
560
|
}
|
|
463
561
|
|
|
464
562
|
const updatedThread = {
|
|
@@ -470,24 +568,49 @@ export class LibSQLStore extends MastraStorage {
|
|
|
470
568
|
},
|
|
471
569
|
};
|
|
472
570
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
571
|
+
try {
|
|
572
|
+
await this.client.execute({
|
|
573
|
+
sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
|
|
574
|
+
args: [title, JSON.stringify(updatedThread.metadata), id],
|
|
575
|
+
});
|
|
477
576
|
|
|
478
|
-
|
|
577
|
+
return updatedThread;
|
|
578
|
+
} catch (error) {
|
|
579
|
+
throw new MastraError(
|
|
580
|
+
{
|
|
581
|
+
id: 'LIBSQL_STORE_UPDATE_THREAD_FAILED',
|
|
582
|
+
domain: ErrorDomain.STORAGE,
|
|
583
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
584
|
+
text: `Failed to update thread ${id}`,
|
|
585
|
+
details: { threadId: id },
|
|
586
|
+
},
|
|
587
|
+
error,
|
|
588
|
+
);
|
|
589
|
+
}
|
|
479
590
|
}
|
|
480
591
|
|
|
481
592
|
async deleteThread({ threadId }: { threadId: string }): Promise<void> {
|
|
482
593
|
// Delete messages for this thread (manual step)
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
594
|
+
try {
|
|
595
|
+
await this.client.execute({
|
|
596
|
+
sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
|
|
597
|
+
args: [threadId],
|
|
598
|
+
});
|
|
599
|
+
await this.client.execute({
|
|
600
|
+
sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
|
|
601
|
+
args: [threadId],
|
|
602
|
+
});
|
|
603
|
+
} catch (error) {
|
|
604
|
+
throw new MastraError(
|
|
605
|
+
{
|
|
606
|
+
id: 'LIBSQL_STORE_DELETE_THREAD_FAILED',
|
|
607
|
+
domain: ErrorDomain.STORAGE,
|
|
608
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
609
|
+
details: { threadId },
|
|
610
|
+
},
|
|
611
|
+
error,
|
|
612
|
+
);
|
|
613
|
+
}
|
|
491
614
|
// TODO: Need to check if CASCADE is enabled so that messages will be automatically deleted due to CASCADE constraint
|
|
492
615
|
}
|
|
493
616
|
|
|
@@ -577,8 +700,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
577
700
|
}): Promise<MastraMessageV1[] | MastraMessageV2[]> {
|
|
578
701
|
try {
|
|
579
702
|
const messages: MastraMessageV2[] = [];
|
|
580
|
-
const limit =
|
|
581
|
-
|
|
703
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
582
704
|
if (selectBy?.include?.length) {
|
|
583
705
|
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
584
706
|
if (includeMessages) {
|
|
@@ -612,8 +734,15 @@ export class LibSQLStore extends MastraStorage {
|
|
|
612
734
|
if (format === `v2`) return list.get.all.v2();
|
|
613
735
|
return list.get.all.v1();
|
|
614
736
|
} catch (error) {
|
|
615
|
-
|
|
616
|
-
|
|
737
|
+
throw new MastraError(
|
|
738
|
+
{
|
|
739
|
+
id: 'LIBSQL_STORE_GET_MESSAGES_FAILED',
|
|
740
|
+
domain: ErrorDomain.STORAGE,
|
|
741
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
742
|
+
details: { threadId },
|
|
743
|
+
},
|
|
744
|
+
error,
|
|
745
|
+
);
|
|
617
746
|
}
|
|
618
747
|
}
|
|
619
748
|
|
|
@@ -623,16 +752,30 @@ export class LibSQLStore extends MastraStorage {
|
|
|
623
752
|
},
|
|
624
753
|
): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
|
|
625
754
|
const { threadId, format, selectBy } = args;
|
|
626
|
-
const { page = 0, perPage
|
|
755
|
+
const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
|
|
756
|
+
const perPage =
|
|
757
|
+
perPageInput !== undefined ? perPageInput : this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
627
758
|
const fromDate = dateRange?.start;
|
|
628
759
|
const toDate = dateRange?.end;
|
|
629
760
|
|
|
630
761
|
const messages: MastraMessageV2[] = [];
|
|
631
762
|
|
|
632
763
|
if (selectBy?.include?.length) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
764
|
+
try {
|
|
765
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
|
|
766
|
+
if (includeMessages) {
|
|
767
|
+
messages.push(...includeMessages);
|
|
768
|
+
}
|
|
769
|
+
} catch (error) {
|
|
770
|
+
throw new MastraError(
|
|
771
|
+
{
|
|
772
|
+
id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_GET_INCLUDE_MESSAGES_FAILED',
|
|
773
|
+
domain: ErrorDomain.STORAGE,
|
|
774
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
775
|
+
details: { threadId },
|
|
776
|
+
},
|
|
777
|
+
error,
|
|
778
|
+
);
|
|
636
779
|
}
|
|
637
780
|
}
|
|
638
781
|
|
|
@@ -658,7 +801,7 @@ export class LibSQLStore extends MastraStorage {
|
|
|
658
801
|
});
|
|
659
802
|
const total = Number(countResult.rows?.[0]?.count ?? 0);
|
|
660
803
|
|
|
661
|
-
if (total === 0) {
|
|
804
|
+
if (total === 0 && messages.length === 0) {
|
|
662
805
|
return {
|
|
663
806
|
messages: [],
|
|
664
807
|
total: 0,
|
|
@@ -668,9 +811,12 @@ export class LibSQLStore extends MastraStorage {
|
|
|
668
811
|
};
|
|
669
812
|
}
|
|
670
813
|
|
|
814
|
+
const excludeIds = messages.map(m => m.id);
|
|
815
|
+
const excludeIdsParam = excludeIds.map((_, idx) => `$${idx + queryParams.length + 1}`).join(', ');
|
|
816
|
+
|
|
671
817
|
const dataResult = await this.client.execute({
|
|
672
|
-
sql: `SELECT id, content, role, type, "createdAt", thread_id FROM ${TABLE_MESSAGES} ${whereClause} ORDER BY "createdAt" DESC LIMIT ? OFFSET ?`,
|
|
673
|
-
args: [...queryParams, perPage, currentOffset],
|
|
818
|
+
sql: `SELECT id, content, role, type, "createdAt", "resourceId", "thread_id" FROM ${TABLE_MESSAGES} ${whereClause} ${excludeIds.length ? `AND id NOT IN (${excludeIdsParam})` : ''} ORDER BY "createdAt" DESC LIMIT ? OFFSET ?`,
|
|
819
|
+
args: [...queryParams, ...excludeIds, perPage, currentOffset],
|
|
674
820
|
});
|
|
675
821
|
|
|
676
822
|
messages.push(...(dataResult.rows || []).map((row: any) => this.parseRow(row)));
|
|
@@ -688,7 +834,17 @@ export class LibSQLStore extends MastraStorage {
|
|
|
688
834
|
hasMore: currentOffset + messages.length < total,
|
|
689
835
|
};
|
|
690
836
|
} catch (error) {
|
|
691
|
-
|
|
837
|
+
const mastraError = new MastraError(
|
|
838
|
+
{
|
|
839
|
+
id: 'LIBSQL_STORE_GET_MESSAGES_PAGINATED_FAILED',
|
|
840
|
+
domain: ErrorDomain.STORAGE,
|
|
841
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
842
|
+
details: { threadId },
|
|
843
|
+
},
|
|
844
|
+
error,
|
|
845
|
+
);
|
|
846
|
+
this.logger?.trackException?.(mastraError);
|
|
847
|
+
this.logger?.error?.(mastraError.toString());
|
|
692
848
|
return { messages: [], total: 0, page, perPage, hasMore: false };
|
|
693
849
|
}
|
|
694
850
|
}
|
|
@@ -724,7 +880,14 @@ export class LibSQLStore extends MastraStorage {
|
|
|
724
880
|
}
|
|
725
881
|
return {
|
|
726
882
|
sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
|
|
727
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
883
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
884
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
885
|
+
thread_id=excluded.thread_id,
|
|
886
|
+
content=excluded.content,
|
|
887
|
+
role=excluded.role,
|
|
888
|
+
type=excluded.type,
|
|
889
|
+
resourceId=excluded.resourceId
|
|
890
|
+
`,
|
|
728
891
|
args: [
|
|
729
892
|
message.id,
|
|
730
893
|
message.threadId!,
|
|
@@ -750,8 +913,14 @@ export class LibSQLStore extends MastraStorage {
|
|
|
750
913
|
if (format === `v2`) return list.get.all.v2();
|
|
751
914
|
return list.get.all.v1();
|
|
752
915
|
} catch (error) {
|
|
753
|
-
|
|
754
|
-
|
|
916
|
+
throw new MastraError(
|
|
917
|
+
{
|
|
918
|
+
id: 'LIBSQL_STORE_SAVE_MESSAGES_FAILED',
|
|
919
|
+
domain: ErrorDomain.STORAGE,
|
|
920
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
921
|
+
},
|
|
922
|
+
error,
|
|
923
|
+
);
|
|
755
924
|
}
|
|
756
925
|
}
|
|
757
926
|
|
|
@@ -905,8 +1074,15 @@ export class LibSQLStore extends MastraStorage {
|
|
|
905
1074
|
if (error instanceof Error && error.message.includes('no such table')) {
|
|
906
1075
|
return [];
|
|
907
1076
|
}
|
|
908
|
-
|
|
909
|
-
|
|
1077
|
+
throw new MastraError(
|
|
1078
|
+
{
|
|
1079
|
+
id: 'LIBSQL_STORE_GET_EVALS_BY_AGENT_NAME_FAILED',
|
|
1080
|
+
domain: ErrorDomain.STORAGE,
|
|
1081
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1082
|
+
details: { agentName },
|
|
1083
|
+
},
|
|
1084
|
+
error,
|
|
1085
|
+
);
|
|
910
1086
|
}
|
|
911
1087
|
}
|
|
912
1088
|
|
|
@@ -946,37 +1122,48 @@ export class LibSQLStore extends MastraStorage {
|
|
|
946
1122
|
|
|
947
1123
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
948
1124
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1125
|
+
try {
|
|
1126
|
+
const countResult = await this.client.execute({
|
|
1127
|
+
sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
|
|
1128
|
+
args: queryParams,
|
|
1129
|
+
});
|
|
1130
|
+
const total = Number(countResult.rows?.[0]?.count ?? 0);
|
|
954
1131
|
|
|
955
|
-
|
|
956
|
-
|
|
1132
|
+
const currentOffset = page * perPage;
|
|
1133
|
+
const hasMore = currentOffset + perPage < total;
|
|
1134
|
+
|
|
1135
|
+
if (total === 0) {
|
|
1136
|
+
return {
|
|
1137
|
+
evals: [],
|
|
1138
|
+
total: 0,
|
|
1139
|
+
page,
|
|
1140
|
+
perPage,
|
|
1141
|
+
hasMore: false,
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
const dataResult = await this.client.execute({
|
|
1146
|
+
sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
|
|
1147
|
+
args: [...queryParams, perPage, currentOffset],
|
|
1148
|
+
});
|
|
957
1149
|
|
|
958
|
-
if (total === 0) {
|
|
959
1150
|
return {
|
|
960
|
-
evals: [],
|
|
961
|
-
total
|
|
1151
|
+
evals: dataResult.rows?.map(row => this.transformEvalRow(row)) ?? [],
|
|
1152
|
+
total,
|
|
962
1153
|
page,
|
|
963
1154
|
perPage,
|
|
964
|
-
hasMore
|
|
1155
|
+
hasMore,
|
|
965
1156
|
};
|
|
1157
|
+
} catch (error) {
|
|
1158
|
+
throw new MastraError(
|
|
1159
|
+
{
|
|
1160
|
+
id: 'LIBSQL_STORE_GET_EVALS_FAILED',
|
|
1161
|
+
domain: ErrorDomain.STORAGE,
|
|
1162
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1163
|
+
},
|
|
1164
|
+
error,
|
|
1165
|
+
);
|
|
966
1166
|
}
|
|
967
|
-
|
|
968
|
-
const dataResult = await this.client.execute({
|
|
969
|
-
sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
|
|
970
|
-
args: [...queryParams, perPage, currentOffset],
|
|
971
|
-
});
|
|
972
|
-
|
|
973
|
-
return {
|
|
974
|
-
evals: dataResult.rows?.map(row => this.transformEvalRow(row)) ?? [],
|
|
975
|
-
total,
|
|
976
|
-
page,
|
|
977
|
-
perPage,
|
|
978
|
-
hasMore,
|
|
979
|
-
};
|
|
980
1167
|
}
|
|
981
1168
|
|
|
982
1169
|
/**
|
|
@@ -998,8 +1185,19 @@ export class LibSQLStore extends MastraStorage {
|
|
|
998
1185
|
end: args.toDate,
|
|
999
1186
|
};
|
|
1000
1187
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1188
|
+
try {
|
|
1189
|
+
const result = await this.getTracesPaginated(args);
|
|
1190
|
+
return result.traces;
|
|
1191
|
+
} catch (error) {
|
|
1192
|
+
throw new MastraError(
|
|
1193
|
+
{
|
|
1194
|
+
id: 'LIBSQL_STORE_GET_TRACES_FAILED',
|
|
1195
|
+
domain: ErrorDomain.STORAGE,
|
|
1196
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1197
|
+
},
|
|
1198
|
+
error,
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1003
1201
|
}
|
|
1004
1202
|
|
|
1005
1203
|
public async getTracesPaginated(
|
|
@@ -1049,55 +1247,66 @@ export class LibSQLStore extends MastraStorage {
|
|
|
1049
1247
|
|
|
1050
1248
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
1051
1249
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1250
|
+
try {
|
|
1251
|
+
const countResult = await this.client.execute({
|
|
1252
|
+
sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
|
|
1253
|
+
args: queryArgs,
|
|
1254
|
+
});
|
|
1255
|
+
const total = Number(countResult.rows?.[0]?.count ?? 0);
|
|
1256
|
+
|
|
1257
|
+
if (total === 0) {
|
|
1258
|
+
return {
|
|
1259
|
+
traces: [],
|
|
1260
|
+
total: 0,
|
|
1261
|
+
page,
|
|
1262
|
+
perPage,
|
|
1263
|
+
hasMore: false,
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
const dataResult = await this.client.execute({
|
|
1268
|
+
sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
|
|
1269
|
+
args: [...queryArgs, perPage, currentOffset],
|
|
1270
|
+
});
|
|
1271
|
+
|
|
1272
|
+
const traces =
|
|
1273
|
+
dataResult.rows?.map(
|
|
1274
|
+
row =>
|
|
1275
|
+
({
|
|
1276
|
+
id: row.id,
|
|
1277
|
+
parentSpanId: row.parentSpanId,
|
|
1278
|
+
traceId: row.traceId,
|
|
1279
|
+
name: row.name,
|
|
1280
|
+
scope: row.scope,
|
|
1281
|
+
kind: row.kind,
|
|
1282
|
+
status: safelyParseJSON(row.status as string),
|
|
1283
|
+
events: safelyParseJSON(row.events as string),
|
|
1284
|
+
links: safelyParseJSON(row.links as string),
|
|
1285
|
+
attributes: safelyParseJSON(row.attributes as string),
|
|
1286
|
+
startTime: row.startTime,
|
|
1287
|
+
endTime: row.endTime,
|
|
1288
|
+
other: safelyParseJSON(row.other as string),
|
|
1289
|
+
createdAt: row.createdAt,
|
|
1290
|
+
}) as Trace,
|
|
1291
|
+
) ?? [];
|
|
1057
1292
|
|
|
1058
|
-
if (total === 0) {
|
|
1059
1293
|
return {
|
|
1060
|
-
traces
|
|
1061
|
-
total
|
|
1294
|
+
traces,
|
|
1295
|
+
total,
|
|
1062
1296
|
page,
|
|
1063
1297
|
perPage,
|
|
1064
|
-
hasMore:
|
|
1298
|
+
hasMore: currentOffset + traces.length < total,
|
|
1065
1299
|
};
|
|
1300
|
+
} catch (error) {
|
|
1301
|
+
throw new MastraError(
|
|
1302
|
+
{
|
|
1303
|
+
id: 'LIBSQL_STORE_GET_TRACES_PAGINATED_FAILED',
|
|
1304
|
+
domain: ErrorDomain.STORAGE,
|
|
1305
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1306
|
+
},
|
|
1307
|
+
error,
|
|
1308
|
+
);
|
|
1066
1309
|
}
|
|
1067
|
-
|
|
1068
|
-
const dataResult = await this.client.execute({
|
|
1069
|
-
sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
|
|
1070
|
-
args: [...queryArgs, perPage, currentOffset],
|
|
1071
|
-
});
|
|
1072
|
-
|
|
1073
|
-
const traces =
|
|
1074
|
-
dataResult.rows?.map(
|
|
1075
|
-
row =>
|
|
1076
|
-
({
|
|
1077
|
-
id: row.id,
|
|
1078
|
-
parentSpanId: row.parentSpanId,
|
|
1079
|
-
traceId: row.traceId,
|
|
1080
|
-
name: row.name,
|
|
1081
|
-
scope: row.scope,
|
|
1082
|
-
kind: row.kind,
|
|
1083
|
-
status: safelyParseJSON(row.status as string),
|
|
1084
|
-
events: safelyParseJSON(row.events as string),
|
|
1085
|
-
links: safelyParseJSON(row.links as string),
|
|
1086
|
-
attributes: safelyParseJSON(row.attributes as string),
|
|
1087
|
-
startTime: row.startTime,
|
|
1088
|
-
endTime: row.endTime,
|
|
1089
|
-
other: safelyParseJSON(row.other as string),
|
|
1090
|
-
createdAt: row.createdAt,
|
|
1091
|
-
}) as Trace,
|
|
1092
|
-
) ?? [];
|
|
1093
|
-
|
|
1094
|
-
return {
|
|
1095
|
-
traces,
|
|
1096
|
-
total,
|
|
1097
|
-
page,
|
|
1098
|
-
perPage,
|
|
1099
|
-
hasMore: currentOffset + traces.length < total,
|
|
1100
|
-
};
|
|
1101
1310
|
}
|
|
1102
1311
|
|
|
1103
1312
|
async getWorkflowRuns({
|
|
@@ -1167,8 +1376,14 @@ export class LibSQLStore extends MastraStorage {
|
|
|
1167
1376
|
// Use runs.length as total when not paginating
|
|
1168
1377
|
return { runs, total: total || runs.length };
|
|
1169
1378
|
} catch (error) {
|
|
1170
|
-
|
|
1171
|
-
|
|
1379
|
+
throw new MastraError(
|
|
1380
|
+
{
|
|
1381
|
+
id: 'LIBSQL_STORE_GET_WORKFLOW_RUNS_FAILED',
|
|
1382
|
+
domain: ErrorDomain.STORAGE,
|
|
1383
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1384
|
+
},
|
|
1385
|
+
error,
|
|
1386
|
+
);
|
|
1172
1387
|
}
|
|
1173
1388
|
}
|
|
1174
1389
|
|
|
@@ -1194,16 +1409,117 @@ export class LibSQLStore extends MastraStorage {
|
|
|
1194
1409
|
|
|
1195
1410
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
1196
1411
|
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1412
|
+
try {
|
|
1413
|
+
const result = await this.client.execute({
|
|
1414
|
+
sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
|
|
1415
|
+
args,
|
|
1416
|
+
});
|
|
1417
|
+
|
|
1418
|
+
if (!result.rows?.[0]) {
|
|
1419
|
+
return null;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
return this.parseWorkflowRun(result.rows[0]);
|
|
1423
|
+
} catch (error) {
|
|
1424
|
+
throw new MastraError(
|
|
1425
|
+
{
|
|
1426
|
+
id: 'LIBSQL_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED',
|
|
1427
|
+
domain: ErrorDomain.STORAGE,
|
|
1428
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1429
|
+
},
|
|
1430
|
+
error,
|
|
1431
|
+
);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {
|
|
1436
|
+
const result = await this.load<StorageResourceType>({
|
|
1437
|
+
tableName: TABLE_RESOURCES,
|
|
1438
|
+
keys: { id: resourceId },
|
|
1200
1439
|
});
|
|
1201
1440
|
|
|
1202
|
-
if (!result
|
|
1441
|
+
if (!result) {
|
|
1203
1442
|
return null;
|
|
1204
1443
|
}
|
|
1205
1444
|
|
|
1206
|
-
return
|
|
1445
|
+
return {
|
|
1446
|
+
...result,
|
|
1447
|
+
// Ensure workingMemory is always returned as a string, even if auto-parsed as JSON
|
|
1448
|
+
workingMemory:
|
|
1449
|
+
typeof result.workingMemory === 'object' ? JSON.stringify(result.workingMemory) : result.workingMemory,
|
|
1450
|
+
metadata: typeof result.metadata === 'string' ? JSON.parse(result.metadata) : result.metadata,
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {
|
|
1455
|
+
await this.insert({
|
|
1456
|
+
tableName: TABLE_RESOURCES,
|
|
1457
|
+
record: {
|
|
1458
|
+
...resource,
|
|
1459
|
+
metadata: JSON.stringify(resource.metadata),
|
|
1460
|
+
},
|
|
1461
|
+
});
|
|
1462
|
+
|
|
1463
|
+
return resource;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
async updateResource({
|
|
1467
|
+
resourceId,
|
|
1468
|
+
workingMemory,
|
|
1469
|
+
metadata,
|
|
1470
|
+
}: {
|
|
1471
|
+
resourceId: string;
|
|
1472
|
+
workingMemory?: string;
|
|
1473
|
+
metadata?: Record<string, unknown>;
|
|
1474
|
+
}): Promise<StorageResourceType> {
|
|
1475
|
+
const existingResource = await this.getResourceById({ resourceId });
|
|
1476
|
+
|
|
1477
|
+
if (!existingResource) {
|
|
1478
|
+
// Create new resource if it doesn't exist
|
|
1479
|
+
const newResource: StorageResourceType = {
|
|
1480
|
+
id: resourceId,
|
|
1481
|
+
workingMemory,
|
|
1482
|
+
metadata: metadata || {},
|
|
1483
|
+
createdAt: new Date(),
|
|
1484
|
+
updatedAt: new Date(),
|
|
1485
|
+
};
|
|
1486
|
+
return this.saveResource({ resource: newResource });
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
const updatedResource = {
|
|
1490
|
+
...existingResource,
|
|
1491
|
+
workingMemory: workingMemory !== undefined ? workingMemory : existingResource.workingMemory,
|
|
1492
|
+
metadata: {
|
|
1493
|
+
...existingResource.metadata,
|
|
1494
|
+
...metadata,
|
|
1495
|
+
},
|
|
1496
|
+
updatedAt: new Date(),
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
const updates: string[] = [];
|
|
1500
|
+
const values: InValue[] = [];
|
|
1501
|
+
|
|
1502
|
+
if (workingMemory !== undefined) {
|
|
1503
|
+
updates.push('workingMemory = ?');
|
|
1504
|
+
values.push(workingMemory);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
if (metadata) {
|
|
1508
|
+
updates.push('metadata = ?');
|
|
1509
|
+
values.push(JSON.stringify(updatedResource.metadata));
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
updates.push('updatedAt = ?');
|
|
1513
|
+
values.push(updatedResource.updatedAt.toISOString());
|
|
1514
|
+
|
|
1515
|
+
values.push(resourceId);
|
|
1516
|
+
|
|
1517
|
+
await this.client.execute({
|
|
1518
|
+
sql: `UPDATE ${TABLE_RESOURCES} SET ${updates.join(', ')} WHERE id = ?`,
|
|
1519
|
+
args: values,
|
|
1520
|
+
});
|
|
1521
|
+
|
|
1522
|
+
return updatedResource;
|
|
1207
1523
|
}
|
|
1208
1524
|
|
|
1209
1525
|
private async hasColumn(table: string, column: string): Promise<boolean> {
|