@mastra/libsql 0.11.0 → 0.11.1-alpha.0

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,17 +1,5 @@
1
- import { randomUUID } from 'crypto';
2
- import {
3
- createSampleEval,
4
- createSampleTraceForDB,
5
- createSampleThread,
6
- createTestSuite,
7
- createSampleMessageV1,
8
- resetRole,
9
- createSampleMessageV2,
10
- } from '@internal/storage-test-utils';
11
- import type { MastraMessageV1, StorageThreadType } from '@mastra/core';
1
+ import { createTestSuite } from '@internal/storage-test-utils';
12
2
  import { Mastra } from '@mastra/core/mastra';
13
- import { TABLE_EVALS, TABLE_TRACES, TABLE_MESSAGES, TABLE_THREADS } from '@mastra/core/storage';
14
- import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
15
3
 
16
4
  import { LibSQLStore } from './index';
17
5
 
@@ -20,510 +8,9 @@ const TEST_DB_URL = 'file::memory:?cache=shared';
20
8
  const libsql = new LibSQLStore({
21
9
  url: TEST_DB_URL,
22
10
  });
11
+
23
12
  const mastra = new Mastra({
24
13
  storage: libsql,
25
14
  });
26
15
 
27
16
  createTestSuite(mastra.getStorage()!);
