@retrivora-ai/rag-engine 0.1.1 → 0.1.3
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 +1 -1
- package/README.md +8 -8
- package/dist/{chunk-NCG2JKXB.mjs → chunk-NVOMLHXW.mjs} +8 -3
- package/dist/handlers/index.js +8 -3
- package/dist/handlers/index.mjs +1 -1
- package/dist/index.js +3 -2
- package/dist/index.mjs +3 -2
- package/dist/server.js +8 -3
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
- package/src/app/page.tsx +8 -8
- package/src/components/ChatWidget.tsx +3 -2
- package/src/index.ts +1 -1
- package/src/rag/RAGPipeline.ts +4 -0
- package/src/vectordb/adapters/PineconeAdapter.ts +12 -6
package/.env.example
CHANGED
|
@@ -11,7 +11,7 @@ PINECONE_API_KEY=your-pinecone-api-key
|
|
|
11
11
|
PINECONE_ENVIRONMENT=us-east-1
|
|
12
12
|
|
|
13
13
|
# pgVector (if provider=pgvector)
|
|
14
|
-
PGVECTOR_CONNECTION_STRING=postgresql://user:password@localhost:5432/
|
|
14
|
+
PGVECTOR_CONNECTION_STRING=postgresql://user:password@localhost:5432/StagVectorDB
|
|
15
15
|
|
|
16
16
|
# Generic REST (if provider=rest)
|
|
17
17
|
VECTOR_DB_REST_URL=http://localhost:8080
|
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @retrivora-ai/rag-engine
|
|
2
2
|
|
|
3
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
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@retrivora-ai/rag-engine)
|
|
6
|
+
[](https://www.npmjs.com/package/@retrivora-ai/rag-engine)
|
|
7
7
|
[](https://github.com/abhinav1201/ai-accelerator)
|
|
8
8
|

|
|
9
9
|

|
|
@@ -35,7 +35,7 @@ Retrivora AI acts as a universal bridge between your data and your users. It nor
|
|
|
35
35
|
To integrate Retrivora AI into your existing Next.js project, simply run:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
npm install @
|
|
38
|
+
npm install @retrivora-ai/rag-engine
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Alternatively, if you want to run the standalone demo application:
|
|
@@ -58,7 +58,7 @@ npm run dev
|
|
|
58
58
|
Wrap your application in the `ConfigProvider` and add the `ChatWidget`.
|
|
59
59
|
|
|
60
60
|
```tsx
|
|
61
|
-
import { ConfigProvider, ChatWidget } from '@
|
|
61
|
+
import { ConfigProvider, ChatWidget } from '@retrivora-ai/rag-engine';
|
|
62
62
|
|
|
63
63
|
export default function Layout({ children }) {
|
|
64
64
|
return (
|
|
@@ -86,18 +86,18 @@ Create standard Next.js route handlers and plug in the library's factories.
|
|
|
86
86
|
|
|
87
87
|
```ts
|
|
88
88
|
// src/app/api/chat/route.ts
|
|
89
|
-
import { createChatHandler, getRagConfig } from '@
|
|
89
|
+
import { createChatHandler, getRagConfig } from '@retrivora-ai/rag-engine/server';
|
|
90
90
|
export const POST = createChatHandler(getRagConfig());
|
|
91
91
|
|
|
92
92
|
// src/app/api/upload/route.ts (Handles PDF, DOCX, etc.)
|
|
93
|
-
import { createUploadHandler, getRagConfig } from '@
|
|
93
|
+
import { createUploadHandler, getRagConfig } from '@retrivora-ai/rag-engine/server';
|
|
94
94
|
export const POST = createUploadHandler(getRagConfig());
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
### 3. Use RAGPipeline programmatically
|
|
98
98
|
|
|
99
99
|
```ts
|
|
100
|
-
import { RAGPipeline } from '@
|
|
100
|
+
import { RAGPipeline } from '@retrivora-ai/rag-engine/server';
|
|
101
101
|
|
|
102
102
|
const pipeline = new RAGPipeline(config);
|
|
103
103
|
await pipeline.ingest([{ docId: 'readme', content: 'Your document text here' }]);
|
|
@@ -70,12 +70,14 @@ var PineconeAdapter = class {
|
|
|
70
70
|
includeMetadata: true
|
|
71
71
|
}, filter ? { filter } : {}));
|
|
72
72
|
return ((_a = result.matches) != null ? _a : []).map((m) => {
|
|
73
|
-
var _a2
|
|
73
|
+
var _a2;
|
|
74
|
+
const metadata = m.metadata;
|
|
75
|
+
const content = (metadata == null ? void 0 : metadata.content) || (metadata == null ? void 0 : metadata.text) || (metadata == null ? void 0 : metadata.body) || (metadata == null ? void 0 : metadata.description) || "";
|
|
74
76
|
return {
|
|
75
77
|
id: m.id,
|
|
76
78
|
score: (_a2 = m.score) != null ? _a2 : 0,
|
|
77
|
-
content
|
|
78
|
-
metadata
|
|
79
|
+
content,
|
|
80
|
+
metadata
|
|
79
81
|
};
|
|
80
82
|
});
|
|
81
83
|
}
|
|
@@ -1020,9 +1022,12 @@ var RAGPipeline = class {
|
|
|
1020
1022
|
const ns = namespace != null ? namespace : this.config.projectId;
|
|
1021
1023
|
const topK = (_b = (_a = this.config.rag) == null ? void 0 : _a.topK) != null ? _b : 5;
|
|
1022
1024
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0;
|
|
1025
|
+
console.log(`[RAGPipeline] Searching Pinecone (Namespace: "${ns}", TopK: ${topK})...`);
|
|
1023
1026
|
const queryVector = await this.embeddingProvider.embed(question);
|
|
1024
1027
|
const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
|
|
1028
|
+
console.log(`[RAGPipeline] Found ${rawMatches.length} raw matches in Pinecone.`);
|
|
1025
1029
|
const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
|
|
1030
|
+
console.log(`[RAGPipeline] ${sources.length} sources remaining after threshold filter (min: ${scoreThreshold}).`);
|
|
1026
1031
|
const context = sources.length ? sources.map((m, i) => `[Source ${i + 1}]
|
|
1027
1032
|
${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
|
|
1028
1033
|
const messages = [
|
package/dist/handlers/index.js
CHANGED
|
@@ -117,12 +117,14 @@ var PineconeAdapter = class {
|
|
|
117
117
|
includeMetadata: true
|
|
118
118
|
}, filter ? { filter } : {}));
|
|
119
119
|
return ((_a = result.matches) != null ? _a : []).map((m) => {
|
|
120
|
-
var _a2
|
|
120
|
+
var _a2;
|
|
121
|
+
const metadata = m.metadata;
|
|
122
|
+
const content = (metadata == null ? void 0 : metadata.content) || (metadata == null ? void 0 : metadata.text) || (metadata == null ? void 0 : metadata.body) || (metadata == null ? void 0 : metadata.description) || "";
|
|
121
123
|
return {
|
|
122
124
|
id: m.id,
|
|
123
125
|
score: (_a2 = m.score) != null ? _a2 : 0,
|
|
124
|
-
content
|
|
125
|
-
metadata
|
|
126
|
+
content,
|
|
127
|
+
metadata
|
|
126
128
|
};
|
|
127
129
|
});
|
|
128
130
|
}
|
|
@@ -1095,9 +1097,12 @@ var RAGPipeline = class {
|
|
|
1095
1097
|
const ns = namespace != null ? namespace : this.config.projectId;
|
|
1096
1098
|
const topK = (_b = (_a = this.config.rag) == null ? void 0 : _a.topK) != null ? _b : 5;
|
|
1097
1099
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0;
|
|
1100
|
+
console.log(`[RAGPipeline] Searching Pinecone (Namespace: "${ns}", TopK: ${topK})...`);
|
|
1098
1101
|
const queryVector = await this.embeddingProvider.embed(question);
|
|
1099
1102
|
const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
|
|
1103
|
+
console.log(`[RAGPipeline] Found ${rawMatches.length} raw matches in Pinecone.`);
|
|
1100
1104
|
const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
|
|
1105
|
+
console.log(`[RAGPipeline] ${sources.length} sources remaining after threshold filter (min: ${scoreThreshold}).`);
|
|
1101
1106
|
const context = sources.length ? sources.map((m, i) => `[Source ${i + 1}]
|
|
1102
1107
|
${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
|
|
1103
1108
|
const messages = [
|
package/dist/handlers/index.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -545,6 +545,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
545
545
|
const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
|
|
546
546
|
const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
|
|
547
547
|
const handleOpen = () => {
|
|
548
|
+
console.log("ChatWidget: Opening...");
|
|
548
549
|
setIsOpen(true);
|
|
549
550
|
setHasUnread(false);
|
|
550
551
|
};
|
|
@@ -552,7 +553,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
552
553
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
553
554
|
"div",
|
|
554
555
|
{
|
|
555
|
-
className: `fixed z-[
|
|
556
|
+
className: `fixed z-[9998] w-[380px] max-w-[calc(100vw-3rem)] transition-all duration-300 ease-in-out ${windowPositionClass} ${isOpen ? "opacity-100 translate-y-0 pointer-events-auto" : "opacity-0 translate-y-4 pointer-events-none"}`,
|
|
556
557
|
style: { height: "600px", maxHeight: "calc(100vh - 6rem)" },
|
|
557
558
|
children: [
|
|
558
559
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -576,7 +577,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
576
577
|
"button",
|
|
577
578
|
{
|
|
578
579
|
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
579
|
-
className: `fixed z-[
|
|
580
|
+
className: `fixed z-[9999] w-14 h-14 shadow-2xl flex items-center justify-center transition-all duration-300 cursor-pointer hover:scale-110 active:scale-95 ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"} ${positionClass}`,
|
|
580
581
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
581
582
|
"aria-label": "Open chat",
|
|
582
583
|
children: [
|
package/dist/index.mjs
CHANGED
|
@@ -485,6 +485,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
485
485
|
const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
|
|
486
486
|
const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
|
|
487
487
|
const handleOpen = () => {
|
|
488
|
+
console.log("ChatWidget: Opening...");
|
|
488
489
|
setIsOpen(true);
|
|
489
490
|
setHasUnread(false);
|
|
490
491
|
};
|
|
@@ -492,7 +493,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
492
493
|
/* @__PURE__ */ jsxs4(
|
|
493
494
|
"div",
|
|
494
495
|
{
|
|
495
|
-
className: `fixed z-[
|
|
496
|
+
className: `fixed z-[9998] w-[380px] max-w-[calc(100vw-3rem)] transition-all duration-300 ease-in-out ${windowPositionClass} ${isOpen ? "opacity-100 translate-y-0 pointer-events-auto" : "opacity-0 translate-y-4 pointer-events-none"}`,
|
|
496
497
|
style: { height: "600px", maxHeight: "calc(100vh - 6rem)" },
|
|
497
498
|
children: [
|
|
498
499
|
/* @__PURE__ */ jsx5(
|
|
@@ -516,7 +517,7 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
516
517
|
"button",
|
|
517
518
|
{
|
|
518
519
|
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
519
|
-
className: `fixed z-[
|
|
520
|
+
className: `fixed z-[9999] w-14 h-14 shadow-2xl flex items-center justify-center transition-all duration-300 cursor-pointer hover:scale-110 active:scale-95 ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"} ${positionClass}`,
|
|
520
521
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
521
522
|
"aria-label": "Open chat",
|
|
522
523
|
children: [
|
package/dist/server.js
CHANGED
|
@@ -127,12 +127,14 @@ var PineconeAdapter = class {
|
|
|
127
127
|
includeMetadata: true
|
|
128
128
|
}, filter ? { filter } : {}));
|
|
129
129
|
return ((_a = result.matches) != null ? _a : []).map((m) => {
|
|
130
|
-
var _a2
|
|
130
|
+
var _a2;
|
|
131
|
+
const metadata = m.metadata;
|
|
132
|
+
const content = (metadata == null ? void 0 : metadata.content) || (metadata == null ? void 0 : metadata.text) || (metadata == null ? void 0 : metadata.body) || (metadata == null ? void 0 : metadata.description) || "";
|
|
131
133
|
return {
|
|
132
134
|
id: m.id,
|
|
133
135
|
score: (_a2 = m.score) != null ? _a2 : 0,
|
|
134
|
-
content
|
|
135
|
-
metadata
|
|
136
|
+
content,
|
|
137
|
+
metadata
|
|
136
138
|
};
|
|
137
139
|
});
|
|
138
140
|
}
|
|
@@ -1105,9 +1107,12 @@ var RAGPipeline = class {
|
|
|
1105
1107
|
const ns = namespace != null ? namespace : this.config.projectId;
|
|
1106
1108
|
const topK = (_b = (_a = this.config.rag) == null ? void 0 : _a.topK) != null ? _b : 5;
|
|
1107
1109
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0;
|
|
1110
|
+
console.log(`[RAGPipeline] Searching Pinecone (Namespace: "${ns}", TopK: ${topK})...`);
|
|
1108
1111
|
const queryVector = await this.embeddingProvider.embed(question);
|
|
1109
1112
|
const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
|
|
1113
|
+
console.log(`[RAGPipeline] Found ${rawMatches.length} raw matches in Pinecone.`);
|
|
1110
1114
|
const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
|
|
1115
|
+
console.log(`[RAGPipeline] ${sources.length} sources remaining after threshold filter (min: ${scoreThreshold}).`);
|
|
1111
1116
|
const context = sources.length ? sources.map((m, i) => `[Source ${i + 1}]
|
|
1112
1117
|
${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
|
|
1113
1118
|
const messages = [
|
package/dist/server.mjs
CHANGED
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.3",
|
|
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
|
@@ -143,7 +143,7 @@ export default function HomePage() {
|
|
|
143
143
|
<div className="flex items-center gap-3">
|
|
144
144
|
<ThemeToggle />
|
|
145
145
|
<a
|
|
146
|
-
href="https://www.npmjs.com/package/@
|
|
146
|
+
href="https://www.npmjs.com/package/@retrivora-ai/rag-engine"
|
|
147
147
|
target="_blank"
|
|
148
148
|
rel="noreferrer"
|
|
149
149
|
className="text-slate-500 hover:text-[#CB3837] dark:text-white/40 dark:hover:text-[#CB3837] text-sm transition-colors flex items-center gap-1.5"
|
|
@@ -333,9 +333,9 @@ export default function HomePage() {
|
|
|
333
333
|
|
|
334
334
|
<div className="relative group/code">
|
|
335
335
|
<div className="bg-slate-950 rounded-xl p-5 font-mono text-sm text-indigo-300 border border-white/5 flex items-center justify-between overflow-x-auto shadow-inner">
|
|
336
|
-
<span className="whitespace-nowrap">$ npm install @
|
|
336
|
+
<span className="whitespace-nowrap">$ npm install @retrivora-ai/rag-engine</span>
|
|
337
337
|
<button
|
|
338
|
-
onClick={() => copy('npm install @
|
|
338
|
+
onClick={() => copy('npm install @retrivora-ai/rag-engine', 'step1')}
|
|
339
339
|
className="ml-4 p-2 rounded-lg bg-white/5 hover:bg-white/10 text-white/50 hover:text-white transition-all flex-shrink-0"
|
|
340
340
|
title="Copy to clipboard"
|
|
341
341
|
>
|
|
@@ -373,7 +373,7 @@ export default function HomePage() {
|
|
|
373
373
|
<div className="relative flex-1 group/code z-10">
|
|
374
374
|
<div className="absolute top-3 right-3 z-20">
|
|
375
375
|
<button
|
|
376
|
-
onClick={() => copy(`import { ConfigProvider, ChatWidget } from '@
|
|
376
|
+
onClick={() => copy(`import { ConfigProvider, ChatWidget } from '@retrivora-ai/rag-engine';\n\n<ConfigProvider config={{ projectId: 'demo' }}>\n {children}\n <ChatWidget position="bottom-right" />\n</ConfigProvider>`, 'step2')}
|
|
377
377
|
className="p-1.5 rounded-md bg-white/5 hover:bg-white/10 text-white/30 hover:text-white transition-all"
|
|
378
378
|
>
|
|
379
379
|
{copied === 'step2' ? <Check className="w-3 h-3 text-emerald-400" /> : <Copy className="w-3 h-3" />}
|
|
@@ -384,7 +384,7 @@ export default function HomePage() {
|
|
|
384
384
|
<FileText className="w-3 h-3" /> src/app/layout.tsx
|
|
385
385
|
</div>
|
|
386
386
|
<pre className="text-slate-300">
|
|
387
|
-
{`import { ConfigProvider, ChatWidget } from '@
|
|
387
|
+
{`import { ConfigProvider, ChatWidget } from '@retrivora-ai/rag-engine';
|
|
388
388
|
|
|
389
389
|
<ConfigProvider config={{ projectId: 'demo' }}>
|
|
390
390
|
{children}
|
|
@@ -420,7 +420,7 @@ export default function HomePage() {
|
|
|
420
420
|
<div className="relative flex-1 group/code z-10">
|
|
421
421
|
<div className="absolute top-3 right-3 z-20">
|
|
422
422
|
<button
|
|
423
|
-
onClick={() => copy(`import { createChatHandler, getRagConfig } from '@
|
|
423
|
+
onClick={() => copy(`import { createChatHandler, getRagConfig } from '@retrivora-ai/rag-engine/server';\n\nexport const POST = createChatHandler(getRagConfig());`, 'step3')}
|
|
424
424
|
className="p-1.5 rounded-md bg-white/5 hover:bg-white/10 text-white/30 hover:text-white transition-all"
|
|
425
425
|
>
|
|
426
426
|
{copied === 'step3' ? <Check className="w-3 h-3 text-emerald-400" /> : <Copy className="w-3 h-3" />}
|
|
@@ -431,7 +431,7 @@ export default function HomePage() {
|
|
|
431
431
|
<FileText className="w-3 h-3" /> api/chat/route.ts
|
|
432
432
|
</div>
|
|
433
433
|
<pre className="text-slate-300">
|
|
434
|
-
{`import { createChatHandler, getRagConfig } from '@
|
|
434
|
+
{`import { createChatHandler, getRagConfig } from '@retrivora-ai/rag-engine/server';
|
|
435
435
|
|
|
436
436
|
export const POST = createChatHandler(getRagConfig());`}
|
|
437
437
|
</pre>
|
|
@@ -488,7 +488,7 @@ export const POST = createChatHandler(getRagConfig());`}
|
|
|
488
488
|
|
|
489
489
|
<div className="mt-16 text-center">
|
|
490
490
|
<a
|
|
491
|
-
href="https://www.npmjs.com/package/@
|
|
491
|
+
href="https://www.npmjs.com/package/@retrivora-ai/rag-engine"
|
|
492
492
|
className="inline-flex items-center gap-3 px-8 py-4 rounded-2xl bg-slate-900 dark:bg-white text-white dark:text-slate-900 font-bold hover:scale-[1.02] active:scale-[0.98] transition-all shadow-xl shadow-indigo-500/20"
|
|
493
493
|
>
|
|
494
494
|
<Package className="w-5 h-5" />
|
|
@@ -28,6 +28,7 @@ export function ChatWidget({ position = 'bottom-right' }: ChatWidgetProps) {
|
|
|
28
28
|
: 'bottom-20 right-6';
|
|
29
29
|
|
|
30
30
|
const handleOpen = () => {
|
|
31
|
+
console.log('ChatWidget: Opening...');
|
|
31
32
|
setIsOpen(true);
|
|
32
33
|
setHasUnread(false);
|
|
33
34
|
};
|
|
@@ -36,7 +37,7 @@ export function ChatWidget({ position = 'bottom-right' }: ChatWidgetProps) {
|
|
|
36
37
|
<>
|
|
37
38
|
{/* ── Chat Window (slides up) ── */}
|
|
38
39
|
<div
|
|
39
|
-
className={`fixed z-[
|
|
40
|
+
className={`fixed z-[9998] w-[380px] max-w-[calc(100vw-3rem)] transition-all duration-300 ease-in-out ${windowPositionClass} ${isOpen
|
|
40
41
|
? 'opacity-100 translate-y-0 pointer-events-auto'
|
|
41
42
|
: 'opacity-0 translate-y-4 pointer-events-none'
|
|
42
43
|
}`}
|
|
@@ -58,7 +59,7 @@ export function ChatWidget({ position = 'bottom-right' }: ChatWidgetProps) {
|
|
|
58
59
|
{/* ── Floating Action Button ── */}
|
|
59
60
|
<button
|
|
60
61
|
onClick={isOpen ? () => setIsOpen(false) : handleOpen}
|
|
61
|
-
className={`fixed z-[
|
|
62
|
+
className={`fixed z-[9999] w-14 h-14 shadow-2xl flex items-center justify-center transition-all duration-300 cursor-pointer hover:scale-110 active:scale-95 ${
|
|
62
63
|
ui.borderRadius === 'full' ? 'rounded-full' : 'rounded-2xl'
|
|
63
64
|
} ${positionClass}`}
|
|
64
65
|
style={{ background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }}
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* This entry point is CLIENT-SAFE and can be imported in React Client Components.
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* import { ChatWidget, ConfigProvider, useRagChat } from '@rag
|
|
6
|
+
* import { ChatWidget, ConfigProvider, useRagChat } from '@retrivora-ai/rag-engine';
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
// ── React Components ─────────────────────────────────────────
|
package/src/rag/RAGPipeline.ts
CHANGED
|
@@ -140,14 +140,18 @@ export class RAGPipeline {
|
|
|
140
140
|
const topK = this.config.rag?.topK ?? 5;
|
|
141
141
|
const scoreThreshold = this.config.rag?.scoreThreshold ?? 0.0;
|
|
142
142
|
|
|
143
|
+
console.log(`[RAGPipeline] Searching Pinecone (Namespace: "${ns}", TopK: ${topK})...`);
|
|
144
|
+
|
|
143
145
|
// 1. Embed the question
|
|
144
146
|
const queryVector = await this.embeddingProvider.embed(question);
|
|
145
147
|
|
|
146
148
|
// 2. Retrieve relevant chunks
|
|
147
149
|
const rawMatches = await this.vectorDB.query(queryVector, topK, ns);
|
|
150
|
+
console.log(`[RAGPipeline] Found ${rawMatches.length} raw matches in Pinecone.`);
|
|
148
151
|
|
|
149
152
|
// 3. Apply score threshold filter
|
|
150
153
|
const sources = rawMatches.filter((m) => m.score >= scoreThreshold);
|
|
154
|
+
console.log(`[RAGPipeline] ${sources.length} sources remaining after threshold filter (min: ${scoreThreshold}).`);
|
|
151
155
|
|
|
152
156
|
// 4. Build context
|
|
153
157
|
const context = sources.length
|
|
@@ -83,12 +83,18 @@ export class PineconeAdapter implements IVectorDB {
|
|
|
83
83
|
...(filter ? { filter } : {}),
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
return (result.matches ?? []).map((m) =>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
content
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
return (result.matches ?? []).map((m) => {
|
|
87
|
+
const metadata = m.metadata as Record<string, unknown>;
|
|
88
|
+
// Try multiple common fields for content
|
|
89
|
+
const content = (metadata?.content || metadata?.text || metadata?.body || metadata?.description || '') as string;
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
id: m.id,
|
|
93
|
+
score: m.score ?? 0,
|
|
94
|
+
content,
|
|
95
|
+
metadata,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
async delete(id: string, namespace?: string): Promise<void> {
|