@retrivora-ai/rag-engine 0.1.3 → 0.1.5
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/dist/ChromaDBProvider-QNI7UCX4.mjs +8 -0
- package/dist/DocumentChunker-cfaMidtA.d.mts +93 -0
- package/dist/DocumentChunker-cfaMidtA.d.ts +93 -0
- package/dist/LLMFactory-JFOY2V4X.mjs +8 -0
- package/dist/MilvusProvider-OO6QGZDZ.mjs +8 -0
- package/dist/MongoDBProvider-WWVJG3WT.mjs +8 -0
- package/dist/PineconeProvider-NJ675H7U.mjs +8 -0
- package/dist/PostgreSQLProvider-ISNMD3BE.mjs +8 -0
- package/dist/QdrantProvider-LJWOIGES.mjs +8 -0
- package/dist/RagConfig-DG_0f8ka.d.mts +145 -0
- package/dist/RagConfig-DG_0f8ka.d.ts +145 -0
- package/dist/RedisProvider-ASONNYBI.mjs +8 -0
- package/dist/WeaviateProvider-PSDCUGC7.mjs +8 -0
- package/dist/chunk-6FODXNUF.mjs +91 -0
- package/dist/chunk-7NXI6ZWX.mjs +89 -0
- package/dist/chunk-AALIF3AL.mjs +91 -0
- package/dist/chunk-BP4U4TT5.mjs +548 -0
- package/dist/chunk-HUGLYKD6.mjs +84 -0
- package/dist/chunk-I4E63NIC.mjs +24 -0
- package/dist/chunk-JI6VD5TJ.mjs +387 -0
- package/dist/chunk-QEYVWVT5.mjs +102 -0
- package/dist/chunk-S5DRHETN.mjs +110 -0
- package/dist/{chunk-ZPXLQR5Q.mjs → chunk-UKDXCXW7.mjs} +5 -23
- package/dist/chunk-V75V7BT2.mjs +117 -0
- package/dist/chunk-VOIWNO5O.mjs +11 -0
- package/dist/chunk-VPNRDXIA.mjs +74 -0
- package/dist/handlers/index.d.mts +9 -33
- package/dist/handlers/index.d.ts +9 -33
- package/dist/handlers/index.js +1477 -962
- package/dist/handlers/index.mjs +4 -2
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -2
- package/dist/index.mjs +4 -2
- package/dist/server.d.mts +220 -53
- package/dist/server.d.ts +220 -53
- package/dist/server.js +1531 -1099
- package/dist/server.mjs +55 -131
- package/package.json +19 -2
- package/src/app/page.tsx +1 -1
- package/src/components/MessageBubble.tsx +1 -1
- package/src/components/SourceCard.tsx +1 -1
- package/src/config/RagConfig.ts +1 -1
- package/src/config/serverConfig.ts +2 -2
- package/src/core/ConfigResolver.ts +69 -0
- package/src/core/Pipeline.ts +101 -0
- package/src/core/ProviderRegistry.ts +71 -0
- package/src/core/VectorPlugin.ts +52 -0
- package/src/handlers/index.ts +21 -100
- package/src/hooks/useRagChat.ts +1 -1
- package/src/index.ts +2 -6
- package/src/providers/vectordb/BaseVectorProvider.ts +61 -0
- package/src/providers/vectordb/ChromaDBProvider.ts +94 -0
- package/src/providers/vectordb/MilvusProvider.ts +100 -0
- package/src/providers/vectordb/MongoDBProvider.ts +118 -0
- package/src/{vectordb/adapters/PineconeAdapter.ts → providers/vectordb/PineconeProvider.ts} +21 -56
- package/src/{vectordb/adapters/PgVectorAdapter.ts → providers/vectordb/PostgreSQLProvider.ts} +23 -58
- package/src/providers/vectordb/QdrantProvider.ts +95 -0
- package/src/providers/vectordb/RedisProvider.ts +84 -0
- package/src/providers/vectordb/WeaviateProvider.ts +124 -0
- package/src/server.ts +16 -8
- package/src/test-refactor.ts +59 -0
- package/src/types/index.ts +24 -0
- package/src/utils/templateUtils.ts +6 -6
- package/dist/DocumentChunker-BUrIrcPk.d.mts +0 -43
- package/dist/DocumentChunker-BUrIrcPk.d.ts +0 -43
- package/dist/RAGPipeline-BmkIv1HD.d.mts +0 -298
- package/dist/RAGPipeline-BmkIv1HD.d.ts +0 -298
- package/dist/chunk-NVOMLHXW.mjs +0 -1259
- package/src/rag/RAGPipeline.ts +0 -200
- package/src/vectordb/IVectorDB.ts +0 -75
- package/src/vectordb/VectorDBFactory.ts +0 -41
- package/src/vectordb/adapters/MongoDbAdapter.ts +0 -175
- package/src/vectordb/adapters/UniversalVectorDBAdapter.ts +0 -177
package/dist/server.mjs
CHANGED
|
@@ -1,145 +1,69 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
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 {
|
|
14
|
+
ConfigResolver,
|
|
3
15
|
DocumentChunker,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
OpenAIProvider,
|
|
8
|
-
PgVectorAdapter,
|
|
9
|
-
PineconeAdapter,
|
|
10
|
-
RAGPipeline,
|
|
11
|
-
VectorDBFactory,
|
|
16
|
+
Pipeline,
|
|
17
|
+
ProviderRegistry,
|
|
18
|
+
VectorPlugin,
|
|
12
19
|
createChatHandler,
|
|
13
20
|
createHealthHandler,
|
|
14
21
|
createIngestHandler,
|
|
15
|
-
createUploadHandler
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
}
|
|
22
|
+
createUploadHandler,
|
|
23
|
+
getRagConfig
|
|
24
|
+
} from "./chunk-BP4U4TT5.mjs";
|
|
25
|
+
import {
|
|
26
|
+
AnthropicProvider,
|
|
27
|
+
LLMFactory,
|
|
28
|
+
OllamaProvider,
|
|
29
|
+
OpenAIProvider
|
|
30
|
+
} from "./chunk-JI6VD5TJ.mjs";
|
|
31
|
+
import "./chunk-UKDXCXW7.mjs";
|
|
32
|
+
import {
|
|
33
|
+
PineconeProvider
|
|
34
|
+
} from "./chunk-AALIF3AL.mjs";
|
|
35
|
+
import {
|
|
36
|
+
PostgreSQLProvider
|
|
37
|
+
} from "./chunk-S5DRHETN.mjs";
|
|
38
|
+
import {
|
|
39
|
+
MongoDBProvider
|
|
40
|
+
} from "./chunk-QEYVWVT5.mjs";
|
|
41
|
+
import {
|
|
42
|
+
MilvusProvider
|
|
43
|
+
} from "./chunk-7NXI6ZWX.mjs";
|
|
44
|
+
import {
|
|
45
|
+
BaseVectorProvider
|
|
46
|
+
} from "./chunk-VOIWNO5O.mjs";
|
|
47
|
+
import "./chunk-I4E63NIC.mjs";
|
|
132
48
|
export {
|
|
133
49
|
AnthropicProvider,
|
|
50
|
+
BaseVectorProvider,
|
|
51
|
+
ChromaDBProvider,
|
|
52
|
+
ConfigResolver,
|
|
134
53
|
DocumentChunker,
|
|
135
54
|
LLMFactory,
|
|
136
|
-
|
|
55
|
+
MilvusProvider,
|
|
56
|
+
MongoDBProvider,
|
|
137
57
|
OllamaProvider,
|
|
138
58
|
OpenAIProvider,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
59
|
+
PineconeProvider,
|
|
60
|
+
Pipeline,
|
|
61
|
+
PostgreSQLProvider,
|
|
62
|
+
ProviderRegistry,
|
|
63
|
+
QdrantProvider,
|
|
64
|
+
RedisProvider,
|
|
65
|
+
VectorPlugin,
|
|
66
|
+
WeaviateProvider,
|
|
143
67
|
createChatHandler,
|
|
144
68
|
createHealthHandler,
|
|
145
69
|
createIngestHandler,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
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",
|
|
@@ -38,6 +38,23 @@
|
|
|
38
38
|
"import": "./dist/server.mjs"
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
|
+
"browser": {
|
|
42
|
+
"child_process": false,
|
|
43
|
+
"fs": false,
|
|
44
|
+
"net": false,
|
|
45
|
+
"tls": false,
|
|
46
|
+
"crypto": false,
|
|
47
|
+
"os": false,
|
|
48
|
+
"path": false,
|
|
49
|
+
"stream": false,
|
|
50
|
+
"http": false,
|
|
51
|
+
"https": false,
|
|
52
|
+
"zlib": false,
|
|
53
|
+
"mongodb": false,
|
|
54
|
+
"pg": false,
|
|
55
|
+
"pdf-parse": false,
|
|
56
|
+
"mammoth": false
|
|
57
|
+
},
|
|
41
58
|
"files": [
|
|
42
59
|
"dist",
|
|
43
60
|
"src",
|
|
@@ -47,7 +64,7 @@
|
|
|
47
64
|
"scripts": {
|
|
48
65
|
"dev": "next dev",
|
|
49
66
|
"build": "next build",
|
|
50
|
-
"build:pkg": "tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --dts --clean --tsconfig tsconfig.build.json --external react,react-dom,next",
|
|
67
|
+
"build:pkg": "tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --dts --clean --tsconfig tsconfig.build.json --external react,react-dom,next,mongodb,pg,openai,@anthropic-ai/sdk,@pinecone-database/pinecone,axios,lucide-react,mammoth,pdf-parse,react-markdown,remark-gfm,next-themes",
|
|
51
68
|
"start": "next start",
|
|
52
69
|
"lint": "eslint",
|
|
53
70
|
"prepublishOnly": "npm run build:pkg"
|
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
|
|
481
|
+
<span>NEXT_PUBLIC_UI_TITLE="AI Assistant"</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 '@/
|
|
8
|
+
import { VectorMatch } from '@/types';
|
|
9
9
|
import { SourceCard } from './SourceCard';
|
|
10
10
|
|
|
11
11
|
interface MessageBubbleProps {
|
package/src/config/RagConfig.ts
CHANGED
|
@@ -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') ?? '
|
|
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,101 @@
|
|
|
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
|
+
// Moved to src/types/index.ts
|
|
9
|
+
import { IngestDocument, ChatResponse } from '../types';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Pipeline — orchestrates the RAG flow: Embed → Search → Augment → Generate.
|
|
13
|
+
*/
|
|
14
|
+
export class Pipeline {
|
|
15
|
+
private vectorDB!: BaseVectorProvider;
|
|
16
|
+
private llmProvider!: ILLMProvider;
|
|
17
|
+
private embeddingProvider!: ILLMProvider;
|
|
18
|
+
private chunker: DocumentChunker;
|
|
19
|
+
private config: RagConfig;
|
|
20
|
+
private initialised = false;
|
|
21
|
+
|
|
22
|
+
constructor(config: RagConfig) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.chunker = new DocumentChunker(
|
|
25
|
+
config.rag?.chunkSize ?? 1000,
|
|
26
|
+
config.rag?.chunkOverlap ?? 200
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async initialize(): Promise<void> {
|
|
31
|
+
if (this.initialised) return;
|
|
32
|
+
|
|
33
|
+
this.vectorDB = await ProviderRegistry.createVectorProvider(this.config.vectorDb);
|
|
34
|
+
this.llmProvider = ProviderRegistry.createLLMProvider(this.config.llm, this.config.embedding);
|
|
35
|
+
|
|
36
|
+
if (this.config.llm.provider === 'anthropic') {
|
|
37
|
+
// Logic for Anthropic as seen in RAGPipeline
|
|
38
|
+
const { LLMFactory } = await import('../llm/LLMFactory');
|
|
39
|
+
this.embeddingProvider = LLMFactory.createEmbeddingProvider(this.config.embedding);
|
|
40
|
+
} else {
|
|
41
|
+
this.embeddingProvider = this.llmProvider;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await this.vectorDB.initialize();
|
|
45
|
+
this.initialised = true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async ingest(documents: IngestDocument[], namespace?: string): Promise<Array<{ docId: string; chunksIngested: number }>> {
|
|
49
|
+
await this.initialize();
|
|
50
|
+
const ns = namespace ?? this.config.projectId;
|
|
51
|
+
const results = [];
|
|
52
|
+
|
|
53
|
+
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 });
|
|
69
|
+
}
|
|
70
|
+
return results;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async ask(question: string, history: ChatMessage[] = [], namespace?: string): Promise<ChatResponse> {
|
|
74
|
+
await this.initialize();
|
|
75
|
+
const ns = namespace ?? this.config.projectId;
|
|
76
|
+
const topK = this.config.rag?.topK ?? 5;
|
|
77
|
+
const scoreThreshold = this.config.rag?.scoreThreshold ?? 0.0;
|
|
78
|
+
|
|
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 };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -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,52 @@
|
|
|
1
|
+
import { RagConfig } from '../config/RagConfig';
|
|
2
|
+
import { ConfigResolver } from './ConfigResolver';
|
|
3
|
+
import { Pipeline } from './Pipeline';
|
|
4
|
+
import { IngestDocument, ChatResponse } from '../types';
|
|
5
|
+
import { ChatMessage } from '../llm/ILLMProvider';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* VectorPlugin — main orchestrator class.
|
|
9
|
+
* This is the primary interface for host applications.
|
|
10
|
+
*/
|
|
11
|
+
export class VectorPlugin {
|
|
12
|
+
private config: RagConfig;
|
|
13
|
+
private pipeline: Pipeline;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Initializes the plugin with the host configuration.
|
|
17
|
+
* @param hostConfig - Configuration object passed from the host application.
|
|
18
|
+
*/
|
|
19
|
+
constructor(hostConfig?: Partial<RagConfig>) {
|
|
20
|
+
this.config = ConfigResolver.resolve(hostConfig);
|
|
21
|
+
ConfigResolver.validate(this.config);
|
|
22
|
+
this.pipeline = new Pipeline(this.config);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the current resolved configuration.
|
|
27
|
+
*/
|
|
28
|
+
getConfig(): RagConfig {
|
|
29
|
+
return this.config;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Run a chat query.
|
|
34
|
+
*/
|
|
35
|
+
async chat(message: string, history: ChatMessage[] = [], namespace?: string): Promise<ChatResponse> {
|
|
36
|
+
return this.pipeline.ask(message, history, namespace);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Ingest documents into the vector database.
|
|
41
|
+
*/
|
|
42
|
+
async ingest(documents: IngestDocument[], namespace?: string): Promise<Array<{ docId: string; chunksIngested: number }>> {
|
|
43
|
+
return this.pipeline.ingest(documents, namespace);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check the health of the connected providers.
|
|
48
|
+
*/
|
|
49
|
+
async health(): Promise<Record<string, boolean>> {
|
|
50
|
+
return this.pipeline.health();
|
|
51
|
+
}
|
|
52
|
+
}
|