@retrivora-ai/rag-engine 1.0.0 → 1.0.2
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-APQVJ5F7.mjs → ChromaDBProvider-MIDOR4FW.mjs} +2 -2
- package/dist/{MilvusProvider-35US67MS.mjs → MilvusProvider-U7SKC27V.mjs} +2 -2
- package/dist/{MongoDBProvider-COVYZDP6.mjs → MongoDBProvider-BO2Y5DRR.mjs} +2 -2
- package/dist/{PineconeProvider-AWFJQDZL.mjs → PineconeProvider-QZNRKTN2.mjs} +2 -2
- package/dist/{PostgreSQLProvider-IEYRJ7XJ.mjs → PostgreSQLProvider-BMOETDZA.mjs} +1 -1
- package/dist/{QdrantProvider-M6TQYZRO.mjs → QdrantProvider-YNUNEOZH.mjs} +2 -2
- package/dist/{RedisProvider-3G5PBLZ4.mjs → RedisProvider-SR65SCKV.mjs} +2 -2
- package/dist/{SimpleGraphProvider-UK7DJW37.mjs → SimpleGraphProvider-SLOXO4M7.mjs} +1 -1
- package/dist/{UniversalVectorProvider-FYQ3B2PW.mjs → UniversalVectorProvider-IN67OS56.mjs} +3 -3
- package/dist/{WeaviateProvider-ITHO36IL.mjs → WeaviateProvider-5FWDFITI.mjs} +2 -2
- package/dist/{chunk-4A47RCG2.mjs → chunk-3DSHW676.mjs} +1 -1
- package/dist/{chunk-NXUCKY5L.mjs → chunk-5YGUXK7Z.mjs} +1 -1
- package/dist/{chunk-7SOSCZGS.mjs → chunk-73I6VWU3.mjs} +2 -2
- package/dist/{chunk-WGSZNY3X.mjs → chunk-CFVEZTBJ.mjs} +1 -1
- package/dist/{chunk-U6KHVZLF.mjs → chunk-LR3VMDVK.mjs} +2 -2
- package/dist/{chunk-OOQXNLXD.mjs → chunk-M6JSPGAR.mjs} +1 -1
- package/dist/{chunk-P4HAQ7KB.mjs → chunk-OJNAKSQ2.mjs} +90 -34
- package/dist/{chunk-TYHTZIDP.mjs → chunk-U55XRW3U.mjs} +1 -1
- package/dist/{chunk-ZNBKHNJ4.mjs → chunk-VUQJVIJT.mjs} +1 -1
- package/dist/{chunk-QMIKLALV.mjs → chunk-X4TOT24V.mjs} +32 -0
- package/dist/{chunk-67AJ6SMD.mjs → chunk-YLTMFW4M.mjs} +1 -1
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +109 -22
- package/dist/handlers/index.mjs +5 -3
- package/dist/{index-CrGMwXfO.d.ts → index-B2mutkgp.d.ts} +5 -1
- package/dist/{index-v669iV-k.d.mts → index-Bjy0es5a.d.mts} +5 -1
- package/dist/index.d.mts +13 -7
- package/dist/index.d.ts +13 -7
- package/dist/index.js +325 -380
- package/dist/index.mjs +315 -370
- package/dist/server.d.mts +7 -22
- package/dist/server.d.ts +7 -22
- package/dist/server.js +48 -22
- package/dist/server.mjs +11 -11
- package/package.json +1 -1
- package/src/components/ChatWindow.tsx +4 -3
- package/src/components/MessageBubble.tsx +5 -2
- package/src/core/Pipeline.ts +1 -0
- package/src/core/VectorPlugin.ts +13 -22
- package/src/handlers/index.ts +53 -0
- package/src/hooks/useRagChat.ts +79 -15
- package/src/providers/vectordb/MongoDBProvider.ts +1 -1
- package/src/rag/EntityExtractor.ts +3 -0
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mergeDefined
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YLTMFW4M.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__spreadProps,
|
|
6
6
|
__spreadValues
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-X4TOT24V.mjs";
|
|
8
8
|
|
|
9
9
|
// src/components/ChatWidget.tsx
|
|
10
|
-
import { useState as useState4 } from "react";
|
|
10
|
+
import React7, { useState as useState4 } from "react";
|
|
11
11
|
import { MessageSquare as MessageSquare2, X as X2 } from "lucide-react";
|
|
12
12
|
|
|
13
13
|
// src/components/ChatWindow.tsx
|
|
14
|
-
import { useState as useState3, useRef as useRef2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
|
|
14
|
+
import React6, { useState as useState3, useRef as useRef2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
|
|
15
15
|
import {
|
|
16
16
|
Bot as Bot3,
|
|
17
17
|
Trash2,
|
|
@@ -30,7 +30,6 @@ import remarkGfm from "remark-gfm";
|
|
|
30
30
|
// src/components/SourceCard.tsx
|
|
31
31
|
import React from "react";
|
|
32
32
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
33
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
34
33
|
function SourceCard({ source, index }) {
|
|
35
34
|
var _a, _b;
|
|
36
35
|
const [expanded, setExpanded] = React.useState(false);
|
|
@@ -39,37 +38,19 @@ function SourceCard({ source, index }) {
|
|
|
39
38
|
const scoreBg = source.score >= 0.8 ? "bg-emerald-50 border-emerald-100 dark:bg-emerald-400/10 dark:border-emerald-400/20" : source.score >= 0.6 ? "bg-amber-50 border-amber-100 dark:bg-amber-400/10 dark:border-amber-400/20" : "bg-rose-50 border-rose-100 dark:bg-rose-400/10 dark:border-rose-400/20";
|
|
40
39
|
const preview = source.content.slice(0, 120);
|
|
41
40
|
const hasMore = source.content.length > 120;
|
|
42
|
-
return /* @__PURE__ */
|
|
41
|
+
return /* @__PURE__ */ React.createElement(
|
|
43
42
|
"div",
|
|
44
43
|
{
|
|
45
44
|
className: `rounded-xl border backdrop-blur-sm p-3 transition-all duration-200 hover:scale-[1.01] cursor-pointer ${scoreBg}`,
|
|
46
|
-
onClick: () => setExpanded((e) => !e)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono", children: (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id })
|
|
52
|
-
] }),
|
|
53
|
-
/* @__PURE__ */ jsxs("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums`, children: [
|
|
54
|
-
scorePercent,
|
|
55
|
-
"%"
|
|
56
|
-
] })
|
|
57
|
-
] }),
|
|
58
|
-
/* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed", children: expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}` }),
|
|
59
|
-
hasMore && /* @__PURE__ */ jsx("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5", children: expanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60
|
-
/* @__PURE__ */ jsx(ChevronUp, { className: "w-3 h-3" }),
|
|
61
|
-
" Show less"
|
|
62
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: "w-3 h-3" }),
|
|
64
|
-
" Show more"
|
|
65
|
-
] }) })
|
|
66
|
-
]
|
|
67
|
-
}
|
|
45
|
+
onClick: () => setExpanded((e) => !e)
|
|
46
|
+
},
|
|
47
|
+
/* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ React.createElement("span", { className: "flex-shrink-0 w-5 h-5 rounded-full bg-slate-200 dark:bg-white/10 flex items-center justify-center text-[10px] font-bold text-slate-500 dark:text-white/60" }, index + 1), /* @__PURE__ */ React.createElement("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono" }, (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id)), /* @__PURE__ */ React.createElement("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums` }, scorePercent, "%")),
|
|
48
|
+
/* @__PURE__ */ React.createElement("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed" }, expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}`),
|
|
49
|
+
hasMore && /* @__PURE__ */ React.createElement("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5" }, expanded ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ChevronUp, { className: "w-3 h-3" }), " Show less") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ChevronDown, { className: "w-3 h-3" }), " Show more"))
|
|
68
50
|
);
|
|
69
51
|
}
|
|
70
52
|
|
|
71
53
|
// src/components/MessageBubble.tsx
|
|
72
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
73
54
|
function MessageBubble({
|
|
74
55
|
message,
|
|
75
56
|
sources,
|
|
@@ -79,52 +60,36 @@ function MessageBubble({
|
|
|
79
60
|
}) {
|
|
80
61
|
const isUser = message.role === "user";
|
|
81
62
|
const [showSources, setShowSources] = React2.useState(false);
|
|
82
|
-
return /* @__PURE__ */
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
onClick: () => setShowSources((s) => !s),
|
|
109
|
-
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1",
|
|
110
|
-
children: [
|
|
111
|
-
showSources ? /* @__PURE__ */ jsx2(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ jsx2(ChevronRight, { className: "w-3 h-3" }),
|
|
112
|
-
sources.length,
|
|
113
|
-
" source",
|
|
114
|
-
sources.length !== 1 ? "s" : "",
|
|
115
|
-
" used"
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
),
|
|
119
|
-
showSources && /* @__PURE__ */ jsx2("div", { className: "mt-2 flex flex-col gap-2", children: sources.map((src, i) => /* @__PURE__ */ jsx2(SourceCard, { source: src, index: i }, src.id)) })
|
|
120
|
-
] })
|
|
121
|
-
] })
|
|
122
|
-
] });
|
|
63
|
+
return /* @__PURE__ */ React2.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React2.createElement(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: `flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center shadow-lg ${isUser ? "text-white" : "bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80"}`,
|
|
67
|
+
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
68
|
+
},
|
|
69
|
+
isUser ? /* @__PURE__ */ React2.createElement(User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ React2.createElement(Bot, { className: "w-4 h-4" })
|
|
70
|
+
), /* @__PURE__ */ React2.createElement("div", { className: `flex flex-col gap-1 max-w-[75%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React2.createElement(
|
|
71
|
+
"div",
|
|
72
|
+
{
|
|
73
|
+
className: `relative px-4 py-3 rounded-2xl text-sm leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
74
|
+
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
75
|
+
},
|
|
76
|
+
isStreaming && !message.content ? /* @__PURE__ */ React2.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ React2.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ React2.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ React2.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ React2.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ React2.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm] }, message.content), isStreaming && message.content && /* @__PURE__ */ React2.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
77
|
+
), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "w-full" }, /* @__PURE__ */ React2.createElement(
|
|
78
|
+
"button",
|
|
79
|
+
{
|
|
80
|
+
onClick: () => setShowSources((s) => !s),
|
|
81
|
+
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
|
|
82
|
+
},
|
|
83
|
+
showSources ? /* @__PURE__ */ React2.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React2.createElement(ChevronRight, { className: "w-3 h-3" }),
|
|
84
|
+
sources.length,
|
|
85
|
+
" source",
|
|
86
|
+
sources.length !== 1 ? "s" : "",
|
|
87
|
+
" used"
|
|
88
|
+
), showSources && /* @__PURE__ */ React2.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ React2.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
|
|
123
89
|
}
|
|
124
90
|
|
|
125
91
|
// src/components/ConfigProvider.tsx
|
|
126
|
-
import { createContext, useContext } from "react";
|
|
127
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
92
|
+
import React3, { createContext, useContext } from "react";
|
|
128
93
|
var defaultConfig = {
|
|
129
94
|
projectId: "default",
|
|
130
95
|
ui: {
|
|
@@ -152,7 +117,7 @@ function ConfigProvider({
|
|
|
152
117
|
projectId: (config == null ? void 0 : config.projectId) || defaultConfig.projectId,
|
|
153
118
|
ui: mergeDefined(defaultConfig.ui, config == null ? void 0 : config.ui)
|
|
154
119
|
};
|
|
155
|
-
return /* @__PURE__ */
|
|
120
|
+
return /* @__PURE__ */ React3.createElement(ConfigContext.Provider, { value: merged }, children);
|
|
156
121
|
}
|
|
157
122
|
function useConfig() {
|
|
158
123
|
return useContext(ConfigContext);
|
|
@@ -160,7 +125,6 @@ function useConfig() {
|
|
|
160
125
|
|
|
161
126
|
// src/hooks/useRagChat.ts
|
|
162
127
|
import { useState as useState2, useCallback, useRef, useEffect as useEffect2 } from "react";
|
|
163
|
-
import axios from "axios";
|
|
164
128
|
|
|
165
129
|
// src/hooks/useStoredMessages.ts
|
|
166
130
|
import * as React4 from "react";
|
|
@@ -214,7 +178,6 @@ function useRagChat(projectId, options = {}) {
|
|
|
214
178
|
}, [messages]);
|
|
215
179
|
const sendMessage = useCallback(
|
|
216
180
|
async (text, options2) => {
|
|
217
|
-
var _a, _b, _c;
|
|
218
181
|
const trimmed = text.trim();
|
|
219
182
|
if (!trimmed || isLoading) return;
|
|
220
183
|
lastInputRef.current = trimmed;
|
|
@@ -231,22 +194,77 @@ function useRagChat(projectId, options = {}) {
|
|
|
231
194
|
setIsLoading(true);
|
|
232
195
|
try {
|
|
233
196
|
const history = messagesRef.current.map(({ role, content }) => ({ role, content }));
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
197
|
+
const response = await fetch(apiUrl, {
|
|
198
|
+
method: "POST",
|
|
199
|
+
headers: { "Content-Type": "application/json" },
|
|
200
|
+
body: JSON.stringify({
|
|
201
|
+
message: trimmed,
|
|
202
|
+
history,
|
|
203
|
+
namespace: namespace != null ? namespace : projectId
|
|
204
|
+
})
|
|
238
205
|
});
|
|
239
|
-
|
|
240
|
-
|
|
206
|
+
if (!response.ok) {
|
|
207
|
+
const errorData = await response.json().catch(() => ({}));
|
|
208
|
+
throw new Error(errorData.error || `Server returned ${response.status}`);
|
|
209
|
+
}
|
|
210
|
+
if (!response.body) {
|
|
211
|
+
throw new Error("No response body received from server");
|
|
212
|
+
}
|
|
213
|
+
const reader = response.body.getReader();
|
|
214
|
+
const decoder = new TextDecoder();
|
|
215
|
+
let assistantContent = "";
|
|
216
|
+
let sources = [];
|
|
217
|
+
const assistantMessageId = `assistant_${Date.now()}`;
|
|
218
|
+
setMessages((prev) => [
|
|
219
|
+
...prev,
|
|
220
|
+
{
|
|
221
|
+
id: assistantMessageId,
|
|
222
|
+
role: "assistant",
|
|
223
|
+
content: "",
|
|
224
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
225
|
+
}
|
|
226
|
+
]);
|
|
227
|
+
while (true) {
|
|
228
|
+
const { done, value } = await reader.read();
|
|
229
|
+
if (done) break;
|
|
230
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
231
|
+
if (chunk.includes("__METADATA__")) {
|
|
232
|
+
const [text2, metadataStr] = chunk.split("__METADATA__");
|
|
233
|
+
if (text2) assistantContent += text2;
|
|
234
|
+
try {
|
|
235
|
+
const meta = JSON.parse(metadataStr);
|
|
236
|
+
sources = meta.sources || [];
|
|
237
|
+
} catch (e) {
|
|
238
|
+
console.warn("[useRagChat] Failed to parse metadata");
|
|
239
|
+
}
|
|
240
|
+
} else if (chunk.includes("__ERROR__")) {
|
|
241
|
+
const [text2, errorStr] = chunk.split("__ERROR__");
|
|
242
|
+
if (text2) assistantContent += text2;
|
|
243
|
+
try {
|
|
244
|
+
const err = JSON.parse(errorStr);
|
|
245
|
+
setError(err.error || "Stream error");
|
|
246
|
+
} catch (e) {
|
|
247
|
+
setError("An error occurred during streaming");
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
assistantContent += chunk;
|
|
251
|
+
}
|
|
252
|
+
setMessages(
|
|
253
|
+
(prev) => prev.map(
|
|
254
|
+
(msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), { content: assistantContent, sources: sources.length > 0 ? sources : msg.sources }) : msg
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
const finalAssistantMessage = {
|
|
259
|
+
id: assistantMessageId,
|
|
241
260
|
role: "assistant",
|
|
242
|
-
content:
|
|
243
|
-
sources:
|
|
261
|
+
content: assistantContent,
|
|
262
|
+
sources: sources.length > 0 ? sources : void 0,
|
|
244
263
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
245
264
|
};
|
|
246
|
-
|
|
247
|
-
onReply == null ? void 0 : onReply(assistantMessage);
|
|
265
|
+
onReply == null ? void 0 : onReply(finalAssistantMessage);
|
|
248
266
|
} catch (err) {
|
|
249
|
-
const msg =
|
|
267
|
+
const msg = err instanceof Error ? err.message : "Something went wrong. Please try again.";
|
|
250
268
|
setError(msg);
|
|
251
269
|
onError == null ? void 0 : onError(msg);
|
|
252
270
|
} finally {
|
|
@@ -280,6 +298,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
280
298
|
}
|
|
281
299
|
|
|
282
300
|
// src/app/constants.tsx
|
|
301
|
+
import React5 from "react";
|
|
283
302
|
import {
|
|
284
303
|
Zap,
|
|
285
304
|
Database,
|
|
@@ -299,7 +318,6 @@ import {
|
|
|
299
318
|
Puzzle,
|
|
300
319
|
MessageSquare
|
|
301
320
|
} from "lucide-react";
|
|
302
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
303
321
|
var CHAT_SUGGESTIONS = [
|
|
304
322
|
"What can you help me with?",
|
|
305
323
|
"Summarise the key topics",
|
|
@@ -315,8 +333,8 @@ var BORDER_RADIUS_MAP = {
|
|
|
315
333
|
};
|
|
316
334
|
|
|
317
335
|
// src/components/ChatWindow.tsx
|
|
318
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
319
336
|
function ChatWindow({ className = "", style, onClose, showClose = false }) {
|
|
337
|
+
var _a;
|
|
320
338
|
const { ui, projectId } = useConfig();
|
|
321
339
|
const [input, setInput] = useState3("");
|
|
322
340
|
const [mounted, setMounted] = useState3(false);
|
|
@@ -329,9 +347,9 @@ function ChatWindow({ className = "", style, onClose, showClose = false }) {
|
|
|
329
347
|
setMounted(true);
|
|
330
348
|
}, []);
|
|
331
349
|
useEffect3(() => {
|
|
332
|
-
var
|
|
350
|
+
var _a2;
|
|
333
351
|
if (messages.length > 0 || isLoading) {
|
|
334
|
-
(
|
|
352
|
+
(_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
|
|
335
353
|
}
|
|
336
354
|
}, [messages, isLoading]);
|
|
337
355
|
const sendMessage = useCallback2(async () => {
|
|
@@ -340,8 +358,8 @@ function ChatWindow({ className = "", style, onClose, showClose = false }) {
|
|
|
340
358
|
setInput("");
|
|
341
359
|
await send(text);
|
|
342
360
|
window.setTimeout(() => {
|
|
343
|
-
var
|
|
344
|
-
return (
|
|
361
|
+
var _a2;
|
|
362
|
+
return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
|
|
345
363
|
}, 50);
|
|
346
364
|
}, [input, isLoading, send]);
|
|
347
365
|
const handleKeyDown = (e) => {
|
|
@@ -356,158 +374,120 @@ function ChatWindow({ className = "", style, onClose, showClose = false }) {
|
|
|
356
374
|
const isEmpty = messages.length === 0;
|
|
357
375
|
const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
|
|
358
376
|
const isGlass = ui.visualStyle !== "solid";
|
|
359
|
-
return /* @__PURE__ */
|
|
377
|
+
return /* @__PURE__ */ React6.createElement(
|
|
360
378
|
"div",
|
|
361
379
|
{
|
|
362
380
|
className: `flex flex-col border border-slate-200 dark:border-white/10 shadow-2xl transition-all duration-300 ${currentRadius} ${isGlass ? "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl" : "bg-white dark:bg-[#0f0f1a]"} ${className}`,
|
|
363
|
-
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
381
|
+
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
382
|
+
},
|
|
383
|
+
/* @__PURE__ */ React6.createElement(
|
|
384
|
+
"div",
|
|
385
|
+
{
|
|
386
|
+
className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
|
|
387
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
|
|
388
|
+
},
|
|
389
|
+
/* @__PURE__ */ React6.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
|
|
390
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
391
|
+
/* @__PURE__ */ React6.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
392
|
+
) : /* @__PURE__ */ React6.createElement(
|
|
393
|
+
"div",
|
|
394
|
+
{
|
|
395
|
+
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
396
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
397
|
+
},
|
|
398
|
+
/* @__PURE__ */ React6.createElement(Bot3, { className: "w-5 h-5 text-white" })
|
|
399
|
+
), /* @__PURE__ */ React6.createElement("div", null, /* @__PURE__ */ React6.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ React6.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
|
|
400
|
+
/* @__PURE__ */ React6.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React6.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400" }, /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), mounted && messages.length > 0 && /* @__PURE__ */ React6.createElement(
|
|
401
|
+
"button",
|
|
402
|
+
{
|
|
403
|
+
onClick: clearHistory,
|
|
404
|
+
title: "Clear conversation",
|
|
405
|
+
className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer"
|
|
406
|
+
},
|
|
407
|
+
/* @__PURE__ */ React6.createElement(Trash2, { className: "w-3.5 h-3.5" })
|
|
408
|
+
), showClose && onClose && /* @__PURE__ */ React6.createElement(
|
|
409
|
+
"button",
|
|
410
|
+
{
|
|
411
|
+
onClick: onClose,
|
|
412
|
+
title: "Close chat",
|
|
413
|
+
className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer"
|
|
414
|
+
},
|
|
415
|
+
/* @__PURE__ */ React6.createElement(X, { className: "w-4 h-4" })
|
|
416
|
+
))
|
|
417
|
+
),
|
|
418
|
+
/* @__PURE__ */ React6.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5 scrollbar-thin scrollbar-thumb-slate-200 dark:scrollbar-thumb-white/10 scrollbar-track-transparent min-h-0 bg-slate-50 dark:bg-transparent" }, !mounted || isEmpty ? (
|
|
419
|
+
/* Welcome state */
|
|
420
|
+
/* @__PURE__ */ React6.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ React6.createElement(
|
|
421
|
+
"div",
|
|
422
|
+
{
|
|
423
|
+
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
424
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
425
|
+
},
|
|
426
|
+
/* @__PURE__ */ React6.createElement(Sparkles2, { className: "w-8 h-8 text-white" })
|
|
427
|
+
), /* @__PURE__ */ React6.createElement("div", null, /* @__PURE__ */ React6.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ React6.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ React6.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
|
|
428
|
+
(suggestion) => /* @__PURE__ */ React6.createElement(
|
|
429
|
+
"button",
|
|
367
430
|
{
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
374
|
-
/* @__PURE__ */ jsx5("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
375
|
-
) : /* @__PURE__ */ jsx5(
|
|
376
|
-
"div",
|
|
377
|
-
{
|
|
378
|
-
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
379
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
380
|
-
children: /* @__PURE__ */ jsx5(Bot3, { className: "w-5 h-5 text-white" })
|
|
381
|
-
}
|
|
382
|
-
),
|
|
383
|
-
/* @__PURE__ */ jsxs3("div", { children: [
|
|
384
|
-
/* @__PURE__ */ jsx5("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight", children: ui.title }),
|
|
385
|
-
ui.poweredBy && /* @__PURE__ */ jsx5("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight", children: `Powered by ${ui.poweredBy}` })
|
|
386
|
-
] })
|
|
387
|
-
] }),
|
|
388
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
389
|
-
/* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400", children: [
|
|
390
|
-
/* @__PURE__ */ jsx5("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
|
|
391
|
-
"Online"
|
|
392
|
-
] }),
|
|
393
|
-
mounted && messages.length > 0 && /* @__PURE__ */ jsx5(
|
|
394
|
-
"button",
|
|
395
|
-
{
|
|
396
|
-
onClick: clearHistory,
|
|
397
|
-
title: "Clear conversation",
|
|
398
|
-
className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer",
|
|
399
|
-
children: /* @__PURE__ */ jsx5(Trash2, { className: "w-3.5 h-3.5" })
|
|
400
|
-
}
|
|
401
|
-
),
|
|
402
|
-
showClose && onClose && /* @__PURE__ */ jsx5(
|
|
403
|
-
"button",
|
|
404
|
-
{
|
|
405
|
-
onClick: onClose,
|
|
406
|
-
title: "Close chat",
|
|
407
|
-
className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer",
|
|
408
|
-
children: /* @__PURE__ */ jsx5(X, { className: "w-4 h-4" })
|
|
409
|
-
}
|
|
410
|
-
)
|
|
411
|
-
] })
|
|
412
|
-
]
|
|
413
|
-
}
|
|
414
|
-
),
|
|
415
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5 scrollbar-thin scrollbar-thumb-slate-200 dark:scrollbar-thumb-white/10 scrollbar-track-transparent min-h-0 bg-slate-50 dark:bg-transparent", children: [
|
|
416
|
-
!mounted || isEmpty ? (
|
|
417
|
-
/* Welcome state */
|
|
418
|
-
/* @__PURE__ */ jsxs3("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12", children: [
|
|
419
|
-
/* @__PURE__ */ jsx5(
|
|
420
|
-
"div",
|
|
421
|
-
{
|
|
422
|
-
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
423
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
424
|
-
children: /* @__PURE__ */ jsx5(Sparkles2, { className: "w-8 h-8 text-white" })
|
|
425
|
-
}
|
|
426
|
-
),
|
|
427
|
-
/* @__PURE__ */ jsxs3("div", { children: [
|
|
428
|
-
/* @__PURE__ */ jsx5("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed", children: ui.welcomeMessage }),
|
|
429
|
-
/* @__PURE__ */ jsx5("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2", children: "Ask a question to get started" })
|
|
430
|
-
] }),
|
|
431
|
-
/* @__PURE__ */ jsx5("div", { className: "flex flex-wrap gap-2 justify-center mt-2", children: CHAT_SUGGESTIONS.map(
|
|
432
|
-
(suggestion) => /* @__PURE__ */ jsx5(
|
|
433
|
-
"button",
|
|
434
|
-
{
|
|
435
|
-
onClick: () => {
|
|
436
|
-
var _a;
|
|
437
|
-
setInput(suggestion);
|
|
438
|
-
(_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
439
|
-
},
|
|
440
|
-
className: "px-3 py-1.5 rounded-full 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:border-slate-300 dark:hover:border-white/20 hover:bg-slate-100 dark:hover:bg-white/5 transition-all",
|
|
441
|
-
children: suggestion
|
|
442
|
-
},
|
|
443
|
-
suggestion
|
|
444
|
-
)
|
|
445
|
-
) })
|
|
446
|
-
] })
|
|
447
|
-
) : messages.map((msg) => /* @__PURE__ */ jsx5(
|
|
448
|
-
MessageBubble,
|
|
449
|
-
{
|
|
450
|
-
message: msg,
|
|
451
|
-
sources: msg.sources,
|
|
452
|
-
primaryColor: ui.primaryColor,
|
|
453
|
-
accentColor: ui.accentColor
|
|
431
|
+
key: suggestion,
|
|
432
|
+
onClick: () => {
|
|
433
|
+
var _a2;
|
|
434
|
+
setInput(suggestion);
|
|
435
|
+
(_a2 = inputRef.current) == null ? void 0 : _a2.focus();
|
|
454
436
|
},
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
}
|
|
437
|
+
className: "px-3 py-1.5 rounded-full 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:border-slate-300 dark:hover:border-white/20 hover:bg-slate-100 dark:hover:bg-white/5 transition-all"
|
|
438
|
+
},
|
|
439
|
+
suggestion
|
|
440
|
+
)
|
|
441
|
+
)))
|
|
442
|
+
) : messages.map((msg, index) => /* @__PURE__ */ React6.createElement(
|
|
443
|
+
MessageBubble,
|
|
444
|
+
{
|
|
445
|
+
key: msg.id,
|
|
446
|
+
message: msg,
|
|
447
|
+
sources: msg.sources,
|
|
448
|
+
isStreaming: isLoading && index === messages.length - 1 && msg.role === "assistant",
|
|
449
|
+
primaryColor: ui.primaryColor,
|
|
450
|
+
accentColor: ui.accentColor
|
|
451
|
+
}
|
|
452
|
+
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React6.createElement(
|
|
453
|
+
MessageBubble,
|
|
454
|
+
{
|
|
455
|
+
message: { role: "assistant", content: "" },
|
|
456
|
+
isStreaming: true,
|
|
457
|
+
primaryColor: ui.primaryColor,
|
|
458
|
+
accentColor: ui.accentColor
|
|
459
|
+
}
|
|
460
|
+
), error && /* @__PURE__ */ React6.createElement("div", { className: "flex items-center gap-2 text-rose-500 dark:text-rose-400 text-sm bg-rose-50 dark:bg-rose-400/10 border border-rose-200 dark:border-rose-400/20 rounded-xl px-4 py-3" }, /* @__PURE__ */ React6.createElement(TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ React6.createElement("span", null, error)), /* @__PURE__ */ React6.createElement("div", { ref: bottomRef })),
|
|
461
|
+
/* @__PURE__ */ React6.createElement("div", { className: `px-4 pb-4 pt-2 border-t border-slate-200 dark:border-white/10 ${isGlass ? "bg-transparent" : "bg-white dark:bg-[#0f0f1a]"}` }, /* @__PURE__ */ React6.createElement("div", { className: `flex items-end gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 p-2 focus-within:border-slate-300 dark:focus-within:border-white/20 transition-all ${ui.borderRadius === "full" ? "rounded-3xl" : "rounded-2xl"}` }, /* @__PURE__ */ React6.createElement(
|
|
462
|
+
"textarea",
|
|
463
|
+
{
|
|
464
|
+
ref: inputRef,
|
|
465
|
+
value: input,
|
|
466
|
+
onChange: (e) => setInput(e.target.value),
|
|
467
|
+
onKeyDown: handleKeyDown,
|
|
468
|
+
placeholder: ui.placeholder,
|
|
469
|
+
rows: 1,
|
|
470
|
+
disabled: isLoading,
|
|
471
|
+
className: "flex-1 bg-transparent text-slate-900 dark:text-white/90 placeholder-slate-400 dark:placeholder-white/30 text-sm resize-none outline-none py-1.5 px-2 max-h-32 leading-relaxed disabled:opacity-50",
|
|
472
|
+
style: { scrollbarWidth: "none" }
|
|
473
|
+
}
|
|
474
|
+
), /* @__PURE__ */ React6.createElement(
|
|
475
|
+
"button",
|
|
476
|
+
{
|
|
477
|
+
onClick: sendMessage,
|
|
478
|
+
disabled: !input.trim() || isLoading,
|
|
479
|
+
className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all disabled:opacity-30 disabled:cursor-not-allowed hover:scale-105 active:scale-95 shadow-md",
|
|
480
|
+
style: {
|
|
481
|
+
background: input.trim() && !isLoading ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
|
|
482
|
+
// slate-400/20 for light mode disabled
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
/* @__PURE__ */ React6.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
|
|
486
|
+
)), /* @__PURE__ */ React6.createElement("p", { className: "text-center text-[10px] text-slate-400 dark:text-white/20 mt-2" }, "Press Enter to send \xB7 Shift+Enter for new line"))
|
|
506
487
|
);
|
|
507
488
|
}
|
|
508
489
|
|
|
509
490
|
// src/components/ChatWidget.tsx
|
|
510
|
-
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
511
491
|
function ChatWidget({ position = "bottom-right" }) {
|
|
512
492
|
const { ui } = useConfig();
|
|
513
493
|
const [isOpen, setIsOpen] = useState4(false);
|
|
@@ -520,63 +500,55 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
520
500
|
setIsOpen(true);
|
|
521
501
|
setHasUnread(false);
|
|
522
502
|
};
|
|
523
|
-
return /* @__PURE__ */
|
|
524
|
-
|
|
525
|
-
|
|
503
|
+
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(
|
|
504
|
+
"div",
|
|
505
|
+
{
|
|
506
|
+
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"}`,
|
|
507
|
+
style: { height: "600px", maxHeight: "calc(100vh - 6rem)" }
|
|
508
|
+
},
|
|
509
|
+
/* @__PURE__ */ React7.createElement(
|
|
510
|
+
ChatWindow,
|
|
526
511
|
{
|
|
527
|
-
className:
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
/* @__PURE__ */ jsx6(
|
|
531
|
-
ChatWindow,
|
|
532
|
-
{
|
|
533
|
-
className: "h-full relative z-10",
|
|
534
|
-
showClose: true,
|
|
535
|
-
onClose: () => setIsOpen(false)
|
|
536
|
-
}
|
|
537
|
-
),
|
|
538
|
-
/* @__PURE__ */ jsx6(
|
|
539
|
-
"div",
|
|
540
|
-
{
|
|
541
|
-
className: `absolute -bottom-1.5 w-4 h-4 rotate-45 border-r border-b border-slate-200 dark:border-white/10 z-0 ${ui.visualStyle === "solid" ? "bg-white dark:bg-[#0f0f1a]" : "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl"} ${position === "bottom-left" ? "left-5" : "right-5"}`
|
|
542
|
-
}
|
|
543
|
-
)
|
|
544
|
-
]
|
|
512
|
+
className: "h-full relative z-10",
|
|
513
|
+
showClose: true,
|
|
514
|
+
onClose: () => setIsOpen(false)
|
|
545
515
|
}
|
|
546
516
|
),
|
|
547
|
-
/* @__PURE__ */
|
|
548
|
-
"
|
|
517
|
+
/* @__PURE__ */ React7.createElement(
|
|
518
|
+
"div",
|
|
549
519
|
{
|
|
550
|
-
|
|
551
|
-
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}`,
|
|
552
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
553
|
-
"aria-label": "Open chat",
|
|
554
|
-
children: [
|
|
555
|
-
/* @__PURE__ */ jsx6(
|
|
556
|
-
"span",
|
|
557
|
-
{
|
|
558
|
-
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
559
|
-
style: { background: ui.primaryColor }
|
|
560
|
-
}
|
|
561
|
-
),
|
|
562
|
-
/* @__PURE__ */ jsx6(
|
|
563
|
-
"span",
|
|
564
|
-
{
|
|
565
|
-
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`,
|
|
566
|
-
children: isOpen ? /* @__PURE__ */ jsx6(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ jsx6(MessageSquare2, { className: "w-6 h-6 text-white" })
|
|
567
|
-
}
|
|
568
|
-
),
|
|
569
|
-
hasUnread && !isOpen && /* @__PURE__ */ jsx6("span", { className: "absolute top-0 right-0 w-4 h-4 bg-rose-500 rounded-full border-2 border-white flex items-center justify-center text-[9px] font-bold text-white", children: "1" })
|
|
570
|
-
]
|
|
520
|
+
className: `absolute -bottom-1.5 w-4 h-4 rotate-45 border-r border-b border-slate-200 dark:border-white/10 z-0 ${ui.visualStyle === "solid" ? "bg-white dark:bg-[#0f0f1a]" : "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl"} ${position === "bottom-left" ? "left-5" : "right-5"}`
|
|
571
521
|
}
|
|
572
522
|
)
|
|
573
|
-
|
|
523
|
+
), /* @__PURE__ */ React7.createElement(
|
|
524
|
+
"button",
|
|
525
|
+
{
|
|
526
|
+
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
527
|
+
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}`,
|
|
528
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
529
|
+
"aria-label": "Open chat"
|
|
530
|
+
},
|
|
531
|
+
/* @__PURE__ */ React7.createElement(
|
|
532
|
+
"span",
|
|
533
|
+
{
|
|
534
|
+
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
535
|
+
style: { background: ui.primaryColor }
|
|
536
|
+
}
|
|
537
|
+
),
|
|
538
|
+
/* @__PURE__ */ React7.createElement(
|
|
539
|
+
"span",
|
|
540
|
+
{
|
|
541
|
+
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
|
|
542
|
+
},
|
|
543
|
+
isOpen ? /* @__PURE__ */ React7.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React7.createElement(MessageSquare2, { className: "w-6 h-6 text-white" })
|
|
544
|
+
),
|
|
545
|
+
hasUnread && !isOpen && /* @__PURE__ */ React7.createElement("span", { className: "absolute top-0 right-0 w-4 h-4 bg-rose-500 rounded-full border-2 border-white flex items-center justify-center text-[9px] font-bold text-white" }, "1")
|
|
546
|
+
));
|
|
574
547
|
}
|
|
575
548
|
|
|
576
549
|
// src/components/DocumentUpload.tsx
|
|
577
|
-
import { useState as useState5, useRef as useRef3 } from "react";
|
|
550
|
+
import React8, { useState as useState5, useRef as useRef3 } from "react";
|
|
578
551
|
import { Upload, File, X as X3, CheckCircle, AlertCircle, Loader2 } from "lucide-react";
|
|
579
|
-
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
580
552
|
function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
581
553
|
const { ui } = useConfig();
|
|
582
554
|
const [fileStates, setFileStates] = useState5([]);
|
|
@@ -631,99 +603,72 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
631
603
|
};
|
|
632
604
|
const isUploading = fileStates.some((s) => s.status === "uploading");
|
|
633
605
|
const hasIdle = fileStates.some((s) => s.status === "idle");
|
|
634
|
-
return /* @__PURE__ */
|
|
606
|
+
return /* @__PURE__ */ React8.createElement(
|
|
635
607
|
"div",
|
|
636
608
|
{
|
|
637
609
|
className: `p-6 border-2 border-dashed transition-all duration-300 rounded-2xl ${isDragging ? "border-emerald-500 bg-emerald-50/50 dark:bg-emerald-500/5" : "border-slate-200 dark:border-white/10 bg-white dark:bg-white/5"} ${className}`,
|
|
638
610
|
onDragOver,
|
|
639
611
|
onDragLeave,
|
|
640
|
-
onDrop
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
state.status === "success" && /* @__PURE__ */ jsx7(CheckCircle, { className: "w-4 h-4 text-emerald-500" }),
|
|
701
|
-
state.status === "error" && /* @__PURE__ */ jsx7("div", { title: state.error, children: /* @__PURE__ */ jsx7(AlertCircle, { className: "w-4 h-4 text-rose-500" }) }),
|
|
702
|
-
state.status !== "uploading" && /* @__PURE__ */ jsx7(
|
|
703
|
-
"button",
|
|
704
|
-
{
|
|
705
|
-
onClick: () => removeFile(i),
|
|
706
|
-
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors",
|
|
707
|
-
children: /* @__PURE__ */ jsx7(X3, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
708
|
-
}
|
|
709
|
-
)
|
|
710
|
-
] })
|
|
711
|
-
]
|
|
712
|
-
},
|
|
713
|
-
i
|
|
714
|
-
)),
|
|
715
|
-
hasIdle && !isUploading && /* @__PURE__ */ jsx7(
|
|
716
|
-
"button",
|
|
717
|
-
{
|
|
718
|
-
onClick: uploadFiles,
|
|
719
|
-
className: "w-full mt-4 py-2.5 rounded-xl text-sm font-semibold text-white shadow-lg transition-all hover:scale-[1.02] active:scale-[0.98]",
|
|
720
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
721
|
-
children: "Start Upload"
|
|
722
|
-
}
|
|
723
|
-
)
|
|
724
|
-
] })
|
|
725
|
-
]
|
|
726
|
-
}
|
|
612
|
+
onDrop
|
|
613
|
+
},
|
|
614
|
+
/* @__PURE__ */ React8.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React8.createElement(
|
|
615
|
+
"div",
|
|
616
|
+
{
|
|
617
|
+
className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
|
|
618
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
|
|
619
|
+
},
|
|
620
|
+
/* @__PURE__ */ React8.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
|
|
621
|
+
), /* @__PURE__ */ React8.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ React8.createElement("p", { className: "text-slate-500 dark:text-white/40 text-sm mb-6 max-w-xs" }, "Drag and drop PDF, DOCX, TXT, or JSON files to train your AI on your own data."), /* @__PURE__ */ React8.createElement(
|
|
622
|
+
"button",
|
|
623
|
+
{
|
|
624
|
+
onClick: () => {
|
|
625
|
+
var _a;
|
|
626
|
+
return (_a = fileInputRef.current) == null ? void 0 : _a.click();
|
|
627
|
+
},
|
|
628
|
+
disabled: isUploading,
|
|
629
|
+
className: "px-4 py-2 rounded-lg text-sm font-medium transition-all hover:scale-105 active:scale-95 disabled:opacity-50",
|
|
630
|
+
style: {
|
|
631
|
+
backgroundColor: `${ui.primaryColor}15`,
|
|
632
|
+
color: ui.primaryColor,
|
|
633
|
+
border: `1px solid ${ui.primaryColor}30`
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
"Select Files"
|
|
637
|
+
), /* @__PURE__ */ React8.createElement(
|
|
638
|
+
"input",
|
|
639
|
+
{
|
|
640
|
+
ref: fileInputRef,
|
|
641
|
+
type: "file",
|
|
642
|
+
multiple: true,
|
|
643
|
+
onChange: onFileSelect,
|
|
644
|
+
className: "hidden",
|
|
645
|
+
accept: ".pdf,.docx,.txt,.md,.json,.csv"
|
|
646
|
+
}
|
|
647
|
+
)),
|
|
648
|
+
fileStates.length > 0 && /* @__PURE__ */ React8.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React8.createElement(
|
|
649
|
+
"div",
|
|
650
|
+
{
|
|
651
|
+
key: i,
|
|
652
|
+
className: "flex items-center justify-between p-3 rounded-xl bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/10"
|
|
653
|
+
},
|
|
654
|
+
/* @__PURE__ */ React8.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React8.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ React8.createElement(File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ React8.createElement("div", { className: "truncate" }, /* @__PURE__ */ React8.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ React8.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
|
|
655
|
+
/* @__PURE__ */ React8.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ React8.createElement(Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ React8.createElement(CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ React8.createElement("div", { title: state.error }, /* @__PURE__ */ React8.createElement(AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ React8.createElement(
|
|
656
|
+
"button",
|
|
657
|
+
{
|
|
658
|
+
onClick: () => removeFile(i),
|
|
659
|
+
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
|
|
660
|
+
},
|
|
661
|
+
/* @__PURE__ */ React8.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
662
|
+
))
|
|
663
|
+
)), hasIdle && !isUploading && /* @__PURE__ */ React8.createElement(
|
|
664
|
+
"button",
|
|
665
|
+
{
|
|
666
|
+
onClick: uploadFiles,
|
|
667
|
+
className: "w-full mt-4 py-2.5 rounded-xl text-sm font-semibold text-white shadow-lg transition-all hover:scale-[1.02] active:scale-[0.98]",
|
|
668
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
669
|
+
},
|
|
670
|
+
"Start Upload"
|
|
671
|
+
))
|
|
727
672
|
);
|
|
728
673
|
}
|
|
729
674
|
export {
|