@retrivora-ai/rag-engine 0.1.5 → 0.1.6

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.
Files changed (40) hide show
  1. package/dist/{DocumentChunker-cfaMidtA.d.mts → DocumentChunker-BEyzadsv.d.mts} +2 -2
  2. package/dist/{DocumentChunker-cfaMidtA.d.ts → DocumentChunker-BEyzadsv.d.ts} +2 -2
  3. package/dist/{PineconeProvider-NJ675H7U.mjs → PineconeProvider-ZRAFNFEC.mjs} +1 -1
  4. package/dist/{PostgreSQLProvider-ISNMD3BE.mjs → PostgreSQLProvider-ZNXA67IM.mjs} +1 -1
  5. package/dist/{QdrantProvider-LJWOIGES.mjs → QdrantProvider-NYGHAA7C.mjs} +1 -1
  6. package/dist/{RagConfig-DG_0f8ka.d.mts → RagConfig-hBGXJmSx.d.mts} +3 -3
  7. package/dist/{RagConfig-DG_0f8ka.d.ts → RagConfig-hBGXJmSx.d.ts} +3 -3
  8. package/dist/{chunk-6FODXNUF.mjs → chunk-5K23H7JL.mjs} +27 -1
  9. package/dist/chunk-HSBXE2WV.mjs +1758 -0
  10. package/dist/{chunk-S5DRHETN.mjs → chunk-IUTAZ7QR.mjs} +31 -2
  11. package/dist/{chunk-AALIF3AL.mjs → chunk-ZM6TYIDH.mjs} +3 -3
  12. package/dist/handlers/index.d.mts +3 -44
  13. package/dist/handlers/index.d.ts +3 -44
  14. package/dist/handlers/index.js +1322 -57
  15. package/dist/handlers/index.mjs +1 -1
  16. package/dist/index-Bx182KKn.d.ts +64 -0
  17. package/dist/index-Ck2pt7-8.d.mts +64 -0
  18. package/dist/index.d.mts +4 -4
  19. package/dist/index.d.ts +4 -4
  20. package/dist/server.d.mts +65 -18
  21. package/dist/server.d.ts +65 -18
  22. package/dist/server.js +1322 -57
  23. package/dist/server.mjs +4 -4
  24. package/package.json +2 -1
  25. package/src/config/serverConfig.ts +3 -0
  26. package/src/core/BatchProcessor.ts +347 -0
  27. package/src/core/ConfigValidator.ts +560 -0
  28. package/src/core/Pipeline.ts +89 -39
  29. package/src/core/ProviderHealthCheck.ts +565 -0
  30. package/src/core/VectorPlugin.ts +49 -8
  31. package/src/handlers/index.ts +2 -2
  32. package/src/providers/vectordb/BaseVectorProvider.ts +1 -1
  33. package/src/providers/vectordb/MilvusProvider.ts +1 -1
  34. package/src/providers/vectordb/MongoDBProvider.ts +1 -1
  35. package/src/providers/vectordb/PineconeProvider.ts +4 -4
  36. package/src/providers/vectordb/PostgreSQLProvider.ts +35 -3
  37. package/src/providers/vectordb/QdrantProvider.ts +32 -2
  38. package/src/rag/DocumentChunker.ts +2 -2
  39. package/src/types/index.ts +3 -3
  40. package/dist/chunk-BP4U4TT5.mjs +0 -548
@@ -2,14 +2,21 @@ import { BaseVectorProvider } from '../providers/vectordb/BaseVectorProvider';
2
2
  import { ILLMProvider, ChatMessage } from '../llm/ILLMProvider';
3
3
  import { DocumentChunker } from '../rag/DocumentChunker';
4
4
  import { RagConfig } from '../config/RagConfig';
5
- import { VectorMatch } from '../types';
6
5
  import { ProviderRegistry } from './ProviderRegistry';
6
+ import { BatchProcessor, BatchOptions } from './BatchProcessor';
7
7
 
8
8
  // Moved to src/types/index.ts
9
9
  import { IngestDocument, ChatResponse } from '../types';
10
10
 
11
11
  /**
12
12
  * Pipeline — orchestrates the RAG flow: Embed → Search → Augment → Generate.
13
+ *
14
+ * Features:
15
+ * - Lazy initialization of providers
16
+ * - Batch processing with retry logic
17
+ * - Configurable embedding strategies
18
+ * - Error recovery for transient failures
19
+ * - Support for multi-tenancy via namespacing
13
20
  */
