@yamo/memory-mesh 3.2.4 → 3.2.5
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/lib/memory/adapters/client.d.ts +5 -0
- package/lib/memory/adapters/client.js +28 -3
- package/lib/memory/adapters/client.ts +29 -3
- package/lib/memory/memory-mesh.d.ts +5 -0
- package/lib/memory/memory-mesh.js +7 -0
- package/lib/memory/memory-mesh.ts +7 -0
- package/lib/memory/schema.d.ts +7 -0
- package/lib/memory/schema.js +32 -0
- package/lib/memory/schema.ts +30 -0
- package/package.json +1 -1
|
@@ -85,6 +85,11 @@ export declare class LanceDBClient {
|
|
|
85
85
|
* @throws {QueryError} If stats query fails
|
|
86
86
|
*/
|
|
87
87
|
getStats(): Promise<any>;
|
|
88
|
+
/**
|
|
89
|
+
* Compact old data files and prune versions older than 7 days.
|
|
90
|
+
* Best-effort — never throws.
|
|
91
|
+
*/
|
|
92
|
+
optimize(): Promise<void>;
|
|
88
93
|
/**
|
|
89
94
|
* Sanitize an ID to prevent SQL injection
|
|
90
95
|
* Removes any characters that aren't alphanumeric, underscore, or hyphen
|
|
@@ -201,7 +201,7 @@ export class LanceDBClient {
|
|
|
201
201
|
await this.connect();
|
|
202
202
|
}
|
|
203
203
|
this._validateVector(vector);
|
|
204
|
-
const { limit = 10, nprobes = 20, filter = null } = options;
|
|
204
|
+
const { limit = 10, nprobes = 20, filter = null, refineFactor, timeoutMs } = options;
|
|
205
205
|
return this._retryOperation(async () => {
|
|
206
206
|
if (!this.table) {
|
|
207
207
|
throw new StorageError("Table not initialized");
|
|
@@ -217,12 +217,21 @@ export class LanceDBClient {
|
|
|
217
217
|
// ignore
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
+
// Apply refineFactor for improved ANN recall (fetches N×candidates, reranks)
|
|
221
|
+
if (refineFactor && typeof refineFactor === "number") {
|
|
222
|
+
try {
|
|
223
|
+
query = query.refineFactor(refineFactor);
|
|
224
|
+
}
|
|
225
|
+
catch (_e) {
|
|
226
|
+
// ignore if not supported
|
|
227
|
+
}
|
|
228
|
+
}
|
|
220
229
|
// Apply filter if provided
|
|
221
230
|
if (filter) {
|
|
222
231
|
query = query.where(filter);
|
|
223
232
|
}
|
|
224
|
-
// Execute search with limit
|
|
225
|
-
const resultsArray = await query.limit(limit).toArray();
|
|
233
|
+
// Execute search with limit (and optional timeout)
|
|
234
|
+
const resultsArray = await query.limit(limit).toArray(timeoutMs ? { timeoutMs } : undefined);
|
|
226
235
|
return resultsArray.map((row) => ({
|
|
227
236
|
id: row.id,
|
|
228
237
|
content: row.content,
|
|
@@ -385,6 +394,22 @@ export class LanceDBClient {
|
|
|
385
394
|
};
|
|
386
395
|
});
|
|
387
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* Compact old data files and prune versions older than 7 days.
|
|
399
|
+
* Best-effort — never throws.
|
|
400
|
+
*/
|
|
401
|
+
async optimize() {
|
|
402
|
+
if (!this.isConnected || !this.table)
|
|
403
|
+
return;
|
|
404
|
+
try {
|
|
405
|
+
await this.table.optimize({
|
|
406
|
+
cleanupOlderThan: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
catch (_e) {
|
|
410
|
+
// Best-effort — never block normal operations
|
|
411
|
+
}
|
|
412
|
+
}
|
|
388
413
|
/**
|
|
389
414
|
* Sanitize an ID to prevent SQL injection
|
|
390
415
|
* Removes any characters that aren't alphanumeric, underscore, or hyphen
|
|
@@ -201,7 +201,7 @@ export class LanceDBClient {
|
|
|
201
201
|
await this.connect();
|
|
202
202
|
}
|
|
203
203
|
this._validateVector(vector);
|
|
204
|
-
const { limit = 10, nprobes = 20, filter = null } = options;
|
|
204
|
+
const { limit = 10, nprobes = 20, filter = null, refineFactor, timeoutMs } = options;
|
|
205
205
|
return this._retryOperation(async () => {
|
|
206
206
|
if (!this.table) {
|
|
207
207
|
throw new StorageError("Table not initialized");
|
|
@@ -217,12 +217,23 @@ export class LanceDBClient {
|
|
|
217
217
|
// ignore
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
+
// Apply refineFactor for improved ANN recall (fetches N×candidates, reranks)
|
|
221
|
+
if (refineFactor && typeof refineFactor === "number") {
|
|
222
|
+
try {
|
|
223
|
+
query = query.refineFactor(refineFactor);
|
|
224
|
+
}
|
|
225
|
+
catch (_e) {
|
|
226
|
+
// ignore if not supported
|
|
227
|
+
}
|
|
228
|
+
}
|
|
220
229
|
// Apply filter if provided
|
|
221
230
|
if (filter) {
|
|
222
231
|
query = query.where(filter);
|
|
223
232
|
}
|
|
224
|
-
// Execute search with limit
|
|
225
|
-
const resultsArray = await query.limit(limit).toArray(
|
|
233
|
+
// Execute search with limit (and optional timeout)
|
|
234
|
+
const resultsArray = await query.limit(limit).toArray(
|
|
235
|
+
timeoutMs ? { timeoutMs } : undefined,
|
|
236
|
+
);
|
|
226
237
|
return resultsArray.map((row) => ({
|
|
227
238
|
id: row.id,
|
|
228
239
|
content: row.content,
|
|
@@ -385,6 +396,21 @@ export class LanceDBClient {
|
|
|
385
396
|
};
|
|
386
397
|
});
|
|
387
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Compact old data files and prune versions older than 7 days.
|
|
401
|
+
* Best-effort — never throws.
|
|
402
|
+
*/
|
|
403
|
+
async optimize() {
|
|
404
|
+
if (!this.isConnected || !this.table) return;
|
|
405
|
+
try {
|
|
406
|
+
await this.table.optimize({
|
|
407
|
+
cleanupOlderThan: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
catch (_e) {
|
|
411
|
+
// Best-effort — never block normal operations
|
|
412
|
+
}
|
|
413
|
+
}
|
|
388
414
|
/**
|
|
389
415
|
* Sanitize an ID to prevent SQL injection
|
|
390
416
|
* Removes any characters that aren't alphanumeric, underscore, or hyphen
|
|
@@ -444,6 +444,11 @@ export declare class MemoryMesh {
|
|
|
444
444
|
* await mesh.close(); // Clean up
|
|
445
445
|
* ```
|
|
446
446
|
*/
|
|
447
|
+
/**
|
|
448
|
+
* Compact old data files and prune versions older than 7 days.
|
|
449
|
+
* Best-effort — delegates to LanceDBClient.optimize().
|
|
450
|
+
*/
|
|
451
|
+
optimize(): Promise<any>;
|
|
447
452
|
close(): Promise<void>;
|
|
448
453
|
}
|
|
449
454
|
/**
|
|
@@ -1714,6 +1714,13 @@ description: Auto-generated skill to handle: ${enrichedPrompt || topic}
|
|
|
1714
1714
|
* await mesh.close(); // Clean up
|
|
1715
1715
|
* ```
|
|
1716
1716
|
*/
|
|
1717
|
+
/**
|
|
1718
|
+
* Compact old data files and prune versions older than 7 days.
|
|
1719
|
+
* Best-effort — delegates to LanceDBClient.optimize().
|
|
1720
|
+
*/
|
|
1721
|
+
async optimize() {
|
|
1722
|
+
return this.client?.optimize?.();
|
|
1723
|
+
}
|
|
1717
1724
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
1718
1725
|
async close() {
|
|
1719
1726
|
try {
|
|
@@ -1801,6 +1801,13 @@ description: Auto-generated skill to handle: ${enrichedPrompt || topic}
|
|
|
1801
1801
|
* await mesh.close(); // Clean up
|
|
1802
1802
|
* ```
|
|
1803
1803
|
*/
|
|
1804
|
+
/**
|
|
1805
|
+
* Compact old data files and prune versions older than 7 days.
|
|
1806
|
+
* Best-effort — delegates to LanceDBClient.optimize().
|
|
1807
|
+
*/
|
|
1808
|
+
async optimize() {
|
|
1809
|
+
return this.client?.optimize?.();
|
|
1810
|
+
}
|
|
1804
1811
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
1805
1812
|
async close() {
|
|
1806
1813
|
try {
|
package/lib/memory/schema.d.ts
CHANGED
|
@@ -65,6 +65,12 @@ export declare function isSchemaV2(schema: any): any;
|
|
|
65
65
|
* Safe to call on any table — non-memory tables skip the schema column additions.
|
|
66
66
|
*/
|
|
67
67
|
export declare function migrateTableV2(table: any): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Ensure the vector column has an IVF_PQ index.
|
|
70
|
+
* Skipped when: table has too few rows, index already exists, or table is a mock.
|
|
71
|
+
* Called automatically by createMemoryTableWithDimension after migration.
|
|
72
|
+
*/
|
|
73
|
+
export declare function ensureVectorIndex(table: any): Promise<void>;
|
|
68
74
|
/**
|
|
69
75
|
* Memory table schema using Apache Arrow format (default 384 dimensions)
|
|
70
76
|
* @deprecated Use createMemorySchema(vectorDim) for dynamic dimensions
|
|
@@ -122,6 +128,7 @@ declare const _default: {
|
|
|
122
128
|
createMemorySchemaV2: typeof createMemorySchemaV2;
|
|
123
129
|
isSchemaV2: typeof isSchemaV2;
|
|
124
130
|
migrateTableV2: typeof migrateTableV2;
|
|
131
|
+
ensureVectorIndex: typeof ensureVectorIndex;
|
|
125
132
|
getEmbeddingDimension: typeof getEmbeddingDimension;
|
|
126
133
|
DEFAULT_VECTOR_DIMENSION: number;
|
|
127
134
|
EMBEDDING_DIMENSIONS: {
|
package/lib/memory/schema.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - text-embedding-3-small: 1536 dimensions
|
|
10
10
|
*/
|
|
11
11
|
import * as arrow from "apache-arrow";
|
|
12
|
+
import { Index } from "@lancedb/lancedb";
|
|
12
13
|
/**
|
|
13
14
|
* Default vector dimension (all-MiniLM-L6-v2)
|
|
14
15
|
*/
|
|
@@ -153,6 +154,34 @@ export async function migrateTableV2(table) {
|
|
|
153
154
|
{ name: "last_accessed", valueSql: "cast(null as timestamp)" },
|
|
154
155
|
]);
|
|
155
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Ensure the vector column has an IVF_PQ index.
|
|
159
|
+
* Skipped when: table has too few rows, index already exists, or table is a mock.
|
|
160
|
+
* Called automatically by createMemoryTableWithDimension after migration.
|
|
161
|
+
*/
|
|
162
|
+
export async function ensureVectorIndex(table) {
|
|
163
|
+
if (typeof table.listIndices !== "function")
|
|
164
|
+
return;
|
|
165
|
+
try {
|
|
166
|
+
const indices = await table.listIndices();
|
|
167
|
+
if (indices.some((i) => i.columns.includes("vector")))
|
|
168
|
+
return;
|
|
169
|
+
const rowCount = await table.countRows();
|
|
170
|
+
if (rowCount < INDEX_CONFIG.vector.num_partitions)
|
|
171
|
+
return;
|
|
172
|
+
await table.createIndex("vector", {
|
|
173
|
+
config: Index.ivfPq({
|
|
174
|
+
numPartitions: INDEX_CONFIG.vector.num_partitions,
|
|
175
|
+
numSubVectors: INDEX_CONFIG.vector.num_sub_vectors,
|
|
176
|
+
distanceType: INDEX_CONFIG.vector.metric,
|
|
177
|
+
}),
|
|
178
|
+
replace: false,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// Index creation is best-effort — never block table access
|
|
183
|
+
}
|
|
184
|
+
}
|
|
156
185
|
/**
|
|
157
186
|
* Memory table schema using Apache Arrow format (default 384 dimensions)
|
|
158
187
|
* @deprecated Use createMemorySchema(vectorDim) for dynamic dimensions
|
|
@@ -209,6 +238,8 @@ export async function createMemoryTableWithDimension(db, tableName, vectorDim) {
|
|
|
209
238
|
}
|
|
210
239
|
// Migrate existing tables to V2 (manifest paths + schema columns, idempotent)
|
|
211
240
|
await migrateTableV2(table);
|
|
241
|
+
// Ensure vector index exists (no-op if already present or insufficient rows)
|
|
242
|
+
await ensureVectorIndex(table);
|
|
212
243
|
return table;
|
|
213
244
|
}
|
|
214
245
|
catch (error) {
|
|
@@ -225,6 +256,7 @@ export default {
|
|
|
225
256
|
createMemorySchemaV2,
|
|
226
257
|
isSchemaV2,
|
|
227
258
|
migrateTableV2,
|
|
259
|
+
ensureVectorIndex,
|
|
228
260
|
getEmbeddingDimension,
|
|
229
261
|
DEFAULT_VECTOR_DIMENSION,
|
|
230
262
|
EMBEDDING_DIMENSIONS,
|
package/lib/memory/schema.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - text-embedding-3-small: 1536 dimensions
|
|
10
10
|
*/
|
|
11
11
|
import * as arrow from "apache-arrow";
|
|
12
|
+
import * as lancedb from "@lancedb/lancedb";
|
|
13
|
+
import { Index } from "@lancedb/lancedb";
|
|
12
14
|
/**
|
|
13
15
|
* Default vector dimension (all-MiniLM-L6-v2)
|
|
14
16
|
*/
|
|
@@ -150,6 +152,31 @@ export async function migrateTableV2(table) {
|
|
|
150
152
|
{ name: "last_accessed", valueSql: "cast(null as timestamp)" },
|
|
151
153
|
]);
|
|
152
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Ensure the vector column has an IVF_PQ index.
|
|
157
|
+
* Skipped when: table has too few rows, index already exists, or table is a mock.
|
|
158
|
+
* Called automatically by createMemoryTableWithDimension after migration.
|
|
159
|
+
*/
|
|
160
|
+
export async function ensureVectorIndex(table) {
|
|
161
|
+
if (typeof table.listIndices !== "function") return;
|
|
162
|
+
try {
|
|
163
|
+
const indices = await table.listIndices();
|
|
164
|
+
if (indices.some((i) => i.columns.includes("vector"))) return;
|
|
165
|
+
const rowCount = await table.countRows();
|
|
166
|
+
if (rowCount < INDEX_CONFIG.vector.num_partitions) return;
|
|
167
|
+
await table.createIndex("vector", {
|
|
168
|
+
config: Index.ivfPq({
|
|
169
|
+
numPartitions: INDEX_CONFIG.vector.num_partitions,
|
|
170
|
+
numSubVectors: INDEX_CONFIG.vector.num_sub_vectors,
|
|
171
|
+
distanceType: INDEX_CONFIG.vector.metric,
|
|
172
|
+
}),
|
|
173
|
+
replace: false,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Index creation is best-effort — never block table access
|
|
178
|
+
}
|
|
179
|
+
}
|
|
153
180
|
/**
|
|
154
181
|
* Memory table schema using Apache Arrow format (default 384 dimensions)
|
|
155
182
|
* @deprecated Use createMemorySchema(vectorDim) for dynamic dimensions
|
|
@@ -206,6 +233,8 @@ export async function createMemoryTableWithDimension(db, tableName, vectorDim) {
|
|
|
206
233
|
}
|
|
207
234
|
// Migrate existing tables to V2 (manifest paths + schema columns, idempotent)
|
|
208
235
|
await migrateTableV2(table);
|
|
236
|
+
// Ensure vector index exists (no-op if already present or insufficient rows)
|
|
237
|
+
await ensureVectorIndex(table);
|
|
209
238
|
return table;
|
|
210
239
|
}
|
|
211
240
|
catch (error) {
|
|
@@ -222,6 +251,7 @@ export default {
|
|
|
222
251
|
createMemorySchemaV2,
|
|
223
252
|
isSchemaV2,
|
|
224
253
|
migrateTableV2,
|
|
254
|
+
ensureVectorIndex,
|
|
225
255
|
getEmbeddingDimension,
|
|
226
256
|
DEFAULT_VECTOR_DIMENSION,
|
|
227
257
|
EMBEDDING_DIMENSIONS,
|