@retrivora-ai/rag-engine 0.1.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/.env.example +77 -0
- package/README.md +149 -0
- package/dist/DocumentChunker-BUrIrcPk.d.mts +43 -0
- package/dist/DocumentChunker-BUrIrcPk.d.ts +43 -0
- package/dist/RAGPipeline-BmkIv1HD.d.mts +298 -0
- package/dist/RAGPipeline-BmkIv1HD.d.ts +298 -0
- package/dist/chunk-NCG2JKXB.mjs +1254 -0
- package/dist/chunk-ZPXLQR5Q.mjs +67 -0
- package/dist/handlers/index.d.mts +68 -0
- package/dist/handlers/index.d.ts +68 -0
- package/dist/handlers/index.js +1319 -0
- package/dist/handlers/index.mjs +13 -0
- package/dist/index.d.mts +93 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +612 -0
- package/dist/index.mjs +551 -0
- package/dist/server.d.mts +211 -0
- package/dist/server.d.ts +211 -0
- package/dist/server.js +1457 -0
- package/dist/server.mjs +148 -0
- package/package.json +90 -0
- package/src/app/api/chat/route.ts +4 -0
- package/src/app/api/health/route.ts +4 -0
- package/src/app/api/ingest/route.ts +26 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +163 -0
- package/src/app/layout.tsx +35 -0
- package/src/app/page.tsx +506 -0
- package/src/components/ChatWidget.tsx +91 -0
- package/src/components/ChatWindow.tsx +248 -0
- package/src/components/ConfigProvider.tsx +56 -0
- package/src/components/MessageBubble.tsx +99 -0
- package/src/components/SourceCard.tsx +66 -0
- package/src/components/ThemeProvider.tsx +8 -0
- package/src/components/ThemeToggle.tsx +29 -0
- package/src/config/RagConfig.ts +159 -0
- package/src/config/UniversalProfiles.ts +83 -0
- package/src/config/serverConfig.ts +142 -0
- package/src/handlers/index.ts +202 -0
- package/src/hooks/useHydrated.ts +13 -0
- package/src/hooks/useRagChat.ts +167 -0
- package/src/hooks/useStoredMessages.ts +53 -0
- package/src/index.ts +27 -0
- package/src/llm/ILLMProvider.ts +60 -0
- package/src/llm/LLMFactory.ts +54 -0
- package/src/llm/providers/AnthropicProvider.ts +87 -0
- package/src/llm/providers/OllamaProvider.ts +102 -0
- package/src/llm/providers/OpenAIProvider.ts +92 -0
- package/src/llm/providers/UniversalLLMAdapter.ts +154 -0
- package/src/rag/DocumentChunker.ts +105 -0
- package/src/rag/RAGPipeline.ts +196 -0
- package/src/server.ts +30 -0
- package/src/types/pdf-parse.d.ts +13 -0
- package/src/utils/DocumentParser.ts +75 -0
- package/src/utils/templateUtils.ts +78 -0
- package/src/vectordb/IVectorDB.ts +75 -0
- package/src/vectordb/VectorDBFactory.ts +41 -0
- package/src/vectordb/adapters/MongoDbAdapter.ts +175 -0
- package/src/vectordb/adapters/PgVectorAdapter.ts +159 -0
- package/src/vectordb/adapters/PineconeAdapter.ts +115 -0
- package/src/vectordb/adapters/UniversalVectorDBAdapter.ts +177 -0
package/.env.example
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# ─── Project ─────────────────────────────────────────────────
|
|
2
|
+
RAG_PROJECT_ID=my-project
|
|
3
|
+
|
|
4
|
+
# ─── Vector Database ──────────────────────────────────────────
|
|
5
|
+
# Choose: pinecone | pgvector | rest | universal_rest
|
|
6
|
+
VECTOR_DB_PROVIDER=pinecone
|
|
7
|
+
VECTOR_DB_INDEX=rag-index
|
|
8
|
+
|
|
9
|
+
# Pinecone (if provider=pinecone)
|
|
10
|
+
PINECONE_API_KEY=your-pinecone-api-key
|
|
11
|
+
PINECONE_ENVIRONMENT=us-east-1
|
|
12
|
+
|
|
13
|
+
# pgVector (if provider=pgvector)
|
|
14
|
+
PGVECTOR_CONNECTION_STRING=postgresql://user:password@localhost:5432/ragdb
|
|
15
|
+
|
|
16
|
+
# Generic REST (if provider=rest)
|
|
17
|
+
VECTOR_DB_REST_URL=http://localhost:8080
|
|
18
|
+
VECTOR_DB_REST_API_KEY=your-rest-api-key
|
|
19
|
+
# VECTOR_DB_QUERY_PATH=/query
|
|
20
|
+
# VECTOR_DB_UPSERT_PATH=/upsert
|
|
21
|
+
|
|
22
|
+
# ─── LLM ──────────────────────────────────────────────────────
|
|
23
|
+
# Choose: openai | anthropic | ollama | universal_rest
|
|
24
|
+
LLM_PROVIDER=openai
|
|
25
|
+
LLM_MODEL=gpt-4o
|
|
26
|
+
LLM_MAX_TOKENS=1024
|
|
27
|
+
LLM_TEMPERATURE=0.7
|
|
28
|
+
LLM_SYSTEM_PROMPT=You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
29
|
+
|
|
30
|
+
# OpenAI (if provider=openai)
|
|
31
|
+
OPENAI_API_KEY=sk-...
|
|
32
|
+
|
|
33
|
+
# Anthropic (if provider=anthropic)
|
|
34
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
35
|
+
|
|
36
|
+
# Ollama (if provider=ollama)
|
|
37
|
+
LLM_BASE_URL=http://localhost:11434
|
|
38
|
+
|
|
39
|
+
# ── Master Universal Provider (LiteLLM, Qdrant, etc.) ─────────
|
|
40
|
+
# Use 'universal_rest' for ANY model or DB via pre-set profiles.
|
|
41
|
+
LLM_PROVIDER=universal_rest
|
|
42
|
+
LLM_MODEL=gpt-4o
|
|
43
|
+
# Profile: litellm | ollama-standard | openai-compatible
|
|
44
|
+
LLM_UNIVERSAL_PROFILE=litellm
|
|
45
|
+
LLM_BASE_URL=https://proxy.example.com/api
|
|
46
|
+
LLM_API_KEY=your-key
|
|
47
|
+
|
|
48
|
+
VECTOR_DB_PROVIDER=universal_rest
|
|
49
|
+
# Profile: qdrant | chromadb
|
|
50
|
+
VECTOR_UNIVERSAL_PROFILE=qdrant
|
|
51
|
+
VECTOR_BASE_URL=http://localhost:6333
|
|
52
|
+
VECTOR_DB_INDEX=my-index
|
|
53
|
+
|
|
54
|
+
# ─── Embedding ────────────────────────────────────────────────
|
|
55
|
+
# Choose: openai | ollama | custom
|
|
56
|
+
EMBEDDING_PROVIDER=openai
|
|
57
|
+
EMBEDDING_MODEL=text-embedding-3-small
|
|
58
|
+
EMBEDDING_DIMENSIONS=1536
|
|
59
|
+
# EMBEDDING_BASE_URL=http://localhost:11434 # for ollama
|
|
60
|
+
# EMBEDDING_API_KEY=your-embedding-key # for custom embedding endpoints
|
|
61
|
+
|
|
62
|
+
# ─── RAG Pipeline Tuning ──────────────────────────────────────
|
|
63
|
+
RAG_TOP_K=5
|
|
64
|
+
RAG_SCORE_THRESHOLD=0.0
|
|
65
|
+
RAG_CHUNK_SIZE=1000
|
|
66
|
+
RAG_CHUNK_OVERLAP=200
|
|
67
|
+
|
|
68
|
+
# ─── UI Branding (NEXT_PUBLIC_ = safe to expose to browser) ───
|
|
69
|
+
NEXT_PUBLIC_PROJECT_ID=my-project
|
|
70
|
+
NEXT_PUBLIC_UI_TITLE=AI Assistant
|
|
71
|
+
NEXT_PUBLIC_UI_SUBTITLE=Powered by RAG
|
|
72
|
+
NEXT_PUBLIC_PRIMARY_COLOR=#6366f1
|
|
73
|
+
NEXT_PUBLIC_ACCENT_COLOR=#8b5cf6
|
|
74
|
+
NEXT_PUBLIC_PLACEHOLDER=Ask me anything…
|
|
75
|
+
NEXT_PUBLIC_SHOW_SOURCES=true
|
|
76
|
+
NEXT_PUBLIC_WELCOME_MESSAGE=Hello! I'm your AI assistant. Ask me anything about your documents.
|
|
77
|
+
# NEXT_PUBLIC_LOGO_URL=https://your-domain.com/logo.png
|
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# @abhinav1201/rag-ai-accelerator
|
|
2
|
+
|
|
3
|
+
> **Retrivora AI is a plug-and-play AI engine for RAG chat experiences** that can be embedded into Next.js apps or used as a standalone demo app. Bring your own vector database, LLM, embeddings, and UI branding.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@abhinav1201/rag-ai-accelerator)
|
|
6
|
+
[](https://www.npmjs.com/package/@abhinav1201/rag-ai-accelerator)
|
|
7
|
+
[](https://github.com/abhinav1201/ai-accelerator)
|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ✨ Features
|
|
14
|
+
|
|
15
|
+
| Category | Options |
|
|
16
|
+
|---|---|
|
|
17
|
+
| **Vector DBs** | Pinecone, pgVector (PostgreSQL), MongoDB Atlas, ChromaDB, Qdrant, universal REST adapters |
|
|
18
|
+
| **LLM Providers** | OpenAI, Anthropic Claude, Google Gemini, Ollama, LiteLLM, universal REST adapters |
|
|
19
|
+
| **Document Ingestion** | Universal support for **PDF**, **DOCX**, **CSV**, **JSON**, **MD**, **TXT** |
|
|
20
|
+
| **UI** | Full-page `ChatWindow` + floating `ChatWidget`, fully branded & responsive |
|
|
21
|
+
| **RAG** | Configurable chunk size/overlap, top-K retrieval, score threshold, namespaced multi-tenancy |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🚀 How it Works
|
|
26
|
+
|
|
27
|
+
Retrivora AI acts as a universal bridge between your data and your users. It normalizes different AI providers and Vector databases into a single interface.
|
|
28
|
+
|
|
29
|
+
1. **Ingest**: Upload or send documents to the `/api/upload` endpoint. They are automatically parsed, chunked, and embedded.
|
|
30
|
+
2. **Retrieve**: When a user asks a question, the system converts it to a vector and searches your configured database.
|
|
31
|
+
3. **Generate**: The retrieved context is combined with the user query and sent to your configured LLM (OpenAI, Claude, etc.) to generate a grounded response.
|
|
32
|
+
|
|
33
|
+
### 📦 How to Install
|
|
34
|
+
|
|
35
|
+
To integrate Retrivora AI into your existing Next.js project, simply run:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @abhinav1201/rag-ai-accelerator
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Alternatively, if you want to run the standalone demo application:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/abhinav1201/ai-accelerator
|
|
45
|
+
cd ai-accelerator
|
|
46
|
+
npm install
|
|
47
|
+
cp .env.example .env.local
|
|
48
|
+
# Fill in your API keys in .env.local
|
|
49
|
+
npm run dev
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## NPM Package Usage
|
|
55
|
+
|
|
56
|
+
### 1. Embed the ChatWidget
|
|
57
|
+
|
|
58
|
+
Wrap your application in the `ConfigProvider` and add the `ChatWidget`.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { ConfigProvider, ChatWidget } from '@abhinav1201/rag-ai-accelerator';
|
|
62
|
+
|
|
63
|
+
export default function Layout({ children }) {
|
|
64
|
+
return (
|
|
65
|
+
<ConfigProvider
|
|
66
|
+
config={{
|
|
67
|
+
projectId: 'my-project',
|
|
68
|
+
ui: {
|
|
69
|
+
title: 'Support Bot',
|
|
70
|
+
primaryColor: '#6366f1',
|
|
71
|
+
accentColor: '#8b5cf6',
|
|
72
|
+
welcomeMessage: 'Hi! How can I help you today?',
|
|
73
|
+
},
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
{children}
|
|
77
|
+
<ChatWidget position="bottom-right" />
|
|
78
|
+
</ConfigProvider>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. Mount the API routes
|
|
84
|
+
|
|
85
|
+
Create standard Next.js route handlers and plug in the library's factories.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
// src/app/api/chat/route.ts
|
|
89
|
+
import { createChatHandler, getRagConfig } from '@abhinav1201/rag-ai-accelerator/server';
|
|
90
|
+
export const POST = createChatHandler(getRagConfig());
|
|
91
|
+
|
|
92
|
+
// src/app/api/upload/route.ts (Handles PDF, DOCX, etc.)
|
|
93
|
+
import { createUploadHandler, getRagConfig } from '@abhinav1201/rag-ai-accelerator/server';
|
|
94
|
+
export const POST = createUploadHandler(getRagConfig());
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. Use RAGPipeline programmatically
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { RAGPipeline } from '@abhinav1201/rag-ai-accelerator/server';
|
|
101
|
+
|
|
102
|
+
const pipeline = new RAGPipeline(config);
|
|
103
|
+
await pipeline.ingest([{ docId: 'readme', content: 'Your document text here' }]);
|
|
104
|
+
const { reply, sources } = await pipeline.ask('What is the refund policy?');
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Configuration Reference
|
|
110
|
+
|
|
111
|
+
The library is entirely dynamic. You can switch between providers simply by updating your environment variables.
|
|
112
|
+
|
|
113
|
+
| Variable | Description |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `RAG_PROJECT_ID` | Project namespace for data isolation |
|
|
116
|
+
| `VECTOR_DB_PROVIDER` | `pinecone`, `pgvector`, `mongodb`, or `universal_rest` |
|
|
117
|
+
| `VECTOR_UNIVERSAL_PROFILE` | `pinecone-rest`, `mongodb-atlas`, `chromadb`, `qdrant` |
|
|
118
|
+
| `LLM_PROVIDER` | `openai`, `anthropic`, `ollama`, or `universal_rest` |
|
|
119
|
+
| `LLM_UNIVERSAL_PROFILE` | `openai-compatible`, `litellm`, `anthropic-claude`, `google-gemini` |
|
|
120
|
+
| `EMBEDDING_PROVIDER` | `openai`, `ollama`, or `rest` |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Architecture
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
User Query
|
|
128
|
+
|
|
|
129
|
+
v
|
|
130
|
+
[embed query] <-- EmbeddingProvider (OpenAI / Ollama / Custom)
|
|
131
|
+
|
|
|
132
|
+
v
|
|
133
|
+
[vector search] <-- IVectorDB (Pinecone / pgVector / MongoDB / Chroma / REST)
|
|
134
|
+
|
|
|
135
|
+
v
|
|
136
|
+
[build context]
|
|
137
|
+
|
|
|
138
|
+
v
|
|
139
|
+
[LLM chat] <-- ILLMProvider (OpenAI / Anthropic / Gemini / LiteLLM)
|
|
140
|
+
|
|
|
141
|
+
v
|
|
142
|
+
ChatResponse { reply, sources[] }
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## License
|
|
148
|
+
|
|
149
|
+
MIT - GSPANN Technologies
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentChunker — splits long text into overlapping chunks
|
|
3
|
+
* suitable for vector embedding and retrieval.
|
|
4
|
+
*
|
|
5
|
+
* Strategy: sentence-aware sliding window
|
|
6
|
+
* 1. Split on sentence boundaries
|
|
7
|
+
* 2. Accumulate sentences into chunks up to `chunkSize` characters
|
|
8
|
+
* 3. Carry over `chunkOverlap` characters from the previous chunk
|
|
9
|
+
*/
|
|
10
|
+
interface Chunk {
|
|
11
|
+
id: string;
|
|
12
|
+
content: string;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
interface ChunkOptions {
|
|
16
|
+
/** Target chunk size in characters (default 1000) */
|
|
17
|
+
chunkSize?: number;
|
|
18
|
+
/** Overlap between consecutive chunks in characters (default 200) */
|
|
19
|
+
chunkOverlap?: number;
|
|
20
|
+
/** Source document identifier used as ID prefix */
|
|
21
|
+
docId?: string;
|
|
22
|
+
/** Extra metadata to attach to every chunk */
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
declare class DocumentChunker {
|
|
26
|
+
private readonly chunkSize;
|
|
27
|
+
private readonly chunkOverlap;
|
|
28
|
+
constructor(chunkSize?: number, chunkOverlap?: number);
|
|
29
|
+
/**
|
|
30
|
+
* Split a single text string into overlapping chunks.
|
|
31
|
+
*/
|
|
32
|
+
chunk(text: string, options?: ChunkOptions): Chunk[];
|
|
33
|
+
/**
|
|
34
|
+
* Chunk multiple documents at once.
|
|
35
|
+
*/
|
|
36
|
+
chunkMany(documents: Array<{
|
|
37
|
+
content: string;
|
|
38
|
+
docId?: string;
|
|
39
|
+
metadata?: Record<string, unknown>;
|
|
40
|
+
}>): Chunk[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { type Chunk as C, DocumentChunker as D, type ChunkOptions as a };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentChunker — splits long text into overlapping chunks
|
|
3
|
+
* suitable for vector embedding and retrieval.
|
|
4
|
+
*
|
|
5
|
+
* Strategy: sentence-aware sliding window
|
|
6
|
+
* 1. Split on sentence boundaries
|
|
7
|
+
* 2. Accumulate sentences into chunks up to `chunkSize` characters
|
|
8
|
+
* 3. Carry over `chunkOverlap` characters from the previous chunk
|
|
9
|
+
*/
|
|
10
|
+
interface Chunk {
|
|
11
|
+
id: string;
|
|
12
|
+
content: string;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
interface ChunkOptions {
|
|
16
|
+
/** Target chunk size in characters (default 1000) */
|
|
17
|
+
chunkSize?: number;
|
|
18
|
+
/** Overlap between consecutive chunks in characters (default 200) */
|
|
19
|
+
chunkOverlap?: number;
|
|
20
|
+
/** Source document identifier used as ID prefix */
|
|
21
|
+
docId?: string;
|
|
22
|
+
/** Extra metadata to attach to every chunk */
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
declare class DocumentChunker {
|
|
26
|
+
private readonly chunkSize;
|
|
27
|
+
private readonly chunkOverlap;
|
|
28
|
+
constructor(chunkSize?: number, chunkOverlap?: number);
|
|
29
|
+
/**
|
|
30
|
+
* Split a single text string into overlapping chunks.
|
|
31
|
+
*/
|
|
32
|
+
chunk(text: string, options?: ChunkOptions): Chunk[];
|
|
33
|
+
/**
|
|
34
|
+
* Chunk multiple documents at once.
|
|
35
|
+
*/
|
|
36
|
+
chunkMany(documents: Array<{
|
|
37
|
+
content: string;
|
|
38
|
+
docId?: string;
|
|
39
|
+
metadata?: Record<string, unknown>;
|
|
40
|
+
}>): Chunk[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { type Chunk as C, DocumentChunker as D, type ChunkOptions as a };
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic LLM Provider interface.
|
|
3
|
+
* Covers both chat completion and embedding generation so a single
|
|
4
|
+
* provider can handle both responsibilities when appropriate.
|
|
5
|
+
*/
|
|
6
|
+
interface ChatMessage {
|
|
7
|
+
role: 'user' | 'assistant' | 'system';
|
|
8
|
+
content: string;
|
|
9
|
+
}
|
|
10
|
+
interface ChatOptions {
|
|
11
|
+
/** Override max tokens for this specific call */
|
|
12
|
+
maxTokens?: number;
|
|
13
|
+
/** Override temperature for this specific call */
|
|
14
|
+
temperature?: number;
|
|
15
|
+
/** Stop sequences */
|
|
16
|
+
stop?: string[];
|
|
17
|
+
}
|
|
18
|
+
interface EmbedOptions {
|
|
19
|
+
/** Override model for this specific embed call */
|
|
20
|
+
model?: string;
|
|
21
|
+
}
|
|
22
|
+
interface ILLMProvider {
|
|
23
|
+
/**
|
|
24
|
+
* Send a chat completion request.
|
|
25
|
+
* @param messages – the full conversation history
|
|
26
|
+
* @param context – retrieved RAG context to inject
|
|
27
|
+
* @param options – optional per-call overrides
|
|
28
|
+
* @returns – the assistant's reply text
|
|
29
|
+
*/
|
|
30
|
+
chat(messages: ChatMessage[], context: string, options?: ChatOptions): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Generate an embedding vector for the given text.
|
|
33
|
+
* @param text – text to embed
|
|
34
|
+
* @param options – optional overrides
|
|
35
|
+
* @returns – float array (the embedding)
|
|
36
|
+
*/
|
|
37
|
+
embed(text: string, options?: EmbedOptions): Promise<number[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Generate embedding vectors for multiple texts in a single batch.
|
|
40
|
+
* @param texts – array of texts to embed
|
|
41
|
+
* @param options – optional overrides
|
|
42
|
+
* @returns – array of float arrays
|
|
43
|
+
*/
|
|
44
|
+
batchEmbed(texts: string[], options?: EmbedOptions): Promise<number[][]>;
|
|
45
|
+
/**
|
|
46
|
+
* Check if the provider endpoint is reachable.
|
|
47
|
+
*/
|
|
48
|
+
ping(): Promise<boolean>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Generic Vector Database interface.
|
|
53
|
+
* Any adapter (Pinecone, pgVector, REST, Chroma, Qdrant, …) must implement this.
|
|
54
|
+
*/
|
|
55
|
+
interface VectorMatch {
|
|
56
|
+
/** Unique identifier of the stored chunk */
|
|
57
|
+
id: string;
|
|
58
|
+
/** Cosine or dot-product similarity score (0–1) */
|
|
59
|
+
score: number;
|
|
60
|
+
/** The original text content of the chunk */
|
|
61
|
+
content: string;
|
|
62
|
+
/** Arbitrary metadata attached at upsert time */
|
|
63
|
+
metadata?: Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
interface UpsertDocument {
|
|
66
|
+
id: string;
|
|
67
|
+
vector: number[];
|
|
68
|
+
content: string;
|
|
69
|
+
metadata?: Record<string, unknown>;
|
|
70
|
+
}
|
|
71
|
+
interface IVectorDB {
|
|
72
|
+
/**
|
|
73
|
+
* Initialise the connection (create tables, verify index, etc.)
|
|
74
|
+
* Called once during RAGPipeline construction.
|
|
75
|
+
*/
|
|
76
|
+
initialize(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Insert or update a single vector + content pair.
|
|
79
|
+
* @param namespace – optional project/tenant namespace
|
|
80
|
+
*/
|
|
81
|
+
upsert(doc: UpsertDocument, namespace?: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Batch upsert for efficient ingestion of many documents.
|
|
84
|
+
*/
|
|
85
|
+
batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Find the top-K most similar vectors to the query vector.
|
|
88
|
+
* @param vector – embedding of the user query
|
|
89
|
+
* @param topK – number of results to return
|
|
90
|
+
* @param namespace – optional project/tenant namespace
|
|
91
|
+
* @param filter – optional metadata filter (provider-specific shape)
|
|
92
|
+
*/
|
|
93
|
+
query(vector: number[], topK: number, namespace?: string, filter?: Record<string, unknown>): Promise<VectorMatch[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Delete a stored vector by ID.
|
|
96
|
+
*/
|
|
97
|
+
delete(id: string, namespace?: string): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Delete all vectors in a namespace (full data reset for a project).
|
|
100
|
+
*/
|
|
101
|
+
deleteNamespace(namespace: string): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Check if the underlying DB is reachable.
|
|
104
|
+
*/
|
|
105
|
+
ping(): Promise<boolean>;
|
|
106
|
+
/**
|
|
107
|
+
* Gracefully close the connection.
|
|
108
|
+
*/
|
|
109
|
+
disconnect(): Promise<void>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Master configuration interface for Retrivora AI.
|
|
114
|
+
* Each consuming project provides one RagConfig object to drive
|
|
115
|
+
* vector DB selection, LLM selection, embedding, and UI branding.
|
|
116
|
+
*/
|
|
117
|
+
type VectorDBProvider = 'pinecone' | 'pgvector' | 'mongodb' | 'rest' | 'universal_rest' | 'custom';
|
|
118
|
+
interface VectorDBConfig {
|
|
119
|
+
/** Which vector database to use */
|
|
120
|
+
provider: VectorDBProvider;
|
|
121
|
+
/** The index / table name to query */
|
|
122
|
+
indexName: string;
|
|
123
|
+
/** Provider-specific options (API keys, connection strings, etc.)
|
|
124
|
+
*
|
|
125
|
+
* For 'universal_rest', the following options are supported:
|
|
126
|
+
* - baseUrl: string
|
|
127
|
+
* - headers?: Record<string, string>
|
|
128
|
+
* - queryPath?: string
|
|
129
|
+
* - upsertPath?: string
|
|
130
|
+
* - queryPayloadTemplate?: string (e.g. '{"vector": {{vector}}, "limit": {{topK}}}')
|
|
131
|
+
* - upsertPayloadTemplate?: string (e.g. '{"id": "{{id}}", "vector": {{vector}}}')
|
|
132
|
+
* - responseExtractPath?: string (e.g. 'data.results')
|
|
133
|
+
* - idPath?: string (e.g. '_id')
|
|
134
|
+
* - scorePath?: string (e.g. 'similarity')
|
|
135
|
+
* - contentPath?: string (e.g. 'text')
|
|
136
|
+
*/
|
|
137
|
+
options: Record<string, unknown>;
|
|
138
|
+
}
|
|
139
|
+
type LLMProvider = 'openai' | 'anthropic' | 'ollama' | 'rest' | 'universal_rest' | 'custom';
|
|
140
|
+
interface LLMConfig {
|
|
141
|
+
/** Which LLM provider to use */
|
|
142
|
+
provider: LLMProvider;
|
|
143
|
+
/** Model name, e.g. "gpt-4o", "claude-3-opus-20240229", "llama3" */
|
|
144
|
+
model: string;
|
|
145
|
+
/** API key for cloud providers */
|
|
146
|
+
apiKey?: string;
|
|
147
|
+
/** Base URL — required for Ollama or self-hosted endpoints */
|
|
148
|
+
baseUrl?: string;
|
|
149
|
+
/** Custom system prompt injected before every chat */
|
|
150
|
+
systemPrompt?: string;
|
|
151
|
+
/** Max tokens in the LLM response */
|
|
152
|
+
maxTokens?: number;
|
|
153
|
+
/** Sampling temperature (0–1) */
|
|
154
|
+
temperature?: number;
|
|
155
|
+
/** Provider-specific options
|
|
156
|
+
*
|
|
157
|
+
* For 'universal_rest', the following options are supported:
|
|
158
|
+
* - headers?: Record<string, string>
|
|
159
|
+
* - chatPath?: string
|
|
160
|
+
* - chatPayloadTemplate?: string (e.g. '{"prompt": "{{prompt}}", "max_tokens": {{maxTokens}}}')
|
|
161
|
+
* - responseExtractPath?: string (e.g. 'choices[0].text' or 'response')
|
|
162
|
+
*/
|
|
163
|
+
options?: Record<string, unknown>;
|
|
164
|
+
}
|
|
165
|
+
type EmbeddingProvider = 'openai' | 'ollama' | 'rest' | 'universal_rest' | 'custom';
|
|
166
|
+
interface EmbeddingConfig {
|
|
167
|
+
/** Which embedding provider to use */
|
|
168
|
+
provider: EmbeddingProvider;
|
|
169
|
+
/** Model name, e.g. "text-embedding-ada-002", "nomic-embed-text" */
|
|
170
|
+
model: string;
|
|
171
|
+
/** API key (if needed) */
|
|
172
|
+
apiKey?: string;
|
|
173
|
+
/** Base URL for custom / Ollama embedding endpoints */
|
|
174
|
+
baseUrl?: string;
|
|
175
|
+
/** Output vector dimension — must match the index dimension */
|
|
176
|
+
dimensions?: number;
|
|
177
|
+
/** Provider-specific options for custom adapters */
|
|
178
|
+
options?: Record<string, unknown>;
|
|
179
|
+
}
|
|
180
|
+
interface UIConfig {
|
|
181
|
+
/** Title shown in the chat header */
|
|
182
|
+
title?: string;
|
|
183
|
+
/** Subtitle / description below the title */
|
|
184
|
+
subtitle?: string;
|
|
185
|
+
/** Primary brand colour (CSS colour string) */
|
|
186
|
+
primaryColor?: string;
|
|
187
|
+
/** Accent colour for user message bubbles */
|
|
188
|
+
accentColor?: string;
|
|
189
|
+
/** URL to a logo image */
|
|
190
|
+
logoUrl?: string;
|
|
191
|
+
/** Input placeholder text */
|
|
192
|
+
placeholder?: string;
|
|
193
|
+
/** Show source cards after each answer */
|
|
194
|
+
showSources?: boolean;
|
|
195
|
+
/** Welcome message shown on first load */
|
|
196
|
+
welcomeMessage?: string;
|
|
197
|
+
/** Whether to show the floating chat widget. Defaults to true. */
|
|
198
|
+
showWidget?: boolean;
|
|
199
|
+
/** Custom 'Powered by' text shown in the header */
|
|
200
|
+
poweredBy?: string;
|
|
201
|
+
/** Visual style: 'glass' (default) or 'solid' */
|
|
202
|
+
visualStyle?: 'glass' | 'solid';
|
|
203
|
+
/** Border radius: 'none', 'sm', 'md', 'lg', 'xl', 'full' */
|
|
204
|
+
borderRadius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
205
|
+
}
|
|
206
|
+
interface RAGConfig {
|
|
207
|
+
/** Number of top-K chunks retrieved per query */
|
|
208
|
+
topK?: number;
|
|
209
|
+
/** Minimum similarity score to include a chunk (0–1) */
|
|
210
|
+
scoreThreshold?: number;
|
|
211
|
+
/** Target chunk size in tokens */
|
|
212
|
+
chunkSize?: number;
|
|
213
|
+
/** Overlap between adjacent chunks in tokens */
|
|
214
|
+
chunkOverlap?: number;
|
|
215
|
+
}
|
|
216
|
+
interface RagConfig {
|
|
217
|
+
/**
|
|
218
|
+
* Unique identifier for the consuming project.
|
|
219
|
+
* Used as the vector DB namespace to achieve multi-tenancy.
|
|
220
|
+
*/
|
|
221
|
+
projectId: string;
|
|
222
|
+
/** Vector database configuration */
|
|
223
|
+
vectorDb: VectorDBConfig;
|
|
224
|
+
/** LLM configuration */
|
|
225
|
+
llm: LLMConfig;
|
|
226
|
+
/** Embedding configuration */
|
|
227
|
+
embedding: EmbeddingConfig;
|
|
228
|
+
/** Optional UI branding overrides */
|
|
229
|
+
ui?: UIConfig;
|
|
230
|
+
/** Optional RAG pipeline tuning knobs */
|
|
231
|
+
rag?: RAGConfig;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* RAGPipeline — the central orchestrator for the RAG workflow.
|
|
236
|
+
*
|
|
237
|
+
* Responsibilities:
|
|
238
|
+
* 1. INGEST: chunk → embed → upsert into vector DB
|
|
239
|
+
* 2. ASK: embed query → retrieve top-K chunks → call LLM with context
|
|
240
|
+
*
|
|
241
|
+
* It is LLM-agnostic and vector-DB-agnostic; concrete implementations are
|
|
242
|
+
* injected via ILLMProvider and IVectorDB.
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
interface IngestDocument {
|
|
246
|
+
/** Unique document ID (used as chunk ID prefix) */
|
|
247
|
+
docId: string;
|
|
248
|
+
/** Full text content of the document */
|
|
249
|
+
content: string;
|
|
250
|
+
/** Optional metadata stored alongside each chunk */
|
|
251
|
+
metadata?: Record<string, unknown>;
|
|
252
|
+
}
|
|
253
|
+
interface ChatResponse {
|
|
254
|
+
/** The LLM's answer */
|
|
255
|
+
reply: string;
|
|
256
|
+
/** Retrieved source chunks used to generate the answer */
|
|
257
|
+
sources: VectorMatch[];
|
|
258
|
+
}
|
|
259
|
+
declare class RAGPipeline {
|
|
260
|
+
private readonly vectorDB;
|
|
261
|
+
private readonly llmProvider;
|
|
262
|
+
private readonly embeddingProvider;
|
|
263
|
+
private readonly chunker;
|
|
264
|
+
private readonly config;
|
|
265
|
+
private initialised;
|
|
266
|
+
constructor(config: RagConfig, adapters?: {
|
|
267
|
+
vectorDB?: IVectorDB;
|
|
268
|
+
llmProvider?: ILLMProvider;
|
|
269
|
+
embeddingProvider?: ILLMProvider;
|
|
270
|
+
});
|
|
271
|
+
/** Lazily initialise the vector DB connection */
|
|
272
|
+
init(): Promise<void>;
|
|
273
|
+
/**
|
|
274
|
+
* Ingest one or more documents into the vector DB.
|
|
275
|
+
* Automatically chunks, embeds, and upserts each chunk.
|
|
276
|
+
*/
|
|
277
|
+
ingest(documents: IngestDocument[], namespace?: string): Promise<{
|
|
278
|
+
docId: string;
|
|
279
|
+
chunksIngested: number;
|
|
280
|
+
}[]>;
|
|
281
|
+
/**
|
|
282
|
+
* Run a full RAG query:
|
|
283
|
+
* 1. Embed the user question
|
|
284
|
+
* 2. Retrieve top-K relevant chunks from the vector DB
|
|
285
|
+
* 3. Filter by score threshold
|
|
286
|
+
* 4. Build context string
|
|
287
|
+
* 5. Call the LLM with chat history + context
|
|
288
|
+
*/
|
|
289
|
+
ask(question: string, history?: ChatMessage[], namespace?: string): Promise<ChatResponse>;
|
|
290
|
+
health(): Promise<{
|
|
291
|
+
vectorDB: boolean;
|
|
292
|
+
llm: boolean;
|
|
293
|
+
}>;
|
|
294
|
+
deleteDocument(docId: string, namespace?: string): Promise<void>;
|
|
295
|
+
deleteProject(namespace?: string): Promise<void>;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { type ChatMessage as C, type EmbedOptions as E, type ILLMProvider as I, type LLMConfig as L, type RAGConfig as R, type UIConfig as U, type VectorMatch as V, type ChatOptions as a, type ChatResponse as b, type EmbeddingConfig as c, type IVectorDB as d, type IngestDocument as e, type RagConfig as f, type UpsertDocument as g, type VectorDBConfig as h, RAGPipeline as i };
|