embedded-raptor 1.0.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 +20 -20
- 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-D06Gh_gw.mjs → engine-BvJ0ls3b.mjs} +74 -12
- package/dist/engine-Cuz0P5Od.mjs +1164 -0
- package/dist/engine-DLM7PWhV.cjs +1203 -0
- package/dist/{engine-Bl1yeWoe.cjs → engine-Iq0_dbnk.cjs} +75 -13
- 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 +9 -5
- 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
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# Raptor
|
|
1
|
+
# Embedded Raptor
|
|
2
2
|
|
|
3
|
-
[](https://github.com/artmann/raptor/actions/workflows/ci.yml)
|
|
4
|
-
[](https://www.npmjs.com/package/raptor)
|
|
5
|
-
[](https://www.npmjs.com/package/raptor)
|
|
3
|
+
[](https://github.com/artmann/embedded-raptor/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/embedded-raptor)
|
|
5
|
+
[](https://www.npmjs.com/package/embedded-raptor)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
|
|
9
9
|
> A lightweight semantic search database with text embeddings for Node.js and
|
|
10
10
|
> Bun
|
|
11
11
|
|
|
12
|
-
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
|
-
## What is Raptor?
|
|
16
|
+
## What is Embedded Raptor?
|
|
17
17
|
|
|
18
|
-
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".
|
|
25
25
|
|
|
26
|
-
## Why Raptor?
|
|
26
|
+
## Why Embedded Raptor?
|
|
27
27
|
|
|
28
28
|
- **Simple API** - No complex setup, just store and search
|
|
29
29
|
- **Semantic Search** - Find content by meaning, not just keywords
|
|
@@ -44,10 +44,10 @@ login credentials" or "change account password".
|
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
# Using npm
|
|
47
|
-
npm install raptor
|
|
47
|
+
npm install embedded-raptor
|
|
48
48
|
|
|
49
49
|
# Using bun
|
|
50
|
-
bun add raptor
|
|
50
|
+
bun add embedded-raptor
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
## Quick Start
|
|
@@ -55,7 +55,7 @@ bun add raptor
|
|
|
55
55
|
### Programmatic API
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
|
-
import { EmbeddingEngine } from 'raptor'
|
|
58
|
+
import { EmbeddingEngine } from 'embedded-raptor'
|
|
59
59
|
|
|
60
60
|
const engine = new EmbeddingEngine({
|
|
61
61
|
storePath: './my-database.raptor'
|
|
@@ -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**: 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, 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,22 +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;
|
|
229
|
+
cacheDir;
|
|
230
|
+
llama;
|
|
231
|
+
model;
|
|
232
|
+
embeddingContext;
|
|
233
|
+
initPromise;
|
|
227
234
|
constructor(options) {
|
|
228
235
|
this.storePath = options.storePath;
|
|
229
236
|
this.fileReader = new BinaryFileReader(options.storePath);
|
|
237
|
+
this.cacheDir = options.cacheDir ?? DEFAULT_CACHE_DIR;
|
|
230
238
|
}
|
|
231
239
|
/**
|
|
232
|
-
*
|
|
240
|
+
* Gets or initializes the embedding model
|
|
241
|
+
* Caches the model instance to avoid repeated initialization overhead
|
|
242
|
+
*/
|
|
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);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Generates embedding from text using node-llama-cpp with bge-small-en-v1.5 model
|
|
233
273
|
* @param text - Text to embed
|
|
234
|
-
* @returns
|
|
274
|
+
* @returns 384-dimensional embedding vector (normalized)
|
|
235
275
|
*/
|
|
236
276
|
async generateEmbedding(text) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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);
|
|
240
282
|
}
|
|
241
283
|
/**
|
|
242
284
|
* Retrieves an embedding entry by key
|
|
@@ -290,16 +332,20 @@ var EmbeddingEngine = class {
|
|
|
290
332
|
/**
|
|
291
333
|
* Stores multiple text embeddings in batch
|
|
292
334
|
* More efficient than calling store() multiple times
|
|
293
|
-
* Generates embeddings in
|
|
335
|
+
* Generates embeddings in parallel and writes all records at once
|
|
294
336
|
* @param items - Array of {key, text} objects to store
|
|
295
337
|
*/
|
|
296
338
|
async storeMany(items) {
|
|
297
339
|
invariant(items.length > 0, "Items array must not be empty.");
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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);
|
|
347
|
+
});
|
|
348
|
+
const embeddingsList = await Promise.all(embeddingPromises);
|
|
303
349
|
await mkdir(dirname(this.storePath), { recursive: true });
|
|
304
350
|
if (!existsSync(this.storePath)) await writeHeader(this.storePath, embeddingsList[0].length);
|
|
305
351
|
const records = items.map((item, index) => ({
|
|
@@ -329,6 +375,22 @@ var EmbeddingEngine = class {
|
|
|
329
375
|
if (magnitudeA === 0 || magnitudeB === 0) return 0;
|
|
330
376
|
return dotProduct / (magnitudeA * magnitudeB);
|
|
331
377
|
}
|
|
378
|
+
/**
|
|
379
|
+
* Disposes of the cached embedding model and releases resources
|
|
380
|
+
* Call this when you're done using the engine to free up memory
|
|
381
|
+
*/
|
|
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;
|
|
393
|
+
}
|
|
332
394
|
};
|
|
333
395
|
|
|
334
396
|
//#endregion
|