@mastra/longmemeval 0.0.0-add-libsql-changeset-20250910154739
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/CHANGELOG.md +919 -0
- package/DATA_DOWNLOAD_GUIDE.md +117 -0
- package/LICENSE.md +15 -0
- package/README.md +173 -0
- package/USAGE.md +105 -0
- package/package.json +67 -0
- package/scripts/download.ts +180 -0
- package/scripts/find-failed.ts +176 -0
- package/scripts/generate-embeddings.ts +56 -0
- package/scripts/generate-wm-templates.ts +296 -0
- package/scripts/setup.ts +60 -0
- package/src/__fixtures__/embeddings.json +2319 -0
- package/src/__fixtures__/test-dataset.json +82 -0
- package/src/cli.ts +690 -0
- package/src/commands/__tests__/prepare.test.ts +230 -0
- package/src/commands/__tests__/run.test.ts +403 -0
- package/src/commands/prepare.ts +793 -0
- package/src/commands/run.ts +553 -0
- package/src/config.ts +83 -0
- package/src/data/loader.ts +163 -0
- package/src/data/types.ts +61 -0
- package/src/embeddings/cached-openai-embedding-model.ts +227 -0
- package/src/embeddings/cached-openai-provider.ts +40 -0
- package/src/embeddings/index.ts +2 -0
- package/src/evaluation/__tests__/longmemeval-metric.test.ts +169 -0
- package/src/evaluation/longmemeval-metric.ts +173 -0
- package/src/retry-model.ts +60 -0
- package/src/storage/__tests__/benchmark-store.test.ts +280 -0
- package/src/storage/__tests__/benchmark-vector.test.ts +214 -0
- package/src/storage/benchmark-store.ts +540 -0
- package/src/storage/benchmark-vector.ts +234 -0
- package/src/storage/index.ts +2 -0
- package/src/test-utils/mock-embeddings.ts +54 -0
- package/src/test-utils/mock-model.ts +49 -0
- package/tests/data-loader.test.ts +96 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { BenchmarkVectorStore } from '../benchmark-vector';
|
|
3
|
+
import { rm } from 'fs/promises';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { tmpdir } from 'os';
|
|
7
|
+
|
|
8
|
+
describe('BenchmarkVectorStore', () => {
|
|
9
|
+
let vectorStore: BenchmarkVectorStore;
|
|
10
|
+
let testFilePath: string;
|
|
11
|
+
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
vectorStore = new BenchmarkVectorStore();
|
|
14
|
+
testFilePath = join(tmpdir(), `benchmark-vector-test-${Date.now()}.json`);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
// Clean up
|
|
19
|
+
await vectorStore.clear();
|
|
20
|
+
if (existsSync(testFilePath)) {
|
|
21
|
+
await rm(testFilePath);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('createIndex', () => {
|
|
26
|
+
it('should create a new index', async () => {
|
|
27
|
+
await vectorStore.createIndex({
|
|
28
|
+
indexName: 'test-index',
|
|
29
|
+
dimension: 1536,
|
|
30
|
+
metric: 'cosine',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const indexes = await vectorStore.listIndexes();
|
|
34
|
+
expect(indexes).toContain('test-index');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should validate dimension on existing index', async () => {
|
|
38
|
+
await vectorStore.createIndex({
|
|
39
|
+
indexName: 'test-index',
|
|
40
|
+
dimension: 1536,
|
|
41
|
+
metric: 'cosine',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Try to create again with different dimension
|
|
45
|
+
await expect(
|
|
46
|
+
vectorStore.createIndex({
|
|
47
|
+
indexName: 'test-index',
|
|
48
|
+
dimension: 384,
|
|
49
|
+
metric: 'cosine',
|
|
50
|
+
}),
|
|
51
|
+
).rejects.toThrow();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('upsert and query', () => {
|
|
56
|
+
beforeEach(async () => {
|
|
57
|
+
await vectorStore.createIndex({
|
|
58
|
+
indexName: 'test-index',
|
|
59
|
+
dimension: 3,
|
|
60
|
+
metric: 'cosine',
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should upsert vectors and query them', async () => {
|
|
65
|
+
const vectors = [
|
|
66
|
+
[1, 0, 0],
|
|
67
|
+
[0, 1, 0],
|
|
68
|
+
[0, 0, 1],
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
const metadata = [{ text: 'First vector' }, { text: 'Second vector' }, { text: 'Third vector' }];
|
|
72
|
+
|
|
73
|
+
const ids = await vectorStore.upsert({
|
|
74
|
+
indexName: 'test-index',
|
|
75
|
+
vectors,
|
|
76
|
+
metadata,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(ids).toHaveLength(3);
|
|
80
|
+
|
|
81
|
+
// Query - note: imvectordb's query behavior might be different
|
|
82
|
+
// This test might need adjustment based on actual behavior
|
|
83
|
+
const results = await vectorStore.query({
|
|
84
|
+
indexName: 'test-index',
|
|
85
|
+
queryVector: [1, 0, 0],
|
|
86
|
+
topK: 2,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
expect(results).toBeDefined();
|
|
90
|
+
expect(results.length).toBeLessThanOrEqual(2);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('persist and hydrate', () => {
|
|
95
|
+
it('should persist and restore vector store state', async () => {
|
|
96
|
+
// Create index and add vectors
|
|
97
|
+
await vectorStore.createIndex({
|
|
98
|
+
indexName: 'test-index',
|
|
99
|
+
dimension: 3,
|
|
100
|
+
metric: 'cosine',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const ids = await vectorStore.upsert({
|
|
104
|
+
indexName: 'test-index',
|
|
105
|
+
vectors: [
|
|
106
|
+
[1, 0, 0],
|
|
107
|
+
[0, 1, 0],
|
|
108
|
+
],
|
|
109
|
+
metadata: [{ text: 'Vector 1' }, { text: 'Vector 2' }],
|
|
110
|
+
ids: ['vec-1', 'vec-2'],
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Persist
|
|
114
|
+
await vectorStore.persist(testFilePath);
|
|
115
|
+
|
|
116
|
+
// Create new store and hydrate
|
|
117
|
+
const newStore = new BenchmarkVectorStore();
|
|
118
|
+
await newStore.hydrate(testFilePath);
|
|
119
|
+
|
|
120
|
+
// Verify index exists
|
|
121
|
+
const indexes = await newStore.listIndexes();
|
|
122
|
+
expect(indexes).toContain('test-index');
|
|
123
|
+
|
|
124
|
+
// Verify index stats
|
|
125
|
+
const stats = await newStore.describeIndex({ indexName: 'test-index' });
|
|
126
|
+
expect(stats.dimension).toBe(3);
|
|
127
|
+
expect(stats.count).toBe(2);
|
|
128
|
+
expect(stats.metric).toBe('cosine');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should throw error if file does not exist', async () => {
|
|
132
|
+
await expect(vectorStore.hydrate('/non/existent/file.json')).rejects.toThrow('Vector store file not found');
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('updateVector', () => {
|
|
137
|
+
beforeEach(async () => {
|
|
138
|
+
await vectorStore.createIndex({
|
|
139
|
+
indexName: 'test-index',
|
|
140
|
+
dimension: 3,
|
|
141
|
+
metric: 'cosine',
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should update an existing vector', async () => {
|
|
146
|
+
await vectorStore.upsert({
|
|
147
|
+
indexName: 'test-index',
|
|
148
|
+
vectors: [[1, 0, 0]],
|
|
149
|
+
metadata: [{ text: 'Original' }],
|
|
150
|
+
ids: ['vec-1'],
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
await vectorStore.updateVector({
|
|
154
|
+
indexName: 'test-index',
|
|
155
|
+
id: 'vec-1',
|
|
156
|
+
update: {
|
|
157
|
+
vector: [0, 1, 0],
|
|
158
|
+
metadata: { text: 'Updated' },
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Verify update by checking the store after persist/hydrate
|
|
163
|
+
await vectorStore.persist(testFilePath);
|
|
164
|
+
const newStore = new BenchmarkVectorStore();
|
|
165
|
+
await newStore.hydrate(testFilePath);
|
|
166
|
+
|
|
167
|
+
const stats = await newStore.describeIndex({ indexName: 'test-index' });
|
|
168
|
+
expect(stats.count).toBe(1);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe('deleteVector', () => {
|
|
173
|
+
beforeEach(async () => {
|
|
174
|
+
await vectorStore.createIndex({
|
|
175
|
+
indexName: 'test-index',
|
|
176
|
+
dimension: 3,
|
|
177
|
+
metric: 'cosine',
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should delete a vector', async () => {
|
|
182
|
+
await vectorStore.upsert({
|
|
183
|
+
indexName: 'test-index',
|
|
184
|
+
vectors: [
|
|
185
|
+
[1, 0, 0],
|
|
186
|
+
[0, 1, 0],
|
|
187
|
+
],
|
|
188
|
+
ids: ['vec-1', 'vec-2'],
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
await vectorStore.deleteVector({
|
|
192
|
+
indexName: 'test-index',
|
|
193
|
+
id: 'vec-1',
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const stats = await vectorStore.describeIndex({ indexName: 'test-index' });
|
|
197
|
+
expect(stats.count).toBe(1);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe('deleteIndex', () => {
|
|
202
|
+
it('should delete an index', async () => {
|
|
203
|
+
await vectorStore.createIndex({
|
|
204
|
+
indexName: 'test-index',
|
|
205
|
+
dimension: 3,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await vectorStore.deleteIndex({ indexName: 'test-index' });
|
|
209
|
+
|
|
210
|
+
const indexes = await vectorStore.listIndexes();
|
|
211
|
+
expect(indexes).not.toContain('test-index');
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|