@mastra/libsql 0.13.7 → 0.13.8-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.
@@ -1,499 +0,0 @@
1
- import { createClient } from '@libsql/client';
2
- import type { Client } from '@libsql/client';
3
- import type { MastraMessageContentV2, MastraMessageV2 } from '@mastra/core/agent';
4
- import type { MastraMessageV1, StorageThreadType } from '@mastra/core/memory';
5
- import type { ScoreRowData, ScoringSource } from '@mastra/core/scores';
6
- import { MastraStorage } from '@mastra/core/storage';
7
- import type {
8
- EvalRow,
9
- PaginationArgs,
10
- PaginationInfo,
11
- StorageColumn,
12
- StoragePagination,
13
- StorageGetMessagesArg,
14
- StorageResourceType,
15
- TABLE_NAMES,
16
- WorkflowRun,
17
- WorkflowRuns,
18
- StorageGetTracesArg,
19
- StorageDomains,
20
- ThreadSortOptions,
21
- AISpanRecord,
22
- AITraceRecord,
23
- AITracesPaginatedArg,
24
- } from '@mastra/core/storage';
25
-
26
- import type { Trace } from '@mastra/core/telemetry';
27
- import type { StepResult, WorkflowRunState } from '@mastra/core/workflows';
28
- import { LegacyEvalsLibSQL } from './domains/legacy-evals';
29
- import { MemoryLibSQL } from './domains/memory';
30
- import { ObservabilityLibSQL } from './domains/observability';
31
- import { StoreOperationsLibSQL } from './domains/operations';
32
- import { ScoresLibSQL } from './domains/scores';
33
- import { TracesLibSQL } from './domains/traces';
34
- import { WorkflowsLibSQL } from './domains/workflows';
35
-
36
- export type LibSQLConfig =
37
- | {
38
- url: string;
39
- authToken?: string;
40
- /**
41
- * Maximum number of retries for write operations if an SQLITE_BUSY error occurs.
42
- * @default 5
43
- */
44
- maxRetries?: number;
45
- /**
46
- * Initial backoff time in milliseconds for retrying write operations on SQLITE_BUSY.
47
- * The backoff time will double with each retry (exponential backoff).
48
- * @default 100
49
- */
50
- initialBackoffMs?: number;
51
- }
52
- | {
53
- client: Client;
54
- maxRetries?: number;
55
- initialBackoffMs?: number;
56
- };
57
-
58
- export class LibSQLStore extends MastraStorage {
59
- private client: Client;
60
- private readonly maxRetries: number;
61
- private readonly initialBackoffMs: number;
62
-
63
- stores: StorageDomains;
64
-
65
- constructor(config: LibSQLConfig) {
66
- super({ name: `LibSQLStore` });
67
-
68
- this.maxRetries = config.maxRetries ?? 5;
69
- this.initialBackoffMs = config.initialBackoffMs ?? 100;
70
-
71
- if ('url' in config) {
72
- // need to re-init every time for in memory dbs or the tables might not exist
73
- if (config.url.endsWith(':memory:')) {
74
- this.shouldCacheInit = false;
75
- }
76
-
77
- this.client = createClient({
78
- url: config.url,
79
- ...(config.authToken ? { authToken: config.authToken } : {}),
80
- });
81
-
82
- // Set PRAGMAs for better concurrency, especially for file-based databases
83
- if (config.url.startsWith('file:') || config.url.includes(':memory:')) {
84
- this.client
85
- .execute('PRAGMA journal_mode=WAL;')
86
- .then(() => this.logger.debug('LibSQLStore: PRAGMA journal_mode=WAL set.'))
87
- .catch(err => this.logger.warn('LibSQLStore: Failed to set PRAGMA journal_mode=WAL.', err));
88
- this.client
89
- .execute('PRAGMA busy_timeout = 5000;') // 5 seconds
90
- .then(() => this.logger.debug('LibSQLStore: PRAGMA busy_timeout=5000 set.'))
91
- .catch(err => this.logger.warn('LibSQLStore: Failed to set PRAGMA busy_timeout.', err));
92
- }
93
- } else {
94
- this.client = config.client;
95
- }
96
-
97
- const operations = new StoreOperationsLibSQL({
98
- client: this.client,
99
- maxRetries: this.maxRetries,
100
- initialBackoffMs: this.initialBackoffMs,
101
- });
102
-
103
- const scores = new ScoresLibSQL({ client: this.client, operations });
104
- const traces = new TracesLibSQL({ client: this.client, operations });
105
- const workflows = new WorkflowsLibSQL({ client: this.client, operations });
106
- const memory = new MemoryLibSQL({ client: this.client, operations });
107
- const legacyEvals = new LegacyEvalsLibSQL({ client: this.client });
108
- const observability = new ObservabilityLibSQL({ operations });
109
-
110
- this.stores = {
111
- operations,
112
- scores,
113
- traces,
114
- workflows,
115
- memory,
116
- legacyEvals,
117
- observability,
118
- };
119
- }
120
-
121
- public get supports() {
122
- return {
123
- selectByIncludeResourceScope: true,
124
- resourceWorkingMemory: true,
125
- hasColumn: true,
126
- createTable: true,
127
- deleteMessages: true,
128
- aiTracing: true,
129
- };
130
- }
131
-
132
- async createTable({
133
- tableName,
134
- schema,
135
- }: {
136
- tableName: TABLE_NAMES;
137
- schema: Record<string, StorageColumn>;
138
- }): Promise<void> {
139
- await this.stores.operations.createTable({ tableName, schema });
140
- }
141
-
142
- /**
143
- * Alters table schema to add columns if they don't exist
144
- * @param tableName Name of the table
145
- * @param schema Schema of the table
146
- * @param ifNotExists Array of column names to add if they don't exist
147
- */
148
- async alterTable({
149
- tableName,
150
- schema,
151
- ifNotExists,
152
- }: {
153
- tableName: TABLE_NAMES;
154
- schema: Record<string, StorageColumn>;
155
- ifNotExists: string[];
156
- }): Promise<void> {
157
- await this.stores.operations.alterTable({ tableName, schema, ifNotExists });
158
- }
159
-
160
- async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
161
- await this.stores.operations.clearTable({ tableName });
162
- }
163
-
164
- async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
165
- await this.stores.operations.dropTable({ tableName });
166
- }
167
-
168
- public insert(args: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {
169
- return this.stores.operations.insert(args);
170
- }
171
-
172
- public batchInsert(args: { tableName: TABLE_NAMES; records: Record<string, any>[] }): Promise<void> {
173
- return this.stores.operations.batchInsert(args);
174
- }
175
-
176
- async load<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {
177
- return this.stores.operations.load({ tableName, keys });
178
- }
179
-
180
- async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
181
- return this.stores.memory.getThreadById({ threadId });
182
- }
183
-
184
- /**
185
- * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.
186
- */
187
- public async getThreadsByResourceId(args: { resourceId: string } & ThreadSortOptions): Promise<StorageThreadType[]> {
188
- return this.stores.memory.getThreadsByResourceId(args);
189
- }
190
-
191
- public async getThreadsByResourceIdPaginated(
192
- args: {
193
- resourceId: string;
194
- page: number;
195
- perPage: number;
196
- } & ThreadSortOptions,
197
- ): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
198
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
199
- }
200
-
201
- async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
202
- return this.stores.memory.saveThread({ thread });
203
- }
204
-
205
- async updateThread({
206
- id,
207
- title,
208
- metadata,
209
- }: {
210
- id: string;
211
- title: string;
212
- metadata: Record<string, unknown>;
213
- }): Promise<StorageThreadType> {
214
- return this.stores.memory.updateThread({ id, title, metadata });
215
- }
216
-
217
- async deleteThread({ threadId }: { threadId: string }): Promise<void> {
218
- return this.stores.memory.deleteThread({ threadId });
219
- }
220
-
221
- /**
222
- * @deprecated use getMessagesPaginated instead for paginated results.
223
- */
224
- public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;
225
- public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;
226
- public async getMessages({
227
- threadId,
228
- selectBy,
229
- format,
230
- }: StorageGetMessagesArg & {
231
- format?: 'v1' | 'v2';
232
- }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
233
- return this.stores.memory.getMessages({ threadId, selectBy, format });
234
- }
235
-
236
- async getMessagesById({ messageIds, format }: { messageIds: string[]; format: 'v1' }): Promise<MastraMessageV1[]>;
237
- async getMessagesById({ messageIds, format }: { messageIds: string[]; format?: 'v2' }): Promise<MastraMessageV2[]>;
238
- async getMessagesById({
239
- messageIds,
240
- format,
241
- }: {
242
- messageIds: string[];
243
- format?: 'v1' | 'v2';
244
- }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
245
- return this.stores.memory.getMessagesById({ messageIds, format });
246
- }
247
-
248
- public async getMessagesPaginated(
249
- args: StorageGetMessagesArg & {
250
- format?: 'v1' | 'v2';
251
- },
252
- ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
253
- return this.stores.memory.getMessagesPaginated(args);
254
- }
255
-
256
- async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;
257
- async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;
258
- async saveMessages(
259
- args: { messages: MastraMessageV1[]; format?: undefined | 'v1' } | { messages: MastraMessageV2[]; format: 'v2' },
260
- ): Promise<MastraMessageV2[] | MastraMessageV1[]> {
261
- return this.stores.memory.saveMessages(args);
262
- }
263
-
264
- async updateMessages({
265
- messages,
266
- }: {
267
- messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {
268
- id: string;
269
- content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
270
- })[];
271
- }): Promise<MastraMessageV2[]> {
272
- return this.stores.memory.updateMessages({ messages });
273
- }
274
-
275
- async deleteMessages(messageIds: string[]): Promise<void> {
276
- return this.stores.memory.deleteMessages(messageIds);
277
- }
278
-
279
- /** @deprecated use getEvals instead */
280
- async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {
281
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
282
- }
283
-
284
- async getEvals(
285
- options: {
286
- agentName?: string;
287
- type?: 'test' | 'live';
288
- } & PaginationArgs = {},
289
- ): Promise<PaginationInfo & { evals: EvalRow[] }> {
290
- return this.stores.legacyEvals.getEvals(options);
291
- }
292
-
293
- async getScoreById({ id }: { id: string }): Promise<ScoreRowData | null> {
294
- return this.stores.scores.getScoreById({ id });
295
- }
296
-
297
- async saveScore(score: Omit<ScoreRowData, 'id' | 'createdAt' | 'updatedAt'>): Promise<{ score: ScoreRowData }> {
298
- return this.stores.scores.saveScore(score);
299
- }
300
-
301
- async getScoresByScorerId({
302
- scorerId,
303
- entityId,
304
- entityType,
305
- source,
306
- pagination,
307
- }: {
308
- scorerId: string;
309
- entityId?: string;
310
- entityType?: string;
311
- source?: ScoringSource;
312
- pagination: StoragePagination;
313
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
314
- return this.stores.scores.getScoresByScorerId({ scorerId, entityId, entityType, source, pagination });
315
- }
316
-
317
- async getScoresByRunId({
318
- runId,
319
- pagination,
320
- }: {
321
- runId: string;
322
- pagination: StoragePagination;
323
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
324
- return this.stores.scores.getScoresByRunId({ runId, pagination });
325
- }
326
-
327
- async getScoresByEntityId({
328
- entityId,
329
- entityType,
330
- pagination,
331
- }: {
332
- pagination: StoragePagination;
333
- entityId: string;
334
- entityType: string;
335
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
336
- return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
337
- }
338
-
339
- /**
340
- * TRACES
341
- */
342
-
343
- /**
344
- * @deprecated use getTracesPaginated instead.
345
- */
346
- async getTraces(args: StorageGetTracesArg): Promise<Trace[]> {
347
- return this.stores.traces.getTraces(args);
348
- }
349
-
350
- async getTracesPaginated(args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {
351
- return this.stores.traces.getTracesPaginated(args);
352
- }
353
-
354
- async batchTraceInsert(args: { records: Record<string, any>[] }): Promise<void> {
355
- return this.stores.traces.batchTraceInsert(args);
356
- }
357
-
358
- /**
359
- * WORKFLOWS
360
- */
361
-
362
- async updateWorkflowResults({
363
- workflowName,
364
- runId,
365
- stepId,
366
- result,
367
- runtimeContext,
368
- }: {
369
- workflowName: string;
370
- runId: string;
371
- stepId: string;
372
- result: StepResult<any, any, any, any>;
373
- runtimeContext: Record<string, any>;
374
- }): Promise<Record<string, StepResult<any, any, any, any>>> {
375
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
376
- }
377
-
378
- async updateWorkflowState({
379
- workflowName,
380
- runId,
381
- opts,
382
- }: {
383
- workflowName: string;
384
- runId: string;
385
- opts: {
386
- status: string;
387
- result?: StepResult<any, any, any, any>;
388
- error?: string;
389
- suspendedPaths?: Record<string, number[]>;
390
- waitingPaths?: Record<string, number[]>;
391
- };
392
- }): Promise<WorkflowRunState | undefined> {
393
- return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
394
- }
395
-
396
- async persistWorkflowSnapshot({
397
- workflowName,
398
- runId,
399
- snapshot,
400
- }: {
401
- workflowName: string;
402
- runId: string;
403
- snapshot: WorkflowRunState;
404
- }): Promise<void> {
405
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
406
- }
407
-
408
- async loadWorkflowSnapshot({
409
- workflowName,
410
- runId,
411
- }: {
412
- workflowName: string;
413
- runId: string;
414
- }): Promise<WorkflowRunState | null> {
415
- return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
416
- }
417
-
418
- async getWorkflowRuns({
419
- workflowName,
420
- fromDate,
421
- toDate,
422
- limit,
423
- offset,
424
- resourceId,
425
- }: {
426
- workflowName?: string;
427
- fromDate?: Date;
428
- toDate?: Date;
429
- limit?: number;
430
- offset?: number;
431
- resourceId?: string;
432
- } = {}): Promise<WorkflowRuns> {
433
- return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
434
- }
435
-
436
- async getWorkflowRunById({
437
- runId,
438
- workflowName,
439
- }: {
440
- runId: string;
441
- workflowName?: string;
442
- }): Promise<WorkflowRun | null> {
443
- return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
444
- }
445
-
446
- async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {
447
- return this.stores.memory.getResourceById({ resourceId });
448
- }
449
-
450
- async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {
451
- return this.stores.memory.saveResource({ resource });
452
- }
453
-
454
- async updateResource({
455
- resourceId,
456
- workingMemory,
457
- metadata,
458
- }: {
459
- resourceId: string;
460
- workingMemory?: string;
461
- metadata?: Record<string, unknown>;
462
- }): Promise<StorageResourceType> {
463
- return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
464
- }
465
-
466
- async createAISpan(span: AISpanRecord): Promise<void> {
467
- return this.stores.observability!.createAISpan(span);
468
- }
469
-
470
- async updateAISpan(params: {
471
- spanId: string;
472
- traceId: string;
473
- updates: Partial<Omit<AISpanRecord, 'spanId' | 'traceId'>>;
474
- }): Promise<void> {
475
- return this.stores.observability!.updateAISpan(params);
476
- }
477
-
478
- async getAITrace(traceId: string): Promise<AITraceRecord | null> {
479
- return this.stores.observability!.getAITrace(traceId);
480
- }
481
-
482
- async getAITracesPaginated(
483
- args: AITracesPaginatedArg,
484
- ): Promise<{ pagination: PaginationInfo; spans: AISpanRecord[] }> {
485
- return this.stores.observability!.getAITracesPaginated(args);
486
- }
487
-
488
- async batchCreateAISpans(args: { records: AISpanRecord[] }): Promise<void> {
489
- return this.stores.observability!.batchCreateAISpans(args);
490
- }
491
-
492
- async batchUpdateAISpans(args: {
493
- records: { traceId: string; spanId: string; updates: Partial<Omit<AISpanRecord, 'spanId' | 'traceId'>> }[];
494
- }): Promise<void> {
495
- return this.stores.observability!.batchUpdateAISpans(args);
496
- }
497
- }
498
-
499
- export { LibSQLStore as DefaultStorage };