embedded-raptor 1.1.0 → 2.0.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.
- package/README.md +11 -11
- package/dist/cli.cjs +26 -4
- package/dist/cli.mjs +25 -3
- package/dist/commands/delete.d.ts +41 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/{engine-ez6nFONK.mjs → engine-BvJ0ls3b.mjs} +62 -30
- package/dist/engine-Cuz0P5Od.mjs +1164 -0
- package/dist/engine-DLM7PWhV.cjs +1203 -0
- package/dist/{engine-CTvg_66e.cjs → engine-Iq0_dbnk.cjs} +63 -31
- package/dist/engine.d.ts +55 -17
- package/dist/engine.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/storage-engine/constants.d.ts +53 -0
- package/dist/storage-engine/constants.d.ts.map +1 -0
- package/dist/storage-engine/data-format.d.ts +35 -0
- package/dist/storage-engine/data-format.d.ts.map +1 -0
- package/dist/storage-engine/file-lock.d.ts +35 -0
- package/dist/storage-engine/file-lock.d.ts.map +1 -0
- package/dist/storage-engine/index.d.ts +14 -0
- package/dist/storage-engine/index.d.ts.map +1 -0
- package/dist/storage-engine/key-index.d.ts +54 -0
- package/dist/storage-engine/key-index.d.ts.map +1 -0
- package/dist/storage-engine/migration.d.ts +26 -0
- package/dist/storage-engine/migration.d.ts.map +1 -0
- package/dist/storage-engine/mutex.d.ts +23 -0
- package/dist/storage-engine/mutex.d.ts.map +1 -0
- package/dist/storage-engine/storage-engine.d.ts +85 -0
- package/dist/storage-engine/storage-engine.d.ts.map +1 -0
- package/dist/storage-engine/types.d.ts +85 -0
- package/dist/storage-engine/types.d.ts.map +1 -0
- package/dist/storage-engine/wal-format.d.ts +22 -0
- package/dist/storage-engine/wal-format.d.ts.map +1 -0
- package/dist/storage-engine/wal.d.ts +32 -0
- package/dist/storage-engine/wal.d.ts.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/dist/engine-Bl1yeWoe.cjs +0 -374
- package/dist/engine-D06Gh_gw.mjs +0 -335
- package/dist/engine-DISO9uFr.mjs +0 -31601
- package/dist/engine-KhnrAv7v.cjs +0 -38642
- package/dist/engine-r-qHfsLd.cjs +0 -370
package/README.md
CHANGED
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
> A lightweight semantic search database with text embeddings for Node.js and
|
|
10
10
|
> Bun
|
|
11
11
|
|
|
12
|
-
Embedded Raptor lets you build semantic search into your applications with just
|
|
13
|
-
lines of code. Store text, search by meaning, and find similar
|
|
14
|
-
for RAG systems, chatbots, and recommendation engines.
|
|
12
|
+
Embedded Raptor lets you build semantic search into your applications with just
|
|
13
|
+
a few lines of code. Store text, search by meaning, and find similar
|
|
14
|
+
content—perfect for RAG systems, chatbots, and recommendation engines.
|
|
15
15
|
|
|
16
16
|
## What is Embedded Raptor?
|
|
17
17
|
|
|
18
|
-
Embedded Raptor is an embedding database that automatically converts text into
|
|
19
|
-
embeddings and stores them in an efficient binary format. Instead of
|
|
20
|
-
by exact keywords, you can search by semantic similarity—finding
|
|
21
|
-
mean the same thing, even if they use different words.
|
|
18
|
+
Embedded Raptor is an embedding database that automatically converts text into
|
|
19
|
+
vector embeddings and stores them in an efficient binary format. Instead of
|
|
20
|
+
searching by exact keywords, you can search by semantic similarity—finding
|
|
21
|
+
documents that mean the same thing, even if they use different words.
|
|
22
22
|
|
|
23
23
|
**Example:** Search for "how to reset password" and find results like "forgot my
|
|
24
24
|
login credentials" or "change account password".
|
|
@@ -203,12 +203,12 @@ raptor store key1 "Some text" --storePath ./data/custom.raptor
|
|
|
203
203
|
|
|
204
204
|
## How It Works
|
|
205
205
|
|
|
206
|
-
1. **Text → Embeddings**: Embedded Raptor uses the BGE-Base-EN model to convert
|
|
207
|
-
768-dimensional vector embeddings
|
|
206
|
+
1. **Text → Embeddings**: Embedded Raptor uses the BGE-Base-EN model to convert
|
|
207
|
+
text into 768-dimensional vector embeddings
|
|
208
208
|
2. **Storage**: Embeddings are stored in an efficient binary format (.raptor
|
|
209
209
|
files)
|
|
210
|
-
3. **Search**: When you search, Embedded Raptor compares your query embedding
|
|
211
|
-
stored embeddings using cosine similarity
|
|
210
|
+
3. **Search**: When you search, Embedded Raptor compares your query embedding
|
|
211
|
+
against all stored embeddings using cosine similarity
|
|
212
212
|
4. **Results**: Returns the most similar results ranked by similarity score
|
|
213
213
|
|
|
214
214
|
**Embedding Model**:
|
package/dist/cli.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_engine = require('./engine-
|
|
3
|
-
let node_fs = require("node:fs");
|
|
4
|
-
node_fs = require_engine.__toESM(node_fs);
|
|
2
|
+
const require_engine = require('./engine-DLM7PWhV.cjs');
|
|
5
3
|
let node_path = require("node:path");
|
|
6
4
|
node_path = require_engine.__toESM(node_path);
|
|
5
|
+
let node_fs = require("node:fs");
|
|
6
|
+
node_fs = require_engine.__toESM(node_fs);
|
|
7
7
|
let cleye = require("cleye");
|
|
8
8
|
cleye = require_engine.__toESM(cleye);
|
|
9
9
|
let node_url = require("node:url");
|
|
@@ -89,6 +89,27 @@ const search = (0, cleye.command)({
|
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/commands/delete.ts
|
|
94
|
+
const deleteCmd = (0, cleye.command)({
|
|
95
|
+
name: "delete",
|
|
96
|
+
description: "Delete an embedding entry by key",
|
|
97
|
+
parameters: ["<key>"],
|
|
98
|
+
flags: { ...sharedFlags }
|
|
99
|
+
}, async (argv) => {
|
|
100
|
+
const engine = new require_engine.EmbeddingEngine({ storePath: argv.flags.storePath });
|
|
101
|
+
try {
|
|
102
|
+
const [key] = argv._;
|
|
103
|
+
if (await engine.delete(key)) console.log(`Deleted key "${key}"`);
|
|
104
|
+
else {
|
|
105
|
+
console.log(`Key "${key}" not found`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
} finally {
|
|
109
|
+
await engine.dispose();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
92
113
|
//#endregion
|
|
93
114
|
//#region src/cli.ts
|
|
94
115
|
const __dirname$1 = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
|
|
@@ -100,7 +121,8 @@ function main() {
|
|
|
100
121
|
commands: [
|
|
101
122
|
store,
|
|
102
123
|
get,
|
|
103
|
-
search
|
|
124
|
+
search,
|
|
125
|
+
deleteCmd
|
|
104
126
|
]
|
|
105
127
|
}, () => {});
|
|
106
128
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as EmbeddingEngine } from "./engine-
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { t as EmbeddingEngine } from "./engine-Cuz0P5Od.mjs";
|
|
4
3
|
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
5
|
import { cli, command } from "cleye";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
@@ -85,6 +85,27 @@ const search = command({
|
|
|
85
85
|
}
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/commands/delete.ts
|
|
90
|
+
const deleteCmd = command({
|
|
91
|
+
name: "delete",
|
|
92
|
+
description: "Delete an embedding entry by key",
|
|
93
|
+
parameters: ["<key>"],
|
|
94
|
+
flags: { ...sharedFlags }
|
|
95
|
+
}, async (argv) => {
|
|
96
|
+
const engine = new EmbeddingEngine({ storePath: argv.flags.storePath });
|
|
97
|
+
try {
|
|
98
|
+
const [key] = argv._;
|
|
99
|
+
if (await engine.delete(key)) console.log(`Deleted key "${key}"`);
|
|
100
|
+
else {
|
|
101
|
+
console.log(`Key "${key}" not found`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
} finally {
|
|
105
|
+
await engine.dispose();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
88
109
|
//#endregion
|
|
89
110
|
//#region src/cli.ts
|
|
90
111
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -96,7 +117,8 @@ function main() {
|
|
|
96
117
|
commands: [
|
|
97
118
|
store,
|
|
98
119
|
get,
|
|
99
|
-
search
|
|
120
|
+
search,
|
|
121
|
+
deleteCmd
|
|
100
122
|
]
|
|
101
123
|
}, () => {});
|
|
102
124
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const deleteCmd: import("cleye").Command<{
|
|
2
|
+
name: "delete";
|
|
3
|
+
description: string;
|
|
4
|
+
parameters: "<key>"[];
|
|
5
|
+
flags: {
|
|
6
|
+
storePath: {
|
|
7
|
+
readonly type: StringConstructor;
|
|
8
|
+
readonly description: "Path to the embeddings store file";
|
|
9
|
+
readonly default: "./database.raptor";
|
|
10
|
+
readonly alias: "s";
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}, {
|
|
14
|
+
command: "delete";
|
|
15
|
+
} & import("type-flag").TypeFlag<{
|
|
16
|
+
storePath: {
|
|
17
|
+
readonly type: StringConstructor;
|
|
18
|
+
readonly description: "Path to the embeddings store file";
|
|
19
|
+
readonly default: "./database.raptor";
|
|
20
|
+
readonly alias: "s";
|
|
21
|
+
};
|
|
22
|
+
} & {
|
|
23
|
+
help: BooleanConstructor;
|
|
24
|
+
}> & {
|
|
25
|
+
_: {
|
|
26
|
+
key: string;
|
|
27
|
+
};
|
|
28
|
+
showHelp: (options?: {
|
|
29
|
+
version?: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
usage?: false | string | string[];
|
|
32
|
+
examples?: string | string[];
|
|
33
|
+
render?: (nodes: {
|
|
34
|
+
id?: string;
|
|
35
|
+
type: keyof import("cleye").Renderers;
|
|
36
|
+
data: any;
|
|
37
|
+
}[], renderers: import("cleye").Renderers) => string;
|
|
38
|
+
}) => void;
|
|
39
|
+
showVersion: () => void;
|
|
40
|
+
}>;
|
|
41
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA6B2kM,CAAC;;;;;;;;;;;;EADjmM,CAAA"}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getLlama, resolveModelFile } from "node-llama-cpp";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { appendFile, mkdir, open, stat, writeFile } from "node:fs/promises";
|
|
4
4
|
import { dirname } from "node:path";
|
|
@@ -221,35 +221,64 @@ var CandidateSetEntry = class {
|
|
|
221
221
|
|
|
222
222
|
//#endregion
|
|
223
223
|
//#region src/engine.ts
|
|
224
|
+
const DEFAULT_MODEL_URI = "hf:CompendiumLabs/bge-small-en-v1.5-gguf/bge-small-en-v1.5-q8_0.gguf";
|
|
225
|
+
const DEFAULT_CACHE_DIR = "./.cache/models";
|
|
224
226
|
var EmbeddingEngine = class {
|
|
225
227
|
fileReader;
|
|
226
228
|
storePath;
|
|
227
|
-
|
|
229
|
+
cacheDir;
|
|
230
|
+
llama;
|
|
231
|
+
model;
|
|
232
|
+
embeddingContext;
|
|
233
|
+
initPromise;
|
|
228
234
|
constructor(options) {
|
|
229
235
|
this.storePath = options.storePath;
|
|
230
236
|
this.fileReader = new BinaryFileReader(options.storePath);
|
|
231
|
-
|
|
237
|
+
this.cacheDir = options.cacheDir ?? DEFAULT_CACHE_DIR;
|
|
232
238
|
}
|
|
233
239
|
/**
|
|
234
240
|
* Gets or initializes the embedding model
|
|
235
241
|
* Caches the model instance to avoid repeated initialization overhead
|
|
236
|
-
* @returns Initialized feature extraction pipeline
|
|
237
242
|
*/
|
|
238
|
-
async
|
|
239
|
-
|
|
240
|
-
return this.
|
|
243
|
+
async ensureModelLoaded() {
|
|
244
|
+
if (this.embeddingContext) return;
|
|
245
|
+
if (this.initPromise) return this.initPromise;
|
|
246
|
+
this.initPromise = this.initializeModel();
|
|
247
|
+
await this.initPromise;
|
|
248
|
+
}
|
|
249
|
+
async initializeModel() {
|
|
250
|
+
this.llama = await getLlama();
|
|
251
|
+
const modelPath = await resolveModelFile(DEFAULT_MODEL_URI, this.cacheDir);
|
|
252
|
+
this.model = await this.llama.loadModel({ modelPath });
|
|
253
|
+
this.embeddingContext = await this.model.createEmbeddingContext();
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Truncates text to fit within the model's context size
|
|
257
|
+
* Uses the model's tokenizer for accurate token counting
|
|
258
|
+
* BGE-small supports 512 tokens, we use 500 to leave room for special tokens
|
|
259
|
+
*/
|
|
260
|
+
truncateToContextSize(text) {
|
|
261
|
+
if (!this.model) {
|
|
262
|
+
const maxChars = 300 * 3;
|
|
263
|
+
return text.length <= maxChars ? text : text.slice(0, maxChars);
|
|
264
|
+
}
|
|
265
|
+
const maxTokens = 500;
|
|
266
|
+
const tokens = this.model.tokenize(text);
|
|
267
|
+
if (tokens.length <= maxTokens) return text;
|
|
268
|
+
const truncatedTokens = tokens.slice(0, maxTokens);
|
|
269
|
+
return this.model.detokenize(truncatedTokens);
|
|
241
270
|
}
|
|
242
271
|
/**
|
|
243
|
-
* Generates embedding from text using
|
|
272
|
+
* Generates embedding from text using node-llama-cpp with bge-small-en-v1.5 model
|
|
244
273
|
* @param text - Text to embed
|
|
245
274
|
* @returns 384-dimensional embedding vector (normalized)
|
|
246
275
|
*/
|
|
247
276
|
async generateEmbedding(text) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return Array.from(
|
|
277
|
+
await this.ensureModelLoaded();
|
|
278
|
+
invariant(this.embeddingContext, "Embedding context not initialized");
|
|
279
|
+
const truncatedText = this.truncateToContextSize(text);
|
|
280
|
+
const embedding = await this.embeddingContext.getEmbeddingFor(truncatedText);
|
|
281
|
+
return Array.from(embedding.vector);
|
|
253
282
|
}
|
|
254
283
|
/**
|
|
255
284
|
* Retrieves an embedding entry by key
|
|
@@ -303,26 +332,20 @@ var EmbeddingEngine = class {
|
|
|
303
332
|
/**
|
|
304
333
|
* Stores multiple text embeddings in batch
|
|
305
334
|
* More efficient than calling store() multiple times
|
|
306
|
-
* Generates embeddings in
|
|
335
|
+
* Generates embeddings in parallel and writes all records at once
|
|
307
336
|
* @param items - Array of {key, text} objects to store
|
|
308
337
|
*/
|
|
309
338
|
async storeMany(items) {
|
|
310
339
|
invariant(items.length > 0, "Items array must not be empty.");
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
340
|
+
await this.ensureModelLoaded();
|
|
341
|
+
const embeddingContext = this.embeddingContext;
|
|
342
|
+
invariant(embeddingContext, "Embedding context not initialized");
|
|
343
|
+
const embeddingPromises = items.map(async (item) => {
|
|
344
|
+
const truncatedText = this.truncateToContextSize(item.text);
|
|
345
|
+
const embedding = await embeddingContext.getEmbeddingFor(truncatedText);
|
|
346
|
+
return Array.from(embedding.vector);
|
|
315
347
|
});
|
|
316
|
-
const
|
|
317
|
-
const embeddingDim = output.dims[1];
|
|
318
|
-
const embeddingsList = [];
|
|
319
|
-
for (let i = 0; i < batchSize; i++) {
|
|
320
|
-
const start = i * embeddingDim;
|
|
321
|
-
const end = start + embeddingDim;
|
|
322
|
-
const data = Array.from(output.data);
|
|
323
|
-
embeddingsList.push(data.slice(start, end));
|
|
324
|
-
}
|
|
325
|
-
invariant(embeddingsList.length === items.length, "Number of embeddings must match number of items.");
|
|
348
|
+
const embeddingsList = await Promise.all(embeddingPromises);
|
|
326
349
|
await mkdir(dirname(this.storePath), { recursive: true });
|
|
327
350
|
if (!existsSync(this.storePath)) await writeHeader(this.storePath, embeddingsList[0].length);
|
|
328
351
|
const records = items.map((item, index) => ({
|
|
@@ -356,8 +379,17 @@ var EmbeddingEngine = class {
|
|
|
356
379
|
* Disposes of the cached embedding model and releases resources
|
|
357
380
|
* Call this when you're done using the engine to free up memory
|
|
358
381
|
*/
|
|
359
|
-
dispose() {
|
|
360
|
-
this.
|
|
382
|
+
async dispose() {
|
|
383
|
+
if (this.embeddingContext) {
|
|
384
|
+
await this.embeddingContext.dispose();
|
|
385
|
+
this.embeddingContext = void 0;
|
|
386
|
+
}
|
|
387
|
+
if (this.model) {
|
|
388
|
+
await this.model.dispose();
|
|
389
|
+
this.model = void 0;
|
|
390
|
+
}
|
|
391
|
+
this.llama = void 0;
|
|
392
|
+
this.initPromise = void 0;
|
|
361
393
|
}
|
|
362
394
|
};
|
|
363
395
|
|