@retrivora-ai/rag-engine 0.1.2 → 0.1.4

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 (73) hide show
  1. package/dist/ChromaDBProvider-QNI7UCX4.mjs +8 -0
  2. package/dist/DocumentChunker-BQ5kQD7B.d.ts +155 -0
  3. package/dist/DocumentChunker-D9-fObJp.d.mts +155 -0
  4. package/dist/LLMFactory-XC55FTD2.mjs +7 -0
  5. package/dist/MilvusProvider-OO6QGZDZ.mjs +8 -0
  6. package/dist/MongoDBProvider-WWVJG3WT.mjs +8 -0
  7. package/dist/PineconeProvider-NJ675H7U.mjs +8 -0
  8. package/dist/{RAGPipeline-BmkIv1HD.d.mts → Pipeline-Bo6CUCox.d.mts} +76 -159
  9. package/dist/{RAGPipeline-BmkIv1HD.d.ts → Pipeline-Bo6CUCox.d.ts} +76 -159
  10. package/dist/PostgreSQLProvider-ISNMD3BE.mjs +8 -0
  11. package/dist/QdrantProvider-LJWOIGES.mjs +8 -0
  12. package/dist/RedisProvider-ASONNYBI.mjs +8 -0
  13. package/dist/WeaviateProvider-PSDCUGC7.mjs +8 -0
  14. package/dist/chunk-6FODXNUF.mjs +91 -0
  15. package/dist/chunk-7NXI6ZWX.mjs +89 -0
  16. package/dist/chunk-AALIF3AL.mjs +91 -0
  17. package/dist/chunk-AIAB2IEE.mjs +394 -0
  18. package/dist/chunk-FGGSVVSY.mjs +162 -0
  19. package/dist/chunk-GD3QJFNN.mjs +424 -0
  20. package/dist/chunk-HUGLYKD6.mjs +84 -0
  21. package/dist/chunk-I4E63NIC.mjs +24 -0
  22. package/dist/chunk-QEYVWVT5.mjs +102 -0
  23. package/dist/chunk-S5DRHETN.mjs +110 -0
  24. package/dist/chunk-V75V7BT2.mjs +117 -0
  25. package/dist/chunk-VOIWNO5O.mjs +11 -0
  26. package/dist/chunk-VPNRDXIA.mjs +74 -0
  27. package/dist/handlers/index.d.mts +9 -33
  28. package/dist/handlers/index.d.ts +9 -33
  29. package/dist/handlers/index.js +1477 -959
  30. package/dist/handlers/index.mjs +4 -2
  31. package/dist/index.d.mts +3 -3
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.js +1646 -19
  34. package/dist/index.mjs +14 -2
  35. package/dist/server.d.mts +93 -56
  36. package/dist/server.d.ts +93 -56
  37. package/dist/server.js +1531 -1096
  38. package/dist/server.mjs +56 -131
  39. package/package.json +1 -1
  40. package/src/app/page.tsx +1 -1
  41. package/src/components/MessageBubble.tsx +1 -1
  42. package/src/components/SourceCard.tsx +1 -1
  43. package/src/config/RagConfig.ts +1 -1
  44. package/src/config/serverConfig.ts +2 -2
  45. package/src/core/ConfigResolver.ts +69 -0
  46. package/src/core/Pipeline.ts +109 -0
  47. package/src/core/ProviderRegistry.ts +71 -0
  48. package/src/core/VectorPlugin.ts +51 -0
  49. package/src/handlers/index.ts +21 -100
  50. package/src/hooks/useRagChat.ts +1 -1
  51. package/src/index.ts +8 -6
  52. package/src/providers/vectordb/BaseVectorProvider.ts +61 -0
  53. package/src/providers/vectordb/ChromaDBProvider.ts +94 -0
  54. package/src/providers/vectordb/MilvusProvider.ts +100 -0
  55. package/src/providers/vectordb/MongoDBProvider.ts +118 -0
  56. package/src/{vectordb/adapters/PineconeAdapter.ts → providers/vectordb/PineconeProvider.ts} +21 -56
  57. package/src/{vectordb/adapters/PgVectorAdapter.ts → providers/vectordb/PostgreSQLProvider.ts} +23 -58
  58. package/src/providers/vectordb/QdrantProvider.ts +95 -0
  59. package/src/providers/vectordb/RedisProvider.ts +84 -0
  60. package/src/providers/vectordb/WeaviateProvider.ts +124 -0
  61. package/src/server.ts +16 -8
  62. package/src/test-refactor.ts +59 -0
  63. package/src/types/index.ts +13 -0
  64. package/src/utils/templateUtils.ts +6 -6
  65. package/dist/DocumentChunker-BUrIrcPk.d.mts +0 -43
  66. package/dist/DocumentChunker-BUrIrcPk.d.ts +0 -43
  67. package/dist/chunk-W57OWMJK.mjs +0 -1256
  68. package/dist/chunk-ZPXLQR5Q.mjs +0 -67
  69. package/src/rag/RAGPipeline.ts +0 -196
  70. package/src/vectordb/IVectorDB.ts +0 -75
  71. package/src/vectordb/VectorDBFactory.ts +0 -41
  72. package/src/vectordb/adapters/MongoDbAdapter.ts +0 -175
  73. package/src/vectordb/adapters/UniversalVectorDBAdapter.ts +0 -177
