@syncagent/react 0.1.3 → 0.1.4
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/index.d.mts +2 -10
- package/dist/index.d.ts +2 -10
- package/dist/index.js +413 -158
- package/dist/index.mjs +419 -159
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -23,26 +23,18 @@ declare function useSyncAgent(options?: UseSyncAgentOptions): {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
interface SyncAgentChatProps {
|
|
26
|
-
/** Config — required if not wrapped in SyncAgentProvider */
|
|
27
26
|
config?: SyncAgentConfig;
|
|
28
|
-
/** Show as floating widget (FAB + panel) or inline */
|
|
29
27
|
mode?: "floating" | "inline";
|
|
30
|
-
/** FAB position */
|
|
31
28
|
position?: "bottom-right" | "bottom-left";
|
|
32
|
-
/** Start open */
|
|
33
29
|
defaultOpen?: boolean;
|
|
34
|
-
/** Widget title */
|
|
35
30
|
title?: string;
|
|
36
|
-
|
|
31
|
+
subtitle?: string;
|
|
37
32
|
placeholder?: string;
|
|
38
|
-
/** Welcome message */
|
|
39
33
|
welcomeMessage?: string;
|
|
40
|
-
/** Accent color */
|
|
41
34
|
accentColor?: string;
|
|
42
|
-
/** Custom class for the container */
|
|
43
35
|
className?: string;
|
|
44
|
-
/** Custom styles for the container */
|
|
45
36
|
style?: CSSProperties;
|
|
37
|
+
suggestions?: string[];
|
|
46
38
|
}
|
|
47
39
|
declare function SyncAgentChat({ config, ...props }: SyncAgentChatProps): react_jsx_runtime.JSX.Element;
|
|
48
40
|
|
package/dist/index.d.ts
CHANGED
|
@@ -23,26 +23,18 @@ declare function useSyncAgent(options?: UseSyncAgentOptions): {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
interface SyncAgentChatProps {
|
|
26
|
-
/** Config — required if not wrapped in SyncAgentProvider */
|
|
27
26
|
config?: SyncAgentConfig;
|
|
28
|
-
/** Show as floating widget (FAB + panel) or inline */
|
|
29
27
|
mode?: "floating" | "inline";
|
|
30
|
-
/** FAB position */
|
|
31
28
|
position?: "bottom-right" | "bottom-left";
|
|
32
|
-
/** Start open */
|
|
33
29
|
defaultOpen?: boolean;
|
|
34
|
-
/** Widget title */
|
|
35
30
|
title?: string;
|
|
36
|
-
|
|
31
|
+
subtitle?: string;
|
|
37
32
|
placeholder?: string;
|
|
38
|
-
/** Welcome message */
|
|
39
33
|
welcomeMessage?: string;
|
|
40
|
-
/** Accent color */
|
|
41
34
|
accentColor?: string;
|
|
42
|
-
/** Custom class for the container */
|
|
43
35
|
className?: string;
|
|
44
|
-
/** Custom styles for the container */
|
|
45
36
|
style?: CSSProperties;
|
|
37
|
+
suggestions?: string[];
|
|
46
38
|
}
|
|
47
39
|
declare function SyncAgentChat({ config, ...props }: SyncAgentChatProps): react_jsx_runtime.JSX.Element;
|
|
48
40
|
|
package/dist/index.js
CHANGED
|
@@ -125,214 +125,469 @@ function useSyncAgent(options = {}) {
|
|
|
125
125
|
// src/chat.tsx
|
|
126
126
|
var import_react3 = require("react");
|
|
127
127
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
128
|
+
function renderMarkdown(text) {
|
|
129
|
+
return text.replace(/```[\w]*\n?([\s\S]*?)```/g, `<pre style="background:#1e1e2e;color:#cdd6f4;padding:12px 14px;border-radius:8px;overflow-x:auto;font-size:12px;line-height:1.6;margin:8px 0;font-family:'Fira Code','Cascadia Code',monospace">$1</pre>`).replace(/`([^`]+)`/g, '<code style="background:rgba(0,0,0,0.08);padding:2px 6px;border-radius:4px;font-size:12px;font-family:monospace">$1</code>').replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/^### (.+)$/gm, '<div style="font-weight:700;font-size:13px;margin:10px 0 4px">$1</div>').replace(/^## (.+)$/gm, '<div style="font-weight:700;font-size:14px;margin:12px 0 4px">$1</div>').replace(/^# (.+)$/gm, '<div style="font-weight:700;font-size:15px;margin:12px 0 6px">$1</div>').replace(/\|(.+)\|\n\|[-| :]+\|\n((?:\|.+\|\n?)+)/g, (_, header, rows) => {
|
|
130
|
+
const ths = header.split("|").filter((c) => c.trim()).map((c) => `<th style="padding:6px 10px;text-align:left;font-weight:600;border-bottom:2px solid rgba(0,0,0,0.1)">${c.trim()}</th>`).join("");
|
|
131
|
+
const trs = rows.trim().split("\n").map((row) => {
|
|
132
|
+
const tds = row.split("|").filter((c) => c.trim()).map((c) => `<td style="padding:6px 10px;border-bottom:1px solid rgba(0,0,0,0.06)">${c.trim()}</td>`).join("");
|
|
133
|
+
return `<tr>${tds}</tr>`;
|
|
134
|
+
}).join("");
|
|
135
|
+
return `<div style="overflow-x:auto;margin:8px 0"><table style="width:100%;border-collapse:collapse;font-size:13px"><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table></div>`;
|
|
136
|
+
}).replace(/^[-*] (.+)$/gm, '<li style="margin:2px 0;padding-left:4px">$1</li>').replace(/(<li[^>]*>.*<\/li>\n?)+/g, (m) => `<ul style="margin:6px 0;padding-left:18px;list-style:disc">${m}</ul>`).replace(/^\d+\. (.+)$/gm, '<li style="margin:2px 0;padding-left:4px">$1</li>').replace(/\n\n/g, "<br/><br/>").replace(/\n/g, "<br/>");
|
|
137
|
+
}
|
|
138
|
+
function TypingDots({ color }) {
|
|
139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { display: "inline-flex", gap: 4, alignItems: "center", padding: "2px 0" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
|
|
140
|
+
width: 6,
|
|
141
|
+
height: 6,
|
|
142
|
+
borderRadius: "50%",
|
|
143
|
+
background: color,
|
|
144
|
+
animation: "sa-bounce 1.2s infinite",
|
|
145
|
+
animationDelay: `${i * 0.2}s`,
|
|
146
|
+
display: "inline-block"
|
|
147
|
+
} }, i)) });
|
|
148
|
+
}
|
|
149
|
+
function CopyBtn({ text }) {
|
|
150
|
+
const [copied, setCopied] = (0, import_react3.useState)(false);
|
|
151
|
+
const copy = (0, import_react3.useCallback)(() => {
|
|
152
|
+
navigator.clipboard?.writeText(text).then(() => {
|
|
153
|
+
setCopied(true);
|
|
154
|
+
setTimeout(() => setCopied(false), 1500);
|
|
155
|
+
});
|
|
156
|
+
}, [text]);
|
|
157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: copy, title: "Copy", style: {
|
|
158
|
+
background: "none",
|
|
159
|
+
border: "none",
|
|
160
|
+
cursor: "pointer",
|
|
161
|
+
padding: "2px 6px",
|
|
162
|
+
borderRadius: 4,
|
|
163
|
+
fontSize: 11,
|
|
164
|
+
color: "#9ca3af",
|
|
165
|
+
opacity: 0.7,
|
|
166
|
+
transition: "opacity 0.15s"
|
|
167
|
+
}, children: copied ? "\u2713" : "\u2398" });
|
|
168
|
+
}
|
|
169
|
+
function MessageBubble({
|
|
170
|
+
role,
|
|
171
|
+
content,
|
|
172
|
+
isStreaming,
|
|
173
|
+
accentColor,
|
|
174
|
+
timestamp
|
|
175
|
+
}) {
|
|
176
|
+
const isUser = role === "user";
|
|
177
|
+
const timeStr = timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
179
|
+
display: "flex",
|
|
180
|
+
flexDirection: "column",
|
|
181
|
+
alignItems: isUser ? "flex-end" : "flex-start",
|
|
182
|
+
gap: 3,
|
|
183
|
+
maxWidth: "88%",
|
|
184
|
+
alignSelf: isUser ? "flex-end" : "flex-start"
|
|
185
|
+
}, children: [
|
|
186
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
187
|
+
display: "flex",
|
|
188
|
+
alignItems: "center",
|
|
189
|
+
gap: 6,
|
|
190
|
+
flexDirection: isUser ? "row-reverse" : "row"
|
|
191
|
+
}, children: [
|
|
192
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
193
|
+
width: 24,
|
|
194
|
+
height: 24,
|
|
195
|
+
borderRadius: "50%",
|
|
196
|
+
background: isUser ? accentColor : "linear-gradient(135deg,#6366f1,#8b5cf6)",
|
|
197
|
+
display: "flex",
|
|
198
|
+
alignItems: "center",
|
|
199
|
+
justifyContent: "center",
|
|
200
|
+
fontSize: 11,
|
|
201
|
+
color: "white",
|
|
202
|
+
fontWeight: 700,
|
|
203
|
+
flexShrink: 0
|
|
204
|
+
}, children: isUser ? "U" : "\u2726" }),
|
|
205
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 11, color: "#9ca3af", fontWeight: 500 }, children: isUser ? "You" : "SyncAgent" }),
|
|
206
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 10, color: "#d1d5db" }, children: timeStr })
|
|
207
|
+
] }),
|
|
208
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
209
|
+
padding: "10px 14px",
|
|
210
|
+
borderRadius: isUser ? "16px 4px 16px 16px" : "4px 16px 16px 16px",
|
|
211
|
+
background: isUser ? accentColor : "#f8fafc",
|
|
212
|
+
color: isUser ? "white" : "#1e293b",
|
|
213
|
+
fontSize: 13.5,
|
|
214
|
+
lineHeight: 1.6,
|
|
215
|
+
wordBreak: "break-word",
|
|
216
|
+
border: isUser ? "none" : "1px solid #e2e8f0",
|
|
217
|
+
boxShadow: isUser ? `0 2px 8px ${accentColor}33` : "0 1px 4px rgba(0,0,0,0.06)",
|
|
218
|
+
position: "relative"
|
|
219
|
+
}, children: isStreaming && !content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TypingDots, { color: accentColor }) : isUser ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { whiteSpace: "pre-wrap" }, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { dangerouslySetInnerHTML: { __html: renderMarkdown(content) } }) }),
|
|
220
|
+
!isUser && content && !isStreaming && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { paddingLeft: 30 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CopyBtn, { text: content }) })
|
|
221
|
+
] });
|
|
222
|
+
}
|
|
223
|
+
function Suggestions({ items, onSelect, accentColor }) {
|
|
224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, padding: "0 16px 12px" }, children: items.map((s2) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => onSelect(s2), style: {
|
|
225
|
+
padding: "5px 12px",
|
|
226
|
+
borderRadius: 20,
|
|
227
|
+
fontSize: 12,
|
|
228
|
+
cursor: "pointer",
|
|
229
|
+
border: `1px solid ${accentColor}44`,
|
|
230
|
+
background: `${accentColor}0d`,
|
|
231
|
+
color: accentColor,
|
|
232
|
+
fontWeight: 500,
|
|
233
|
+
transition: "all 0.15s"
|
|
234
|
+
}, children: s2 }, s2)) });
|
|
235
|
+
}
|
|
128
236
|
function ChatInner({
|
|
129
237
|
mode = "floating",
|
|
130
238
|
position = "bottom-right",
|
|
131
239
|
defaultOpen = false,
|
|
132
|
-
title = "
|
|
133
|
-
|
|
134
|
-
|
|
240
|
+
title = "SyncAgent",
|
|
241
|
+
subtitle = "AI Database Assistant",
|
|
242
|
+
placeholder = "Ask anything about your data...",
|
|
243
|
+
welcomeMessage = "Hi! I can query, analyze, and manage your database using natural language. What would you like to know?",
|
|
135
244
|
accentColor = "#10b981",
|
|
136
245
|
className,
|
|
137
|
-
style: customStyle
|
|
246
|
+
style: customStyle,
|
|
247
|
+
suggestions = ["Show all records", "Count total entries", "Show recent activity"]
|
|
138
248
|
}) {
|
|
139
|
-
const { messages, isLoading, sendMessage } = useSyncAgent();
|
|
249
|
+
const { messages, isLoading, error, sendMessage, stop, reset } = useSyncAgent();
|
|
140
250
|
const [isOpen, setIsOpen] = (0, import_react3.useState)(defaultOpen);
|
|
141
251
|
const [input, setInput] = (0, import_react3.useState)("");
|
|
252
|
+
const [timestamps] = (0, import_react3.useState)(() => /* @__PURE__ */ new Map());
|
|
142
253
|
const messagesEndRef = (0, import_react3.useRef)(null);
|
|
254
|
+
const inputRef = (0, import_react3.useRef)(null);
|
|
255
|
+
const msgCount = (0, import_react3.useRef)(0);
|
|
256
|
+
if (messages.length > msgCount.current) {
|
|
257
|
+
for (let i = msgCount.current; i < messages.length; i++) {
|
|
258
|
+
if (!timestamps.has(i)) timestamps.set(i, /* @__PURE__ */ new Date());
|
|
259
|
+
}
|
|
260
|
+
msgCount.current = messages.length;
|
|
261
|
+
}
|
|
143
262
|
(0, import_react3.useEffect)(() => {
|
|
144
263
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
145
|
-
}, [messages]);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
264
|
+
}, [messages, isLoading]);
|
|
265
|
+
(0, import_react3.useEffect)(() => {
|
|
266
|
+
if (isOpen) setTimeout(() => inputRef.current?.focus(), 100);
|
|
267
|
+
}, [isOpen]);
|
|
268
|
+
const handleSend = (0, import_react3.useCallback)(() => {
|
|
269
|
+
const text = input.trim();
|
|
270
|
+
if (!text || isLoading) return;
|
|
150
271
|
setInput("");
|
|
272
|
+
sendMessage(text);
|
|
273
|
+
}, [input, isLoading, sendMessage]);
|
|
274
|
+
const handleKeyDown = (e) => {
|
|
275
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
276
|
+
e.preventDefault();
|
|
277
|
+
handleSend();
|
|
278
|
+
}
|
|
151
279
|
};
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
280
|
+
const showSuggestions = messages.length === 0 && suggestions.length > 0;
|
|
281
|
+
const panel = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
282
|
+
...s.panel,
|
|
283
|
+
...mode === "inline" ? s.panelInline : {},
|
|
284
|
+
...customStyle
|
|
285
|
+
}, className, children: [
|
|
286
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
|
|
287
|
+
@keyframes sa-bounce {
|
|
288
|
+
0%,80%,100% { transform: translateY(0); opacity:0.4 }
|
|
289
|
+
40% { transform: translateY(-5px); opacity:1 }
|
|
290
|
+
}
|
|
291
|
+
@keyframes sa-fadein {
|
|
292
|
+
from { opacity:0; transform:translateY(6px) }
|
|
293
|
+
to { opacity:1; transform:translateY(0) }
|
|
294
|
+
}
|
|
295
|
+
.sa-msg-wrap { animation: sa-fadein 0.2s ease }
|
|
296
|
+
.sa-input:focus { outline:none; border-color:${accentColor} !important; box-shadow:0 0 0 3px ${accentColor}22 !important }
|
|
297
|
+
.sa-send:hover:not(:disabled) { opacity:0.88; transform:scale(1.04) }
|
|
298
|
+
.sa-send:disabled { opacity:0.4; cursor:not-allowed }
|
|
299
|
+
.sa-fab-btn:hover { transform:scale(1.08) }
|
|
300
|
+
` }),
|
|
301
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
302
|
+
padding: "14px 16px",
|
|
303
|
+
background: `linear-gradient(135deg, ${accentColor}, ${adjustColor(accentColor, -30)})`,
|
|
304
|
+
display: "flex",
|
|
305
|
+
alignItems: "center",
|
|
306
|
+
justifyContent: "space-between",
|
|
307
|
+
flexShrink: 0
|
|
308
|
+
}, children: [
|
|
309
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
|
|
310
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
311
|
+
width: 34,
|
|
312
|
+
height: 34,
|
|
313
|
+
borderRadius: "50%",
|
|
314
|
+
background: "rgba(255,255,255,0.2)",
|
|
315
|
+
display: "flex",
|
|
316
|
+
alignItems: "center",
|
|
317
|
+
justifyContent: "center",
|
|
318
|
+
fontSize: 16
|
|
319
|
+
}, children: "\u2726" }),
|
|
320
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
321
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "white", fontWeight: 700, fontSize: 14, lineHeight: 1.2 }, children: title }),
|
|
322
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "rgba(255,255,255,0.75)", fontSize: 11 }, children: subtitle })
|
|
323
|
+
] })
|
|
324
|
+
] }),
|
|
325
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 4 }, children: [
|
|
326
|
+
messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: reset, title: "Clear chat", style: {
|
|
327
|
+
background: "rgba(255,255,255,0.15)",
|
|
328
|
+
border: "none",
|
|
329
|
+
color: "white",
|
|
330
|
+
cursor: "pointer",
|
|
331
|
+
borderRadius: 6,
|
|
332
|
+
padding: "4px 8px",
|
|
333
|
+
fontSize: 11
|
|
334
|
+
}, children: "Clear" }),
|
|
335
|
+
mode === "floating" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => setIsOpen(false), style: {
|
|
336
|
+
background: "rgba(255,255,255,0.15)",
|
|
337
|
+
border: "none",
|
|
338
|
+
color: "white",
|
|
339
|
+
cursor: "pointer",
|
|
340
|
+
borderRadius: 6,
|
|
341
|
+
padding: "4px 8px",
|
|
342
|
+
fontSize: 16,
|
|
343
|
+
lineHeight: 1
|
|
344
|
+
}, children: "\xD7" })
|
|
345
|
+
] })
|
|
156
346
|
] }),
|
|
157
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style:
|
|
158
|
-
messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.
|
|
159
|
-
|
|
160
|
-
|
|
347
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: s.messages, children: [
|
|
348
|
+
messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: s.welcome, children: [
|
|
349
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
350
|
+
width: 48,
|
|
351
|
+
height: 48,
|
|
352
|
+
borderRadius: "50%",
|
|
353
|
+
margin: "0 auto 12px",
|
|
354
|
+
background: `linear-gradient(135deg, ${accentColor}22, ${accentColor}44)`,
|
|
355
|
+
display: "flex",
|
|
356
|
+
alignItems: "center",
|
|
357
|
+
justifyContent: "center",
|
|
358
|
+
fontSize: 22
|
|
359
|
+
}, children: "\u2726" }),
|
|
360
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { fontSize: 14, color: "#64748b", lineHeight: 1.6, maxWidth: 260, margin: "0 auto" }, children: welcomeMessage })
|
|
361
|
+
] }),
|
|
362
|
+
messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sa-msg-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
363
|
+
MessageBubble,
|
|
161
364
|
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
)
|
|
365
|
+
role: msg.role,
|
|
366
|
+
content: msg.content,
|
|
367
|
+
isStreaming: isLoading && i === messages.length - 1 && msg.role === "assistant",
|
|
368
|
+
accentColor,
|
|
369
|
+
timestamp: timestamps.get(i) ?? /* @__PURE__ */ new Date()
|
|
370
|
+
}
|
|
371
|
+
) }, i)),
|
|
372
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
373
|
+
padding: "10px 14px",
|
|
374
|
+
borderRadius: 10,
|
|
375
|
+
fontSize: 13,
|
|
376
|
+
background: "#fef2f2",
|
|
377
|
+
color: "#dc2626",
|
|
378
|
+
border: "1px solid #fecaca",
|
|
379
|
+
alignSelf: "flex-start"
|
|
380
|
+
}, children: [
|
|
381
|
+
"\u26A0\uFE0F ",
|
|
382
|
+
error.message
|
|
383
|
+
] }),
|
|
170
384
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: messagesEndRef })
|
|
171
385
|
] }),
|
|
172
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
386
|
+
showSuggestions && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
387
|
+
Suggestions,
|
|
388
|
+
{
|
|
389
|
+
items: suggestions,
|
|
390
|
+
onSelect: (s2) => {
|
|
391
|
+
setInput(s2);
|
|
392
|
+
inputRef.current?.focus();
|
|
393
|
+
},
|
|
394
|
+
accentColor
|
|
395
|
+
}
|
|
396
|
+
),
|
|
397
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
398
|
+
padding: "10px 12px",
|
|
399
|
+
borderTop: "1px solid #f1f5f9",
|
|
400
|
+
background: "#fff",
|
|
401
|
+
flexShrink: 0
|
|
402
|
+
}, children: [
|
|
403
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
404
|
+
display: "flex",
|
|
405
|
+
gap: 8,
|
|
406
|
+
alignItems: "flex-end",
|
|
407
|
+
background: "#f8fafc",
|
|
408
|
+
borderRadius: 12,
|
|
409
|
+
border: "1px solid #e2e8f0",
|
|
410
|
+
padding: "6px 6px 6px 12px",
|
|
411
|
+
transition: "border-color 0.15s, box-shadow 0.15s"
|
|
412
|
+
}, children: [
|
|
413
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
414
|
+
"textarea",
|
|
415
|
+
{
|
|
416
|
+
ref: inputRef,
|
|
417
|
+
className: "sa-input",
|
|
418
|
+
value: input,
|
|
419
|
+
onChange: (e) => {
|
|
420
|
+
setInput(e.target.value);
|
|
421
|
+
e.target.style.height = "auto";
|
|
422
|
+
e.target.style.height = Math.min(e.target.scrollHeight, 120) + "px";
|
|
423
|
+
},
|
|
424
|
+
onKeyDown: handleKeyDown,
|
|
425
|
+
placeholder,
|
|
426
|
+
disabled: isLoading,
|
|
427
|
+
rows: 1,
|
|
428
|
+
style: {
|
|
429
|
+
flex: 1,
|
|
430
|
+
background: "none",
|
|
431
|
+
border: "none",
|
|
432
|
+
resize: "none",
|
|
433
|
+
fontSize: 13.5,
|
|
434
|
+
lineHeight: 1.5,
|
|
435
|
+
color: "#1e293b",
|
|
436
|
+
fontFamily: "inherit",
|
|
437
|
+
padding: 0,
|
|
438
|
+
maxHeight: 120,
|
|
439
|
+
outline: "none"
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
),
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 4, alignItems: "flex-end", flexShrink: 0 }, children: [
|
|
444
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: stop, title: "Stop", style: {
|
|
445
|
+
background: "#fef2f2",
|
|
446
|
+
border: "1px solid #fecaca",
|
|
447
|
+
color: "#dc2626",
|
|
448
|
+
borderRadius: 8,
|
|
449
|
+
padding: "6px 10px",
|
|
450
|
+
cursor: "pointer",
|
|
451
|
+
fontSize: 12,
|
|
452
|
+
fontWeight: 600
|
|
453
|
+
}, children: "\u25A0 Stop" }),
|
|
454
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
455
|
+
"button",
|
|
456
|
+
{
|
|
457
|
+
className: "sa-send",
|
|
458
|
+
onClick: handleSend,
|
|
459
|
+
disabled: isLoading || !input.trim(),
|
|
460
|
+
style: {
|
|
461
|
+
width: 34,
|
|
462
|
+
height: 34,
|
|
463
|
+
borderRadius: 8,
|
|
464
|
+
border: "none",
|
|
465
|
+
background: input.trim() && !isLoading ? accentColor : "#e2e8f0",
|
|
466
|
+
color: input.trim() && !isLoading ? "white" : "#94a3b8",
|
|
467
|
+
cursor: "pointer",
|
|
468
|
+
display: "flex",
|
|
469
|
+
alignItems: "center",
|
|
470
|
+
justifyContent: "center",
|
|
471
|
+
transition: "all 0.15s",
|
|
472
|
+
flexShrink: 0
|
|
473
|
+
},
|
|
474
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" }) })
|
|
475
|
+
}
|
|
476
|
+
)
|
|
477
|
+
] })
|
|
478
|
+
] }),
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "center", marginTop: 6, fontSize: 10, color: "#cbd5e1" }, children: [
|
|
480
|
+
"Powered by ",
|
|
481
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: accentColor, fontWeight: 600 }, children: "SyncAgent" }),
|
|
482
|
+
" \xB7 Enter to send \xB7 Shift+Enter for new line"
|
|
483
|
+
] })
|
|
192
484
|
] })
|
|
193
485
|
] });
|
|
194
486
|
if (mode === "inline") return panel;
|
|
195
487
|
const isLeft = position === "bottom-left";
|
|
196
488
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
197
|
-
|
|
198
|
-
|
|
489
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
490
|
+
position: "fixed",
|
|
491
|
+
bottom: 88,
|
|
492
|
+
zIndex: 99998,
|
|
493
|
+
...isLeft ? { left: 20 } : { right: 20 },
|
|
494
|
+
width: 420,
|
|
495
|
+
maxWidth: "calc(100vw - 40px)",
|
|
496
|
+
transition: "opacity 0.25s, transform 0.25s",
|
|
497
|
+
opacity: isOpen ? 1 : 0,
|
|
498
|
+
transform: isOpen ? "translateY(0) scale(1)" : "translateY(16px) scale(0.96)",
|
|
499
|
+
pointerEvents: isOpen ? "auto" : "none"
|
|
500
|
+
}, children: panel }),
|
|
501
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
199
502
|
"button",
|
|
200
503
|
{
|
|
504
|
+
className: "sa-fab-btn",
|
|
201
505
|
onClick: () => setIsOpen(!isOpen),
|
|
202
506
|
style: {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
507
|
+
position: "fixed",
|
|
508
|
+
bottom: 20,
|
|
509
|
+
zIndex: 99999,
|
|
510
|
+
...isLeft ? { left: 20 } : { right: 20 },
|
|
511
|
+
width: 56,
|
|
512
|
+
height: 56,
|
|
513
|
+
borderRadius: "50%",
|
|
514
|
+
border: "none",
|
|
515
|
+
background: `linear-gradient(135deg, ${accentColor}, ${adjustColor(accentColor, -30)})`,
|
|
516
|
+
cursor: "pointer",
|
|
517
|
+
boxShadow: `0 4px 20px ${accentColor}55, 0 2px 8px rgba(0,0,0,0.15)`,
|
|
518
|
+
display: "flex",
|
|
519
|
+
alignItems: "center",
|
|
520
|
+
justifyContent: "center",
|
|
521
|
+
transition: "transform 0.2s, box-shadow 0.2s"
|
|
206
522
|
},
|
|
207
|
-
children:
|
|
523
|
+
children: [
|
|
524
|
+
isOpen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" }) }),
|
|
525
|
+
!isOpen && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
526
|
+
position: "absolute",
|
|
527
|
+
top: 2,
|
|
528
|
+
right: 2,
|
|
529
|
+
width: 12,
|
|
530
|
+
height: 12,
|
|
531
|
+
borderRadius: "50%",
|
|
532
|
+
background: "#ef4444",
|
|
533
|
+
border: "2px solid white"
|
|
534
|
+
} })
|
|
535
|
+
]
|
|
208
536
|
}
|
|
209
537
|
)
|
|
210
538
|
] });
|
|
211
539
|
}
|
|
212
|
-
|
|
213
|
-
if (config) {
|
|
214
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SyncAgentProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props }) });
|
|
215
|
-
}
|
|
216
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props });
|
|
217
|
-
}
|
|
218
|
-
function adjustColor(hex, amount) {
|
|
219
|
-
const num = parseInt(hex.replace("#", ""), 16);
|
|
220
|
-
const r = Math.min(255, Math.max(0, (num >> 16 & 255) + amount));
|
|
221
|
-
const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
|
|
222
|
-
const b = Math.min(255, Math.max(0, (num & 255) + amount));
|
|
223
|
-
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
224
|
-
}
|
|
225
|
-
var styles = {
|
|
226
|
-
fab: {
|
|
227
|
-
position: "fixed",
|
|
228
|
-
bottom: 24,
|
|
229
|
-
right: 24,
|
|
230
|
-
zIndex: 99999,
|
|
231
|
-
width: 56,
|
|
232
|
-
height: 56,
|
|
233
|
-
borderRadius: "50%",
|
|
234
|
-
border: "none",
|
|
235
|
-
cursor: "pointer",
|
|
236
|
-
boxShadow: "0 4px 20px rgba(0,0,0,0.2)",
|
|
237
|
-
display: "flex",
|
|
238
|
-
alignItems: "center",
|
|
239
|
-
justifyContent: "center"
|
|
240
|
-
},
|
|
241
|
-
floatingPanel: {
|
|
242
|
-
position: "fixed",
|
|
243
|
-
bottom: 96,
|
|
244
|
-
right: 24,
|
|
245
|
-
zIndex: 99998,
|
|
246
|
-
width: 400,
|
|
247
|
-
maxWidth: "calc(100vw - 48px)"
|
|
248
|
-
},
|
|
540
|
+
var s = {
|
|
249
541
|
panel: {
|
|
250
|
-
height:
|
|
251
|
-
maxHeight: "calc(100vh -
|
|
252
|
-
background: "#
|
|
253
|
-
borderRadius:
|
|
254
|
-
boxShadow: "0
|
|
542
|
+
height: 580,
|
|
543
|
+
maxHeight: "calc(100vh - 110px)",
|
|
544
|
+
background: "#ffffff",
|
|
545
|
+
borderRadius: 18,
|
|
546
|
+
boxShadow: "0 20px 60px rgba(0,0,0,0.15), 0 4px 20px rgba(0,0,0,0.08)",
|
|
255
547
|
display: "flex",
|
|
256
548
|
flexDirection: "column",
|
|
257
549
|
overflow: "hidden",
|
|
258
|
-
fontFamily: "
|
|
550
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
551
|
+
border: "1px solid rgba(0,0,0,0.06)"
|
|
259
552
|
},
|
|
260
553
|
panelInline: {
|
|
261
554
|
height: "100%",
|
|
262
555
|
maxHeight: "none",
|
|
263
|
-
borderRadius:
|
|
264
|
-
boxShadow: "0 2px
|
|
265
|
-
},
|
|
266
|
-
header: {
|
|
267
|
-
padding: "16px",
|
|
268
|
-
color: "white",
|
|
269
|
-
fontWeight: 600,
|
|
270
|
-
fontSize: 15,
|
|
271
|
-
display: "flex",
|
|
272
|
-
alignItems: "center",
|
|
273
|
-
justifyContent: "space-between"
|
|
274
|
-
},
|
|
275
|
-
closeBtn: {
|
|
276
|
-
background: "none",
|
|
277
|
-
border: "none",
|
|
278
|
-
color: "white",
|
|
279
|
-
cursor: "pointer",
|
|
280
|
-
padding: 4,
|
|
281
|
-
fontSize: 20
|
|
556
|
+
borderRadius: 14,
|
|
557
|
+
boxShadow: "0 2px 16px rgba(0,0,0,0.08)"
|
|
282
558
|
},
|
|
283
559
|
messages: {
|
|
284
560
|
flex: 1,
|
|
285
561
|
overflowY: "auto",
|
|
286
|
-
padding:
|
|
562
|
+
padding: "16px 16px 8px",
|
|
287
563
|
display: "flex",
|
|
288
564
|
flexDirection: "column",
|
|
289
|
-
gap:
|
|
290
|
-
|
|
291
|
-
welcome: { textAlign: "center", padding: "40px 20px" },
|
|
292
|
-
msg: {
|
|
293
|
-
maxWidth: "85%",
|
|
294
|
-
padding: "10px 14px",
|
|
295
|
-
borderRadius: 12,
|
|
296
|
-
fontSize: 14,
|
|
297
|
-
lineHeight: 1.5,
|
|
298
|
-
wordBreak: "break-word",
|
|
299
|
-
whiteSpace: "pre-wrap"
|
|
300
|
-
},
|
|
301
|
-
msgUser: {
|
|
302
|
-
alignSelf: "flex-end",
|
|
303
|
-
color: "white",
|
|
304
|
-
borderBottomRightRadius: 4
|
|
305
|
-
},
|
|
306
|
-
msgAi: {
|
|
307
|
-
alignSelf: "flex-start",
|
|
308
|
-
background: "#f3f4f6",
|
|
309
|
-
color: "#1f2937",
|
|
310
|
-
borderBottomLeftRadius: 4
|
|
311
|
-
},
|
|
312
|
-
form: {
|
|
313
|
-
padding: "12px 16px",
|
|
314
|
-
borderTop: "1px solid #e5e7eb",
|
|
315
|
-
display: "flex",
|
|
316
|
-
gap: 8
|
|
565
|
+
gap: 14,
|
|
566
|
+
scrollbarWidth: "thin"
|
|
317
567
|
},
|
|
318
|
-
|
|
568
|
+
welcome: {
|
|
569
|
+
textAlign: "center",
|
|
570
|
+
padding: "32px 20px",
|
|
319
571
|
flex: 1,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
outline: "none"
|
|
325
|
-
},
|
|
326
|
-
sendBtn: {
|
|
327
|
-
padding: "10px 16px",
|
|
328
|
-
color: "white",
|
|
329
|
-
border: "none",
|
|
330
|
-
borderRadius: 10,
|
|
331
|
-
cursor: "pointer",
|
|
332
|
-
fontWeight: 600,
|
|
333
|
-
fontSize: 14
|
|
572
|
+
display: "flex",
|
|
573
|
+
flexDirection: "column",
|
|
574
|
+
alignItems: "center",
|
|
575
|
+
justifyContent: "center"
|
|
334
576
|
}
|
|
335
577
|
};
|
|
578
|
+
function adjustColor(hex, amount) {
|
|
579
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
580
|
+
const r = Math.min(255, Math.max(0, (num >> 16 & 255) + amount));
|
|
581
|
+
const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
|
|
582
|
+
const b = Math.min(255, Math.max(0, (num & 255) + amount));
|
|
583
|
+
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
584
|
+
}
|
|
585
|
+
function SyncAgentChat({ config, ...props }) {
|
|
586
|
+
if (config) {
|
|
587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SyncAgentProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props }) });
|
|
588
|
+
}
|
|
589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props });
|
|
590
|
+
}
|
|
336
591
|
|
|
337
592
|
// src/index.ts
|
|
338
593
|
var import_js2 = require("@syncagent/js");
|
package/dist/index.mjs
CHANGED
|
@@ -94,216 +94,476 @@ function useSyncAgent(options = {}) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// src/chat.tsx
|
|
97
|
-
import {
|
|
97
|
+
import {
|
|
98
|
+
useState as useState2,
|
|
99
|
+
useRef as useRef2,
|
|
100
|
+
useEffect,
|
|
101
|
+
useCallback as useCallback2
|
|
102
|
+
} from "react";
|
|
98
103
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
104
|
+
function renderMarkdown(text) {
|
|
105
|
+
return text.replace(/```[\w]*\n?([\s\S]*?)```/g, `<pre style="background:#1e1e2e;color:#cdd6f4;padding:12px 14px;border-radius:8px;overflow-x:auto;font-size:12px;line-height:1.6;margin:8px 0;font-family:'Fira Code','Cascadia Code',monospace">$1</pre>`).replace(/`([^`]+)`/g, '<code style="background:rgba(0,0,0,0.08);padding:2px 6px;border-radius:4px;font-size:12px;font-family:monospace">$1</code>').replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/^### (.+)$/gm, '<div style="font-weight:700;font-size:13px;margin:10px 0 4px">$1</div>').replace(/^## (.+)$/gm, '<div style="font-weight:700;font-size:14px;margin:12px 0 4px">$1</div>').replace(/^# (.+)$/gm, '<div style="font-weight:700;font-size:15px;margin:12px 0 6px">$1</div>').replace(/\|(.+)\|\n\|[-| :]+\|\n((?:\|.+\|\n?)+)/g, (_, header, rows) => {
|
|
106
|
+
const ths = header.split("|").filter((c) => c.trim()).map((c) => `<th style="padding:6px 10px;text-align:left;font-weight:600;border-bottom:2px solid rgba(0,0,0,0.1)">${c.trim()}</th>`).join("");
|
|
107
|
+
const trs = rows.trim().split("\n").map((row) => {
|
|
108
|
+
const tds = row.split("|").filter((c) => c.trim()).map((c) => `<td style="padding:6px 10px;border-bottom:1px solid rgba(0,0,0,0.06)">${c.trim()}</td>`).join("");
|
|
109
|
+
return `<tr>${tds}</tr>`;
|
|
110
|
+
}).join("");
|
|
111
|
+
return `<div style="overflow-x:auto;margin:8px 0"><table style="width:100%;border-collapse:collapse;font-size:13px"><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table></div>`;
|
|
112
|
+
}).replace(/^[-*] (.+)$/gm, '<li style="margin:2px 0;padding-left:4px">$1</li>').replace(/(<li[^>]*>.*<\/li>\n?)+/g, (m) => `<ul style="margin:6px 0;padding-left:18px;list-style:disc">${m}</ul>`).replace(/^\d+\. (.+)$/gm, '<li style="margin:2px 0;padding-left:4px">$1</li>').replace(/\n\n/g, "<br/><br/>").replace(/\n/g, "<br/>");
|
|
113
|
+
}
|
|
114
|
+
function TypingDots({ color }) {
|
|
115
|
+
return /* @__PURE__ */ jsx2("span", { style: { display: "inline-flex", gap: 4, alignItems: "center", padding: "2px 0" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx2("span", { style: {
|
|
116
|
+
width: 6,
|
|
117
|
+
height: 6,
|
|
118
|
+
borderRadius: "50%",
|
|
119
|
+
background: color,
|
|
120
|
+
animation: "sa-bounce 1.2s infinite",
|
|
121
|
+
animationDelay: `${i * 0.2}s`,
|
|
122
|
+
display: "inline-block"
|
|
123
|
+
} }, i)) });
|
|
124
|
+
}
|
|
125
|
+
function CopyBtn({ text }) {
|
|
126
|
+
const [copied, setCopied] = useState2(false);
|
|
127
|
+
const copy = useCallback2(() => {
|
|
128
|
+
navigator.clipboard?.writeText(text).then(() => {
|
|
129
|
+
setCopied(true);
|
|
130
|
+
setTimeout(() => setCopied(false), 1500);
|
|
131
|
+
});
|
|
132
|
+
}, [text]);
|
|
133
|
+
return /* @__PURE__ */ jsx2("button", { onClick: copy, title: "Copy", style: {
|
|
134
|
+
background: "none",
|
|
135
|
+
border: "none",
|
|
136
|
+
cursor: "pointer",
|
|
137
|
+
padding: "2px 6px",
|
|
138
|
+
borderRadius: 4,
|
|
139
|
+
fontSize: 11,
|
|
140
|
+
color: "#9ca3af",
|
|
141
|
+
opacity: 0.7,
|
|
142
|
+
transition: "opacity 0.15s"
|
|
143
|
+
}, children: copied ? "\u2713" : "\u2398" });
|
|
144
|
+
}
|
|
145
|
+
function MessageBubble({
|
|
146
|
+
role,
|
|
147
|
+
content,
|
|
148
|
+
isStreaming,
|
|
149
|
+
accentColor,
|
|
150
|
+
timestamp
|
|
151
|
+
}) {
|
|
152
|
+
const isUser = role === "user";
|
|
153
|
+
const timeStr = timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
154
|
+
return /* @__PURE__ */ jsxs("div", { style: {
|
|
155
|
+
display: "flex",
|
|
156
|
+
flexDirection: "column",
|
|
157
|
+
alignItems: isUser ? "flex-end" : "flex-start",
|
|
158
|
+
gap: 3,
|
|
159
|
+
maxWidth: "88%",
|
|
160
|
+
alignSelf: isUser ? "flex-end" : "flex-start"
|
|
161
|
+
}, children: [
|
|
162
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
163
|
+
display: "flex",
|
|
164
|
+
alignItems: "center",
|
|
165
|
+
gap: 6,
|
|
166
|
+
flexDirection: isUser ? "row-reverse" : "row"
|
|
167
|
+
}, children: [
|
|
168
|
+
/* @__PURE__ */ jsx2("div", { style: {
|
|
169
|
+
width: 24,
|
|
170
|
+
height: 24,
|
|
171
|
+
borderRadius: "50%",
|
|
172
|
+
background: isUser ? accentColor : "linear-gradient(135deg,#6366f1,#8b5cf6)",
|
|
173
|
+
display: "flex",
|
|
174
|
+
alignItems: "center",
|
|
175
|
+
justifyContent: "center",
|
|
176
|
+
fontSize: 11,
|
|
177
|
+
color: "white",
|
|
178
|
+
fontWeight: 700,
|
|
179
|
+
flexShrink: 0
|
|
180
|
+
}, children: isUser ? "U" : "\u2726" }),
|
|
181
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 11, color: "#9ca3af", fontWeight: 500 }, children: isUser ? "You" : "SyncAgent" }),
|
|
182
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 10, color: "#d1d5db" }, children: timeStr })
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsx2("div", { style: {
|
|
185
|
+
padding: "10px 14px",
|
|
186
|
+
borderRadius: isUser ? "16px 4px 16px 16px" : "4px 16px 16px 16px",
|
|
187
|
+
background: isUser ? accentColor : "#f8fafc",
|
|
188
|
+
color: isUser ? "white" : "#1e293b",
|
|
189
|
+
fontSize: 13.5,
|
|
190
|
+
lineHeight: 1.6,
|
|
191
|
+
wordBreak: "break-word",
|
|
192
|
+
border: isUser ? "none" : "1px solid #e2e8f0",
|
|
193
|
+
boxShadow: isUser ? `0 2px 8px ${accentColor}33` : "0 1px 4px rgba(0,0,0,0.06)",
|
|
194
|
+
position: "relative"
|
|
195
|
+
}, children: isStreaming && !content ? /* @__PURE__ */ jsx2(TypingDots, { color: accentColor }) : isUser ? /* @__PURE__ */ jsx2("span", { style: { whiteSpace: "pre-wrap" }, children: content }) : /* @__PURE__ */ jsx2("div", { dangerouslySetInnerHTML: { __html: renderMarkdown(content) } }) }),
|
|
196
|
+
!isUser && content && !isStreaming && /* @__PURE__ */ jsx2("div", { style: { paddingLeft: 30 }, children: /* @__PURE__ */ jsx2(CopyBtn, { text: content }) })
|
|
197
|
+
] });
|
|
198
|
+
}
|
|
199
|
+
function Suggestions({ items, onSelect, accentColor }) {
|
|
200
|
+
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, padding: "0 16px 12px" }, children: items.map((s2) => /* @__PURE__ */ jsx2("button", { onClick: () => onSelect(s2), style: {
|
|
201
|
+
padding: "5px 12px",
|
|
202
|
+
borderRadius: 20,
|
|
203
|
+
fontSize: 12,
|
|
204
|
+
cursor: "pointer",
|
|
205
|
+
border: `1px solid ${accentColor}44`,
|
|
206
|
+
background: `${accentColor}0d`,
|
|
207
|
+
color: accentColor,
|
|
208
|
+
fontWeight: 500,
|
|
209
|
+
transition: "all 0.15s"
|
|
210
|
+
}, children: s2 }, s2)) });
|
|
211
|
+
}
|
|
99
212
|
function ChatInner({
|
|
100
213
|
mode = "floating",
|
|
101
214
|
position = "bottom-right",
|
|
102
215
|
defaultOpen = false,
|
|
103
|
-
title = "
|
|
104
|
-
|
|
105
|
-
|
|
216
|
+
title = "SyncAgent",
|
|
217
|
+
subtitle = "AI Database Assistant",
|
|
218
|
+
placeholder = "Ask anything about your data...",
|
|
219
|
+
welcomeMessage = "Hi! I can query, analyze, and manage your database using natural language. What would you like to know?",
|
|
106
220
|
accentColor = "#10b981",
|
|
107
221
|
className,
|
|
108
|
-
style: customStyle
|
|
222
|
+
style: customStyle,
|
|
223
|
+
suggestions = ["Show all records", "Count total entries", "Show recent activity"]
|
|
109
224
|
}) {
|
|
110
|
-
const { messages, isLoading, sendMessage } = useSyncAgent();
|
|
225
|
+
const { messages, isLoading, error, sendMessage, stop, reset } = useSyncAgent();
|
|
111
226
|
const [isOpen, setIsOpen] = useState2(defaultOpen);
|
|
112
227
|
const [input, setInput] = useState2("");
|
|
228
|
+
const [timestamps] = useState2(() => /* @__PURE__ */ new Map());
|
|
113
229
|
const messagesEndRef = useRef2(null);
|
|
230
|
+
const inputRef = useRef2(null);
|
|
231
|
+
const msgCount = useRef2(0);
|
|
232
|
+
if (messages.length > msgCount.current) {
|
|
233
|
+
for (let i = msgCount.current; i < messages.length; i++) {
|
|
234
|
+
if (!timestamps.has(i)) timestamps.set(i, /* @__PURE__ */ new Date());
|
|
235
|
+
}
|
|
236
|
+
msgCount.current = messages.length;
|
|
237
|
+
}
|
|
114
238
|
useEffect(() => {
|
|
115
239
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
116
|
-
}, [messages]);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
240
|
+
}, [messages, isLoading]);
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (isOpen) setTimeout(() => inputRef.current?.focus(), 100);
|
|
243
|
+
}, [isOpen]);
|
|
244
|
+
const handleSend = useCallback2(() => {
|
|
245
|
+
const text = input.trim();
|
|
246
|
+
if (!text || isLoading) return;
|
|
121
247
|
setInput("");
|
|
248
|
+
sendMessage(text);
|
|
249
|
+
}, [input, isLoading, sendMessage]);
|
|
250
|
+
const handleKeyDown = (e) => {
|
|
251
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
252
|
+
e.preventDefault();
|
|
253
|
+
handleSend();
|
|
254
|
+
}
|
|
122
255
|
};
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
256
|
+
const showSuggestions = messages.length === 0 && suggestions.length > 0;
|
|
257
|
+
const panel = /* @__PURE__ */ jsxs("div", { style: {
|
|
258
|
+
...s.panel,
|
|
259
|
+
...mode === "inline" ? s.panelInline : {},
|
|
260
|
+
...customStyle
|
|
261
|
+
}, className, children: [
|
|
262
|
+
/* @__PURE__ */ jsx2("style", { children: `
|
|
263
|
+
@keyframes sa-bounce {
|
|
264
|
+
0%,80%,100% { transform: translateY(0); opacity:0.4 }
|
|
265
|
+
40% { transform: translateY(-5px); opacity:1 }
|
|
266
|
+
}
|
|
267
|
+
@keyframes sa-fadein {
|
|
268
|
+
from { opacity:0; transform:translateY(6px) }
|
|
269
|
+
to { opacity:1; transform:translateY(0) }
|
|
270
|
+
}
|
|
271
|
+
.sa-msg-wrap { animation: sa-fadein 0.2s ease }
|
|
272
|
+
.sa-input:focus { outline:none; border-color:${accentColor} !important; box-shadow:0 0 0 3px ${accentColor}22 !important }
|
|
273
|
+
.sa-send:hover:not(:disabled) { opacity:0.88; transform:scale(1.04) }
|
|
274
|
+
.sa-send:disabled { opacity:0.4; cursor:not-allowed }
|
|
275
|
+
.sa-fab-btn:hover { transform:scale(1.08) }
|
|
276
|
+
` }),
|
|
277
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
278
|
+
padding: "14px 16px",
|
|
279
|
+
background: `linear-gradient(135deg, ${accentColor}, ${adjustColor(accentColor, -30)})`,
|
|
280
|
+
display: "flex",
|
|
281
|
+
alignItems: "center",
|
|
282
|
+
justifyContent: "space-between",
|
|
283
|
+
flexShrink: 0
|
|
284
|
+
}, children: [
|
|
285
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
|
|
286
|
+
/* @__PURE__ */ jsx2("div", { style: {
|
|
287
|
+
width: 34,
|
|
288
|
+
height: 34,
|
|
289
|
+
borderRadius: "50%",
|
|
290
|
+
background: "rgba(255,255,255,0.2)",
|
|
291
|
+
display: "flex",
|
|
292
|
+
alignItems: "center",
|
|
293
|
+
justifyContent: "center",
|
|
294
|
+
fontSize: 16
|
|
295
|
+
}, children: "\u2726" }),
|
|
296
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
297
|
+
/* @__PURE__ */ jsx2("div", { style: { color: "white", fontWeight: 700, fontSize: 14, lineHeight: 1.2 }, children: title }),
|
|
298
|
+
/* @__PURE__ */ jsx2("div", { style: { color: "rgba(255,255,255,0.75)", fontSize: 11 }, children: subtitle })
|
|
299
|
+
] })
|
|
300
|
+
] }),
|
|
301
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 4 }, children: [
|
|
302
|
+
messages.length > 0 && /* @__PURE__ */ jsx2("button", { onClick: reset, title: "Clear chat", style: {
|
|
303
|
+
background: "rgba(255,255,255,0.15)",
|
|
304
|
+
border: "none",
|
|
305
|
+
color: "white",
|
|
306
|
+
cursor: "pointer",
|
|
307
|
+
borderRadius: 6,
|
|
308
|
+
padding: "4px 8px",
|
|
309
|
+
fontSize: 11
|
|
310
|
+
}, children: "Clear" }),
|
|
311
|
+
mode === "floating" && /* @__PURE__ */ jsx2("button", { onClick: () => setIsOpen(false), style: {
|
|
312
|
+
background: "rgba(255,255,255,0.15)",
|
|
313
|
+
border: "none",
|
|
314
|
+
color: "white",
|
|
315
|
+
cursor: "pointer",
|
|
316
|
+
borderRadius: 6,
|
|
317
|
+
padding: "4px 8px",
|
|
318
|
+
fontSize: 16,
|
|
319
|
+
lineHeight: 1
|
|
320
|
+
}, children: "\xD7" })
|
|
321
|
+
] })
|
|
127
322
|
] }),
|
|
128
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
129
|
-
messages.length === 0 && /* @__PURE__ */
|
|
130
|
-
|
|
131
|
-
|
|
323
|
+
/* @__PURE__ */ jsxs("div", { style: s.messages, children: [
|
|
324
|
+
messages.length === 0 && /* @__PURE__ */ jsxs("div", { style: s.welcome, children: [
|
|
325
|
+
/* @__PURE__ */ jsx2("div", { style: {
|
|
326
|
+
width: 48,
|
|
327
|
+
height: 48,
|
|
328
|
+
borderRadius: "50%",
|
|
329
|
+
margin: "0 auto 12px",
|
|
330
|
+
background: `linear-gradient(135deg, ${accentColor}22, ${accentColor}44)`,
|
|
331
|
+
display: "flex",
|
|
332
|
+
alignItems: "center",
|
|
333
|
+
justifyContent: "center",
|
|
334
|
+
fontSize: 22
|
|
335
|
+
}, children: "\u2726" }),
|
|
336
|
+
/* @__PURE__ */ jsx2("p", { style: { fontSize: 14, color: "#64748b", lineHeight: 1.6, maxWidth: 260, margin: "0 auto" }, children: welcomeMessage })
|
|
337
|
+
] }),
|
|
338
|
+
messages.map((msg, i) => /* @__PURE__ */ jsx2("div", { className: "sa-msg-wrap", children: /* @__PURE__ */ jsx2(
|
|
339
|
+
MessageBubble,
|
|
132
340
|
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
341
|
+
role: msg.role,
|
|
342
|
+
content: msg.content,
|
|
343
|
+
isStreaming: isLoading && i === messages.length - 1 && msg.role === "assistant",
|
|
344
|
+
accentColor,
|
|
345
|
+
timestamp: timestamps.get(i) ?? /* @__PURE__ */ new Date()
|
|
346
|
+
}
|
|
347
|
+
) }, i)),
|
|
348
|
+
error && /* @__PURE__ */ jsxs("div", { style: {
|
|
349
|
+
padding: "10px 14px",
|
|
350
|
+
borderRadius: 10,
|
|
351
|
+
fontSize: 13,
|
|
352
|
+
background: "#fef2f2",
|
|
353
|
+
color: "#dc2626",
|
|
354
|
+
border: "1px solid #fecaca",
|
|
355
|
+
alignSelf: "flex-start"
|
|
356
|
+
}, children: [
|
|
357
|
+
"\u26A0\uFE0F ",
|
|
358
|
+
error.message
|
|
359
|
+
] }),
|
|
141
360
|
/* @__PURE__ */ jsx2("div", { ref: messagesEndRef })
|
|
142
361
|
] }),
|
|
143
|
-
/* @__PURE__ */
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
362
|
+
showSuggestions && /* @__PURE__ */ jsx2(
|
|
363
|
+
Suggestions,
|
|
364
|
+
{
|
|
365
|
+
items: suggestions,
|
|
366
|
+
onSelect: (s2) => {
|
|
367
|
+
setInput(s2);
|
|
368
|
+
inputRef.current?.focus();
|
|
369
|
+
},
|
|
370
|
+
accentColor
|
|
371
|
+
}
|
|
372
|
+
),
|
|
373
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
374
|
+
padding: "10px 12px",
|
|
375
|
+
borderTop: "1px solid #f1f5f9",
|
|
376
|
+
background: "#fff",
|
|
377
|
+
flexShrink: 0
|
|
378
|
+
}, children: [
|
|
379
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
380
|
+
display: "flex",
|
|
381
|
+
gap: 8,
|
|
382
|
+
alignItems: "flex-end",
|
|
383
|
+
background: "#f8fafc",
|
|
384
|
+
borderRadius: 12,
|
|
385
|
+
border: "1px solid #e2e8f0",
|
|
386
|
+
padding: "6px 6px 6px 12px",
|
|
387
|
+
transition: "border-color 0.15s, box-shadow 0.15s"
|
|
388
|
+
}, children: [
|
|
389
|
+
/* @__PURE__ */ jsx2(
|
|
390
|
+
"textarea",
|
|
391
|
+
{
|
|
392
|
+
ref: inputRef,
|
|
393
|
+
className: "sa-input",
|
|
394
|
+
value: input,
|
|
395
|
+
onChange: (e) => {
|
|
396
|
+
setInput(e.target.value);
|
|
397
|
+
e.target.style.height = "auto";
|
|
398
|
+
e.target.style.height = Math.min(e.target.scrollHeight, 120) + "px";
|
|
399
|
+
},
|
|
400
|
+
onKeyDown: handleKeyDown,
|
|
401
|
+
placeholder,
|
|
402
|
+
disabled: isLoading,
|
|
403
|
+
rows: 1,
|
|
404
|
+
style: {
|
|
405
|
+
flex: 1,
|
|
406
|
+
background: "none",
|
|
407
|
+
border: "none",
|
|
408
|
+
resize: "none",
|
|
409
|
+
fontSize: 13.5,
|
|
410
|
+
lineHeight: 1.5,
|
|
411
|
+
color: "#1e293b",
|
|
412
|
+
fontFamily: "inherit",
|
|
413
|
+
padding: 0,
|
|
414
|
+
maxHeight: 120,
|
|
415
|
+
outline: "none"
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
),
|
|
419
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 4, alignItems: "flex-end", flexShrink: 0 }, children: [
|
|
420
|
+
isLoading && /* @__PURE__ */ jsx2("button", { onClick: stop, title: "Stop", style: {
|
|
421
|
+
background: "#fef2f2",
|
|
422
|
+
border: "1px solid #fecaca",
|
|
423
|
+
color: "#dc2626",
|
|
424
|
+
borderRadius: 8,
|
|
425
|
+
padding: "6px 10px",
|
|
426
|
+
cursor: "pointer",
|
|
427
|
+
fontSize: 12,
|
|
428
|
+
fontWeight: 600
|
|
429
|
+
}, children: "\u25A0 Stop" }),
|
|
430
|
+
/* @__PURE__ */ jsx2(
|
|
431
|
+
"button",
|
|
432
|
+
{
|
|
433
|
+
className: "sa-send",
|
|
434
|
+
onClick: handleSend,
|
|
435
|
+
disabled: isLoading || !input.trim(),
|
|
436
|
+
style: {
|
|
437
|
+
width: 34,
|
|
438
|
+
height: 34,
|
|
439
|
+
borderRadius: 8,
|
|
440
|
+
border: "none",
|
|
441
|
+
background: input.trim() && !isLoading ? accentColor : "#e2e8f0",
|
|
442
|
+
color: input.trim() && !isLoading ? "white" : "#94a3b8",
|
|
443
|
+
cursor: "pointer",
|
|
444
|
+
display: "flex",
|
|
445
|
+
alignItems: "center",
|
|
446
|
+
justifyContent: "center",
|
|
447
|
+
transition: "all 0.15s",
|
|
448
|
+
flexShrink: 0
|
|
449
|
+
},
|
|
450
|
+
children: /* @__PURE__ */ jsx2("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" }) })
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
] })
|
|
454
|
+
] }),
|
|
455
|
+
/* @__PURE__ */ jsxs("div", { style: { textAlign: "center", marginTop: 6, fontSize: 10, color: "#cbd5e1" }, children: [
|
|
456
|
+
"Powered by ",
|
|
457
|
+
/* @__PURE__ */ jsx2("span", { style: { color: accentColor, fontWeight: 600 }, children: "SyncAgent" }),
|
|
458
|
+
" \xB7 Enter to send \xB7 Shift+Enter for new line"
|
|
459
|
+
] })
|
|
163
460
|
] })
|
|
164
461
|
] });
|
|
165
462
|
if (mode === "inline") return panel;
|
|
166
463
|
const isLeft = position === "bottom-left";
|
|
167
464
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
168
|
-
|
|
169
|
-
|
|
465
|
+
/* @__PURE__ */ jsx2("div", { style: {
|
|
466
|
+
position: "fixed",
|
|
467
|
+
bottom: 88,
|
|
468
|
+
zIndex: 99998,
|
|
469
|
+
...isLeft ? { left: 20 } : { right: 20 },
|
|
470
|
+
width: 420,
|
|
471
|
+
maxWidth: "calc(100vw - 40px)",
|
|
472
|
+
transition: "opacity 0.25s, transform 0.25s",
|
|
473
|
+
opacity: isOpen ? 1 : 0,
|
|
474
|
+
transform: isOpen ? "translateY(0) scale(1)" : "translateY(16px) scale(0.96)",
|
|
475
|
+
pointerEvents: isOpen ? "auto" : "none"
|
|
476
|
+
}, children: panel }),
|
|
477
|
+
/* @__PURE__ */ jsxs(
|
|
170
478
|
"button",
|
|
171
479
|
{
|
|
480
|
+
className: "sa-fab-btn",
|
|
172
481
|
onClick: () => setIsOpen(!isOpen),
|
|
173
482
|
style: {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
483
|
+
position: "fixed",
|
|
484
|
+
bottom: 20,
|
|
485
|
+
zIndex: 99999,
|
|
486
|
+
...isLeft ? { left: 20 } : { right: 20 },
|
|
487
|
+
width: 56,
|
|
488
|
+
height: 56,
|
|
489
|
+
borderRadius: "50%",
|
|
490
|
+
border: "none",
|
|
491
|
+
background: `linear-gradient(135deg, ${accentColor}, ${adjustColor(accentColor, -30)})`,
|
|
492
|
+
cursor: "pointer",
|
|
493
|
+
boxShadow: `0 4px 20px ${accentColor}55, 0 2px 8px rgba(0,0,0,0.15)`,
|
|
494
|
+
display: "flex",
|
|
495
|
+
alignItems: "center",
|
|
496
|
+
justifyContent: "center",
|
|
497
|
+
transition: "transform 0.2s, box-shadow 0.2s"
|
|
177
498
|
},
|
|
178
|
-
children:
|
|
499
|
+
children: [
|
|
500
|
+
isOpen ? /* @__PURE__ */ jsx2("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ jsx2("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) : /* @__PURE__ */ jsx2("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ jsx2("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" }) }),
|
|
501
|
+
!isOpen && messages.length > 0 && /* @__PURE__ */ jsx2("div", { style: {
|
|
502
|
+
position: "absolute",
|
|
503
|
+
top: 2,
|
|
504
|
+
right: 2,
|
|
505
|
+
width: 12,
|
|
506
|
+
height: 12,
|
|
507
|
+
borderRadius: "50%",
|
|
508
|
+
background: "#ef4444",
|
|
509
|
+
border: "2px solid white"
|
|
510
|
+
} })
|
|
511
|
+
]
|
|
179
512
|
}
|
|
180
513
|
)
|
|
181
514
|
] });
|
|
182
515
|
}
|
|
183
|
-
|
|
184
|
-
if (config) {
|
|
185
|
-
return /* @__PURE__ */ jsx2(SyncAgentProvider, { config, children: /* @__PURE__ */ jsx2(ChatInner, { ...props }) });
|
|
186
|
-
}
|
|
187
|
-
return /* @__PURE__ */ jsx2(ChatInner, { ...props });
|
|
188
|
-
}
|
|
189
|
-
function adjustColor(hex, amount) {
|
|
190
|
-
const num = parseInt(hex.replace("#", ""), 16);
|
|
191
|
-
const r = Math.min(255, Math.max(0, (num >> 16 & 255) + amount));
|
|
192
|
-
const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
|
|
193
|
-
const b = Math.min(255, Math.max(0, (num & 255) + amount));
|
|
194
|
-
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
195
|
-
}
|
|
196
|
-
var styles = {
|
|
197
|
-
fab: {
|
|
198
|
-
position: "fixed",
|
|
199
|
-
bottom: 24,
|
|
200
|
-
right: 24,
|
|
201
|
-
zIndex: 99999,
|
|
202
|
-
width: 56,
|
|
203
|
-
height: 56,
|
|
204
|
-
borderRadius: "50%",
|
|
205
|
-
border: "none",
|
|
206
|
-
cursor: "pointer",
|
|
207
|
-
boxShadow: "0 4px 20px rgba(0,0,0,0.2)",
|
|
208
|
-
display: "flex",
|
|
209
|
-
alignItems: "center",
|
|
210
|
-
justifyContent: "center"
|
|
211
|
-
},
|
|
212
|
-
floatingPanel: {
|
|
213
|
-
position: "fixed",
|
|
214
|
-
bottom: 96,
|
|
215
|
-
right: 24,
|
|
216
|
-
zIndex: 99998,
|
|
217
|
-
width: 400,
|
|
218
|
-
maxWidth: "calc(100vw - 48px)"
|
|
219
|
-
},
|
|
516
|
+
var s = {
|
|
220
517
|
panel: {
|
|
221
|
-
height:
|
|
222
|
-
maxHeight: "calc(100vh -
|
|
223
|
-
background: "#
|
|
224
|
-
borderRadius:
|
|
225
|
-
boxShadow: "0
|
|
518
|
+
height: 580,
|
|
519
|
+
maxHeight: "calc(100vh - 110px)",
|
|
520
|
+
background: "#ffffff",
|
|
521
|
+
borderRadius: 18,
|
|
522
|
+
boxShadow: "0 20px 60px rgba(0,0,0,0.15), 0 4px 20px rgba(0,0,0,0.08)",
|
|
226
523
|
display: "flex",
|
|
227
524
|
flexDirection: "column",
|
|
228
525
|
overflow: "hidden",
|
|
229
|
-
fontFamily: "
|
|
526
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
527
|
+
border: "1px solid rgba(0,0,0,0.06)"
|
|
230
528
|
},
|
|
231
529
|
panelInline: {
|
|
232
530
|
height: "100%",
|
|
233
531
|
maxHeight: "none",
|
|
234
|
-
borderRadius:
|
|
235
|
-
boxShadow: "0 2px
|
|
236
|
-
},
|
|
237
|
-
header: {
|
|
238
|
-
padding: "16px",
|
|
239
|
-
color: "white",
|
|
240
|
-
fontWeight: 600,
|
|
241
|
-
fontSize: 15,
|
|
242
|
-
display: "flex",
|
|
243
|
-
alignItems: "center",
|
|
244
|
-
justifyContent: "space-between"
|
|
245
|
-
},
|
|
246
|
-
closeBtn: {
|
|
247
|
-
background: "none",
|
|
248
|
-
border: "none",
|
|
249
|
-
color: "white",
|
|
250
|
-
cursor: "pointer",
|
|
251
|
-
padding: 4,
|
|
252
|
-
fontSize: 20
|
|
532
|
+
borderRadius: 14,
|
|
533
|
+
boxShadow: "0 2px 16px rgba(0,0,0,0.08)"
|
|
253
534
|
},
|
|
254
535
|
messages: {
|
|
255
536
|
flex: 1,
|
|
256
537
|
overflowY: "auto",
|
|
257
|
-
padding:
|
|
538
|
+
padding: "16px 16px 8px",
|
|
258
539
|
display: "flex",
|
|
259
540
|
flexDirection: "column",
|
|
260
|
-
gap:
|
|
261
|
-
|
|
262
|
-
welcome: { textAlign: "center", padding: "40px 20px" },
|
|
263
|
-
msg: {
|
|
264
|
-
maxWidth: "85%",
|
|
265
|
-
padding: "10px 14px",
|
|
266
|
-
borderRadius: 12,
|
|
267
|
-
fontSize: 14,
|
|
268
|
-
lineHeight: 1.5,
|
|
269
|
-
wordBreak: "break-word",
|
|
270
|
-
whiteSpace: "pre-wrap"
|
|
271
|
-
},
|
|
272
|
-
msgUser: {
|
|
273
|
-
alignSelf: "flex-end",
|
|
274
|
-
color: "white",
|
|
275
|
-
borderBottomRightRadius: 4
|
|
276
|
-
},
|
|
277
|
-
msgAi: {
|
|
278
|
-
alignSelf: "flex-start",
|
|
279
|
-
background: "#f3f4f6",
|
|
280
|
-
color: "#1f2937",
|
|
281
|
-
borderBottomLeftRadius: 4
|
|
282
|
-
},
|
|
283
|
-
form: {
|
|
284
|
-
padding: "12px 16px",
|
|
285
|
-
borderTop: "1px solid #e5e7eb",
|
|
286
|
-
display: "flex",
|
|
287
|
-
gap: 8
|
|
541
|
+
gap: 14,
|
|
542
|
+
scrollbarWidth: "thin"
|
|
288
543
|
},
|
|
289
|
-
|
|
544
|
+
welcome: {
|
|
545
|
+
textAlign: "center",
|
|
546
|
+
padding: "32px 20px",
|
|
290
547
|
flex: 1,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
outline: "none"
|
|
296
|
-
},
|
|
297
|
-
sendBtn: {
|
|
298
|
-
padding: "10px 16px",
|
|
299
|
-
color: "white",
|
|
300
|
-
border: "none",
|
|
301
|
-
borderRadius: 10,
|
|
302
|
-
cursor: "pointer",
|
|
303
|
-
fontWeight: 600,
|
|
304
|
-
fontSize: 14
|
|
548
|
+
display: "flex",
|
|
549
|
+
flexDirection: "column",
|
|
550
|
+
alignItems: "center",
|
|
551
|
+
justifyContent: "center"
|
|
305
552
|
}
|
|
306
553
|
};
|
|
554
|
+
function adjustColor(hex, amount) {
|
|
555
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
556
|
+
const r = Math.min(255, Math.max(0, (num >> 16 & 255) + amount));
|
|
557
|
+
const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
|
|
558
|
+
const b = Math.min(255, Math.max(0, (num & 255) + amount));
|
|
559
|
+
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
560
|
+
}
|
|
561
|
+
function SyncAgentChat({ config, ...props }) {
|
|
562
|
+
if (config) {
|
|
563
|
+
return /* @__PURE__ */ jsx2(SyncAgentProvider, { config, children: /* @__PURE__ */ jsx2(ChatInner, { ...props }) });
|
|
564
|
+
}
|
|
565
|
+
return /* @__PURE__ */ jsx2(ChatInner, { ...props });
|
|
566
|
+
}
|
|
307
567
|
|
|
308
568
|
// src/index.ts
|
|
309
569
|
import { SyncAgentClient as SyncAgentClient2 } from "@syncagent/js";
|