@retrivora-ai/rag-engine 0.1.8 → 0.1.9
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-2JZSBOQX.mjs → ChromaDBProvider-T7TK3ONZ.mjs} +2 -2
- package/dist/{MilvusProvider-CJDBCBVI.mjs → MilvusProvider-Y5FV5EAE.mjs} +2 -2
- package/dist/{MongoDBProvider-WWVJG3WT.mjs → MongoDBProvider-QHMGD2LZ.mjs} +2 -2
- package/dist/{PineconeProvider-E6L5Z2FO.mjs → PineconeProvider-A47MRRYJ.mjs} +2 -2
- package/dist/{PostgreSQLProvider-ZNXA67IM.mjs → PostgreSQLProvider-PJ5ER5Z4.mjs} +1 -1
- package/dist/{QdrantProvider-JITRNJQN.mjs → QdrantProvider-OLPJK7CY.mjs} +2 -2
- package/dist/{RedisProvider-3VKFQXXD.mjs → RedisProvider-ANEJ3BHR.mjs} +2 -2
- package/dist/{UniversalVectorProvider-E6L4U4OX.mjs → UniversalVectorProvider-QJIV2AJJ.mjs} +3 -3
- package/dist/{WeaviateProvider-MXIPP44J.mjs → WeaviateProvider-WIK2QN23.mjs} +2 -2
- package/dist/{chunk-YIYDJQJM.mjs → chunk-2VR5ZMXV.mjs} +11 -11
- package/dist/{chunk-QEYVWVT5.mjs → chunk-5HXNKSCR.mjs} +1 -1
- package/dist/{chunk-MFWJZVF3.mjs → chunk-BMHJTWSU.mjs} +1 -1
- package/dist/{chunk-UKDXCXW7.mjs → chunk-EDLTMSNY.mjs} +1 -1
- package/dist/{chunk-I4E63NIC.mjs → chunk-FWCSY2DS.mjs} +14 -1
- package/dist/{chunk-7BQI4A5J.mjs → chunk-HOMXEE3M.mjs} +1 -1
- package/dist/{chunk-TSX6DQXX.mjs → chunk-RUKZC3ON.mjs} +1 -1
- package/dist/{chunk-YST6KYBJ.mjs → chunk-VEJNRS4B.mjs} +1 -1
- package/dist/{chunk-XZPVJS2B.mjs → chunk-VKE5ZW7Y.mjs} +1 -1
- package/dist/{chunk-Y6HQZDCJ.mjs → chunk-VV2ML6TM.mjs} +2 -2
- package/dist/{chunk-26EMHLIN.mjs → chunk-W2PQR3UK.mjs} +1 -1
- package/dist/handlers/index.mjs +3 -3
- package/dist/index.js +67 -58
- package/dist/index.mjs +74 -47
- package/dist/server.d.mts +36 -1
- package/dist/server.d.ts +36 -1
- package/dist/server.js +127 -0
- package/dist/server.mjs +124 -11
- package/package.json +1 -1
- package/src/app/constants.tsx +220 -0
- package/src/app/page.tsx +193 -363
- package/src/app/types.ts +30 -0
- package/src/components/ChatWindow.tsx +3 -11
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +164 -0
- package/src/server.ts +1 -0
package/src/app/page.tsx
CHANGED
|
@@ -5,87 +5,132 @@ import {
|
|
|
5
5
|
Zap,
|
|
6
6
|
GitBranch,
|
|
7
7
|
HeartPulse,
|
|
8
|
-
Database,
|
|
9
|
-
Layers,
|
|
10
|
-
Bot,
|
|
11
|
-
Brain,
|
|
12
|
-
Rabbit,
|
|
13
8
|
FileText,
|
|
14
|
-
Search,
|
|
15
|
-
Puzzle,
|
|
16
|
-
MessageSquare,
|
|
17
9
|
ExternalLink,
|
|
18
10
|
Package,
|
|
11
|
+
Check,
|
|
12
|
+
Copy,
|
|
19
13
|
} from 'lucide-react';
|
|
20
14
|
import { ChatWindow } from '@/components/ChatWindow';
|
|
21
15
|
import { ChatWidget } from '@/components/ChatWidget';
|
|
22
16
|
import { useConfig } from '@/components/ConfigProvider';
|
|
23
17
|
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
24
|
-
import { Check, Copy } from 'lucide-react';
|
|
25
18
|
import pkg from '../../package.json';
|
|
19
|
+
import { Snippet, ArchitectureCardProps } from './types';
|
|
20
|
+
import {
|
|
21
|
+
LANDING_PAGE_CONTENT,
|
|
22
|
+
VECTOR_DATABASES,
|
|
23
|
+
AI_MODELS,
|
|
24
|
+
PIPELINE_STEPS,
|
|
25
|
+
SNIPPETS,
|
|
26
|
+
ARCHITECTURE_CARDS,
|
|
27
|
+
QUICK_START_STEPS,
|
|
28
|
+
API_ENDPOINTS,
|
|
29
|
+
} from './constants';
|
|
30
|
+
|
|
31
|
+
// ── Components ──────────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
function ArchitectureCard({ icon, title, description, badge, badgeColor }: ArchitectureCardProps) {
|
|
34
|
+
return (
|
|
35
|
+
<div className="group rounded-2xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/5 p-6 shadow-sm transition-all duration-300 hover:border-indigo-500/50 dark:hover:border-indigo-500/30 hover:shadow-xl hover:shadow-indigo-500/5">
|
|
36
|
+
<div className="mb-4 flex items-center justify-between">
|
|
37
|
+
<div className="text-3xl transition-transform duration-300 group-hover:scale-110">{icon}</div>
|
|
38
|
+
<span className={`rounded-full border px-3 py-0.5 text-[10px] font-bold uppercase tracking-wider ${badgeColor}`}>
|
|
39
|
+
{badge}
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
42
|
+
<h3 className="mb-2 font-bold text-slate-900 dark:text-white">{title}</h3>
|
|
43
|
+
<p className="text-xs text-slate-500 dark:text-white/40 leading-relaxed font-medium">{description}</p>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
26
47
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*/
|
|
30
|
-
function useCopyToClipboard() {
|
|
31
|
-
const [copied, setCopied] = React.useState<string | null>(null);
|
|
48
|
+
function CodeViewer({ snippet }: { snippet: Snippet }) {
|
|
49
|
+
const [copied, setCopied] = React.useState(false);
|
|
32
50
|
|
|
33
|
-
const
|
|
34
|
-
navigator.clipboard.writeText(
|
|
35
|
-
setCopied(
|
|
36
|
-
setTimeout(() => setCopied(
|
|
51
|
+
const handleCopy = () => {
|
|
52
|
+
navigator.clipboard.writeText(snippet.code);
|
|
53
|
+
setCopied(true);
|
|
54
|
+
setTimeout(() => setCopied(false), 2000);
|
|
37
55
|
};
|
|
38
56
|
|
|
39
|
-
return
|
|
57
|
+
return (
|
|
58
|
+
<div className="flex flex-col h-full rounded-2xl border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-slate-900/50 shadow-lg overflow-hidden min-h-[440px]">
|
|
59
|
+
<div className="flex items-center justify-between px-5 py-3 border-b border-slate-200 dark:border-white/10 bg-white dark:bg-slate-900">
|
|
60
|
+
<div className="flex items-center gap-3">
|
|
61
|
+
<div className="flex gap-1.5">
|
|
62
|
+
<div className="w-2.5 h-2.5 rounded-full bg-red-500" />
|
|
63
|
+
<div className="w-2.5 h-2.5 rounded-full bg-yellow-500" />
|
|
64
|
+
<div className="w-2.5 h-2.5 rounded-full bg-green-500" />
|
|
65
|
+
</div>
|
|
66
|
+
<span className="text-[10px] font-mono text-slate-400 dark:text-white/30 uppercase tracking-widest ml-2">{snippet.language}</span>
|
|
67
|
+
</div>
|
|
68
|
+
<button
|
|
69
|
+
onClick={handleCopy}
|
|
70
|
+
className="flex items-center gap-2 text-[10px] font-bold text-slate-500 dark:text-white/40 hover:text-indigo-600 dark:hover:text-indigo-400 transition-all active:scale-95"
|
|
71
|
+
>
|
|
72
|
+
{copied ? (
|
|
73
|
+
<>
|
|
74
|
+
<Check size={14} className="text-emerald-500" />
|
|
75
|
+
<span className="text-emerald-500">Copied!</span>
|
|
76
|
+
</>
|
|
77
|
+
) : (
|
|
78
|
+
<>
|
|
79
|
+
<Copy size={14} />
|
|
80
|
+
<span>Copy Code</span>
|
|
81
|
+
</>
|
|
82
|
+
)}
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
85
|
+
<div className="p-8 font-mono text-[12px] leading-relaxed overflow-auto custom-scrollbar flex-grow bg-[#0f172a] text-indigo-50">
|
|
86
|
+
<pre className="whitespace-pre">
|
|
87
|
+
<code>{snippet.code}</code>
|
|
88
|
+
</pre>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
40
92
|
}
|
|
41
93
|
|
|
42
|
-
// ── Feature pills data ────────────────────────────────────────────────────────
|
|
43
|
-
const FEATURE_PILLS = [
|
|
44
|
-
{ Icon: Database, label: 'MongoDB' },
|
|
45
|
-
{ Icon: Layers, label: 'PostgreSQL' },
|
|
46
|
-
{ Icon: Zap, label: 'Pinecone' },
|
|
47
|
-
{ Icon: Bot, label: 'Claude' },
|
|
48
|
-
{ Icon: Brain, label: 'Gemini' },
|
|
49
|
-
{ Icon: MessageSquare, label: 'Copilot' },
|
|
50
|
-
{ Icon: Rabbit, label: 'Ollama' },
|
|
51
|
-
{ Icon: Package, label: 'ChromaDB' },
|
|
52
|
-
] as const;
|
|
53
94
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
|
|
96
|
+
// Data moved to constants.tsx
|
|
97
|
+
|
|
98
|
+
// ── Page ────────────────────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
function DocViewer({ activeSnippet, setActiveSnippet }: { activeSnippet: Snippet, setActiveSnippet: (s: Snippet) => void }) {
|
|
101
|
+
return (
|
|
102
|
+
<>
|
|
103
|
+
<div className="mb-6 flex flex-wrap gap-2 border-b border-slate-100 dark:border-white/5 pb-6">
|
|
104
|
+
{SNIPPETS.map((snippet) => (
|
|
105
|
+
<button
|
|
106
|
+
key={snippet.id}
|
|
107
|
+
onClick={() => setActiveSnippet(snippet)}
|
|
108
|
+
className={`px-5 py-2 rounded-xl text-[10px] font-bold uppercase tracking-wider transition-all border ${activeSnippet.id === snippet.id
|
|
109
|
+
? 'bg-indigo-600 text-white border-indigo-600 shadow-lg shadow-indigo-200 dark:shadow-indigo-500/20 scale-105'
|
|
110
|
+
: 'bg-white dark:bg-white/5 border-slate-200 dark:border-white/10 text-slate-500 dark:text-white/40 hover:text-indigo-600 dark:hover:text-indigo-400 hover:border-indigo-300 dark:hover:border-white/20'
|
|
111
|
+
}`}
|
|
112
|
+
>
|
|
113
|
+
{snippet.title}
|
|
114
|
+
</button>
|
|
115
|
+
))}
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div className="flex-grow flex flex-col gap-6 animate-in fade-in slide-in-from-bottom-2 duration-500">
|
|
119
|
+
<div className="max-w-2xl">
|
|
120
|
+
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-2">{activeSnippet.title}</h3>
|
|
121
|
+
<p className="text-sm text-slate-500 dark:text-white/40 leading-relaxed font-medium italic">
|
|
122
|
+
{activeSnippet.description}
|
|
123
|
+
</p>
|
|
124
|
+
</div>
|
|
125
|
+
<CodeViewer snippet={activeSnippet} />
|
|
126
|
+
</div>
|
|
127
|
+
</>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
85
130
|
|
|
86
131
|
export default function HomePage() {
|
|
87
132
|
const { ui } = useConfig();
|
|
88
|
-
const
|
|
133
|
+
const [activeSnippet, setActiveSnippet] = React.useState<Snippet>(SNIPPETS[0]);
|
|
89
134
|
|
|
90
135
|
return (
|
|
91
136
|
<main className="min-h-screen bg-slate-50 dark:bg-[#080811] relative transition-colors duration-300">
|
|
@@ -99,7 +144,6 @@ export default function HomePage() {
|
|
|
99
144
|
className="absolute -bottom-40 -right-40 w-[600px] h-[600px] rounded-full opacity-15 blur-3xl"
|
|
100
145
|
style={{ background: ui.accentColor }}
|
|
101
146
|
/>
|
|
102
|
-
{/* Grid pattern */}
|
|
103
147
|
<div
|
|
104
148
|
className="absolute inset-0 opacity-[0.05] dark:opacity-[0.03]"
|
|
105
149
|
style={{
|
|
@@ -121,7 +165,6 @@ export default function HomePage() {
|
|
|
121
165
|
<Zap className="w-5 h-5 text-white animate-pulse" />
|
|
122
166
|
<div className="absolute inset-0 bg-white/20 opacity-0 group-hover:opacity-100 transition-opacity" />
|
|
123
167
|
</div>
|
|
124
|
-
{/* Logo Glow */}
|
|
125
168
|
<div
|
|
126
169
|
className="absolute inset-0 blur-lg opacity-40 group-hover:opacity-80 transition-opacity"
|
|
127
170
|
style={{ background: ui.primaryColor }}
|
|
@@ -142,153 +185,89 @@ export default function HomePage() {
|
|
|
142
185
|
|
|
143
186
|
<div className="flex items-center gap-3">
|
|
144
187
|
<ThemeToggle />
|
|
145
|
-
<a
|
|
146
|
-
|
|
147
|
-
target="_blank"
|
|
148
|
-
rel="noreferrer"
|
|
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"
|
|
150
|
-
>
|
|
151
|
-
<Package className="w-4 h-4" />
|
|
152
|
-
NPM
|
|
188
|
+
<a href="https://www.npmjs.com/package/@retrivora-ai/rag-engine" target="_blank" rel="noreferrer" 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">
|
|
189
|
+
<Package className="w-4 h-4" /> NPM
|
|
153
190
|
</a>
|
|
154
|
-
<a
|
|
155
|
-
|
|
156
|
-
target="_blank"
|
|
157
|
-
rel="noreferrer"
|
|
158
|
-
className="text-slate-500 hover:text-slate-900 dark:text-white/40 dark:hover:text-white/70 text-sm transition-colors flex items-center gap-1.5"
|
|
159
|
-
>
|
|
160
|
-
<GitBranch className="w-4 h-4" />
|
|
161
|
-
GitHub
|
|
191
|
+
<a href="https://github.com/abhinav1201/ai-accelerator" target="_blank" rel="noreferrer" className="text-slate-500 hover:text-slate-900 dark:text-white/40 dark:hover:text-white/70 text-sm transition-colors flex items-center gap-1.5">
|
|
192
|
+
<GitBranch className="w-4 h-4" /> GitHub
|
|
162
193
|
</a>
|
|
163
|
-
<a
|
|
164
|
-
|
|
165
|
-
target="_blank"
|
|
166
|
-
rel="noreferrer"
|
|
167
|
-
className="px-3 py-1.5 rounded-lg text-xs border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/50 hover:text-slate-900 dark:hover:text-white/80 hover:bg-slate-100 dark:hover:bg-white/5 transition-all flex items-center gap-1.5"
|
|
168
|
-
>
|
|
169
|
-
<HeartPulse className="w-3.5 h-3.5" />
|
|
170
|
-
Health
|
|
194
|
+
<a href="/api/health" target="_blank" rel="noreferrer" className="px-3 py-1.5 rounded-lg text-xs border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/50 hover:text-slate-900 dark:hover:text-white/80 hover:bg-slate-100 dark:hover:bg-white/5 transition-all flex items-center gap-1.5">
|
|
195
|
+
<HeartPulse className="w-3.5 h-3.5" /> Health
|
|
171
196
|
</a>
|
|
172
197
|
</div>
|
|
173
198
|
</nav>
|
|
174
199
|
|
|
175
|
-
{/* ── Hero + Chat
|
|
200
|
+
{/* ── Hero + Chat ── */}
|
|
176
201
|
<div className="relative z-10 container mx-auto px-6 py-12">
|
|
177
202
|
<div className="grid lg:grid-cols-2 gap-12 items-start">
|
|
178
|
-
{/* Left — Hero copy */}
|
|
179
203
|
<div className="flex flex-col gap-6 pt-4">
|
|
180
204
|
<div
|
|
181
205
|
className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full text-xs font-medium border w-fit"
|
|
182
|
-
style={{
|
|
183
|
-
borderColor: `${ui.primaryColor}40`,
|
|
184
|
-
color: ui.primaryColor,
|
|
185
|
-
background: `${ui.primaryColor}10`,
|
|
186
|
-
}}
|
|
206
|
+
style={{ borderColor: `${ui.primaryColor}40`, color: ui.primaryColor, background: `${ui.primaryColor}10` }}
|
|
187
207
|
>
|
|
188
208
|
<span className="w-1.5 h-1.5 rounded-full animate-pulse" style={{ background: ui.primaryColor }} />
|
|
189
|
-
|
|
209
|
+
{LANDING_PAGE_CONTENT.hero.badge}
|
|
190
210
|
</div>
|
|
191
|
-
|
|
192
211
|
<h1 className="text-5xl md:text-7xl font-black text-slate-900 dark:text-white mb-6 tracking-tight">
|
|
193
|
-
|
|
194
|
-
<span
|
|
195
|
-
|
|
196
|
-
style={{ backgroundImage: `linear-gradient(to right, ${ui.primaryColor}, ${ui.accentColor})` }}
|
|
197
|
-
>
|
|
198
|
-
for Generative AI
|
|
212
|
+
{LANDING_PAGE_CONTENT.hero.title.split('for')[0]} <br />
|
|
213
|
+
<span className="text-transparent bg-clip-text" style={{ backgroundImage: `linear-gradient(to right, ${ui.primaryColor}, ${ui.accentColor})` }}>
|
|
214
|
+
for {LANDING_PAGE_CONTENT.hero.title.split('for')[1]}
|
|
199
215
|
</span>
|
|
200
216
|
</h1>
|
|
201
|
-
<p className="text-lg md:text-xl text-slate-600 dark:text-white/40 max-w-2xl
|
|
202
|
-
|
|
217
|
+
<p className="text-lg md:text-xl text-slate-600 dark:text-white/40 max-w-2xl leading-relaxed">
|
|
218
|
+
{LANDING_PAGE_CONTENT.hero.subtitle}
|
|
203
219
|
</p>
|
|
220
|
+
<div className="flex flex-col gap-4 mt-4">
|
|
221
|
+
<div className="flex flex-col gap-2">
|
|
222
|
+
<span className="text-[10px] font-black text-slate-400 dark:text-white/30 uppercase tracking-[0.2em] ml-1">Vector Ecosystem</span>
|
|
223
|
+
<div className="flex flex-wrap gap-2">
|
|
224
|
+
{VECTOR_DATABASES.map(({ Icon, label }) => (
|
|
225
|
+
<span key={label} className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/60 text-[11px] font-semibold hover:bg-slate-50 dark:hover:bg-white/8 transition-all shadow-sm group">
|
|
226
|
+
<Icon className="w-3 h-3 transition-transform group-hover:scale-110" style={{ color: ui.primaryColor }} /> {label}
|
|
227
|
+
</span>
|
|
228
|
+
))}
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
204
231
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
{label}
|
|
214
|
-
</span>
|
|
215
|
-
))}
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
{/* Stats */}
|
|
219
|
-
<div className="grid grid-cols-3 gap-4 mt-4 pt-4 border-t border-slate-200 dark:border-white/10">
|
|
220
|
-
{[
|
|
221
|
-
{ value: '6+', label: 'Vector DBs' },
|
|
222
|
-
{ value: '5+', label: 'LLM Providers' },
|
|
223
|
-
{ value: 'Universal', label: 'File Parsing' },
|
|
224
|
-
].map(({ value, label }) => (
|
|
225
|
-
<div key={label} className="text-center">
|
|
226
|
-
<div
|
|
227
|
-
className="text-2xl font-bold bg-clip-text text-transparent"
|
|
228
|
-
style={{ backgroundImage: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }}
|
|
229
|
-
>
|
|
230
|
-
{value}
|
|
231
|
-
</div>
|
|
232
|
-
<div className="text-slate-500 dark:text-white/40 text-xs mt-0.5">{label}</div>
|
|
232
|
+
<div className="flex flex-col gap-2">
|
|
233
|
+
<span className="text-[10px] font-black text-slate-400 dark:text-white/30 uppercase tracking-[0.2em] ml-1">AI Model Garden</span>
|
|
234
|
+
<div className="flex flex-wrap gap-2">
|
|
235
|
+
{AI_MODELS.map(({ Icon, label }) => (
|
|
236
|
+
<span key={label} className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/60 text-[11px] font-semibold hover:bg-slate-50 dark:hover:bg-white/8 transition-all shadow-sm group">
|
|
237
|
+
<Icon className="w-3 h-3 transition-transform group-hover:scale-110" style={{ color: ui.accentColor }} /> {label}
|
|
238
|
+
</span>
|
|
239
|
+
))}
|
|
233
240
|
</div>
|
|
234
|
-
|
|
241
|
+
</div>
|
|
235
242
|
</div>
|
|
236
243
|
</div>
|
|
237
|
-
|
|
238
|
-
{/* Right — Full chat window */}
|
|
239
244
|
<div className="lg:sticky lg:top-6">
|
|
240
245
|
<ChatWindow className="w-full" style={{ height: '620px' } as React.CSSProperties} />
|
|
241
246
|
</div>
|
|
242
247
|
</div>
|
|
243
248
|
|
|
244
|
-
{/* ──
|
|
249
|
+
{/* ── Lifecycle ── */}
|
|
245
250
|
<div className="mt-24 mb-12">
|
|
246
|
-
<h2 className="text-2xl font-bold text-slate-900 dark:text-white text-center mb-2">
|
|
247
|
-
<p className="text-slate-500 dark:text-white/40 text-center text-sm mb-10">
|
|
248
|
-
Automated ingestion, semantic retrieval, and grounded generation
|
|
249
|
-
</p>
|
|
250
|
-
|
|
251
|
+
<h2 className="text-2xl font-bold text-slate-900 dark:text-white text-center mb-2">{LANDING_PAGE_CONTENT.lifecycle.title}</h2>
|
|
251
252
|
<div className="relative max-w-5xl mx-auto py-12">
|
|
252
|
-
{/* Center Spine Line */}
|
|
253
253
|
<div className="absolute left-1/2 top-0 bottom-0 w-0.5 bg-slate-200 dark:bg-white/10 -translate-x-1/2 hidden md:block" />
|
|
254
|
-
|
|
255
254
|
<div className="space-y-12 md:space-y-0">
|
|
256
255
|
{PIPELINE_STEPS.map(({ step, Icon, title, desc, colors }, index) => {
|
|
257
256
|
const isLeft = index % 2 === 0;
|
|
258
257
|
return (
|
|
259
|
-
<div
|
|
260
|
-
key={step}
|
|
261
|
-
className={`relative flex flex-col md:flex-row items-center gap-8 cursor-pointer ${isLeft ? 'md:flex-row' : 'md:flex-row-reverse'
|
|
262
|
-
}`}
|
|
263
|
-
>
|
|
264
|
-
{/* Content Card */}
|
|
258
|
+
<div key={step} className={`relative flex flex-col md:flex-row items-center gap-8 ${isLeft ? 'md:flex-row' : 'md:flex-row-reverse'}`}>
|
|
265
259
|
<div className={`w-full md:w-1/2 relative flex ${isLeft ? 'justify-end' : 'justify-start'}`}>
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
{/* Dissolved Background Step Number */}
|
|
271
|
-
<div className="absolute -right-2 -bottom-4 text-7xl font-bold opacity-[0.1] dark:opacity-[0.15] pointer-events-none select-none italic group-hover:scale-110 transition-transform duration-500" style={{ color: colors.from }}>
|
|
272
|
-
{step}
|
|
273
|
-
</div>
|
|
274
|
-
|
|
275
|
-
<h3 className="font-semibold text-slate-900 dark:text-white mb-2 text-lg relative z-10 flex items-center gap-2">
|
|
276
|
-
<Icon className="w-5 h-5 opacity-80" style={{ color: colors.from }} />
|
|
277
|
-
{title}
|
|
260
|
+
<div className="relative p-6 rounded-2xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/3 max-w-md text-left overflow-hidden group">
|
|
261
|
+
<div className="absolute -right-2 -bottom-4 text-7xl font-bold opacity-[0.1] italic" style={{ color: colors.from }}>{step}</div>
|
|
262
|
+
<h3 className="font-semibold text-slate-900 dark:text-white mb-2 text-lg flex items-center gap-2">
|
|
263
|
+
<Icon className="w-5 h-5" style={{ color: colors.from }} /> {title}
|
|
278
264
|
</h3>
|
|
279
|
-
<p className="text-slate-600 dark:text-white/40 text-sm leading-relaxed
|
|
265
|
+
<p className="text-slate-600 dark:text-white/40 text-sm leading-relaxed">{desc}</p>
|
|
280
266
|
</div>
|
|
281
267
|
</div>
|
|
282
|
-
|
|
283
|
-
{/* Center Icon Node */}
|
|
284
|
-
<div
|
|
285
|
-
className="relative z-10 w-12 h-12 rounded-2xl flex items-center justify-center flex-shrink-0 shadow-xl transition-transform hover:scale-110 border-4 border-slate-50 dark:border-[#080811]"
|
|
286
|
-
style={{ background: `linear-gradient(135deg, ${colors.from}, ${colors.to})` }}
|
|
287
|
-
>
|
|
268
|
+
<div className="relative z-10 w-12 h-12 rounded-2xl flex items-center justify-center shadow-xl border-4 border-slate-50 dark:border-[#080811]" style={{ background: `linear-gradient(135deg, ${colors.from}, ${colors.to})` }}>
|
|
288
269
|
<Icon className="w-6 h-6 text-white" />
|
|
289
270
|
</div>
|
|
290
|
-
|
|
291
|
-
{/* Spacer for the other side */}
|
|
292
271
|
<div className="hidden md:block md:w-1/2" />
|
|
293
272
|
</div>
|
|
294
273
|
);
|
|
@@ -297,209 +276,60 @@ export default function HomePage() {
|
|
|
297
276
|
</div>
|
|
298
277
|
</div>
|
|
299
278
|
|
|
300
|
-
{/* ──
|
|
301
|
-
<div className="mt-32 max-w-5xl mx-auto
|
|
279
|
+
{/* ── Architecture Cards ── */}
|
|
280
|
+
<div className="relative z-10 mt-24 mb-32 grid gap-6 sm:grid-cols-3 max-w-5xl mx-auto">
|
|
281
|
+
{ARCHITECTURE_CARDS.map((card, i) => (
|
|
282
|
+
<ArchitectureCard key={i} {...card} />
|
|
283
|
+
))}
|
|
284
|
+
</div>
|
|
285
|
+
|
|
286
|
+
{/* ── Documentation ── */}
|
|
287
|
+
<div className="mt-32 max-w-6xl mx-auto mb-24 relative">
|
|
302
288
|
<div className="text-center mb-16">
|
|
303
|
-
<h2 className="text-3xl font-bold text-slate-900 dark:text-white mb-4">
|
|
304
|
-
<p className="text-slate-600 dark:text-white/40 max-w-2xl mx-auto">
|
|
305
|
-
Integrate universal RAG capabilities into your Next.js application with just a few lines of code.
|
|
306
|
-
</p>
|
|
289
|
+
<h2 className="text-3xl font-bold text-slate-900 dark:text-white mb-4">{LANDING_PAGE_CONTENT.guide.title}</h2>
|
|
290
|
+
<p className="text-slate-600 dark:text-white/40 max-w-2xl mx-auto">{LANDING_PAGE_CONTENT.guide.subtitle}</p>
|
|
307
291
|
</div>
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
>
|
|
325
|
-
<
|
|
326
|
-
</
|
|
327
|
-
<div className="
|
|
328
|
-
|
|
329
|
-
<
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
<p className="text-slate-600 dark:text-white/40 mb-6 text-sm">Add the Retrivora AI core to your project dependencies.</p>
|
|
333
|
-
|
|
334
|
-
<div className="relative group/code">
|
|
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 @retrivora-ai/rag-engine</span>
|
|
337
|
-
<button
|
|
338
|
-
onClick={() => copy('npm install @retrivora-ai/rag-engine', 'step1')}
|
|
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
|
-
title="Copy to clipboard"
|
|
341
|
-
>
|
|
342
|
-
{copied === 'step1' ? <Check className="w-4 h-4 text-emerald-400" /> : <Copy className="w-4 h-4" />}
|
|
343
|
-
</button>
|
|
292
|
+
<div className="relative z-10 w-full grid gap-16 lg:grid-cols-[280px_1fr] items-start">
|
|
293
|
+
<aside className="flex flex-col gap-10">
|
|
294
|
+
<section>
|
|
295
|
+
<h2 className="mb-6 text-[10px] font-black text-slate-400 dark:text-white/30 uppercase tracking-[0.3em] flex items-center gap-3">
|
|
296
|
+
<FileText size={14} className="text-indigo-500" /> Quick Start
|
|
297
|
+
</h2>
|
|
298
|
+
<ol className="space-y-6">
|
|
299
|
+
{QUICK_START_STEPS.map((step, i) => (
|
|
300
|
+
<li key={i} className="group flex items-start gap-4">
|
|
301
|
+
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg bg-white dark:bg-white/5 text-slate-600 dark:text-white/40 font-mono text-[10px] border border-slate-200 dark:border-white/10 shadow-sm">{i + 1}</span>
|
|
302
|
+
<span className="text-xs text-slate-500 dark:text-white/50 font-medium leading-relaxed pt-1">{step}</span>
|
|
303
|
+
</li>
|
|
304
|
+
))}
|
|
305
|
+
</ol>
|
|
306
|
+
</section>
|
|
307
|
+
<section className="rounded-2xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/3 p-6 shadow-sm">
|
|
308
|
+
<h2 className="mb-6 text-[10px] font-black text-slate-400 dark:text-white/30 uppercase tracking-[0.3em] flex items-center gap-3">
|
|
309
|
+
<Zap size={14} className="text-indigo-500" /> API Endpoints
|
|
310
|
+
</h2>
|
|
311
|
+
<div className="grid gap-2.5">
|
|
312
|
+
{API_ENDPOINTS.map((slug) => (
|
|
313
|
+
<div key={slug} className="group flex items-center justify-between p-2 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/5 hover:border-indigo-200 dark:hover:border-indigo-500/30">
|
|
314
|
+
<span className="text-[10px] font-mono text-slate-500 dark:text-white/30 group-hover:text-indigo-600">/api/{slug}</span>
|
|
315
|
+
<span className="text-[8px] font-bold text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-500/10 px-1.5 py-0.5 rounded border border-indigo-100 dark:border-indigo-500/20">POST</span>
|
|
344
316
|
</div>
|
|
345
|
-
|
|
317
|
+
))}
|
|
346
318
|
</div>
|
|
347
|
-
</
|
|
348
|
-
</
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
{/* Step 2: Configure UI */}
|
|
353
|
-
<div className="relative z-10 group">
|
|
354
|
-
<div className="h-full flex flex-col p-8 rounded-3xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/2 backdrop-blur-sm transition-all hover:shadow-2xl hover:shadow-indigo-500/10 overflow-hidden">
|
|
355
|
-
{/* Dissolved Background Step Number */}
|
|
356
|
-
<div className="absolute -right-2 -bottom-6 text-8xl font-bold opacity-[0.08] dark:opacity-[0.12] pointer-events-none select-none italic group-hover:scale-110 transition-transform duration-700" style={{ color: ui.primaryColor }}>
|
|
357
|
-
02
|
|
358
|
-
</div>
|
|
359
|
-
|
|
360
|
-
<div className="flex items-start gap-6 mb-6 relative z-10">
|
|
361
|
-
<div
|
|
362
|
-
className="w-12 h-12 rounded-2xl flex items-center justify-center text-white font-bold shrink-0 shadow-xl transition-transform group-hover:scale-110"
|
|
363
|
-
style={{ background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }}
|
|
364
|
-
>
|
|
365
|
-
<Layers className="w-6 h-6" />
|
|
366
|
-
</div>
|
|
367
|
-
<div>
|
|
368
|
-
<h3 className="text-xl font-semibold text-slate-900 dark:text-white mb-1">Setup UI</h3>
|
|
369
|
-
<p className="text-slate-600 dark:text-white/40 text-xs">Drop the widget into your layout.</p>
|
|
370
|
-
</div>
|
|
371
|
-
</div>
|
|
372
|
-
|
|
373
|
-
<div className="relative flex-1 group/code z-10">
|
|
374
|
-
<div className="absolute top-3 right-3 z-20">
|
|
375
|
-
<button
|
|
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
|
-
className="p-1.5 rounded-md bg-white/5 hover:bg-white/10 text-white/30 hover:text-white transition-all"
|
|
378
|
-
>
|
|
379
|
-
{copied === 'step2' ? <Check className="w-3 h-3 text-emerald-400" /> : <Copy className="w-3 h-3" />}
|
|
380
|
-
</button>
|
|
381
|
-
</div>
|
|
382
|
-
<div className="bg-slate-950 rounded-xl p-4 font-mono text-[11px] text-slate-400 border border-white/5 h-full overflow-x-auto">
|
|
383
|
-
<div className="text-[10px] text-white/20 mb-3 flex items-center gap-1.5 uppercase tracking-widest font-sans">
|
|
384
|
-
<FileText className="w-3 h-3" /> src/app/layout.tsx
|
|
385
|
-
</div>
|
|
386
|
-
<pre className="text-slate-300">
|
|
387
|
-
{`import { ConfigProvider, ChatWidget } from '@retrivora-ai/rag-engine';
|
|
388
|
-
|
|
389
|
-
<ConfigProvider config={{ projectId: 'demo' }}>
|
|
390
|
-
{children}
|
|
391
|
-
<ChatWidget position="bottom-right" />
|
|
392
|
-
</ConfigProvider>`}
|
|
393
|
-
</pre>
|
|
394
|
-
</div>
|
|
395
|
-
</div>
|
|
396
|
-
</div>
|
|
397
|
-
</div>
|
|
398
|
-
|
|
399
|
-
{/* Step 3: API Handler */}
|
|
400
|
-
<div className="relative z-10 group">
|
|
401
|
-
<div className="h-full flex flex-col p-8 rounded-3xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/2 backdrop-blur-sm transition-all hover:shadow-2xl hover:shadow-indigo-500/10 overflow-hidden">
|
|
402
|
-
{/* Dissolved Background Step Number */}
|
|
403
|
-
<div className="absolute -right-2 -bottom-6 text-8xl font-bold opacity-[0.08] dark:opacity-[0.12] pointer-events-none select-none italic group-hover:scale-110 transition-transform duration-700" style={{ color: ui.primaryColor }}>
|
|
404
|
-
03
|
|
405
|
-
</div>
|
|
406
|
-
|
|
407
|
-
<div className="flex items-start gap-6 mb-6 relative z-10">
|
|
408
|
-
<div
|
|
409
|
-
className="w-12 h-12 rounded-2xl flex items-center justify-center text-white font-bold shrink-0 shadow-xl transition-transform group-hover:scale-110"
|
|
410
|
-
style={{ background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }}
|
|
411
|
-
>
|
|
412
|
-
<Search className="w-6 h-6" />
|
|
413
|
-
</div>
|
|
414
|
-
<div>
|
|
415
|
-
<h3 className="text-xl font-semibold text-slate-900 dark:text-white mb-1">Mount Routes</h3>
|
|
416
|
-
<p className="text-slate-600 dark:text-white/40 text-xs">Bridge your server to the AI.</p>
|
|
417
|
-
</div>
|
|
418
|
-
</div>
|
|
419
|
-
|
|
420
|
-
<div className="relative flex-1 group/code z-10">
|
|
421
|
-
<div className="absolute top-3 right-3 z-20">
|
|
422
|
-
<button
|
|
423
|
-
onClick={() => copy(`import { createChatHandler, getRagConfig } from '@retrivora-ai/rag-engine/server';\n\nexport const POST = createChatHandler(getRagConfig());`, 'step3')}
|
|
424
|
-
className="p-1.5 rounded-md bg-white/5 hover:bg-white/10 text-white/30 hover:text-white transition-all"
|
|
425
|
-
>
|
|
426
|
-
{copied === 'step3' ? <Check className="w-3 h-3 text-emerald-400" /> : <Copy className="w-3 h-3" />}
|
|
427
|
-
</button>
|
|
428
|
-
</div>
|
|
429
|
-
<div className="bg-slate-950 rounded-xl p-4 font-mono text-[11px] text-slate-400 border border-white/5 h-full overflow-x-auto">
|
|
430
|
-
<div className="text-[10px] text-white/20 mb-3 flex items-center gap-1.5 uppercase tracking-widest font-sans">
|
|
431
|
-
<FileText className="w-3 h-3" /> api/chat/route.ts
|
|
432
|
-
</div>
|
|
433
|
-
<pre className="text-slate-300">
|
|
434
|
-
{`import { createChatHandler, getRagConfig } from '@retrivora-ai/rag-engine/server';
|
|
435
|
-
|
|
436
|
-
export const POST = createChatHandler(getRagConfig());`}
|
|
437
|
-
</pre>
|
|
438
|
-
</div>
|
|
439
|
-
</div>
|
|
440
|
-
</div>
|
|
441
|
-
</div>
|
|
442
|
-
</div>
|
|
443
|
-
|
|
444
|
-
{/* Step 4: Environment Variables */}
|
|
445
|
-
<div className="relative z-10 group">
|
|
446
|
-
<div className="flex flex-col md:flex-row items-start gap-8 p-8 rounded-3xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/2 backdrop-blur-sm transition-all hover:shadow-2xl hover:shadow-indigo-500/10 overflow-hidden">
|
|
447
|
-
{/* Dissolved Background Step Number */}
|
|
448
|
-
<div className="absolute -right-2 -bottom-6 text-9xl font-bold opacity-[0.08] dark:opacity-[0.12] pointer-events-none select-none italic group-hover:scale-110 transition-transform duration-700" style={{ color: ui.primaryColor }}>
|
|
449
|
-
04
|
|
450
|
-
</div>
|
|
451
|
-
|
|
452
|
-
<div
|
|
453
|
-
className="w-12 h-12 rounded-2xl flex items-center justify-center text-white font-bold shrink-0 shadow-xl transition-transform group-hover:scale-110 relative z-10"
|
|
454
|
-
style={{ background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }}
|
|
455
|
-
>
|
|
456
|
-
<Search className="w-6 h-6" />
|
|
457
|
-
</div>
|
|
458
|
-
<div className="flex-1 w-full relative z-10">
|
|
459
|
-
<div className="flex items-center justify-between mb-2">
|
|
460
|
-
<h3 className="text-xl font-semibold text-slate-900 dark:text-white">Configure Environment</h3>
|
|
461
|
-
<span className="text-[10px] font-mono text-slate-400 bg-slate-100 dark:bg-white/5 px-2 py-0.5 rounded">.env.local</span>
|
|
462
|
-
</div>
|
|
463
|
-
<p className="text-slate-600 dark:text-white/40 mb-6 text-sm">
|
|
464
|
-
Essential variables for both <span className="text-slate-900 dark:text-white font-medium">Server (Adapters)</span> and <span className="text-slate-900 dark:text-white font-medium">Client (UI context)</span>.
|
|
465
|
-
</p>
|
|
466
|
-
|
|
467
|
-
<div className="relative group/code">
|
|
468
|
-
<div className="absolute top-3 right-3 z-20">
|
|
469
|
-
<button
|
|
470
|
-
onClick={() => copy(`VECTOR_DB_PROVIDER=universal_rest\nLLM_PROVIDER=openai\nLLM_MODEL=gpt-4o\nNEXT_PUBLIC_UI_TITLE="AI Assistant"`, 'step4')}
|
|
471
|
-
className="p-1.5 rounded-md bg-white/5 hover:bg-white/10 text-white/30 hover:text-white transition-all"
|
|
472
|
-
>
|
|
473
|
-
{copied === 'step4' ? <Check className="w-3 h-3 text-emerald-400" /> : <Copy className="w-3 h-3" />}
|
|
474
|
-
</button>
|
|
475
|
-
</div>
|
|
476
|
-
<div className="bg-slate-950 rounded-xl p-5 font-mono text-sm text-indigo-300 border border-white/5 flex flex-col shadow-inner">
|
|
477
|
-
<span className="text-slate-500 text-xs mb-2"># Core Providers</span>
|
|
478
|
-
<span className="mb-1">VECTOR_DB_PROVIDER=universal_rest</span>
|
|
479
|
-
<span className="mb-4">LLM_PROVIDER=openai</span>
|
|
480
|
-
<span className="text-slate-500 text-xs mb-2"># Client UI (Public)</span>
|
|
481
|
-
<span>NEXT_PUBLIC_UI_TITLE="AI Assistant"</span>
|
|
482
|
-
</div>
|
|
483
|
-
</div>
|
|
484
|
-
</div>
|
|
485
|
-
</div>
|
|
486
|
-
</div>
|
|
319
|
+
</section>
|
|
320
|
+
</aside>
|
|
321
|
+
<section className="flex flex-col h-full min-h-[560px]">
|
|
322
|
+
<DocViewer activeSnippet={activeSnippet} setActiveSnippet={setActiveSnippet} />
|
|
323
|
+
</section>
|
|
487
324
|
</div>
|
|
488
|
-
|
|
489
325
|
<div className="mt-16 text-center">
|
|
490
|
-
<a
|
|
491
|
-
|
|
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
|
-
>
|
|
494
|
-
<Package className="w-5 h-5" />
|
|
495
|
-
Get Started on NPM
|
|
496
|
-
<ExternalLink className="w-4 h-4" />
|
|
326
|
+
<a href="https://www.npmjs.com/package/@retrivora-ai/rag-engine" 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 shadow-xl shadow-indigo-500/20">
|
|
327
|
+
<Package className="w-5 h-5" /> Get Started on NPM <ExternalLink className="w-4 h-4" />
|
|
497
328
|
</a>
|
|
498
329
|
</div>
|
|
499
330
|
</div>
|
|
500
331
|
</div>
|
|
501
332
|
|
|
502
|
-
{/* ── Floating widget demo (bottom-right corner) ── */}
|
|
503
333
|
<ChatWidget position="bottom-right" />
|
|
504
334
|
</main>
|
|
505
335
|
);
|