28
-
29
- describe('LibSQLStore Pagination Features', () => {
30
- let store: LibSQLStore;
31
-
32
- beforeAll(async () => {
33
- store = libsql;
34
- });
35
-
36
- beforeEach(async () => {
37
- await store.clearTable({ tableName: TABLE_EVALS });
38
- await store.clearTable({ tableName: TABLE_TRACES });
39
- await store.clearTable({ tableName: TABLE_MESSAGES });
40
- await store.clearTable({ tableName: TABLE_THREADS });
41
- });
42
-
43
- describe('getEvals with pagination', () => {
44
- it('should return paginated evals with total count (page/perPage)', async () => {
45
- const agentName = 'libsql-pagination-agent-evals';
46
- const evalRecords = Array.from({ length: 25 }, (_, i) => createSampleEval(agentName, i % 2 === 0));
47
- await store.batchInsert({ tableName: TABLE_EVALS, records: evalRecords.map(r => r as any) });
48
-
49
- const page1 = await store.getEvals({ agentName, page: 0, perPage: 10 });
50
- expect(page1.evals).toHaveLength(10);
51
- expect(page1.total).toBe(25);
52
- expect(page1.page).toBe(0);
53
- expect(page1.perPage).toBe(10);
54
- expect(page1.hasMore).toBe(true);
55
-
56
- const page3 = await store.getEvals({ agentName, page: 2, perPage: 10 });
57
- expect(page3.evals).toHaveLength(5);
58
- expect(page3.total).toBe(25);
59
- expect(page3.page).toBe(2);
60
- expect(page3.hasMore).toBe(false);
61
- });
62
-
63
- it('should support limit/offset pagination for getEvals', async () => {
64
- const agentName = 'libsql-pagination-lo-evals';
65
- const evalRecords = Array.from({ length: 15 }, () => createSampleEval(agentName));
66
- await store.batchInsert({ tableName: TABLE_EVALS, records: evalRecords.map(r => r as any) });
67
-
68
- const result = await store.getEvals({ agentName, page: 2, perPage: 5 });
69
- expect(result.evals).toHaveLength(5);
70
- expect(result.total).toBe(15);
71
- expect(result.page).toBe(2);
72
- expect(result.perPage).toBe(5);
73
- expect(result.hasMore).toBe(false);
74
- });
75
-
76
- it('should filter by type with pagination for getEvals', async () => {
77
- const agentName = 'libsql-pagination-type-evals';
78
- const testEvals = Array.from({ length: 10 }, () => createSampleEval(agentName, true));
79
- const liveEvals = Array.from({ length: 8 }, () => createSampleEval(agentName, false));
80
- await store.batchInsert({ tableName: TABLE_EVALS, records: [...testEvals, ...liveEvals].map(r => r as any) });
81
-
82
- const testResults = await store.getEvals({ agentName, type: 'test', page: 0, perPage: 5 });
83
- expect(testResults.evals).toHaveLength(5);
84
- expect(testResults.total).toBe(10);
85
-
86
- const liveResults = await store.getEvals({ agentName, type: 'live', page: 1, perPage: 3 });
87
- expect(liveResults.evals).toHaveLength(3);
88
- expect(liveResults.total).toBe(8);
89
- expect(liveResults.hasMore).toBe(true);
90
- });
91
-
92
- it('should filter by date with pagination for getEvals', async () => {
93
- const agentName = 'libsql-pagination-date-evals';
94
- const now = new Date();
95
- const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
96
- const dayBeforeYesterday = new Date(now.getTime() - 48 * 60 * 60 * 1000);
97
-
98
- const recordsToInsert = [
99
- createSampleEval(agentName, false, dayBeforeYesterday),
100
- createSampleEval(agentName, false, dayBeforeYesterday),
101
- createSampleEval(agentName, false, yesterday),
102
- createSampleEval(agentName, false, yesterday),
103
- createSampleEval(agentName, false, now),
104
- createSampleEval(agentName, false, now),
105
- ];
106
- await store.batchInsert({ tableName: TABLE_EVALS, records: recordsToInsert.map(r => r as any) });
107
-
108
- const fromYesterday = await store.getEvals({ agentName, dateRange: { start: yesterday }, page: 0, perPage: 3 });
109
- expect(fromYesterday.total).toBe(4);
110
- expect(fromYesterday.evals).toHaveLength(3); // Should get 2 from 'now', 1 from 'yesterday' due to DESC order and limit 3
111
- fromYesterday.evals.forEach(e =>
112
- expect(new Date(e.createdAt).getTime()).toBeGreaterThanOrEqual(new Date(yesterday.toISOString()).getTime()),
113
- );
114
- // Check if the first item is from 'now' if possible (because of DESC order)
115
- if (fromYesterday.evals.length > 0) {
116
- expect(new Date(fromYesterday.evals[0].createdAt).toISOString().slice(0, 10)).toEqual(
117
- now.toISOString().slice(0, 10),
118
- );
119
- }
120
-
121
- const onlyDayBefore = await store.getEvals({
122
- agentName,
123
- dateRange: { end: new Date(yesterday.getTime() - 1) },
124
- page: 0,
125
- perPage: 5,
126
- });
127
- expect(onlyDayBefore.total).toBe(2);
128
- expect(onlyDayBefore.evals).toHaveLength(2);
129
- });
130
- });
131
-
132
- describe('getTraces with pagination', () => {
133
- it('should return paginated traces with total count when returnPaginationResults is true', async () => {
134
- const scope = 'libsql-test-scope-traces';
135
- const traceRecords = Array.from({ length: 18 }, (_, i) => createSampleTraceForDB(`test-trace-${i}`, scope));
136
- await store.batchInsert({ tableName: TABLE_TRACES, records: traceRecords.map(r => r as any) });
137
-
138
- const page1 = await store.getTracesPaginated({
139
- scope,
140
- page: 0,
141
- perPage: 8,
142
- });
143
- expect(page1.traces).toHaveLength(8);
144
- expect(page1.total).toBe(18);
145
- expect(page1.page).toBe(0);
146
- expect(page1.perPage).toBe(8);
147
- expect(page1.hasMore).toBe(true);
148
-
149
- const page3 = await store.getTracesPaginated({
150
- scope,
151
- page: 2,
152
- perPage: 8,
153
- });
154
- expect(page3.traces).toHaveLength(2);
155
- expect(page3.total).toBe(18);
156
- expect(page3.hasMore).toBe(false);
157
- });
158
-
159
- it('should return an array of traces when returnPaginationResults is undefined', async () => {
160
- const scope = 'libsql-array-traces';
161
- const traceRecords = [createSampleTraceForDB('trace-arr-1', scope), createSampleTraceForDB('trace-arr-2', scope)];
162
- await store.batchInsert({ tableName: TABLE_TRACES, records: traceRecords.map(r => r as any) });
163
-
164
- const tracesUndefined = await store.getTraces({
165
- scope,
166
- page: 0,
167
- perPage: 5,
168
- });
169
- expect(Array.isArray(tracesUndefined)).toBe(true);
170
- expect(tracesUndefined.length).toBe(2);
171
- // @ts-expect-error
172
- expect(tracesUndefined.total).toBeUndefined();
173
- });
174
-
175
- it('should filter by attributes with pagination for getTraces', async () => {
176
- const scope = 'libsql-attr-traces';
177
- const tracesWithAttr = Array.from({ length: 8 }, (_, i) =>
178
- createSampleTraceForDB(`trace-prod-${i}`, scope, { environment: 'prod' }),
179
- );
180
- const tracesWithoutAttr = Array.from({ length: 5 }, (_, i) =>
181
- createSampleTraceForDB(`trace-dev-${i}`, scope, { environment: 'dev' }),
182
- );
183
- await store.batchInsert({
184
- tableName: TABLE_TRACES,
185
- records: [...tracesWithAttr, ...tracesWithoutAttr].map(r => r as any),
186
- });
187
-
188
- const prodTraces = await store.getTracesPaginated({
189
- scope,
190
- attributes: { environment: 'prod' },
191
- page: 0,
192
- perPage: 5,
193
- });
194
- expect(prodTraces.traces).toHaveLength(5);
195
- expect(prodTraces.total).toBe(8);
196
- expect(prodTraces.hasMore).toBe(true);
197
- });
198
-
199
- it('should filter by date with pagination for getTraces', async () => {
200
- const scope = 'libsql-date-traces';
201
- const now = new Date();
202
- const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
203
- const dayBeforeYesterday = new Date(now.getTime() - 48 * 60 * 60 * 1000);
204
-
205
- const recordsToInsert = [
206
- createSampleTraceForDB('t_dbf1', scope, undefined, dayBeforeYesterday),
207
- createSampleTraceForDB('t_dbf2', scope, undefined, dayBeforeYesterday),
208
- createSampleTraceForDB('t_y1', scope, undefined, yesterday),
209
- createSampleTraceForDB('t_y3', scope, undefined, yesterday),
210
- createSampleTraceForDB('t_n1', scope, undefined, now),
211
- createSampleTraceForDB('t_n2', scope, undefined, now),
212
- ];
213
- await store.batchInsert({ tableName: TABLE_TRACES, records: recordsToInsert.map(r => r as any) });
214
-
215
- const fromYesterday = await store.getTracesPaginated({
216
- scope,
217
- dateRange: { start: yesterday },
218
- page: 0,
219
- perPage: 3,
220
- });
221
- expect(fromYesterday.total).toBe(4);
222
- expect(fromYesterday.traces).toHaveLength(3);
223
- fromYesterday.traces.forEach(t =>
224
- expect(new Date(t.createdAt).getTime()).toBeGreaterThanOrEqual(new Date(yesterday.toISOString()).getTime()),
225
- );
226
- if (fromYesterday.traces.length > 0 && fromYesterday.traces[0].createdAt === now.toISOString()) {
227
- expect(new Date(fromYesterday.traces[0].createdAt).toISOString().slice(0, 10)).toEqual(
228
- now.toISOString().slice(0, 10),
229
- );
230
- }
231
-
232
- const onlyNow = await store.getTracesPaginated({
233
- scope,
234
- dateRange: { start: now, end: now },
235
- page: 0,
236
- perPage: 5,
237
- });
238
- expect(onlyNow.total).toBe(2);
239
- expect(onlyNow.traces).toHaveLength(2);
240
- onlyNow.traces.forEach(t =>
241
- expect(new Date(t.createdAt).toISOString().slice(0, 10)).toEqual(now.toISOString().slice(0, 10)),
242
- );
243
- });
244
- });
245
-
246
- describe('getMessages with pagination', () => {
247
- it('should return paginated messages with total count', async () => {
248
- resetRole();
249
- const threadData = createSampleThread();
250
- threadData.resourceId = 'resource-msg-pagination';
251
- const thread = await store.saveThread({ thread: threadData as StorageThreadType });
252
-
253
- const messageRecords: MastraMessageV1[] = [];
254
- for (let i = 0; i < 15; i++) {
255
- messageRecords.push(createSampleMessageV1({ threadId: thread.id, content: `Message ${i + 1}` }));
256
- }
257
- await store.saveMessages({ messages: messageRecords });
258
-
259
- const page1 = await store.getMessagesPaginated({
260
- threadId: thread.id,
261
- selectBy: { pagination: { page: 0, perPage: 5 } },
262
- format: 'v1',
263
- });
264
- expect(page1.messages).toHaveLength(5);
265
- expect(page1.total).toBe(15);
266
- expect(page1.page).toBe(0);
267
- expect(page1.perPage).toBe(5);
268
- expect(page1.hasMore).toBe(true);
269
-
270
- const page3 = await store.getMessagesPaginated({
271
- threadId: thread.id,
272
- selectBy: { pagination: { page: 2, perPage: 5 } },
273
- format: 'v1',
274
- });
275
- expect(page3.messages).toHaveLength(5);
276
- expect(page3.total).toBe(15);
277
- expect(page3.hasMore).toBe(false);
278
- });
279
-
280
- it('should filter by date with pagination for getMessages', async () => {
281
- const threadData = createSampleThread();
282
- const thread = await store.saveThread({ thread: threadData as StorageThreadType });
283
- const now = new Date();
284
- const yesterday = new Date(
285
- now.getFullYear(),
286
- now.getMonth(),
287
- now.getDate() - 1,
288
- now.getHours(),
289
- now.getMinutes(),
290
- now.getSeconds(),
291
- );
292
- const dayBeforeYesterday = new Date(
293
- now.getFullYear(),
294
- now.getMonth(),
295
- now.getDate() - 2,
296
- now.getHours(),
297
- now.getMinutes(),
298
- now.getSeconds(),
299
- );
300
-
301
- // Ensure timestamps are distinct for reliable sorting by creating them with a slight delay for testing clarity
302
- const messagesToSave: MastraMessageV1[] = [];
303
- messagesToSave.push(
304
- createSampleMessageV1({ threadId: thread.id, content: 'Message 1', createdAt: dayBeforeYesterday }),
305
- );
306
- await new Promise(r => setTimeout(r, 5));
307
- messagesToSave.push(
308
- createSampleMessageV1({ threadId: thread.id, content: 'Message 2', createdAt: dayBeforeYesterday }),
309
- );
310
- await new Promise(r => setTimeout(r, 5));
311
- messagesToSave.push(createSampleMessageV1({ threadId: thread.id, content: 'Message 3', createdAt: yesterday }));
312
- await new Promise(r => setTimeout(r, 5));
313
- messagesToSave.push(createSampleMessageV1({ threadId: thread.id, content: 'Message 4', createdAt: yesterday }));
314
- await new Promise(r => setTimeout(r, 5));
315
- messagesToSave.push(createSampleMessageV1({ threadId: thread.id, content: 'Message 5', createdAt: now }));
316
- await new Promise(r => setTimeout(r, 5));
317
- messagesToSave.push(createSampleMessageV1({ threadId: thread.id, content: 'Message 6', createdAt: now }));
318
-
319
- await store.saveMessages({ messages: messagesToSave, format: 'v1' });
320
- // Total 6 messages: 2 now, 2 yesterday, 2 dayBeforeYesterday (oldest to newest)
321
-
322
- const fromYesterday = await store.getMessagesPaginated({
323
- threadId: thread.id,
324
- selectBy: { pagination: { page: 0, perPage: 3, dateRange: { start: yesterday } } },
325
- format: 'v2',
326
- });
327
- expect(fromYesterday.total).toBe(4);
328
- expect(fromYesterday.messages).toHaveLength(3);
329
- const firstMessageTime = new Date((fromYesterday.messages[0] as MastraMessageV1).createdAt).getTime();
330
- expect(firstMessageTime).toBeGreaterThanOrEqual(new Date(yesterday.toISOString()).getTime());
331
- if (fromYesterday.messages.length > 0) {
332
- expect(new Date((fromYesterday.messages[0] as MastraMessageV1).createdAt).toISOString().slice(0, 10)).toEqual(
333
- yesterday.toISOString().slice(0, 10),
334
- );
335
- }
336
- });
337
- });
338
-
339
- describe('getThreadsByResourceId with pagination', () => {
340
- it('should return paginated threads with total count', async () => {
341
- const resourceId = `libsql-paginated-resource-${randomUUID()}`;
342
- const threadRecords: StorageThreadType[] = [];
343
- for (let i = 0; i < 17; i++) {
344
- const threadData = createSampleThread();
345
- threadData.resourceId = resourceId;
346
- threadRecords.push(threadData as StorageThreadType);
347
- }
348
- for (const tr of threadRecords) {
349
- await store.saveThread({ thread: tr });
350
- }
351
-
352
- const page1 = await store.getThreadsByResourceIdPaginated({ resourceId, page: 0, perPage: 7 });
353
- expect(page1.threads).toHaveLength(7);
354
- expect(page1.total).toBe(17);
355
- expect(page1.page).toBe(0);
356
- expect(page1.perPage).toBe(7);
357
- expect(page1.hasMore).toBe(true);
358
-
359
- const page3 = await store.getThreadsByResourceIdPaginated({ resourceId, page: 2, perPage: 7 });
360
- expect(page3.threads).toHaveLength(3);
361
- expect(page3.total).toBe(17);
362
- expect(page3.hasMore).toBe(false);
363
- });
364
- });
365
- });
366
-
367
- describe('LibSQLStore updateMessages', () => {
368
- let store: LibSQLStore;
369
- let thread: StorageThreadType;
370
-
371
- beforeAll(async () => {
372
- store = libsql;
373
- });
374
-
375
- beforeEach(async () => {
376
- await store.clearTable({ tableName: TABLE_MESSAGES });
377
- await store.clearTable({ tableName: TABLE_THREADS });
378
- const threadData = createSampleThread();
379
- thread = await store.saveThread({ thread: threadData as StorageThreadType });
380
- });
381
-
382
- it('should update a single field of a message (e.g., role)', async () => {
383
- const originalMessage = createSampleMessageV2({ threadId: thread.id, role: 'user' });
384
- await store.saveMessages({ messages: [originalMessage], format: 'v2' });
385
-
386
- const updatedMessages = await store.updateMessages({
387
- messages: [{ id: originalMessage.id, role: 'assistant' }],
388
- });
389
-
390
- expect(updatedMessages).toHaveLength(1);
391
- expect(updatedMessages[0].role).toBe('assistant');
392
-
393
- const fromDb = await store.getMessages({ threadId: thread.id, format: 'v2' });
394
- expect(fromDb[0].role).toBe('assistant');
395
- });
396
-
397
- it('should update only the metadata within the content field, preserving other content fields', async () => {
398
- const originalMessage = createSampleMessageV2({
399
- threadId: thread.id,
400
- content: { content: 'hello world', parts: [{ type: 'text', text: 'hello world' }] },
401
- });
402
- await store.saveMessages({ messages: [originalMessage], format: 'v2' });
403
-
404
- const newMetadata = { someKey: 'someValue' };
405
- await store.updateMessages({
406
- messages: [{ id: originalMessage.id, content: { metadata: newMetadata } as any }],
407
- });
408
-
409
- const fromDb = await store.getMessages({ threadId: thread.id, format: 'v2' });
410
- expect(fromDb).toHaveLength(1);
411
- expect(fromDb[0].content.metadata).toEqual(newMetadata);
412
- expect(fromDb[0].content.content).toBe('hello world');
413
- expect(fromDb[0].content.parts).toEqual([{ type: 'text', text: 'hello world' }]);
414
- });
415
-
416
- it('should update only the content string within the content field, preserving metadata', async () => {
417
- const originalMessage = createSampleMessageV2({
418
- threadId: thread.id,
419
- content: { metadata: { initial: true } },
420
- });
421
- await store.saveMessages({ messages: [originalMessage], format: 'v2' });
422
-
423
- const newContentString = 'This is the new content string';
424
- await store.updateMessages({
425
- messages: [{ id: originalMessage.id, content: { content: newContentString } as any }],
426
- });
427
-
428
- const fromDb = await store.getMessages({ threadId: thread.id, format: 'v2' });
429
- expect(fromDb[0].content.content).toBe(newContentString);
430
- expect(fromDb[0].content.metadata).toEqual({ initial: true });
431
- });
432
-
433
- it('should deep merge metadata, not overwrite it', async () => {
434
- const originalMessage = createSampleMessageV2({
435
- threadId: thread.id,
436
- content: { metadata: { initial: true }, content: 'old content' },
437
- });
438
- await store.saveMessages({ messages: [originalMessage], format: 'v2' });
439
-
440
- const newMetadata = { updated: true };
441
- await store.updateMessages({
442
- messages: [{ id: originalMessage.id, content: { metadata: newMetadata } as any }],
443
- });
444
-
445
- const fromDb = await store.getMessages({ threadId: thread.id, format: 'v2' });
446
- expect(fromDb[0].content.content).toBe('old content');
447
- expect(fromDb[0].content.metadata).toEqual({ initial: true, updated: true });
448
- });
449
-
450
- it('should update multiple messages at once', async () => {
451
- const msg1 = createSampleMessageV2({ threadId: thread.id, role: 'user' });
452
- const msg2 = createSampleMessageV2({ threadId: thread.id, content: { content: 'original' } });
453
- await store.saveMessages({ messages: [msg1, msg2], format: 'v2' });
454
-
455
- await store.updateMessages({
456
- messages: [
457
- { id: msg1.id, role: 'assistant' },
458
- { id: msg2.id, content: { content: 'updated' } as any },
459
- ],
460
- });
461
-
462
- const fromDb = await store.getMessages({ threadId: thread.id, format: 'v2' });
463
- const updatedMsg1 = fromDb.find(m => m.id === msg1.id)!;
464
- const updatedMsg2 = fromDb.find(m => m.id === msg2.id)!;
465
-
466
- expect(updatedMsg1.role).toBe('assistant');
467
- expect(updatedMsg2.content.content).toBe('updated');
468
- });
469
-
470
- it('should update the parent thread updatedAt timestamp', async () => {
471
- const originalMessage = createSampleMessageV2({ threadId: thread.id });
472
- await store.saveMessages({ messages: [originalMessage], format: 'v2' });
473
- const initialThread = await store.getThreadById({ threadId: thread.id });
474
-
475
- await new Promise(r => setTimeout(r, 10));
476
-
477
- await store.updateMessages({ messages: [{ id: originalMessage.id, role: 'assistant' }] });
478
-
479
- const updatedThread = await store.getThreadById({ threadId: thread.id });
480
-
481
- expect(new Date(updatedThread!.updatedAt).getTime()).toBeGreaterThan(new Date(initialThread!.updatedAt).getTime());
482
- });
483
-
484
- it('should update timestamps on both threads when moving a message', async () => {
485
- const thread2 = await store.saveThread({ thread: createSampleThread() });
486
- const message = createSampleMessageV2({ threadId: thread.id });
487
- await store.saveMessages({ messages: [message], format: 'v2' });
488
-
489
- const initialThread1 = await store.getThreadById({ threadId: thread.id });
490
- const initialThread2 = await store.getThreadById({ threadId: thread2.id });
491
-
492
- await new Promise(r => setTimeout(r, 10));
493
-
494
- await store.updateMessages({
495
- messages: [{ id: message.id, threadId: thread2.id }],
496
- });
497
-
498
- const updatedThread1 = await store.getThreadById({ threadId: thread.id });
499
- const updatedThread2 = await store.getThreadById({ threadId: thread2.id });
500
-
501
- expect(new Date(updatedThread1!.updatedAt).getTime()).toBeGreaterThan(
502
- new Date(initialThread1!.updatedAt).getTime(),
503
- );
504
- expect(new Date(updatedThread2!.updatedAt).getTime()).toBeGreaterThan(
505
- new Date(initialThread2!.updatedAt).getTime(),
506
- );
507
-
508
- // Verify the message was moved
509
- const thread1Messages = await store.getMessages({ threadId: thread.id, format: 'v2' });
510
- const thread2Messages = await store.getMessages({ threadId: thread2.id, format: 'v2' });
511
- expect(thread1Messages).toHaveLength(0);
512
- expect(thread2Messages).toHaveLength(1);
513
- expect(thread2Messages[0].id).toBe(message.id);
514
- });
515
-
516
- it('should not fail when trying to update a non-existent message', async () => {
517
- const originalMessage = createSampleMessageV2({ threadId: thread.id });
518
- await store.saveMessages({ messages: [originalMessage], format: 'v2' });
519
-
520
- await expect(
521
- store.updateMessages({
522
- messages: [{ id: randomUUID(), role: 'assistant' }],
523
- }),
524
- ).resolves.not.toThrow();
525
-
526
- const fromDb = await store.getMessages({ threadId: thread.id, format: 'v2' });
527
- expect(fromDb[0].role).toBe(originalMessage.role);
528
- });
529
- });