@voltx/rag 0.2.0 → 0.3.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 +109 -0
- package/dist/index.d.mts +275 -14
- package/dist/index.d.ts +275 -14
- package/dist/index.js +488 -34
- package/dist/index.mjs +478 -35
- package/package.json +15 -14
- package/LICENSE +0 -21
package/dist/index.d.ts
CHANGED
|
@@ -4,53 +4,314 @@ interface DocumentChunk {
|
|
|
4
4
|
id: string;
|
|
5
5
|
content: string;
|
|
6
6
|
metadata?: Record<string, unknown>;
|
|
7
|
+
embedding?: number[];
|
|
7
8
|
}
|
|
8
9
|
interface DocumentLoader {
|
|
9
10
|
name: string;
|
|
10
|
-
/** Load and return raw text from a source */
|
|
11
|
+
/** Load and return raw text from a source (file path, URL, or raw content) */
|
|
11
12
|
load(source: string): Promise<string>;
|
|
12
13
|
}
|
|
13
14
|
interface TextSplitter {
|
|
14
15
|
/** Split text into chunks */
|
|
15
16
|
split(text: string): DocumentChunk[];
|
|
16
17
|
}
|
|
18
|
+
interface CharacterSplitterOptions {
|
|
19
|
+
/** Maximum characters per chunk (default: 1000) */
|
|
20
|
+
chunkSize?: number;
|
|
21
|
+
/** Overlap between chunks in characters (default: 200) */
|
|
22
|
+
overlap?: number;
|
|
23
|
+
}
|
|
24
|
+
interface RecursiveSplitterOptions {
|
|
25
|
+
/** Maximum characters per chunk (default: 1000) */
|
|
26
|
+
chunkSize?: number;
|
|
27
|
+
/** Overlap between chunks in characters (default: 200) */
|
|
28
|
+
overlap?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Separators to try in order of preference.
|
|
31
|
+
* Default: ["\n\n", "\n", ". ", " ", ""]
|
|
32
|
+
*/
|
|
33
|
+
separators?: string[];
|
|
34
|
+
}
|
|
35
|
+
interface MarkdownSplitterOptions {
|
|
36
|
+
/** Maximum characters per chunk (default: 1500) */
|
|
37
|
+
chunkSize?: number;
|
|
38
|
+
/** Overlap between chunks in characters (default: 100) */
|
|
39
|
+
overlap?: number;
|
|
40
|
+
/** Whether to include header hierarchy in chunk metadata (default: true) */
|
|
41
|
+
includeHeaders?: boolean;
|
|
42
|
+
}
|
|
17
43
|
interface Embedder {
|
|
18
44
|
name: string;
|
|
19
|
-
/** Generate embedding vector for text */
|
|
45
|
+
/** Generate embedding vector for a single text */
|
|
20
46
|
embed(text: string): Promise<number[]>;
|
|
21
47
|
/** Batch embed multiple texts */
|
|
22
48
|
embedBatch(texts: string[]): Promise<number[][]>;
|
|
23
49
|
}
|
|
50
|
+
interface EmbedderConfig {
|
|
51
|
+
/** Model string in "provider:model" format, e.g. "openai:text-embedding-3-small" */
|
|
52
|
+
model: string;
|
|
53
|
+
}
|
|
24
54
|
interface RAGPipelineConfig {
|
|
55
|
+
/** Document loader (optional — if omitted, source is treated as raw text) */
|
|
25
56
|
loader?: DocumentLoader;
|
|
57
|
+
/** Text splitter (default: RecursiveTextSplitter) */
|
|
26
58
|
splitter?: TextSplitter;
|
|
59
|
+
/** Embedder — wraps @voltx/ai embed/embedMany */
|
|
27
60
|
embedder: Embedder;
|
|
61
|
+
/** Vector store from @voltx/db */
|
|
28
62
|
vectorStore: VectorStore;
|
|
29
63
|
}
|
|
64
|
+
interface RAGQueryOptions {
|
|
65
|
+
/** Number of results to return (default: 5) */
|
|
66
|
+
topK?: number;
|
|
67
|
+
/** Minimum similarity score threshold (0-1, default: 0) */
|
|
68
|
+
minScore?: number;
|
|
69
|
+
/** Metadata filter */
|
|
70
|
+
filter?: Record<string, unknown>;
|
|
71
|
+
}
|
|
30
72
|
interface RAGQueryResult {
|
|
31
|
-
|
|
73
|
+
/** Retrieved source documents */
|
|
32
74
|
sources: VectorDocument[];
|
|
75
|
+
/** The query embedding (useful for debugging) */
|
|
76
|
+
queryEmbedding?: number[];
|
|
33
77
|
}
|
|
78
|
+
interface RAGIngestResult {
|
|
79
|
+
/** Number of chunks ingested */
|
|
80
|
+
chunks: number;
|
|
81
|
+
/** Chunk IDs that were stored */
|
|
82
|
+
ids: string[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Simple character-based text splitter with smart boundary detection.
|
|
87
|
+
* Tries to split at sentence/paragraph boundaries near the chunk size.
|
|
88
|
+
*/
|
|
34
89
|
declare class CharacterSplitter implements TextSplitter {
|
|
35
90
|
private chunkSize;
|
|
36
91
|
private overlap;
|
|
37
|
-
constructor(
|
|
92
|
+
constructor(options?: CharacterSplitterOptions);
|
|
93
|
+
private findBreakPoint;
|
|
94
|
+
split(text: string): DocumentChunk[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Recursively splits text using a hierarchy of separators.
|
|
98
|
+
* Tries to keep semantically related text together by splitting on
|
|
99
|
+
* paragraph breaks first, then newlines, then sentences, then words.
|
|
100
|
+
*
|
|
101
|
+
* This is the recommended splitter for generic text (same approach as
|
|
102
|
+
* LangChain's RecursiveCharacterTextSplitter).
|
|
103
|
+
*/
|
|
104
|
+
declare class RecursiveTextSplitter implements TextSplitter {
|
|
105
|
+
private chunkSize;
|
|
106
|
+
private overlap;
|
|
107
|
+
private separators;
|
|
108
|
+
constructor(options?: RecursiveSplitterOptions);
|
|
109
|
+
split(text: string): DocumentChunk[];
|
|
38
110
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
111
|
+
* Recursively split text. Try the first separator; if any resulting piece
|
|
112
|
+
* is still too large, recurse with the next separator in the list.
|
|
41
113
|
*/
|
|
42
|
-
private
|
|
114
|
+
private splitText;
|
|
115
|
+
/**
|
|
116
|
+
* Merge chunks with overlap to maintain context between adjacent chunks.
|
|
117
|
+
*/
|
|
118
|
+
private mergeWithOverlap;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Markdown-aware text splitter that respects heading hierarchy.
|
|
122
|
+
* Splits on headings first, then falls back to paragraph/sentence boundaries
|
|
123
|
+
* within sections that exceed the chunk size.
|
|
124
|
+
*/
|
|
125
|
+
declare class MarkdownSplitter implements TextSplitter {
|
|
126
|
+
private chunkSize;
|
|
127
|
+
private overlap;
|
|
128
|
+
private includeHeaders;
|
|
129
|
+
constructor(options?: MarkdownSplitterOptions);
|
|
43
130
|
split(text: string): DocumentChunk[];
|
|
131
|
+
private splitByHeadings;
|
|
132
|
+
private buildHeaderPrefix;
|
|
44
133
|
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Loads plain text from a file path or treats the source as raw text.
|
|
137
|
+
*/
|
|
138
|
+
declare class TextLoader implements DocumentLoader {
|
|
139
|
+
name: string;
|
|
140
|
+
load(source: string): Promise<string>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Loads markdown files. Strips front-matter (YAML between --- delimiters)
|
|
144
|
+
* and returns the markdown body.
|
|
145
|
+
*/
|
|
146
|
+
declare class MarkdownLoader implements DocumentLoader {
|
|
147
|
+
name: string;
|
|
148
|
+
load(source: string): Promise<string>;
|
|
149
|
+
}
|
|
150
|
+
interface JSONLoaderOptions {
|
|
151
|
+
/** JSON path keys to extract text from (e.g. ["content", "text", "body"]) */
|
|
152
|
+
textKeys?: string[];
|
|
153
|
+
/** Separator between extracted values (default: "\n\n") */
|
|
154
|
+
separator?: string;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Loads JSON files and extracts text content from specified keys.
|
|
158
|
+
* Handles both single objects and arrays of objects.
|
|
159
|
+
*/
|
|
160
|
+
declare class JSONLoader implements DocumentLoader {
|
|
161
|
+
name: string;
|
|
162
|
+
private textKeys;
|
|
163
|
+
private separator;
|
|
164
|
+
constructor(options?: JSONLoaderOptions);
|
|
165
|
+
load(source: string): Promise<string>;
|
|
166
|
+
private extractTexts;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Fetches text content from a URL. Strips HTML tags for basic text extraction.
|
|
170
|
+
*/
|
|
171
|
+
declare class WebLoader implements DocumentLoader {
|
|
172
|
+
name: string;
|
|
173
|
+
load(source: string): Promise<string>;
|
|
174
|
+
private stripHTML;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Creates an embedder that uses @voltx/ai under the hood.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* const embedder = createEmbedder({ model: "openai:text-embedding-3-small" });
|
|
183
|
+
* const vector = await embedder.embed("Hello world");
|
|
184
|
+
* const vectors = await embedder.embedBatch(["Hello", "World"]);
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
declare function createEmbedder(config: EmbedderConfig): Embedder;
|
|
188
|
+
|
|
189
|
+
type ChunkStrategy = "recursive" | "character" | "markdown";
|
|
190
|
+
interface ChunkOptions {
|
|
191
|
+
/** Chunking strategy (default: "recursive") */
|
|
192
|
+
strategy?: ChunkStrategy;
|
|
193
|
+
/** Maximum chunk size in characters */
|
|
194
|
+
chunkSize?: number;
|
|
195
|
+
/** Overlap between chunks in characters */
|
|
196
|
+
overlap?: number;
|
|
197
|
+
/** Custom separators (recursive strategy only) */
|
|
198
|
+
separators?: string[];
|
|
199
|
+
/** Include header hierarchy in metadata (markdown strategy only) */
|
|
200
|
+
includeHeaders?: boolean;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Fluent document processing class.
|
|
204
|
+
* Create from various formats, chunk, and embed in a pipeline.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* const doc = MDocument.fromText("Your long document...");
|
|
209
|
+
* const chunks = doc.chunk({ strategy: "recursive", chunkSize: 500 });
|
|
210
|
+
*
|
|
211
|
+
* // Or from markdown
|
|
212
|
+
* const mdDoc = MDocument.fromMarkdown("# Title\n\nContent...");
|
|
213
|
+
* const mdChunks = mdDoc.chunk({ strategy: "markdown" });
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
declare class MDocument {
|
|
217
|
+
private content;
|
|
218
|
+
private format;
|
|
219
|
+
private chunks;
|
|
220
|
+
private constructor();
|
|
221
|
+
/** Create from plain text */
|
|
222
|
+
static fromText(content: string): MDocument;
|
|
223
|
+
/** Create from markdown */
|
|
224
|
+
static fromMarkdown(content: string): MDocument;
|
|
225
|
+
/** Create from JSON string */
|
|
226
|
+
static fromJSON(content: string): MDocument;
|
|
227
|
+
/** Create from HTML (strips tags) */
|
|
228
|
+
static fromHTML(html: string): MDocument;
|
|
229
|
+
/** Get the raw content */
|
|
230
|
+
getContent(): string;
|
|
231
|
+
/** Get the document format */
|
|
232
|
+
getFormat(): string;
|
|
233
|
+
/**
|
|
234
|
+
* Split the document into chunks using the specified strategy.
|
|
235
|
+
* Returns the chunks and caches them for subsequent embed() calls.
|
|
236
|
+
*/
|
|
237
|
+
chunk(options?: ChunkOptions): DocumentChunk[];
|
|
238
|
+
/**
|
|
239
|
+
* Embed the chunks using the provided embedder.
|
|
240
|
+
* Must call chunk() first.
|
|
241
|
+
*/
|
|
242
|
+
embed(embedder: Embedder): Promise<DocumentChunk[]>;
|
|
243
|
+
/** Get cached chunks (null if chunk() hasn't been called) */
|
|
244
|
+
getChunks(): DocumentChunk[] | null;
|
|
245
|
+
private defaultStrategy;
|
|
246
|
+
private createSplitter;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Calculate cosine similarity between two embedding vectors.
|
|
251
|
+
* Returns a value between -1 and 1, where 1 means identical direction.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```ts
|
|
255
|
+
* const score = cosineSimilarity(embeddingA, embeddingB);
|
|
256
|
+
* // score ≈ 0.95 means very similar
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
260
|
+
|
|
45
261
|
declare class RAGPipeline {
|
|
46
|
-
private
|
|
262
|
+
private loader;
|
|
263
|
+
private splitter;
|
|
264
|
+
private embedder;
|
|
265
|
+
private vectorStore;
|
|
47
266
|
constructor(config: RAGPipelineConfig);
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
267
|
+
/**
|
|
268
|
+
* Ingest a document: load → split → embed (batch) → store in vector DB.
|
|
269
|
+
*
|
|
270
|
+
* @param source - File path, URL, or raw text (depends on loader)
|
|
271
|
+
* @param idPrefix - Optional prefix for chunk IDs (default: "doc")
|
|
272
|
+
* @returns Number of chunks ingested and their IDs
|
|
273
|
+
*/
|
|
274
|
+
ingest(source: string, idPrefix?: string): Promise<RAGIngestResult>;
|
|
275
|
+
/**
|
|
276
|
+
* Query: embed question → search vector store → return ranked sources.
|
|
277
|
+
*
|
|
278
|
+
* @param question - The user's question
|
|
279
|
+
* @param options - Query options (topK, minScore)
|
|
280
|
+
*/
|
|
281
|
+
query(question: string, options?: RAGQueryOptions): Promise<RAGQueryResult>;
|
|
282
|
+
/**
|
|
283
|
+
* Convenience: query + format sources into a context string for LLM prompts.
|
|
284
|
+
*/
|
|
285
|
+
getContext(question: string, options?: RAGQueryOptions): Promise<string>;
|
|
286
|
+
/**
|
|
287
|
+
* Delete documents from the vector store by IDs.
|
|
288
|
+
*/
|
|
289
|
+
delete(ids: string[]): Promise<void>;
|
|
52
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Create a RAG pipeline.
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```ts
|
|
296
|
+
* import { createRAGPipeline, createEmbedder } from "@voltx/rag";
|
|
297
|
+
* import { createVectorStore } from "@voltx/db";
|
|
298
|
+
*
|
|
299
|
+
* const pipeline = createRAGPipeline({
|
|
300
|
+
* embedder: createEmbedder({ model: "openai:text-embedding-3-small" }),
|
|
301
|
+
* vectorStore: createVectorStore("pinecone", { indexName: "my-index" }),
|
|
302
|
+
* });
|
|
303
|
+
*
|
|
304
|
+
* // Ingest documents
|
|
305
|
+
* await pipeline.ingest("Your long document text here...");
|
|
306
|
+
*
|
|
307
|
+
* // Query
|
|
308
|
+
* const { sources } = await pipeline.query("What is TypeScript?");
|
|
309
|
+
*
|
|
310
|
+
* // Or get formatted context for LLM
|
|
311
|
+
* const context = await pipeline.getContext("What is TypeScript?");
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
53
314
|
declare function createRAGPipeline(config: RAGPipelineConfig): RAGPipeline;
|
|
54
|
-
declare const VERSION = "0.
|
|
315
|
+
declare const VERSION = "0.3.0";
|
|
55
316
|
|
|
56
|
-
export { CharacterSplitter, type DocumentChunk, type DocumentLoader, type Embedder, RAGPipeline, type RAGPipelineConfig, type RAGQueryResult, type TextSplitter, VERSION, createRAGPipeline };
|
|
317
|
+
export { CharacterSplitter, type CharacterSplitterOptions, type ChunkOptions, type ChunkStrategy, type DocumentChunk, type DocumentLoader, type Embedder, type EmbedderConfig, JSONLoader, type JSONLoaderOptions, MDocument, MarkdownLoader, MarkdownSplitter, type MarkdownSplitterOptions, type RAGIngestResult, RAGPipeline, type RAGPipelineConfig, type RAGQueryOptions, type RAGQueryResult, type RecursiveSplitterOptions, RecursiveTextSplitter, TextLoader, type TextSplitter, VERSION, WebLoader, cosineSimilarity, createEmbedder, createRAGPipeline };
|