14
21
  export class Pipeline {
15
22
  private vectorDB!: BaseVectorProvider;
@@ -34,7 +41,7 @@ export class Pipeline {
34
41
  this.llmProvider = ProviderRegistry.createLLMProvider(this.config.llm, this.config.embedding);
35
42
 
36
43
  if (this.config.llm.provider === 'anthropic') {
37
- // Logic for Anthropic as seen in RAGPipeline
44
+ // Anthropic doesn't support embeddings, so use separate provider
38
45
  const { LLMFactory } = await import('../llm/LLMFactory');
39
46
  this.embeddingProvider = LLMFactory.createEmbeddingProvider(this.config.embedding);
40
47
  } else {
@@ -45,28 +52,76 @@ export class Pipeline {
45
52
  this.initialised = true;
46
53
  }
47
54
 
48
- async ingest(documents: IngestDocument[], namespace?: string): Promise<Array<{ docId: string; chunksIngested: number }>> {
55
+ /**
56
+ * Ingest documents with automatic chunking, embedding, and batch processing.
57
+ * Handles retries for transient failures.
58
+ */
59
+ async ingest(documents: IngestDocument[], namespace?: string): Promise<Array<{ docId: string | number; chunksIngested: number }>> {
49
60
  await this.initialize();
50
61
  const ns = namespace ?? this.config.projectId;
51
62
  const results = [];
52
63
 
53
64
  for (const doc of documents) {
54
- const chunks = this.chunker.chunk(doc.content, {
55
- docId: doc.docId,
56
- metadata: doc.metadata,
57
- });
58
-
59
- const vectors = await this.embeddingProvider.batchEmbed(chunks.map(c => c.content));
60
- const upsertDocs = chunks.map((chunk, i) => ({
61
- id: chunk.id,
62
- vector: vectors[i],
63
- content: chunk.content,
64
- metadata: chunk.metadata,
65
- }));
66
-
67
- await this.vectorDB.batchUpsert(upsertDocs, ns);
68
- results.push({ docId: doc.docId, chunksIngested: chunks.length });
65
+ try {
66
+ const chunks = this.chunker.chunk(doc.content, {
67
+ docId: doc.docId,
68
+ metadata: doc.metadata,
69
+ });
70
+
71
+ // Batch embed chunks with retry logic
72
+ const batchOptions: BatchOptions = {
73
+ batchSize: 50, // Embedding batch size
74
+ maxRetries: 3,
75
+ initialDelayMs: 100,
76
+ };
77
+
78
+ const vectors = await BatchProcessor.mapWithRetry(
79
+ chunks.map(c => c.content),
80
+ (text) => this.embeddingProvider.embed(text),
81
+ batchOptions
82
+ );
83
+
84
+ if (vectors.length !== chunks.length) {
85
+ throw new Error(`Embedding failed: got ${vectors.length} vectors for ${chunks.length} chunks`);
86
+ }
87
+
88
+ const upsertDocs = chunks.map((chunk, i) => ({
89
+ id: chunk.id,
90
+ vector: vectors[i],
91
+ content: chunk.content,
92
+ metadata: chunk.metadata,
93
+ }));
94
+
95
+ // Batch upsert with retry logic
96
+ const upsertBatchOptions: BatchOptions = {
97
+ batchSize: 100,
98
+ maxRetries: 3,
99
+ initialDelayMs: 100,
100
+ };
101
+
102
+ const upsertResult = await BatchProcessor.processBatch(
103
+ upsertDocs,
104
+ (batch) => this.vectorDB.batchUpsert(batch, ns),
105
+ upsertBatchOptions
106
+ );
107
+
108
+ if (upsertResult.errors.length > 0) {
109
+ console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed for doc ${doc.docId}`);
110
+ }
111
+
112
+ results.push({
113
+ docId: doc.docId,
114
+ chunksIngested: upsertResult.totalProcessed,
115
+ });
116
+ } catch (error) {
117
+ console.error(`[Pipeline] Failed to ingest document ${doc.docId}:`, error);
118
+ results.push({
119
+ docId: doc.docId,
120
+ chunksIngested: 0,
121
+ });
122
+ }
69
123
  }
124
+
70
125
  return results;
71
126
  }
72
127
 
@@ -76,26 +131,21 @@ export class Pipeline {
76
131
  const topK = this.config.rag?.topK ?? 5;
77
132
  const scoreThreshold = this.config.rag?.scoreThreshold ?? 0.0;
78
133
 
79
- const queryVector = await this.embeddingProvider.embed(question);
80
- const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
81
-
82
- const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
83
- const context = sources.length
84
- ? sources.map((m, i) => `[Source ${i + 1}]\n${m.content}`).join('\n\n---\n\n')
85
- : 'No relevant context found.';
86
-
87
- const messages: ChatMessage[] = [...history, { role: 'user', content: question }];
88
- const reply = await this.llmProvider.chat(messages, context);
89
-
90
- return { reply, sources };
91
- }
92
-
93
- async health(): Promise<Record<string, boolean>> {
94
- await this.initialize();
95
- const [vectorDB, llm] = await Promise.all([
96
- this.vectorDB.ping().catch(() => false),
97
- this.llmProvider.ping().catch(() => false),
98
- ]);
99
- return { vectorDB, llm };
134
+ try {
135
+ const queryVector = await this.embeddingProvider.embed(question);
136
+ const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
137
+
138
+ const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
139
+ const context = sources.length
140
+ ? sources.map((m, i) => `[Source ${i + 1}]\n${m.content}`).join('\n\n---\n\n')
141
+ : 'No relevant context found.';
142
+
143
+ const messages: ChatMessage[] = [...history, { role: 'user', content: question }];
144
+ const reply = await this.llmProvider.chat(messages, context);
145
+
146
+ return { reply, sources };
147
+ } catch (error) {
148
+ throw new Error(`[Pipeline] Chat failed: ${error instanceof Error ? error.message : String(error)}`);
149
+ }
100
150
  }
101
151
  }