package/dist/server.mjs CHANGED
@@ -1,145 +1,70 @@
1
1
  import {
2
- AnthropicProvider,
3
- DocumentChunker,
4
- LLMFactory,
5
- MongoDbAdapter,
6
- OllamaProvider,
7
- OpenAIProvider,
8
- PgVectorAdapter,
9
- PineconeAdapter,
10
- RAGPipeline,
11
- VectorDBFactory,
2
+ QdrantProvider
3
+ } from "./chunk-6FODXNUF.mjs";
4
+ import {
5
+ ChromaDBProvider
6
+ } from "./chunk-HUGLYKD6.mjs";
7
+ import {
8
+ RedisProvider
9
+ } from "./chunk-VPNRDXIA.mjs";
10
+ import {
11
+ WeaviateProvider
12
+ } from "./chunk-V75V7BT2.mjs";
13
+ import {
12
14
  createChatHandler,
13
15
  createHealthHandler,
14
16
  createIngestHandler,
15
17
  createUploadHandler
16
- } from "./chunk-W57OWMJK.mjs";
17
- import "./chunk-ZPXLQR5Q.mjs";
18
-
19
- // src/config/serverConfig.ts
20
- var VECTOR_DB_PROVIDERS = ["pinecone", "pgvector", "mongodb", "rest", "universal_rest", "custom"];
21
- var LLM_PROVIDERS = ["openai", "anthropic", "ollama", "rest", "universal_rest", "custom"];
22
- var EMBEDDING_PROVIDERS = ["openai", "ollama", "rest", "universal_rest", "custom"];
23
- function readString(env, name) {
24
- var _a;
25
- const value = (_a = env[name]) == null ? void 0 : _a.trim();
26
- return value ? value : void 0;
27
- }
28
- function readNumber(env, name, fallback) {
29
- const value = env[name];
30
- if (!value) return fallback;
31
- const parsed = Number(value);
32
- if (!Number.isFinite(parsed)) {
33
- throw new Error(`[getRagConfig] ${name} must be a valid number`);
34
- }
35
- return parsed;
36
- }
37
- function readEnum(env, name, fallback, allowed) {
38
- var _a;
39
- const value = (_a = readString(env, name)) != null ? _a : fallback;
40
- if (allowed.includes(value)) {
41
- return value;
42
- }
43
- throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
44
- }
45
- function getRagConfig(env = process.env) {
46
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J;
47
- const projectId = (_b = (_a = readString(env, "RAG_PROJECT_ID")) != null ? _a : readString(env, "NEXT_PUBLIC_PROJECT_ID")) != null ? _b : "default";
48
- const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
49
- const llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
50
- const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
51
- const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
52
- const vectorDbOptions = {};
53
- if (vectorProvider === "pinecone") {
54
- vectorDbOptions.apiKey = (_c = readString(env, "PINECONE_API_KEY")) != null ? _c : "";
55
- vectorDbOptions.environment = (_d = readString(env, "PINECONE_ENVIRONMENT")) != null ? _d : "";
56
- } else if (vectorProvider === "pgvector") {
57
- vectorDbOptions.connectionString = (_e = readString(env, "PGVECTOR_CONNECTION_STRING")) != null ? _e : "";
58
- vectorDbOptions.dimensions = embeddingDimensions;
59
- } else if (vectorProvider === "rest") {
60
- vectorDbOptions.baseUrl = (_f = readString(env, "VECTOR_DB_REST_URL")) != null ? _f : "";
61
- vectorDbOptions.headers = readString(env, "VECTOR_DB_REST_API_KEY") ? { "api-key": readString(env, "VECTOR_DB_REST_API_KEY") } : {};
62
- } else if (vectorProvider === "universal_rest") {
63
- vectorDbOptions.baseUrl = (_h = (_g = readString(env, "VECTOR_BASE_URL")) != null ? _g : readString(env, "VECTOR_DB_REST_URL")) != null ? _h : "";
64
- vectorDbOptions.profile = readString(env, "VECTOR_UNIVERSAL_PROFILE");
65
- vectorDbOptions.headers = readString(env, "VECTOR_DB_REST_API_KEY") ? { Authorization: `Bearer ${readString(env, "VECTOR_DB_REST_API_KEY")}` } : {};
66
- } else if (vectorProvider === "mongodb") {
67
- vectorDbOptions.uri = (_i = readString(env, "MONGODB_URI")) != null ? _i : "";
68
- vectorDbOptions.database = (_j = readString(env, "MONGODB_DB")) != null ? _j : "";
69
- vectorDbOptions.collection = (_k = readString(env, "MONGODB_COLLECTION")) != null ? _k : "";
70
- vectorDbOptions.indexName = (_l = readString(env, "MONGODB_INDEX_NAME")) != null ? _l : "vector_index";
71
- }
72
- const llmApiKeyByProvider = {
73
- openai: readString(env, "OPENAI_API_KEY"),
74
- anthropic: readString(env, "ANTHROPIC_API_KEY"),
75
- ollama: void 0,
76
- universal_rest: readString(env, "LLM_API_KEY")
77
- };
78
- const embeddingApiKeyByProvider = {
79
- openai: readString(env, "OPENAI_API_KEY"),
80
- ollama: void 0,
81
- custom: (_m = readString(env, "EMBEDDING_API_KEY")) != null ? _m : readString(env, "OPENAI_API_KEY")
82
- };
83
- return {
84
- projectId,
85
- vectorDb: {
86
- provider: vectorProvider,
87
- indexName: (_n = readString(env, "VECTOR_DB_INDEX")) != null ? _n : "rag-index",
88
- options: vectorDbOptions
89
- },
90
- llm: {
91
- provider: llmProvider,
92
- model: (_o = readString(env, "LLM_MODEL")) != null ? _o : "gpt-4o",
93
- apiKey: (_p = llmApiKeyByProvider[llmProvider]) != null ? _p : "",
94
- baseUrl: readString(env, "LLM_BASE_URL"),
95
- systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
96
- maxTokens: readNumber(env, "LLM_MAX_TOKENS", 1024),
97
- temperature: readNumber(env, "LLM_TEMPERATURE", 0.7),
98
- options: {
99
- profile: readString(env, "LLM_UNIVERSAL_PROFILE")
100
- }
101
- },
102
- embedding: {
103
- provider: embeddingProvider,
104
- model: (_q = readString(env, "EMBEDDING_MODEL")) != null ? _q : "text-embedding-3-small",
105
- apiKey: embeddingApiKeyByProvider[embeddingProvider],
106
- baseUrl: readString(env, "EMBEDDING_BASE_URL"),
107
- dimensions: embeddingDimensions,
108
- options: {
109
- profile: readString(env, "EMBEDDING_UNIVERSAL_PROFILE")
110
- }
111
- },
112
- ui: {
113
- title: (_s = (_r = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _r : readString(env, "UI_TITLE")) != null ? _s : "AI Assistant",
114
- subtitle: (_u = (_t = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _t : readString(env, "UI_SUBTITLE")) != null ? _u : "Powered by RAG",
115
- primaryColor: (_w = (_v = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _v : readString(env, "UI_PRIMARY_COLOR")) != null ? _w : "#10b981",
116
- accentColor: (_y = (_x = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _x : readString(env, "UI_ACCENT_COLOR")) != null ? _y : "#3b82f6",
117
- logoUrl: (_z = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _z : readString(env, "UI_LOGO_URL"),
118
- placeholder: (_B = (_A = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _A : readString(env, "UI_PLACEHOLDER")) != null ? _B : "Ask me anything\u2026",
119
- showSources: ((_D = (_C = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _C : readString(env, "UI_SHOW_SOURCES")) != null ? _D : "true") !== "false",
120
- welcomeMessage: (_F = (_E = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _E : readString(env, "UI_WELCOME_MESSAGE")) != null ? _F : "Hello! I'm your AI assistant. Ask me anything about your documents.",
121
- visualStyle: (_H = (_G = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _G : readString(env, "UI_VISUAL_STYLE")) != null ? _H : "glass",
122
- borderRadius: (_J = (_I = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _I : readString(env, "UI_BORDER_RADIUS")) != null ? _J : "xl"
123
- },
124
- rag: {
125
- topK: readNumber(env, "RAG_TOP_K", 5),
126
- scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
127
- chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
128
- chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200)
129
- }
130
- };
131
- }
18
+ } from "./chunk-FGGSVVSY.mjs";
19
+ import {
20
+ ConfigResolver,
21
+ DocumentChunker,
22
+ Pipeline,
23
+ ProviderRegistry,
24
+ VectorPlugin,
25
+ getRagConfig
26
+ } from "./chunk-AIAB2IEE.mjs";
27
+ import {
28
+ AnthropicProvider,
29
+ LLMFactory,
30
+ OllamaProvider,
31
+ OpenAIProvider
32
+ } from "./chunk-GD3QJFNN.mjs";
33
+ import {
34
+ PineconeProvider
35
+ } from "./chunk-AALIF3AL.mjs";
36
+ import {
37
+ PostgreSQLProvider
38
+ } from "./chunk-S5DRHETN.mjs";
39
+ import {
40
+ MongoDBProvider
41
+ } from "./chunk-QEYVWVT5.mjs";
42
+ import {
43
+ MilvusProvider
44
+ } from "./chunk-7NXI6ZWX.mjs";
45
+ import {
46
+ BaseVectorProvider
47
+ } from "./chunk-VOIWNO5O.mjs";
48
+ import "./chunk-I4E63NIC.mjs";
132
49
  export {
133
50
  AnthropicProvider,
51
+ BaseVectorProvider,
52
+ ChromaDBProvider,
53
+ ConfigResolver,
134
54
  DocumentChunker,
135
55
  LLMFactory,
136
- MongoDbAdapter,
56
+ MilvusProvider,
57
+ MongoDBProvider,
137
58
  OllamaProvider,
138
59
  OpenAIProvider,
139
- PgVectorAdapter,
140
- PineconeAdapter,
141
- RAGPipeline,
142
- VectorDBFactory,
60
+ PineconeProvider,
61
+ Pipeline,
62
+ PostgreSQLProvider,
63
+ ProviderRegistry,
64
+ QdrantProvider,
65
+ RedisProvider,
66
+ VectorPlugin,
67
+ WeaviateProvider,
143
68
  createChatHandler,
144
69
  createHealthHandler,
145
70
  createIngestHandler,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
5
5
  "author": "Abhinav Alkuchi",
6
6
  "license": "MIT",
package/src/app/page.tsx CHANGED
@@ -478,7 +478,7 @@ export const POST = createChatHandler(getRagConfig());`}
478
478
  <span className="mb-1">VECTOR_DB_PROVIDER=universal_rest</span>
479
479
  <span className="mb-4">LLM_PROVIDER=openai</span>
480
480
  <span className="text-slate-500 text-xs mb-2"># Client UI (Public)</span>
481
- <span>NEXT_PUBLIC_UI_TITLE="AI Assistant"</span>
481
+ <span>NEXT_PUBLIC_UI_TITLE=&quot;AI Assistant&quot;</span>
482
482
  </div>
483
483
  </div>
484
484
  </div>
@@ -5,7 +5,7 @@ import { Bot, User, ChevronDown, ChevronRight } from 'lucide-react';
5
5
  import ReactMarkdown from 'react-markdown';
6
6
  import remarkGfm from 'remark-gfm';
7
7
  import { ChatMessage } from '@/llm/ILLMProvider';
8
- import { VectorMatch } from '@/vectordb/IVectorDB';
8
+ import { VectorMatch } from '@/types';
9
9
  import { SourceCard } from './SourceCard';
10
10
 
11
11
  interface MessageBubbleProps {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React from 'react';
4
4
  import { ChevronDown, ChevronUp } from 'lucide-react';
5
- import { VectorMatch } from '@/vectordb/IVectorDB';
5
+ import { VectorMatch } from '@/types';
6
6
 
7
7
  interface SourceCardProps {
8
8
  source: VectorMatch;
@@ -8,7 +8,7 @@
8
8
  // Vector DB
9
9
  // ---------------------------------------------------------------------------
10
10
 
11
- export type VectorDBProvider = 'pinecone' | 'pgvector' | 'mongodb' | 'rest' | 'universal_rest' | 'custom';
11
+ export type VectorDBProvider = 'pinecone' | 'pgvector' | 'postgresql' | 'mongodb' | 'milvus' | 'qdrant' | 'chromadb' | 'redis' | 'weaviate' | 'rest' | 'universal_rest' | 'custom';
12
12
 
13
13
  export interface VectorDBConfig {
14
14
  /** Which vector database to use */
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { RagConfig } from './RagConfig';
9
9
 
10
- const VECTOR_DB_PROVIDERS = ['pinecone', 'pgvector', 'mongodb', 'rest', 'universal_rest', 'custom'] as const;
10
+ const VECTOR_DB_PROVIDERS = ['pinecone', 'pgvector', 'postgresql', 'mongodb', 'milvus', 'qdrant', 'chromadb', 'redis', 'weaviate', 'rest', 'universal_rest', 'custom'] as const;
11
11
  const LLM_PROVIDERS = ['openai', 'anthropic', 'ollama', 'rest', 'universal_rest', 'custom'] as const;
12
12
  const EMBEDDING_PROVIDERS = ['openai', 'ollama', 'rest', 'universal_rest', 'custom'] as const;
13
13
 
@@ -43,7 +43,7 @@ function readEnum<T extends readonly string[]>(
43
43
  }
44
44
 
45
45
  export function getRagConfig(env: Record<string, string | undefined> = process.env): RagConfig {
46
- const projectId = readString(env, 'RAG_PROJECT_ID') ?? readString(env, 'NEXT_PUBLIC_PROJECT_ID') ?? 'default';
46
+ const projectId = readString(env, 'RAG_PROJECT_ID') ?? readString(env, 'NEXT_PUBLIC_PROJECT_ID') ?? '__default__';
47
47
  const vectorProvider = readEnum(env, 'VECTOR_DB_PROVIDER', 'pinecone', VECTOR_DB_PROVIDERS);
48
48
  const llmProvider = readEnum(env, 'LLM_PROVIDER', 'openai', LLM_PROVIDERS);
49
49
  const embeddingProvider = readEnum(env, 'EMBEDDING_PROVIDER', 'openai', EMBEDDING_PROVIDERS);
@@ -0,0 +1,69 @@
1
+ import { RagConfig } from '../config/RagConfig';
2
+ import { mergeDefined } from '../utils/templateUtils';
3
+ import { getRagConfig as getEnvConfig } from '../config/serverConfig';
4
+
5
+ /**
6
+ * ConfigResolver — validates and normalizes host configuration.
7
+ * It merges host-provided config with environment defaults.
8
+ */
9
+ export class ConfigResolver {
10
+ /**
11
+ * Resolves the final configuration by merging host-provided config with defaults.
12
+ * @param hostConfig - Partial configuration passed from the host application.
13
+ */
14
+ static resolve(hostConfig?: Partial<RagConfig>): RagConfig {
15
+ const envConfig = getEnvConfig();
16
+
17
+ if (!hostConfig) {
18
+ return envConfig;
19
+ }
20
+
21
+ // Deep merge or specific merging logic
22
+ return {
23
+ ...envConfig,
24
+ ...hostConfig,
25
+ projectId: hostConfig.projectId || envConfig.projectId,
26
+ vectorDb: hostConfig.vectorDb ? {
27
+ ...envConfig.vectorDb,
28
+ ...hostConfig.vectorDb,
29
+ options: {
30
+ ...envConfig.vectorDb.options,
31
+ ...(hostConfig.vectorDb.options || {})
32
+ }
33
+ } : envConfig.vectorDb,
34
+ llm: hostConfig.llm ? {
35
+ ...envConfig.llm,
36
+ ...hostConfig.llm,
37
+ options: {
38
+ ...(envConfig.llm.options || {}),
39
+ ...(hostConfig.llm.options || {})
40
+ }
41
+ } : envConfig.llm,
42
+ embedding: hostConfig.embedding ? {
43
+ ...envConfig.embedding,
44
+ ...hostConfig.embedding,
45
+ options: {
46
+ ...(envConfig.embedding.options || {}),
47
+ ...(hostConfig.embedding.options || {})
48
+ }
49
+ } : envConfig.embedding,
50
+ ui: hostConfig.ui ? mergeDefined(envConfig.ui, hostConfig.ui) : envConfig.ui,
51
+ rag: hostConfig.rag ? { ...envConfig.rag, ...hostConfig.rag } : envConfig.rag,
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Validates the configuration for required fields.
57
+ */
58
+ static validate(config: RagConfig): void {
59
+ if (!config.projectId) {
60
+ throw new Error('[ConfigResolver] projectId is required');
61
+ }
62
+ if (!config.vectorDb.provider) {
63
+ throw new Error('[ConfigResolver] vectorDb.provider is required');
64
+ }
65
+ if (!config.llm.provider) {
66
+ throw new Error('[ConfigResolver] llm.provider is required');
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,109 @@
1
+ import { BaseVectorProvider } from '../providers/vectordb/BaseVectorProvider';
2
+ import { ILLMProvider, ChatMessage } from '../llm/ILLMProvider';
3
+ import { DocumentChunker } from '../rag/DocumentChunker';
4
+ import { RagConfig } from '../config/RagConfig';
5
+ import { VectorMatch } from '../types';
6
+ import { ProviderRegistry } from './ProviderRegistry';
7
+
8
+ export interface IngestDocument {
9
+ docId: string;
10
+ content: string;
11
+ metadata?: Record<string, unknown>;
12
+ }
13
+
14
+ export interface ChatResponse {
15
+ reply: string;
16
+ sources: VectorMatch[];
17
+ }
18
+
19
+ /**
20
+ * Pipeline — orchestrates the RAG flow: Embed → Search → Augment → Generate.
21
+ */
22
+ export class Pipeline {
23
+ private vectorDB!: BaseVectorProvider;
24
+ private llmProvider!: ILLMProvider;
25
+ private embeddingProvider!: ILLMProvider;
26
+ private chunker: DocumentChunker;
27
+ private config: RagConfig;
28
+ private initialised = false;
29
+
30
+ constructor(config: RagConfig) {
31
+ this.config = config;
32
+ this.chunker = new DocumentChunker(
33
+ config.rag?.chunkSize ?? 1000,
34
+ config.rag?.chunkOverlap ?? 200
35
+ );
36
+ }
37
+
38
+ async initialize(): Promise<void> {
39
+ if (this.initialised) return;
40
+
41
+ this.vectorDB = await ProviderRegistry.createVectorProvider(this.config.vectorDb);
42
+ this.llmProvider = ProviderRegistry.createLLMProvider(this.config.llm, this.config.embedding);
43
+
44
+ if (this.config.llm.provider === 'anthropic') {
45
+ // Logic for Anthropic as seen in RAGPipeline
46
+ const { LLMFactory } = await import('../llm/LLMFactory');
47
+ this.embeddingProvider = LLMFactory.createEmbeddingProvider(this.config.embedding);
48
+ } else {
49
+ this.embeddingProvider = this.llmProvider;
50
+ }
51
+
52
+ await this.vectorDB.initialize();
53
+ this.initialised = true;
54
+ }
55
+
56
+ async ingest(documents: IngestDocument[], namespace?: string): Promise<Array<{ docId: string; chunksIngested: number }>> {
57
+ await this.initialize();
58
+ const ns = namespace ?? this.config.projectId;
59
+ const results = [];
60
+
61
+ for (const doc of documents) {
62
+ const chunks = this.chunker.chunk(doc.content, {
63
+ docId: doc.docId,
64
+ metadata: doc.metadata,
65
+ });
66
+
67
+ const vectors = await this.embeddingProvider.batchEmbed(chunks.map(c => c.content));
68
+ const upsertDocs = chunks.map((chunk, i) => ({
69
+ id: chunk.id,
70
+ vector: vectors[i],
71
+ content: chunk.content,
72
+ metadata: chunk.metadata,
73
+ }));
74
+
75
+ await this.vectorDB.batchUpsert(upsertDocs, ns);
76
+ results.push({ docId: doc.docId, chunksIngested: chunks.length });
77
+ }
78
+ return results;
79
+ }
80
+
81
+ async ask(question: string, history: ChatMessage[] = [], namespace?: string): Promise<ChatResponse> {
82
+ await this.initialize();
83
+ const ns = namespace ?? this.config.projectId;
84
+ const topK = this.config.rag?.topK ?? 5;
85
+ const scoreThreshold = this.config.rag?.scoreThreshold ?? 0.0;
86
+
87
+ const queryVector = await this.embeddingProvider.embed(question);
88
+ const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
89
+
90
+ const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
91
+ const context = sources.length
92
+ ? sources.map((m, i) => `[Source ${i + 1}]\n${m.content}`).join('\n\n---\n\n')
93
+ : 'No relevant context found.';
94
+
95
+ const messages: ChatMessage[] = [...history, { role: 'user', content: question }];
96
+ const reply = await this.llmProvider.chat(messages, context);
97
+
98
+ return { reply, sources };
99
+ }
100
+
101
+ async health(): Promise<Record<string, boolean>> {
102
+ await this.initialize();
103
+ const [vectorDB, llm] = await Promise.all([
104
+ this.vectorDB.ping().catch(() => false),
105
+ this.llmProvider.ping().catch(() => false),
106
+ ]);
107
+ return { vectorDB, llm };
108
+ }
109
+ }
@@ -0,0 +1,71 @@
1
+ import { BaseVectorProvider } from '../providers/vectordb/BaseVectorProvider';
2
+ import { VectorDBConfig, LLMConfig, EmbeddingConfig } from '../config/RagConfig';
3
+ import { LLMFactory } from '../llm/LLMFactory';
4
+ import { ILLMProvider } from '../llm/ILLMProvider';
5
+
6
+ // We will import these as we create them
7
+ // import { PineconeProvider } from '../providers/vectordb/PineconeProvider';
8
+
9
+ /**
10
+ * ProviderRegistry — dynamic provider loader for Vector DBs and LLMs.
11
+ */
12
+ export class ProviderRegistry {
13
+ private static vectorProviders: Record<string, new (config: VectorDBConfig) => BaseVectorProvider> = {};
14
+
15
+ /**
16
+ * Register a custom vector provider.
17
+ */
18
+ static registerVectorProvider(name: string, providerClass: new (config: VectorDBConfig) => BaseVectorProvider) {
19
+ this.vectorProviders[name] = providerClass;
20
+ }
21
+
22
+ /**
23
+ * Creates a vector database provider based on the configuration.
24
+ */
25
+ static async createVectorProvider(config: VectorDBConfig): Promise<BaseVectorProvider> {
26
+ const { provider } = config;
27
+
28
+ // Check if we have a registered provider (dynamic loading)
29
+ if (this.vectorProviders[provider]) {
30
+ return new this.vectorProviders[provider](config);
31
+ }
32
+
33
+ // Fallback to internal switch for built-in providers
34
+ switch (provider) {
35
+ case 'pinecone':
36
+ const { PineconeProvider } = await import('../providers/vectordb/PineconeProvider');
37
+ return new PineconeProvider(config);
38
+ case 'pgvector':
39
+ case 'postgresql':
40
+ const { PostgreSQLProvider } = await import('../providers/vectordb/PostgreSQLProvider');
41
+ return new PostgreSQLProvider(config);
42
+ case 'mongodb':
43
+ const { MongoDBProvider } = await import('../providers/vectordb/MongoDBProvider');
44
+ return new MongoDBProvider(config);
45
+ case 'milvus':
46
+ const { MilvusProvider } = await import('../providers/vectordb/MilvusProvider');
47
+ return new MilvusProvider(config);
48
+ case 'qdrant':
49
+ const { QdrantProvider } = await import('../providers/vectordb/QdrantProvider');
50
+ return new QdrantProvider(config);
51
+ case 'chromadb':
52
+ const { ChromaDBProvider } = await import('../providers/vectordb/ChromaDBProvider');
53
+ return new ChromaDBProvider(config);
54
+ case 'redis':
55
+ const { RedisProvider } = await import('../providers/vectordb/RedisProvider');
56
+ return new RedisProvider(config);
57
+ case 'weaviate':
58
+ const { WeaviateProvider } = await import('../providers/vectordb/WeaviateProvider');
59
+ return new WeaviateProvider(config);
60
+ default:
61
+ throw new Error(`[ProviderRegistry] Unsupported vector provider: ${provider}`);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Creates an LLM provider based on the configuration.
67
+ */
68
+ static createLLMProvider(llmConfig: LLMConfig, embeddingConfig?: EmbeddingConfig): ILLMProvider {
69
+ return LLMFactory.create(llmConfig, embeddingConfig);
70
+ }
71
+ }
@@ -0,0 +1,51 @@
1
+ import { RagConfig } from '../config/RagConfig';
2
+ import { ConfigResolver } from './ConfigResolver';
3
+ import { Pipeline, IngestDocument, ChatResponse } from './Pipeline';
4
+ import { ChatMessage } from '../llm/ILLMProvider';
5
+
6
+ /**
7
+ * VectorPlugin — main orchestrator class.
8
+ * This is the primary interface for host applications.
9
+ */
10
+ export class VectorPlugin {
11
+ private config: RagConfig;
12
+ private pipeline: Pipeline;
13
+
14
+ /**
15
+ * Initializes the plugin with the host configuration.
16
+ * @param hostConfig - Configuration object passed from the host application.
17
+ */
18
+ constructor(hostConfig?: Partial<RagConfig>) {
19
+ this.config = ConfigResolver.resolve(hostConfig);
20
+ ConfigResolver.validate(this.config);
21
+ this.pipeline = new Pipeline(this.config);
22
+ }
23
+
24
+ /**
25
+ * Get the current resolved configuration.
26
+ */
27
+ getConfig(): RagConfig {
28
+ return this.config;
29
+ }
30
+
31
+ /**
32
+ * Run a chat query.
33
+ */
34
+ async chat(message: string, history: ChatMessage[] = [], namespace?: string): Promise<ChatResponse> {
35
+ return this.pipeline.ask(message, history, namespace);
36
+ }
37
+
38
+ /**
39
+ * Ingest documents into the vector database.
40
+ */
41
+ async ingest(documents: IngestDocument[], namespace?: string): Promise<Array<{ docId: string; chunksIngested: number }>> {
42
+ return this.pipeline.ingest(documents, namespace);
43
+ }
44
+
45
+ /**
46
+ * Check the health of the connected providers.
47
+ */
48
+ async health(): Promise<Record<string, boolean>> {
49
+ return this.pipeline.health();
50
+ }
51
+ }