@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.js
CHANGED
|
@@ -59,11 +59,11 @@ __export(index_exports, {
|
|
|
59
59
|
module.exports = __toCommonJS(index_exports);
|
|
60
60
|
|
|
61
61
|
// src/components/ChatWidget.tsx
|
|
62
|
-
var
|
|
62
|
+
var import_react7 = __toESM(require("react"));
|
|
63
63
|
var import_lucide_react5 = require("lucide-react");
|
|
64
64
|
|
|
65
65
|
// src/components/ChatWindow.tsx
|
|
66
|
-
var
|
|
66
|
+
var import_react6 = __toESM(require("react"));
|
|
67
67
|
var import_lucide_react4 = require("lucide-react");
|
|
68
68
|
|
|
69
69
|
// src/components/MessageBubble.tsx
|
|
@@ -75,7 +75,6 @@ var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
|
75
75
|
// src/components/SourceCard.tsx
|
|
76
76
|
var import_react = __toESM(require("react"));
|
|
77
77
|
var import_lucide_react = require("lucide-react");
|
|
78
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
79
78
|
function SourceCard({ source, index }) {
|
|
80
79
|
var _a, _b;
|
|
81
80
|
const [expanded, setExpanded] = import_react.default.useState(false);
|
|
@@ -84,37 +83,19 @@ function SourceCard({ source, index }) {
|
|
|
84
83
|
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";
|
|
85
84
|
const preview = source.content.slice(0, 120);
|
|
86
85
|
const hasMore = source.content.length > 120;
|
|
87
|
-
return /* @__PURE__ */
|
|
86
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
88
87
|
"div",
|
|
89
88
|
{
|
|
90
89
|
className: `rounded-xl border backdrop-blur-sm p-3 transition-all duration-200 hover:scale-[1.01] cursor-pointer ${scoreBg}`,
|
|
91
|
-
onClick: () => setExpanded((e) => !e)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/* @__PURE__ */ (0, import_jsx_runtime.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 })
|
|
97
|
-
] }),
|
|
98
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums`, children: [
|
|
99
|
-
scorePercent,
|
|
100
|
-
"%"
|
|
101
|
-
] })
|
|
102
|
-
] }),
|
|
103
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed", children: expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}` }),
|
|
104
|
-
hasMore && /* @__PURE__ */ (0, import_jsx_runtime.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__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
105
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronUp, { className: "w-3 h-3" }),
|
|
106
|
-
" Show less"
|
|
107
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
108
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronDown, { className: "w-3 h-3" }),
|
|
109
|
-
" Show more"
|
|
110
|
-
] }) })
|
|
111
|
-
]
|
|
112
|
-
}
|
|
90
|
+
onClick: () => setExpanded((e) => !e)
|
|
91
|
+
},
|
|
92
|
+
/* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ import_react.default.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__ */ import_react.default.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__ */ import_react.default.createElement("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums` }, scorePercent, "%")),
|
|
93
|
+
/* @__PURE__ */ import_react.default.createElement("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed" }, expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}`),
|
|
94
|
+
hasMore && /* @__PURE__ */ import_react.default.createElement("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5" }, expanded ? /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronUp, { className: "w-3 h-3" }), " Show less") : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronDown, { className: "w-3 h-3" }), " Show more"))
|
|
113
95
|
);
|
|
114
96
|
}
|
|
115
97
|
|
|
116
98
|
// src/components/MessageBubble.tsx
|
|
117
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
118
99
|
function MessageBubble({
|
|
119
100
|
message,
|
|
120
101
|
sources,
|
|
@@ -124,51 +105,36 @@ function MessageBubble({
|
|
|
124
105
|
}) {
|
|
125
106
|
const isUser = message.role === "user";
|
|
126
107
|
const [showSources, setShowSources] = import_react2.default.useState(false);
|
|
127
|
-
return /* @__PURE__ */
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
onClick: () => setShowSources((s) => !s),
|
|
154
|
-
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1",
|
|
155
|
-
children: [
|
|
156
|
-
showSources ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.ChevronRight, { className: "w-3 h-3" }),
|
|
157
|
-
sources.length,
|
|
158
|
-
" source",
|
|
159
|
-
sources.length !== 1 ? "s" : "",
|
|
160
|
-
" used"
|
|
161
|
-
]
|
|
162
|
-
}
|
|
163
|
-
),
|
|
164
|
-
showSources && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mt-2 flex flex-col gap-2", children: sources.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SourceCard, { source: src, index: i }, src.id)) })
|
|
165
|
-
] })
|
|
166
|
-
] })
|
|
167
|
-
] });
|
|
108
|
+
return /* @__PURE__ */ import_react2.default.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ import_react2.default.createElement(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
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"}`,
|
|
112
|
+
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
113
|
+
},
|
|
114
|
+
isUser ? /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.Bot, { className: "w-4 h-4" })
|
|
115
|
+
), /* @__PURE__ */ import_react2.default.createElement("div", { className: `flex flex-col gap-1 max-w-[75%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ import_react2.default.createElement(
|
|
116
|
+
"div",
|
|
117
|
+
{
|
|
118
|
+
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"}`,
|
|
119
|
+
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
120
|
+
},
|
|
121
|
+
isStreaming && !message.content ? /* @__PURE__ */ import_react2.default.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ import_react2.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ import_react2.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ import_react2.default.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ import_react2.default.createElement(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default] }, message.content), isStreaming && message.content && /* @__PURE__ */ import_react2.default.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
122
|
+
), !isUser && sources && sources.length > 0 && /* @__PURE__ */ import_react2.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react2.default.createElement(
|
|
123
|
+
"button",
|
|
124
|
+
{
|
|
125
|
+
onClick: () => setShowSources((s) => !s),
|
|
126
|
+
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
|
|
127
|
+
},
|
|
128
|
+
showSources ? /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ChevronRight, { className: "w-3 h-3" }),
|
|
129
|
+
sources.length,
|
|
130
|
+
" source",
|
|
131
|
+
sources.length !== 1 ? "s" : "",
|
|
132
|
+
" used"
|
|
133
|
+
), showSources && /* @__PURE__ */ import_react2.default.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ import_react2.default.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
|
|
168
134
|
}
|
|
169
135
|
|
|
170
136
|
// src/components/ConfigProvider.tsx
|
|
171
|
-
var import_react3 = require("react");
|
|
137
|
+
var import_react3 = __toESM(require("react"));
|
|
172
138
|
|
|
173
139
|
// src/utils/templateUtils.ts
|
|
174
140
|
function mergeDefined(base, override) {
|
|
@@ -185,7 +151,6 @@ function mergeDefined(base, override) {
|
|
|
185
151
|
}
|
|
186
152
|
|
|
187
153
|
// src/components/ConfigProvider.tsx
|
|
188
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
189
154
|
var defaultConfig = {
|
|
190
155
|
projectId: "default",
|
|
191
156
|
ui: {
|
|
@@ -213,7 +178,7 @@ function ConfigProvider({
|
|
|
213
178
|
projectId: (config == null ? void 0 : config.projectId) || defaultConfig.projectId,
|
|
214
179
|
ui: mergeDefined(defaultConfig.ui, config == null ? void 0 : config.ui)
|
|
215
180
|
};
|
|
216
|
-
return /* @__PURE__ */
|
|
181
|
+
return /* @__PURE__ */ import_react3.default.createElement(ConfigContext.Provider, { value: merged }, children);
|
|
217
182
|
}
|
|
218
183
|
function useConfig() {
|
|
219
184
|
return (0, import_react3.useContext)(ConfigContext);
|
|
@@ -221,7 +186,6 @@ function useConfig() {
|
|
|
221
186
|
|
|
222
187
|
// src/hooks/useRagChat.ts
|
|
223
188
|
var import_react4 = require("react");
|
|
224
|
-
var import_axios = __toESM(require("axios"));
|
|
225
189
|
|
|
226
190
|
// src/hooks/useStoredMessages.ts
|
|
227
191
|
var React4 = __toESM(require("react"));
|
|
@@ -275,7 +239,6 @@ function useRagChat(projectId, options = {}) {
|
|
|
275
239
|
}, [messages]);
|
|
276
240
|
const sendMessage = (0, import_react4.useCallback)(
|
|
277
241
|
async (text, options2) => {
|
|
278
|
-
var _a, _b, _c;
|
|
279
242
|
const trimmed = text.trim();
|
|
280
243
|
if (!trimmed || isLoading) return;
|
|
281
244
|
lastInputRef.current = trimmed;
|
|
@@ -292,22 +255,77 @@ function useRagChat(projectId, options = {}) {
|
|
|
292
255
|
setIsLoading(true);
|
|
293
256
|
try {
|
|
294
257
|
const history = messagesRef.current.map(({ role, content }) => ({ role, content }));
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
258
|
+
const response = await fetch(apiUrl, {
|
|
259
|
+
method: "POST",
|
|
260
|
+
headers: { "Content-Type": "application/json" },
|
|
261
|
+
body: JSON.stringify({
|
|
262
|
+
message: trimmed,
|
|
263
|
+
history,
|
|
264
|
+
namespace: namespace != null ? namespace : projectId
|
|
265
|
+
})
|
|
299
266
|
});
|
|
300
|
-
|
|
301
|
-
|
|
267
|
+
if (!response.ok) {
|
|
268
|
+
const errorData = await response.json().catch(() => ({}));
|
|
269
|
+
throw new Error(errorData.error || `Server returned ${response.status}`);
|
|
270
|
+
}
|
|
271
|
+
if (!response.body) {
|
|
272
|
+
throw new Error("No response body received from server");
|
|
273
|
+
}
|
|
274
|
+
const reader = response.body.getReader();
|
|
275
|
+
const decoder = new TextDecoder();
|
|
276
|
+
let assistantContent = "";
|
|
277
|
+
let sources = [];
|
|
278
|
+
const assistantMessageId = `assistant_${Date.now()}`;
|
|
279
|
+
setMessages((prev) => [
|
|
280
|
+
...prev,
|
|
281
|
+
{
|
|
282
|
+
id: assistantMessageId,
|
|
283
|
+
role: "assistant",
|
|
284
|
+
content: "",
|
|
285
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
286
|
+
}
|
|
287
|
+
]);
|
|
288
|
+
while (true) {
|
|
289
|
+
const { done, value } = await reader.read();
|
|
290
|
+
if (done) break;
|
|
291
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
292
|
+
if (chunk.includes("__METADATA__")) {
|
|
293
|
+
const [text2, metadataStr] = chunk.split("__METADATA__");
|
|
294
|
+
if (text2) assistantContent += text2;
|
|
295
|
+
try {
|
|
296
|
+
const meta = JSON.parse(metadataStr);
|
|
297
|
+
sources = meta.sources || [];
|
|
298
|
+
} catch (e) {
|
|
299
|
+
console.warn("[useRagChat] Failed to parse metadata");
|
|
300
|
+
}
|
|
301
|
+
} else if (chunk.includes("__ERROR__")) {
|
|
302
|
+
const [text2, errorStr] = chunk.split("__ERROR__");
|
|
303
|
+
if (text2) assistantContent += text2;
|
|
304
|
+
try {
|
|
305
|
+
const err = JSON.parse(errorStr);
|
|
306
|
+
setError(err.error || "Stream error");
|
|
307
|
+
} catch (e) {
|
|
308
|
+
setError("An error occurred during streaming");
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
assistantContent += chunk;
|
|
312
|
+
}
|
|
313
|
+
setMessages(
|
|
314
|
+
(prev) => prev.map(
|
|
315
|
+
(msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), { content: assistantContent, sources: sources.length > 0 ? sources : msg.sources }) : msg
|
|
316
|
+
)
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const finalAssistantMessage = {
|
|
320
|
+
id: assistantMessageId,
|
|
302
321
|
role: "assistant",
|
|
303
|
-
content:
|
|
304
|
-
sources:
|
|
322
|
+
content: assistantContent,
|
|
323
|
+
sources: sources.length > 0 ? sources : void 0,
|
|
305
324
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
306
325
|
};
|
|
307
|
-
|
|
308
|
-
onReply == null ? void 0 : onReply(assistantMessage);
|
|
326
|
+
onReply == null ? void 0 : onReply(finalAssistantMessage);
|
|
309
327
|
} catch (err) {
|
|
310
|
-
const msg =
|
|
328
|
+
const msg = err instanceof Error ? err.message : "Something went wrong. Please try again.";
|
|
311
329
|
setError(msg);
|
|
312
330
|
onError == null ? void 0 : onError(msg);
|
|
313
331
|
} finally {
|
|
@@ -341,8 +359,8 @@ function useRagChat(projectId, options = {}) {
|
|
|
341
359
|
}
|
|
342
360
|
|
|
343
361
|
// src/app/constants.tsx
|
|
362
|
+
var import_react5 = __toESM(require("react"));
|
|
344
363
|
var import_lucide_react3 = require("lucide-react");
|
|
345
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
346
364
|
var CHAT_SUGGESTIONS = [
|
|
347
365
|
"What can you help me with?",
|
|
348
366
|
"Summarise the key topics",
|
|
@@ -358,36 +376,33 @@ var BORDER_RADIUS_MAP = {
|
|
|
358
376
|
};
|
|
359
377
|
|
|
360
378
|
// src/components/ChatWindow.tsx
|
|
361
|
-
var import_jsx_runtime5 = (
|
|
362
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
363
|
-
require("react/jsx-runtime")
|
|
364
|
-
);
|
|
365
379
|
function ChatWindow({ className = "", style, onClose, showClose = false }) {
|
|
380
|
+
var _a;
|
|
366
381
|
const { ui, projectId } = useConfig();
|
|
367
|
-
const [input, setInput] = (0,
|
|
368
|
-
const [mounted, setMounted] = (0,
|
|
369
|
-
const bottomRef = (0,
|
|
370
|
-
const inputRef = (0,
|
|
382
|
+
const [input, setInput] = (0, import_react6.useState)("");
|
|
383
|
+
const [mounted, setMounted] = (0, import_react6.useState)(false);
|
|
384
|
+
const bottomRef = (0, import_react6.useRef)(null);
|
|
385
|
+
const inputRef = (0, import_react6.useRef)(null);
|
|
371
386
|
const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
|
|
372
387
|
namespace: projectId
|
|
373
388
|
});
|
|
374
|
-
(0,
|
|
389
|
+
(0, import_react6.useEffect)(() => {
|
|
375
390
|
setMounted(true);
|
|
376
391
|
}, []);
|
|
377
|
-
(0,
|
|
378
|
-
var
|
|
392
|
+
(0, import_react6.useEffect)(() => {
|
|
393
|
+
var _a2;
|
|
379
394
|
if (messages.length > 0 || isLoading) {
|
|
380
|
-
(
|
|
395
|
+
(_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
|
|
381
396
|
}
|
|
382
397
|
}, [messages, isLoading]);
|
|
383
|
-
const sendMessage = (0,
|
|
398
|
+
const sendMessage = (0, import_react6.useCallback)(async () => {
|
|
384
399
|
const text = input.trim();
|
|
385
400
|
if (!text || isLoading) return;
|
|
386
401
|
setInput("");
|
|
387
402
|
await send(text);
|
|
388
403
|
window.setTimeout(() => {
|
|
389
|
-
var
|
|
390
|
-
return (
|
|
404
|
+
var _a2;
|
|
405
|
+
return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
|
|
391
406
|
}, 50);
|
|
392
407
|
}, [input, isLoading, send]);
|
|
393
408
|
const handleKeyDown = (e) => {
|
|
@@ -402,159 +417,124 @@ function ChatWindow({ className = "", style, onClose, showClose = false }) {
|
|
|
402
417
|
const isEmpty = messages.length === 0;
|
|
403
418
|
const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
|
|
404
419
|
const isGlass = ui.visualStyle !== "solid";
|
|
405
|
-
return /* @__PURE__ */
|
|
420
|
+
return /* @__PURE__ */ import_react6.default.createElement(
|
|
406
421
|
"div",
|
|
407
422
|
{
|
|
408
423
|
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}`,
|
|
409
|
-
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
424
|
+
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
425
|
+
},
|
|
426
|
+
/* @__PURE__ */ import_react6.default.createElement(
|
|
427
|
+
"div",
|
|
428
|
+
{
|
|
429
|
+
className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
|
|
430
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
|
|
431
|
+
},
|
|
432
|
+
/* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
|
|
433
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
434
|
+
/* @__PURE__ */ import_react6.default.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
435
|
+
) : /* @__PURE__ */ import_react6.default.createElement(
|
|
436
|
+
"div",
|
|
437
|
+
{
|
|
438
|
+
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
439
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
440
|
+
},
|
|
441
|
+
/* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.Bot, { className: "w-5 h-5 text-white" })
|
|
442
|
+
), /* @__PURE__ */ import_react6.default.createElement("div", null, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
|
|
443
|
+
/* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400" }, /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement(
|
|
444
|
+
"button",
|
|
445
|
+
{
|
|
446
|
+
onClick: clearHistory,
|
|
447
|
+
title: "Clear conversation",
|
|
448
|
+
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"
|
|
449
|
+
},
|
|
450
|
+
/* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.Trash2, { className: "w-3.5 h-3.5" })
|
|
451
|
+
), showClose && onClose && /* @__PURE__ */ import_react6.default.createElement(
|
|
452
|
+
"button",
|
|
453
|
+
{
|
|
454
|
+
onClick: onClose,
|
|
455
|
+
title: "Close chat",
|
|
456
|
+
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"
|
|
457
|
+
},
|
|
458
|
+
/* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.X, { className: "w-4 h-4" })
|
|
459
|
+
))
|
|
460
|
+
),
|
|
461
|
+
/* @__PURE__ */ import_react6.default.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 ? (
|
|
462
|
+
/* Welcome state */
|
|
463
|
+
/* @__PURE__ */ import_react6.default.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ import_react6.default.createElement(
|
|
464
|
+
"div",
|
|
465
|
+
{
|
|
466
|
+
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
467
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
468
|
+
},
|
|
469
|
+
/* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.Sparkles, { className: "w-8 h-8 text-white" })
|
|
470
|
+
), /* @__PURE__ */ import_react6.default.createElement("div", null, /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
|
|
471
|
+
(suggestion) => /* @__PURE__ */ import_react6.default.createElement(
|
|
472
|
+
"button",
|
|
413
473
|
{
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
"div",
|
|
420
|
-
{
|
|
421
|
-
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
422
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
423
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Bot, { className: "w-5 h-5 text-white" })
|
|
424
|
-
}
|
|
425
|
-
),
|
|
426
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
427
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight", children: ui.title }),
|
|
428
|
-
ui.poweredBy && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight", children: `Powered by ${ui.poweredBy}` })
|
|
429
|
-
] })
|
|
430
|
-
] }),
|
|
431
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
432
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400", children: [
|
|
433
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
|
|
434
|
-
"Online"
|
|
435
|
-
] }),
|
|
436
|
-
mounted && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
437
|
-
"button",
|
|
438
|
-
{
|
|
439
|
-
onClick: clearHistory,
|
|
440
|
-
title: "Clear conversation",
|
|
441
|
-
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",
|
|
442
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Trash2, { className: "w-3.5 h-3.5" })
|
|
443
|
-
}
|
|
444
|
-
),
|
|
445
|
-
showClose && onClose && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
446
|
-
"button",
|
|
447
|
-
{
|
|
448
|
-
onClick: onClose,
|
|
449
|
-
title: "Close chat",
|
|
450
|
-
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",
|
|
451
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.X, { className: "w-4 h-4" })
|
|
452
|
-
}
|
|
453
|
-
)
|
|
454
|
-
] })
|
|
455
|
-
]
|
|
456
|
-
}
|
|
457
|
-
),
|
|
458
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("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: [
|
|
459
|
-
!mounted || isEmpty ? (
|
|
460
|
-
/* Welcome state */
|
|
461
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12", children: [
|
|
462
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
463
|
-
"div",
|
|
464
|
-
{
|
|
465
|
-
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
466
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
467
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Sparkles, { className: "w-8 h-8 text-white" })
|
|
468
|
-
}
|
|
469
|
-
),
|
|
470
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
471
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed", children: ui.welcomeMessage }),
|
|
472
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2", children: "Ask a question to get started" })
|
|
473
|
-
] }),
|
|
474
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex flex-wrap gap-2 justify-center mt-2", children: CHAT_SUGGESTIONS.map(
|
|
475
|
-
(suggestion) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
476
|
-
"button",
|
|
477
|
-
{
|
|
478
|
-
onClick: () => {
|
|
479
|
-
var _a;
|
|
480
|
-
setInput(suggestion);
|
|
481
|
-
(_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
482
|
-
},
|
|
483
|
-
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",
|
|
484
|
-
children: suggestion
|
|
485
|
-
},
|
|
486
|
-
suggestion
|
|
487
|
-
)
|
|
488
|
-
) })
|
|
489
|
-
] })
|
|
490
|
-
) : messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
491
|
-
MessageBubble,
|
|
492
|
-
{
|
|
493
|
-
message: msg,
|
|
494
|
-
sources: msg.sources,
|
|
495
|
-
primaryColor: ui.primaryColor,
|
|
496
|
-
accentColor: ui.accentColor
|
|
474
|
+
key: suggestion,
|
|
475
|
+
onClick: () => {
|
|
476
|
+
var _a2;
|
|
477
|
+
setInput(suggestion);
|
|
478
|
+
(_a2 = inputRef.current) == null ? void 0 : _a2.focus();
|
|
497
479
|
},
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
480
|
+
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"
|
|
481
|
+
},
|
|
482
|
+
suggestion
|
|
483
|
+
)
|
|
484
|
+
)))
|
|
485
|
+
) : messages.map((msg, index) => /* @__PURE__ */ import_react6.default.createElement(
|
|
486
|
+
MessageBubble,
|
|
487
|
+
{
|
|
488
|
+
key: msg.id,
|
|
489
|
+
message: msg,
|
|
490
|
+
sources: msg.sources,
|
|
491
|
+
isStreaming: isLoading && index === messages.length - 1 && msg.role === "assistant",
|
|
492
|
+
primaryColor: ui.primaryColor,
|
|
493
|
+
accentColor: ui.accentColor
|
|
494
|
+
}
|
|
495
|
+
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ import_react6.default.createElement(
|
|
496
|
+
MessageBubble,
|
|
497
|
+
{
|
|
498
|
+
message: { role: "assistant", content: "" },
|
|
499
|
+
isStreaming: true,
|
|
500
|
+
primaryColor: ui.primaryColor,
|
|
501
|
+
accentColor: ui.accentColor
|
|
502
|
+
}
|
|
503
|
+
), error && /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement(import_lucide_react4.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ import_react6.default.createElement("span", null, error)), /* @__PURE__ */ import_react6.default.createElement("div", { ref: bottomRef })),
|
|
504
|
+
/* @__PURE__ */ import_react6.default.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__ */ import_react6.default.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__ */ import_react6.default.createElement(
|
|
505
|
+
"textarea",
|
|
506
|
+
{
|
|
507
|
+
ref: inputRef,
|
|
508
|
+
value: input,
|
|
509
|
+
onChange: (e) => setInput(e.target.value),
|
|
510
|
+
onKeyDown: handleKeyDown,
|
|
511
|
+
placeholder: ui.placeholder,
|
|
512
|
+
rows: 1,
|
|
513
|
+
disabled: isLoading,
|
|
514
|
+
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",
|
|
515
|
+
style: { scrollbarWidth: "none" }
|
|
516
|
+
}
|
|
517
|
+
), /* @__PURE__ */ import_react6.default.createElement(
|
|
518
|
+
"button",
|
|
519
|
+
{
|
|
520
|
+
onClick: sendMessage,
|
|
521
|
+
disabled: !input.trim() || isLoading,
|
|
522
|
+
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",
|
|
523
|
+
style: {
|
|
524
|
+
background: input.trim() && !isLoading ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
|
|
525
|
+
// slate-400/20 for light mode disabled
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
/* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.ArrowUp, { className: "w-4 h-4 text-white" })
|
|
529
|
+
)), /* @__PURE__ */ import_react6.default.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"))
|
|
549
530
|
);
|
|
550
531
|
}
|
|
551
532
|
|
|
552
533
|
// src/components/ChatWidget.tsx
|
|
553
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
554
534
|
function ChatWidget({ position = "bottom-right" }) {
|
|
555
535
|
const { ui } = useConfig();
|
|
556
|
-
const [isOpen, setIsOpen] = (0,
|
|
557
|
-
const [hasUnread, setHasUnread] = (0,
|
|
536
|
+
const [isOpen, setIsOpen] = (0, import_react7.useState)(false);
|
|
537
|
+
const [hasUnread, setHasUnread] = (0, import_react7.useState)(false);
|
|
558
538
|
if (ui.showWidget === false) return null;
|
|
559
539
|
const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
|
|
560
540
|
const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
|
|
@@ -563,68 +543,60 @@ function ChatWidget({ position = "bottom-right" }) {
|
|
|
563
543
|
setIsOpen(true);
|
|
564
544
|
setHasUnread(false);
|
|
565
545
|
};
|
|
566
|
-
return /* @__PURE__ */
|
|
567
|
-
|
|
568
|
-
|
|
546
|
+
return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(
|
|
547
|
+
"div",
|
|
548
|
+
{
|
|
549
|
+
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"}`,
|
|
550
|
+
style: { height: "600px", maxHeight: "calc(100vh - 6rem)" }
|
|
551
|
+
},
|
|
552
|
+
/* @__PURE__ */ import_react7.default.createElement(
|
|
553
|
+
ChatWindow,
|
|
569
554
|
{
|
|
570
|
-
className:
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
574
|
-
ChatWindow,
|
|
575
|
-
{
|
|
576
|
-
className: "h-full relative z-10",
|
|
577
|
-
showClose: true,
|
|
578
|
-
onClose: () => setIsOpen(false)
|
|
579
|
-
}
|
|
580
|
-
),
|
|
581
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
582
|
-
"div",
|
|
583
|
-
{
|
|
584
|
-
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"}`
|
|
585
|
-
}
|
|
586
|
-
)
|
|
587
|
-
]
|
|
555
|
+
className: "h-full relative z-10",
|
|
556
|
+
showClose: true,
|
|
557
|
+
onClose: () => setIsOpen(false)
|
|
588
558
|
}
|
|
589
559
|
),
|
|
590
|
-
/* @__PURE__ */
|
|
591
|
-
"
|
|
560
|
+
/* @__PURE__ */ import_react7.default.createElement(
|
|
561
|
+
"div",
|
|
592
562
|
{
|
|
593
|
-
|
|
594
|
-
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}`,
|
|
595
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
596
|
-
"aria-label": "Open chat",
|
|
597
|
-
children: [
|
|
598
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
599
|
-
"span",
|
|
600
|
-
{
|
|
601
|
-
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
602
|
-
style: { background: ui.primaryColor }
|
|
603
|
-
}
|
|
604
|
-
),
|
|
605
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
606
|
-
"span",
|
|
607
|
-
{
|
|
608
|
-
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`,
|
|
609
|
-
children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.MessageSquare, { className: "w-6 h-6 text-white" })
|
|
610
|
-
}
|
|
611
|
-
),
|
|
612
|
-
hasUnread && !isOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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" })
|
|
613
|
-
]
|
|
563
|
+
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"}`
|
|
614
564
|
}
|
|
615
565
|
)
|
|
616
|
-
|
|
566
|
+
), /* @__PURE__ */ import_react7.default.createElement(
|
|
567
|
+
"button",
|
|
568
|
+
{
|
|
569
|
+
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
570
|
+
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}`,
|
|
571
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
572
|
+
"aria-label": "Open chat"
|
|
573
|
+
},
|
|
574
|
+
/* @__PURE__ */ import_react7.default.createElement(
|
|
575
|
+
"span",
|
|
576
|
+
{
|
|
577
|
+
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
578
|
+
style: { background: ui.primaryColor }
|
|
579
|
+
}
|
|
580
|
+
),
|
|
581
|
+
/* @__PURE__ */ import_react7.default.createElement(
|
|
582
|
+
"span",
|
|
583
|
+
{
|
|
584
|
+
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
|
|
585
|
+
},
|
|
586
|
+
isOpen ? /* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.MessageSquare, { className: "w-6 h-6 text-white" })
|
|
587
|
+
),
|
|
588
|
+
hasUnread && !isOpen && /* @__PURE__ */ import_react7.default.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")
|
|
589
|
+
));
|
|
617
590
|
}
|
|
618
591
|
|
|
619
592
|
// src/components/DocumentUpload.tsx
|
|
620
|
-
var
|
|
593
|
+
var import_react8 = __toESM(require("react"));
|
|
621
594
|
var import_lucide_react6 = require("lucide-react");
|
|
622
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
623
595
|
function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
624
596
|
const { ui } = useConfig();
|
|
625
|
-
const [fileStates, setFileStates] = (0,
|
|
626
|
-
const [isDragging, setIsDragging] = (0,
|
|
627
|
-
const fileInputRef = (0,
|
|
597
|
+
const [fileStates, setFileStates] = (0, import_react8.useState)([]);
|
|
598
|
+
const [isDragging, setIsDragging] = (0, import_react8.useState)(false);
|
|
599
|
+
const fileInputRef = (0, import_react8.useRef)(null);
|
|
628
600
|
const addFiles = (files) => {
|
|
629
601
|
const newStates = files.map((file) => ({ file, status: "idle" }));
|
|
630
602
|
setFileStates((prev) => [...prev, ...newStates]);
|
|
@@ -674,99 +646,72 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
674
646
|
};
|
|
675
647
|
const isUploading = fileStates.some((s) => s.status === "uploading");
|
|
676
648
|
const hasIdle = fileStates.some((s) => s.status === "idle");
|
|
677
|
-
return /* @__PURE__ */
|
|
649
|
+
return /* @__PURE__ */ import_react8.default.createElement(
|
|
678
650
|
"div",
|
|
679
651
|
{
|
|
680
652
|
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}`,
|
|
681
653
|
onDragOver,
|
|
682
654
|
onDragLeave,
|
|
683
|
-
onDrop
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
state.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.CheckCircle, { className: "w-4 h-4 text-emerald-500" }),
|
|
744
|
-
state.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { title: state.error, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.AlertCircle, { className: "w-4 h-4 text-rose-500" }) }),
|
|
745
|
-
state.status !== "uploading" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
746
|
-
"button",
|
|
747
|
-
{
|
|
748
|
-
onClick: () => removeFile(i),
|
|
749
|
-
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors",
|
|
750
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.X, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
751
|
-
}
|
|
752
|
-
)
|
|
753
|
-
] })
|
|
754
|
-
]
|
|
755
|
-
},
|
|
756
|
-
i
|
|
757
|
-
)),
|
|
758
|
-
hasIdle && !isUploading && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
759
|
-
"button",
|
|
760
|
-
{
|
|
761
|
-
onClick: uploadFiles,
|
|
762
|
-
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]",
|
|
763
|
-
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
764
|
-
children: "Start Upload"
|
|
765
|
-
}
|
|
766
|
-
)
|
|
767
|
-
] })
|
|
768
|
-
]
|
|
769
|
-
}
|
|
655
|
+
onDrop
|
|
656
|
+
},
|
|
657
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ import_react8.default.createElement(
|
|
658
|
+
"div",
|
|
659
|
+
{
|
|
660
|
+
className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
|
|
661
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
|
|
662
|
+
},
|
|
663
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
|
|
664
|
+
), /* @__PURE__ */ import_react8.default.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ import_react8.default.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__ */ import_react8.default.createElement(
|
|
665
|
+
"button",
|
|
666
|
+
{
|
|
667
|
+
onClick: () => {
|
|
668
|
+
var _a;
|
|
669
|
+
return (_a = fileInputRef.current) == null ? void 0 : _a.click();
|
|
670
|
+
},
|
|
671
|
+
disabled: isUploading,
|
|
672
|
+
className: "px-4 py-2 rounded-lg text-sm font-medium transition-all hover:scale-105 active:scale-95 disabled:opacity-50",
|
|
673
|
+
style: {
|
|
674
|
+
backgroundColor: `${ui.primaryColor}15`,
|
|
675
|
+
color: ui.primaryColor,
|
|
676
|
+
border: `1px solid ${ui.primaryColor}30`
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
"Select Files"
|
|
680
|
+
), /* @__PURE__ */ import_react8.default.createElement(
|
|
681
|
+
"input",
|
|
682
|
+
{
|
|
683
|
+
ref: fileInputRef,
|
|
684
|
+
type: "file",
|
|
685
|
+
multiple: true,
|
|
686
|
+
onChange: onFileSelect,
|
|
687
|
+
className: "hidden",
|
|
688
|
+
accept: ".pdf,.docx,.txt,.md,.json,.csv"
|
|
689
|
+
}
|
|
690
|
+
)),
|
|
691
|
+
fileStates.length > 0 && /* @__PURE__ */ import_react8.default.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ import_react8.default.createElement(
|
|
692
|
+
"div",
|
|
693
|
+
{
|
|
694
|
+
key: i,
|
|
695
|
+
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"
|
|
696
|
+
},
|
|
697
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ import_react8.default.createElement("div", { className: "truncate" }, /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
|
|
698
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ import_react8.default.createElement("div", { title: state.error }, /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ import_react8.default.createElement(
|
|
699
|
+
"button",
|
|
700
|
+
{
|
|
701
|
+
onClick: () => removeFile(i),
|
|
702
|
+
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
|
|
703
|
+
},
|
|
704
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.X, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
705
|
+
))
|
|
706
|
+
)), hasIdle && !isUploading && /* @__PURE__ */ import_react8.default.createElement(
|
|
707
|
+
"button",
|
|
708
|
+
{
|
|
709
|
+
onClick: uploadFiles,
|
|
710
|
+
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]",
|
|
711
|
+
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
712
|
+
},
|
|
713
|
+
"Start Upload"
|
|
714
|
+
))
|
|
770
715
|
);
|
|
771
716
|
}
|
|
772
717
|
// Annotate the CommonJS export names for ESM import in node:
|