@mordn/chat-widget 0.6.2 → 0.7.1
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 +105 -13
- package/dist/index.d.ts +105 -13
- package/dist/index.js +772 -397
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +725 -347
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
// src/ChatWidget.tsx
|
|
5
|
-
import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as
|
|
5
|
+
import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
|
|
6
6
|
|
|
7
7
|
// src/ui/button.tsx
|
|
8
8
|
import { Slot } from "@radix-ui/react-slot";
|
|
@@ -191,10 +191,13 @@ Textarea.displayName = "Textarea";
|
|
|
191
191
|
|
|
192
192
|
// src/components/prompt-input.tsx
|
|
193
193
|
import {
|
|
194
|
+
FileIcon,
|
|
195
|
+
FileSpreadsheetIcon,
|
|
196
|
+
FileTextIcon,
|
|
194
197
|
ImageIcon,
|
|
195
198
|
Loader2Icon,
|
|
196
|
-
PaperclipIcon,
|
|
197
199
|
PlusIcon,
|
|
200
|
+
PresentationIcon,
|
|
198
201
|
SendIcon,
|
|
199
202
|
SquareIcon,
|
|
200
203
|
XIcon
|
|
@@ -229,13 +232,22 @@ function PromptInputAttachment({
|
|
|
229
232
|
...props
|
|
230
233
|
}) {
|
|
231
234
|
const attachments = usePromptInputAttachments();
|
|
235
|
+
const isImage = data.mediaType?.startsWith("image/") && !!data.url;
|
|
232
236
|
return /* @__PURE__ */ jsxs5(
|
|
233
237
|
"div",
|
|
234
238
|
{
|
|
235
|
-
className: cn(
|
|
239
|
+
className: cn(
|
|
240
|
+
"group relative rounded-lg border",
|
|
241
|
+
// Images keep the square thumbnail. Other files use a wider
|
|
242
|
+
// pill-shaped chip showing icon + filename — without it,
|
|
243
|
+
// non-image attachments rendered as identical paperclip
|
|
244
|
+
// squares with no way to tell them apart.
|
|
245
|
+
isImage ? "h-14 w-14" : "h-14 max-w-[200px]",
|
|
246
|
+
className
|
|
247
|
+
),
|
|
236
248
|
...props,
|
|
237
249
|
children: [
|
|
238
|
-
|
|
250
|
+
isImage ? /* @__PURE__ */ jsx8(
|
|
239
251
|
"img",
|
|
240
252
|
{
|
|
241
253
|
alt: data.filename || "attachment",
|
|
@@ -244,7 +256,7 @@ function PromptInputAttachment({
|
|
|
244
256
|
src: data.url,
|
|
245
257
|
width: 56
|
|
246
258
|
}
|
|
247
|
-
) : /* @__PURE__ */ jsx8(
|
|
259
|
+
) : /* @__PURE__ */ jsx8(NonImageChip, { data }),
|
|
248
260
|
/* @__PURE__ */ jsx8(
|
|
249
261
|
Button,
|
|
250
262
|
{
|
|
@@ -262,6 +274,34 @@ function PromptInputAttachment({
|
|
|
262
274
|
data.id
|
|
263
275
|
);
|
|
264
276
|
}
|
|
277
|
+
function NonImageChip({ data }) {
|
|
278
|
+
const { Icon: Icon2, label } = describeFile(data);
|
|
279
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex size-full items-center gap-2 px-2.5", children: [
|
|
280
|
+
/* @__PURE__ */ jsx8(Icon2, { className: "size-5 flex-shrink-0 text-muted-foreground" }),
|
|
281
|
+
/* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex flex-col leading-tight", children: [
|
|
282
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[12px] font-medium truncate", children: data.filename || "attachment" }),
|
|
283
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[10px] text-muted-foreground uppercase tracking-wide", children: label })
|
|
284
|
+
] })
|
|
285
|
+
] });
|
|
286
|
+
}
|
|
287
|
+
function describeFile(data) {
|
|
288
|
+
const mt = (data.mediaType || "").toLowerCase();
|
|
289
|
+
const ext = (data.filename || "").toLowerCase().split(".").pop() || "";
|
|
290
|
+
if (mt === "application/pdf" || ext === "pdf") return { Icon: FileTextIcon, label: "PDF" };
|
|
291
|
+
if (mt.includes("spreadsheet") || mt.includes("excel") || ext === "xlsx" || ext === "xls" || ext === "csv" || ext === "tsv") {
|
|
292
|
+
return { Icon: FileSpreadsheetIcon, label: ext.toUpperCase() || "Spreadsheet" };
|
|
293
|
+
}
|
|
294
|
+
if (mt.includes("presentation") || mt.includes("powerpoint") || ext === "pptx" || ext === "ppt") {
|
|
295
|
+
return { Icon: PresentationIcon, label: ext.toUpperCase() || "Slides" };
|
|
296
|
+
}
|
|
297
|
+
if (mt.includes("wordprocessing") || mt.includes("msword") || ext === "docx" || ext === "doc") {
|
|
298
|
+
return { Icon: FileTextIcon, label: ext.toUpperCase() || "Doc" };
|
|
299
|
+
}
|
|
300
|
+
if (mt.startsWith("text/") || ext === "txt" || ext === "md" || ext === "json") {
|
|
301
|
+
return { Icon: FileTextIcon, label: ext.toUpperCase() || "Text" };
|
|
302
|
+
}
|
|
303
|
+
return { Icon: FileIcon, label: ext.toUpperCase() || "File" };
|
|
304
|
+
}
|
|
265
305
|
function PromptInputAttachments({
|
|
266
306
|
className,
|
|
267
307
|
children,
|
|
@@ -326,10 +366,18 @@ var PromptInput = ({
|
|
|
326
366
|
if (!accept || accept.trim() === "") {
|
|
327
367
|
return true;
|
|
328
368
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return
|
|
369
|
+
const tokens = accept.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean);
|
|
370
|
+
const fileType = (f.type || "").toLowerCase();
|
|
371
|
+
const fileName = f.name.toLowerCase();
|
|
372
|
+
return tokens.some((token) => {
|
|
373
|
+
if (token === "*/*") return true;
|
|
374
|
+
if (token.startsWith(".")) return fileName.endsWith(token);
|
|
375
|
+
if (token.endsWith("/*")) {
|
|
376
|
+
const prefix = token.slice(0, -1);
|
|
377
|
+
return fileType.startsWith(prefix);
|
|
378
|
+
}
|
|
379
|
+
return fileType === token;
|
|
380
|
+
});
|
|
333
381
|
},
|
|
334
382
|
[accept]
|
|
335
383
|
);
|
|
@@ -631,6 +679,8 @@ var PromptInputSubmit = ({
|
|
|
631
679
|
variant = "default",
|
|
632
680
|
size = "icon",
|
|
633
681
|
status,
|
|
682
|
+
onStop,
|
|
683
|
+
onClick,
|
|
634
684
|
children,
|
|
635
685
|
...props
|
|
636
686
|
}) => {
|
|
@@ -642,13 +692,22 @@ var PromptInputSubmit = ({
|
|
|
642
692
|
} else if (status === "error") {
|
|
643
693
|
Icon2 = /* @__PURE__ */ jsx8(XIcon, { className: "size-4" });
|
|
644
694
|
}
|
|
695
|
+
const isStopping = status === "streaming" && !!onStop;
|
|
645
696
|
return /* @__PURE__ */ jsx8(
|
|
646
697
|
Button,
|
|
647
698
|
{
|
|
648
699
|
className: cn("gap-1.5 rounded-lg", className),
|
|
649
700
|
size,
|
|
650
|
-
type: "submit",
|
|
701
|
+
type: isStopping ? "button" : "submit",
|
|
651
702
|
variant,
|
|
703
|
+
onClick: (e) => {
|
|
704
|
+
if (isStopping) {
|
|
705
|
+
e.preventDefault();
|
|
706
|
+
onStop();
|
|
707
|
+
}
|
|
708
|
+
onClick?.(e);
|
|
709
|
+
},
|
|
710
|
+
"aria-label": isStopping ? "Stop generating" : void 0,
|
|
652
711
|
...props,
|
|
653
712
|
children: children ?? Icon2
|
|
654
713
|
}
|
|
@@ -656,62 +715,87 @@ var PromptInputSubmit = ({
|
|
|
656
715
|
};
|
|
657
716
|
|
|
658
717
|
// src/components/message-attachments.tsx
|
|
659
|
-
import {
|
|
660
|
-
|
|
718
|
+
import {
|
|
719
|
+
FileIcon as FileIcon2,
|
|
720
|
+
FileSpreadsheetIcon as FileSpreadsheetIcon2,
|
|
721
|
+
FileTextIcon as FileTextIcon2,
|
|
722
|
+
PresentationIcon as PresentationIcon2
|
|
723
|
+
} from "lucide-react";
|
|
724
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
725
|
+
function openAttachment(attachment) {
|
|
726
|
+
if (attachment.url.startsWith("data:")) {
|
|
727
|
+
const w = window.open("", "_blank");
|
|
728
|
+
if (w) {
|
|
729
|
+
w.document.write(
|
|
730
|
+
`<html><head><title>${attachment.filename}</title></head><body style="margin:0;padding:20px;background:#f5f5f5;display:flex;justify-content:center;align-items:center;min-height:100vh;"><img src="${attachment.url}" alt="${attachment.filename}" style="max-width:100%;max-height:100%;object-fit:contain;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.15);" /></body></html>`
|
|
731
|
+
);
|
|
732
|
+
w.document.close();
|
|
733
|
+
}
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
window.open(attachment.url, "_blank");
|
|
737
|
+
}
|
|
738
|
+
function describeFile2(att) {
|
|
739
|
+
const mt = (att.mediaType || "").toLowerCase();
|
|
740
|
+
const ext = (att.filename || "").toLowerCase().split(".").pop() || "";
|
|
741
|
+
if (mt === "application/pdf" || ext === "pdf") return { Icon: FileTextIcon2, label: "PDF" };
|
|
742
|
+
if (mt.includes("spreadsheet") || mt.includes("excel") || ext === "xlsx" || ext === "xls" || ext === "csv" || ext === "tsv") {
|
|
743
|
+
return { Icon: FileSpreadsheetIcon2, label: ext.toUpperCase() || "Spreadsheet" };
|
|
744
|
+
}
|
|
745
|
+
if (mt.includes("presentation") || mt.includes("powerpoint") || ext === "pptx" || ext === "ppt") {
|
|
746
|
+
return { Icon: PresentationIcon2, label: ext.toUpperCase() || "Slides" };
|
|
747
|
+
}
|
|
748
|
+
if (mt.includes("wordprocessing") || mt.includes("msword") || ext === "docx" || ext === "doc") {
|
|
749
|
+
return { Icon: FileTextIcon2, label: ext.toUpperCase() || "Doc" };
|
|
750
|
+
}
|
|
751
|
+
if (mt.startsWith("text/") || ext === "txt" || ext === "md" || ext === "json") {
|
|
752
|
+
return { Icon: FileTextIcon2, label: ext.toUpperCase() || "Text" };
|
|
753
|
+
}
|
|
754
|
+
return { Icon: FileIcon2, label: ext.toUpperCase() || "File" };
|
|
755
|
+
}
|
|
661
756
|
function MessageAttachments({ attachments, className }) {
|
|
662
757
|
if (!attachments || attachments.length === 0) {
|
|
663
758
|
return null;
|
|
664
759
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
newWindow.document.write(`
|
|
670
|
-
<html>
|
|
671
|
-
<head><title>${attachment.filename}</title></head>
|
|
672
|
-
<body style="margin:0; padding:20px; background:#f5f5f5; display:flex; justify-content:center; align-items:center; min-height:100vh;">
|
|
673
|
-
<img src="${attachment.url}" alt="${attachment.filename}" style="max-width:100%; max-height:100%; object-fit:contain; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.15);" />
|
|
674
|
-
</body>
|
|
675
|
-
</html>
|
|
676
|
-
`);
|
|
677
|
-
newWindow.document.close();
|
|
678
|
-
}
|
|
679
|
-
} else if (attachment.url.startsWith("blob:")) {
|
|
680
|
-
window.open(attachment.url, "_blank");
|
|
681
|
-
} else if (attachment.url.startsWith("http")) {
|
|
682
|
-
window.open(attachment.url, "_blank");
|
|
683
|
-
} else {
|
|
684
|
-
window.open(attachment.url, "_blank");
|
|
685
|
-
}
|
|
686
|
-
};
|
|
687
|
-
return /* @__PURE__ */ jsx9("div", { className: cn("flex flex-wrap gap-2", className), children: attachments.map((attachment, index) => /* @__PURE__ */ jsx9(
|
|
688
|
-
"div",
|
|
689
|
-
{
|
|
690
|
-
className: "group relative h-14 w-14 rounded-lg",
|
|
691
|
-
children: attachment.mediaType.startsWith("image/") ? /* @__PURE__ */ jsx9(
|
|
760
|
+
return /* @__PURE__ */ jsx9("div", { className: cn("flex flex-wrap gap-2", className), children: attachments.map((attachment, index) => {
|
|
761
|
+
const isImage = attachment.mediaType.startsWith("image/");
|
|
762
|
+
if (isImage) {
|
|
763
|
+
return /* @__PURE__ */ jsx9("div", { className: "group relative h-14 w-14 rounded-lg", children: /* @__PURE__ */ jsx9(
|
|
692
764
|
"img",
|
|
693
765
|
{
|
|
694
766
|
src: attachment.url,
|
|
695
767
|
alt: attachment.filename,
|
|
696
768
|
className: "size-full rounded-lg object-cover cursor-pointer hover:opacity-80 transition-opacity",
|
|
697
|
-
onClick: () =>
|
|
698
|
-
}
|
|
699
|
-
) : /* @__PURE__ */ jsx9(
|
|
700
|
-
"div",
|
|
701
|
-
{
|
|
702
|
-
className: "flex size-full items-center justify-center text-muted-foreground cursor-pointer hover:bg-secondary/50 rounded-lg transition-colors",
|
|
703
|
-
onClick: () => handleAttachmentClick(attachment),
|
|
704
|
-
children: /* @__PURE__ */ jsx9(PaperclipIcon2, { className: "size-4" })
|
|
769
|
+
onClick: () => openAttachment(attachment)
|
|
705
770
|
}
|
|
706
|
-
)
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
|
|
771
|
+
) }, index);
|
|
772
|
+
}
|
|
773
|
+
const { Icon: Icon2, label } = describeFile2(attachment);
|
|
774
|
+
return /* @__PURE__ */ jsxs6(
|
|
775
|
+
"button",
|
|
776
|
+
{
|
|
777
|
+
type: "button",
|
|
778
|
+
onClick: () => openAttachment(attachment),
|
|
779
|
+
className: cn(
|
|
780
|
+
"group flex items-center gap-2 px-2.5 h-14 rounded-lg border max-w-[220px]",
|
|
781
|
+
"hover:bg-[hsl(var(--chat-text)/0.04)] transition-colors text-left cursor-pointer"
|
|
782
|
+
),
|
|
783
|
+
children: [
|
|
784
|
+
/* @__PURE__ */ jsx9(Icon2, { className: "size-5 flex-shrink-0 text-muted-foreground" }),
|
|
785
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex flex-col leading-tight", children: [
|
|
786
|
+
/* @__PURE__ */ jsx9("span", { className: "text-[12px] font-medium truncate", children: attachment.filename }),
|
|
787
|
+
/* @__PURE__ */ jsx9("span", { className: "text-[10px] text-muted-foreground uppercase tracking-wide", children: label })
|
|
788
|
+
] })
|
|
789
|
+
]
|
|
790
|
+
},
|
|
791
|
+
index
|
|
792
|
+
);
|
|
793
|
+
}) });
|
|
710
794
|
}
|
|
711
795
|
|
|
712
796
|
// src/components/input-plugin-popover.tsx
|
|
713
797
|
import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
714
|
-
import { jsx as jsx10, jsxs as
|
|
798
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
715
799
|
var FETCH_DEBOUNCE_MS = 120;
|
|
716
800
|
function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
717
801
|
const [active, setActive] = useState2(null);
|
|
@@ -720,6 +804,7 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
720
804
|
const [loading, setLoading] = useState2(false);
|
|
721
805
|
const debounceRef = useRef2(null);
|
|
722
806
|
const requestIdRef = useRef2(0);
|
|
807
|
+
const sessionValidatedRef = useRef2(false);
|
|
723
808
|
const pluginsByTrigger = useMemo2(() => {
|
|
724
809
|
const map = /* @__PURE__ */ new Map();
|
|
725
810
|
for (const p of plugins ?? []) {
|
|
@@ -736,9 +821,14 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
736
821
|
return value.slice(active.triggerIndex + 1, cursor);
|
|
737
822
|
}, [active, value, textareaRef]);
|
|
738
823
|
useEffect2(() => {
|
|
739
|
-
if (!active)
|
|
740
|
-
|
|
741
|
-
|
|
824
|
+
if (!active) {
|
|
825
|
+
sessionValidatedRef.current = false;
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (value[active.triggerIndex] === active.plugin.trigger) {
|
|
829
|
+
sessionValidatedRef.current = true;
|
|
830
|
+
}
|
|
831
|
+
if (!sessionValidatedRef.current) return;
|
|
742
832
|
if (value[active.triggerIndex] !== active.plugin.trigger) {
|
|
743
833
|
setActive(null);
|
|
744
834
|
return;
|
|
@@ -746,7 +836,7 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
746
836
|
if (/\s/.test(query)) {
|
|
747
837
|
setActive(null);
|
|
748
838
|
}
|
|
749
|
-
}, [active, value, query
|
|
839
|
+
}, [active, value, query]);
|
|
750
840
|
useEffect2(() => {
|
|
751
841
|
if (!active) {
|
|
752
842
|
setItems([]);
|
|
@@ -754,13 +844,20 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
754
844
|
return;
|
|
755
845
|
}
|
|
756
846
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
757
|
-
setLoading(true);
|
|
758
847
|
const reqId = ++requestIdRef.current;
|
|
848
|
+
const result = active.plugin.fetch(query);
|
|
849
|
+
if (Array.isArray(result)) {
|
|
850
|
+
setItems(result);
|
|
851
|
+
setHighlight(0);
|
|
852
|
+
setLoading(false);
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
setLoading(true);
|
|
759
856
|
debounceRef.current = setTimeout(async () => {
|
|
760
857
|
try {
|
|
761
|
-
const
|
|
858
|
+
const items2 = await result;
|
|
762
859
|
if (reqId !== requestIdRef.current) return;
|
|
763
|
-
setItems(
|
|
860
|
+
setItems(items2);
|
|
764
861
|
setHighlight(0);
|
|
765
862
|
} catch (err) {
|
|
766
863
|
console.error("[input-plugin] fetch failed:", err);
|
|
@@ -841,14 +938,8 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
841
938
|
},
|
|
842
939
|
[active, items, highlight, selectItem, close, pluginsByTrigger, value]
|
|
843
940
|
);
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
if (value[active.triggerIndex] !== active.plugin.trigger) {
|
|
847
|
-
close();
|
|
848
|
-
}
|
|
849
|
-
}, [value, active, close]);
|
|
850
|
-
const popover = active && (loading || items.length > 0 || active.plugin.emptyText) ? /* @__PURE__ */ jsx10(
|
|
851
|
-
PluginPopover,
|
|
941
|
+
const panel = active ? /* @__PURE__ */ jsx10(
|
|
942
|
+
PluginPanel,
|
|
852
943
|
{
|
|
853
944
|
plugin: active.plugin,
|
|
854
945
|
items,
|
|
@@ -858,51 +949,257 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
858
949
|
onSelect: selectItem
|
|
859
950
|
}
|
|
860
951
|
) : null;
|
|
861
|
-
return { onKeyDown,
|
|
952
|
+
return { onKeyDown, panel, isOpen: !!active };
|
|
862
953
|
}
|
|
863
|
-
function
|
|
864
|
-
|
|
954
|
+
function PluginPanel({ plugin, items, loading, highlight, onHover, onSelect }) {
|
|
955
|
+
const viewportRef = useRef2(null);
|
|
956
|
+
const itemRefs = useRef2([]);
|
|
957
|
+
useEffect2(() => {
|
|
958
|
+
const btn = itemRefs.current[highlight];
|
|
959
|
+
const viewport = viewportRef.current;
|
|
960
|
+
if (!btn || !viewport) return;
|
|
961
|
+
const btnRect = btn.getBoundingClientRect();
|
|
962
|
+
const viewRect = viewport.getBoundingClientRect();
|
|
963
|
+
if (btnRect.top < viewRect.top) {
|
|
964
|
+
viewport.scrollTop -= viewRect.top - btnRect.top;
|
|
965
|
+
} else if (btnRect.bottom > viewRect.bottom) {
|
|
966
|
+
viewport.scrollTop += btnRect.bottom - viewRect.bottom;
|
|
967
|
+
}
|
|
968
|
+
}, [highlight]);
|
|
969
|
+
return /* @__PURE__ */ jsxs7(
|
|
865
970
|
"div",
|
|
866
971
|
{
|
|
867
972
|
role: "listbox",
|
|
868
|
-
className:
|
|
869
|
-
"absolute bottom-full left-0 right-0 mb-2 z-30",
|
|
870
|
-
"rounded-md border border-border bg-popover text-popover-foreground shadow-md",
|
|
871
|
-
"max-h-64 overflow-y-auto"
|
|
872
|
-
),
|
|
973
|
+
className: "rounded-t-xl bg-[hsl(var(--chat-background))] overflow-hidden mx-auto",
|
|
873
974
|
onMouseDown: (e) => e.preventDefault(),
|
|
975
|
+
style: {
|
|
976
|
+
width: "96%",
|
|
977
|
+
borderTop: "1px solid var(--chat-divider)",
|
|
978
|
+
borderLeft: "1px solid var(--chat-divider)",
|
|
979
|
+
borderRight: "1px solid var(--chat-divider)",
|
|
980
|
+
// Pull down 1px so our bottom edge overlaps the form's top
|
|
981
|
+
// border, removing the visible seam between the two surfaces.
|
|
982
|
+
marginBottom: -1
|
|
983
|
+
},
|
|
874
984
|
children: [
|
|
875
|
-
plugin.heading && /* @__PURE__ */ jsx10(
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
985
|
+
plugin.heading && /* @__PURE__ */ jsx10(
|
|
986
|
+
"div",
|
|
987
|
+
{
|
|
988
|
+
className: "px-3 py-1.5 text-[11px] font-semibold uppercase tracking-wide",
|
|
989
|
+
style: {
|
|
990
|
+
color: "hsl(var(--chat-text)/0.5)",
|
|
991
|
+
borderBottom: "1px solid var(--chat-divider)"
|
|
992
|
+
},
|
|
993
|
+
children: plugin.heading
|
|
994
|
+
}
|
|
995
|
+
),
|
|
996
|
+
loading && items.length === 0 && /* @__PURE__ */ jsx10(
|
|
997
|
+
"div",
|
|
998
|
+
{
|
|
999
|
+
className: "px-3 py-2 text-[13px]",
|
|
1000
|
+
style: { color: "hsl(var(--chat-text)/0.5)" },
|
|
1001
|
+
children: "Loading\u2026"
|
|
1002
|
+
}
|
|
1003
|
+
),
|
|
1004
|
+
!loading && items.length === 0 && /* @__PURE__ */ jsx10(
|
|
1005
|
+
"div",
|
|
1006
|
+
{
|
|
1007
|
+
className: "px-3 py-2 text-[13px]",
|
|
1008
|
+
style: { color: "hsl(var(--chat-text)/0.5)" },
|
|
1009
|
+
children: plugin.emptyText ?? "No results"
|
|
1010
|
+
}
|
|
1011
|
+
),
|
|
1012
|
+
items.length > 0 && /* @__PURE__ */ jsx10(
|
|
1013
|
+
"div",
|
|
1014
|
+
{
|
|
1015
|
+
ref: viewportRef,
|
|
1016
|
+
className: "max-h-[200px] overflow-y-auto",
|
|
1017
|
+
children: /* @__PURE__ */ jsx10("div", { className: "py-1", children: items.map((item, idx) => /* @__PURE__ */ jsxs7("div", { children: [
|
|
1018
|
+
/* @__PURE__ */ jsxs7(
|
|
1019
|
+
"button",
|
|
1020
|
+
{
|
|
1021
|
+
ref: (el) => {
|
|
1022
|
+
itemRefs.current[idx] = el;
|
|
1023
|
+
},
|
|
1024
|
+
type: "button",
|
|
1025
|
+
role: "option",
|
|
1026
|
+
"aria-selected": idx === highlight,
|
|
1027
|
+
onMouseEnter: () => onHover(idx),
|
|
1028
|
+
onClick: () => onSelect(item),
|
|
1029
|
+
className: cn(
|
|
1030
|
+
"w-full text-left px-3 py-2",
|
|
1031
|
+
"flex items-center justify-between gap-3",
|
|
1032
|
+
"transition-colors duration-150 ease-out",
|
|
1033
|
+
"cursor-pointer"
|
|
1034
|
+
),
|
|
1035
|
+
style: {
|
|
1036
|
+
backgroundColor: idx === highlight ? "hsl(var(--chat-text)/0.06)" : "transparent"
|
|
1037
|
+
},
|
|
1038
|
+
children: [
|
|
1039
|
+
/* @__PURE__ */ jsx10(
|
|
1040
|
+
"span",
|
|
1041
|
+
{
|
|
1042
|
+
className: "text-[13px] truncate",
|
|
1043
|
+
style: { color: "hsl(var(--chat-text)/0.85)" },
|
|
1044
|
+
children: item.label
|
|
1045
|
+
}
|
|
1046
|
+
),
|
|
1047
|
+
item.sublabel && /* @__PURE__ */ jsx10(
|
|
1048
|
+
"span",
|
|
1049
|
+
{
|
|
1050
|
+
className: "text-[11px] flex-shrink-0",
|
|
1051
|
+
style: { color: "hsl(var(--chat-text)/0.4)" },
|
|
1052
|
+
children: item.sublabel
|
|
1053
|
+
}
|
|
1054
|
+
)
|
|
1055
|
+
]
|
|
1056
|
+
}
|
|
1057
|
+
),
|
|
1058
|
+
idx < items.length - 1 && /* @__PURE__ */ jsx10(
|
|
1059
|
+
"div",
|
|
1060
|
+
{
|
|
1061
|
+
className: "h-px mx-3",
|
|
1062
|
+
style: { backgroundColor: "var(--chat-divider)" }
|
|
1063
|
+
}
|
|
1064
|
+
)
|
|
1065
|
+
] }, item.id)) })
|
|
1066
|
+
}
|
|
1067
|
+
)
|
|
1068
|
+
]
|
|
1069
|
+
}
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
// src/components/chat-error-banner.tsx
|
|
1074
|
+
import { AlertTriangleIcon, XIcon as XIcon2 } from "lucide-react";
|
|
1075
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1076
|
+
function ChatErrorBanner({
|
|
1077
|
+
error,
|
|
1078
|
+
canRetry = true,
|
|
1079
|
+
onRetry,
|
|
1080
|
+
onDismiss
|
|
1081
|
+
}) {
|
|
1082
|
+
if (!error) return null;
|
|
1083
|
+
const friendly = friendlyErrorMessage(error);
|
|
1084
|
+
return /* @__PURE__ */ jsxs8(
|
|
1085
|
+
"div",
|
|
1086
|
+
{
|
|
1087
|
+
role: "alert",
|
|
1088
|
+
className: "flex items-start gap-2 px-3 py-2 mb-2 rounded-lg text-[13px]",
|
|
1089
|
+
style: {
|
|
1090
|
+
backgroundColor: "hsl(var(--chat-text)/0.04)",
|
|
1091
|
+
border: "1px solid var(--chat-divider)"
|
|
1092
|
+
},
|
|
1093
|
+
title: error.message,
|
|
1094
|
+
children: [
|
|
1095
|
+
/* @__PURE__ */ jsx11(
|
|
1096
|
+
AlertTriangleIcon,
|
|
1097
|
+
{
|
|
1098
|
+
className: "size-4 mt-0.5 flex-shrink-0",
|
|
1099
|
+
style: { color: "hsl(var(--chat-text)/0.6)" }
|
|
1100
|
+
}
|
|
1101
|
+
),
|
|
1102
|
+
/* @__PURE__ */ jsx11("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx11("span", { style: { color: "hsl(var(--chat-text)/0.85)" }, children: friendly }) }),
|
|
1103
|
+
canRetry && onRetry && /* @__PURE__ */ jsx11(
|
|
879
1104
|
"button",
|
|
880
1105
|
{
|
|
881
1106
|
type: "button",
|
|
882
|
-
|
|
883
|
-
"
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
]
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
1107
|
+
onClick: onRetry,
|
|
1108
|
+
className: "text-[12px] font-medium underline-offset-2 hover:underline",
|
|
1109
|
+
style: { color: "hsl(var(--chat-text)/0.85)" },
|
|
1110
|
+
children: "Try again"
|
|
1111
|
+
}
|
|
1112
|
+
),
|
|
1113
|
+
onDismiss && /* @__PURE__ */ jsx11(
|
|
1114
|
+
"button",
|
|
1115
|
+
{
|
|
1116
|
+
type: "button",
|
|
1117
|
+
onClick: onDismiss,
|
|
1118
|
+
"aria-label": "Dismiss",
|
|
1119
|
+
className: "flex-shrink-0 -mr-1 -mt-0.5 p-1 rounded hover:bg-[hsl(var(--chat-text)/0.06)] transition-colors",
|
|
1120
|
+
style: { color: "hsl(var(--chat-text)/0.5)" },
|
|
1121
|
+
children: /* @__PURE__ */ jsx11(XIcon2, { className: "size-3.5" })
|
|
1122
|
+
}
|
|
1123
|
+
)
|
|
1124
|
+
]
|
|
1125
|
+
}
|
|
1126
|
+
);
|
|
1127
|
+
}
|
|
1128
|
+
function friendlyErrorMessage(error) {
|
|
1129
|
+
const raw = error.message ?? "";
|
|
1130
|
+
if (/abort/i.test(raw)) return "Stopped.";
|
|
1131
|
+
if (/network|fetch|disconnect|ECONN/i.test(raw)) {
|
|
1132
|
+
return "Connection issue. Check your network and try again.";
|
|
1133
|
+
}
|
|
1134
|
+
if (/rate.?limit|429/i.test(raw)) {
|
|
1135
|
+
return "You're sending messages too fast. Wait a moment and try again.";
|
|
1136
|
+
}
|
|
1137
|
+
if (/timeout/i.test(raw)) return "The response took too long.";
|
|
1138
|
+
return "Something went wrong while generating the response.";
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// src/components/message-actions.tsx
|
|
1142
|
+
import { useState as useState3 } from "react";
|
|
1143
|
+
import { CheckIcon as CheckIcon3, CopyIcon, RotateCcwIcon } from "lucide-react";
|
|
1144
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1145
|
+
function MessageActions({
|
|
1146
|
+
text,
|
|
1147
|
+
onRegenerate,
|
|
1148
|
+
regenerateDisabled,
|
|
1149
|
+
className
|
|
1150
|
+
}) {
|
|
1151
|
+
const [copied, setCopied] = useState3(false);
|
|
1152
|
+
const handleCopy = async () => {
|
|
1153
|
+
if (!text) return;
|
|
1154
|
+
try {
|
|
1155
|
+
await navigator.clipboard.writeText(text);
|
|
1156
|
+
setCopied(true);
|
|
1157
|
+
setTimeout(() => setCopied(false), 1500);
|
|
1158
|
+
} catch {
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
return /* @__PURE__ */ jsxs9(
|
|
1162
|
+
"div",
|
|
1163
|
+
{
|
|
1164
|
+
className: cn(
|
|
1165
|
+
"flex items-center gap-1 mt-1.5 -ml-1.5",
|
|
1166
|
+
// Pulled left a touch so the icons line up with the message
|
|
1167
|
+
// text edge instead of its padding box.
|
|
1168
|
+
className
|
|
1169
|
+
),
|
|
1170
|
+
children: [
|
|
1171
|
+
/* @__PURE__ */ jsx12(ActionButton, { onClick: handleCopy, ariaLabel: "Copy message", children: copied ? /* @__PURE__ */ jsx12(CheckIcon3, { className: "size-3.5" }) : /* @__PURE__ */ jsx12(CopyIcon, { className: "size-3.5" }) }),
|
|
1172
|
+
onRegenerate && /* @__PURE__ */ jsx12(
|
|
1173
|
+
ActionButton,
|
|
1174
|
+
{
|
|
1175
|
+
onClick: onRegenerate,
|
|
1176
|
+
disabled: regenerateDisabled,
|
|
1177
|
+
ariaLabel: "Regenerate response",
|
|
1178
|
+
children: /* @__PURE__ */ jsx12(RotateCcwIcon, { className: "size-3.5" })
|
|
1179
|
+
}
|
|
1180
|
+
)
|
|
898
1181
|
]
|
|
899
1182
|
}
|
|
900
1183
|
);
|
|
901
1184
|
}
|
|
1185
|
+
function ActionButton({ onClick, disabled, ariaLabel, children }) {
|
|
1186
|
+
return /* @__PURE__ */ jsx12(
|
|
1187
|
+
"button",
|
|
1188
|
+
{
|
|
1189
|
+
type: "button",
|
|
1190
|
+
onClick,
|
|
1191
|
+
disabled,
|
|
1192
|
+
"aria-label": ariaLabel,
|
|
1193
|
+
className: "p-1.5 rounded-md transition-colors hover:bg-[hsl(var(--chat-text)/0.06)] disabled:opacity-40 disabled:cursor-not-allowed",
|
|
1194
|
+
style: { color: "hsl(var(--chat-text)/0.55)" },
|
|
1195
|
+
children
|
|
1196
|
+
}
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
902
1199
|
|
|
903
1200
|
// src/components/interface.tsx
|
|
904
|
-
import { useState as
|
|
905
|
-
import { HistoryIcon, MessageSquareIcon, SearchIcon, ChevronRightIcon as ChevronRightIcon2, PlusIcon as PlusIcon2, XIcon as
|
|
1201
|
+
import { useState as useState6, useEffect as useEffect5, useRef as useRef4, useMemo as useMemo3, useCallback as useCallback4 } from "react";
|
|
1202
|
+
import { HistoryIcon, MessageSquareIcon, SearchIcon, ChevronRightIcon as ChevronRightIcon2, PlusIcon as PlusIcon2, XIcon as XIcon3 } from "lucide-react";
|
|
906
1203
|
import { Fragment as Fragment5 } from "react";
|
|
907
1204
|
import { useChat } from "@ai-sdk/react";
|
|
908
1205
|
import { DefaultChatTransport } from "ai";
|
|
@@ -946,11 +1243,11 @@ function useCodeBlockAutoScroll(isStreaming) {
|
|
|
946
1243
|
}
|
|
947
1244
|
|
|
948
1245
|
// src/components/response.tsx
|
|
949
|
-
import { jsx as
|
|
1246
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
950
1247
|
var Response = memo(
|
|
951
1248
|
({ className, isStreaming = false, ...props }) => {
|
|
952
1249
|
const containerRef = useCodeBlockAutoScroll(isStreaming);
|
|
953
|
-
return /* @__PURE__ */
|
|
1250
|
+
return /* @__PURE__ */ jsx13("div", { ref: containerRef, children: /* @__PURE__ */ jsx13(
|
|
954
1251
|
Streamdown,
|
|
955
1252
|
{
|
|
956
1253
|
className: cn(
|
|
@@ -967,16 +1264,16 @@ Response.displayName = "Response";
|
|
|
967
1264
|
|
|
968
1265
|
// src/ui/collapsible.tsx
|
|
969
1266
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
970
|
-
import { jsx as
|
|
1267
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
971
1268
|
function Collapsible({
|
|
972
1269
|
...props
|
|
973
1270
|
}) {
|
|
974
|
-
return /* @__PURE__ */
|
|
1271
|
+
return /* @__PURE__ */ jsx14(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
|
|
975
1272
|
}
|
|
976
1273
|
function CollapsibleTrigger2({
|
|
977
1274
|
...props
|
|
978
1275
|
}) {
|
|
979
|
-
return /* @__PURE__ */
|
|
1276
|
+
return /* @__PURE__ */ jsx14(
|
|
980
1277
|
CollapsiblePrimitive.CollapsibleTrigger,
|
|
981
1278
|
{
|
|
982
1279
|
"data-slot": "collapsible-trigger",
|
|
@@ -987,7 +1284,7 @@ function CollapsibleTrigger2({
|
|
|
987
1284
|
function CollapsibleContent2({
|
|
988
1285
|
...props
|
|
989
1286
|
}) {
|
|
990
|
-
return /* @__PURE__ */
|
|
1287
|
+
return /* @__PURE__ */ jsx14(
|
|
991
1288
|
CollapsiblePrimitive.CollapsibleContent,
|
|
992
1289
|
{
|
|
993
1290
|
"data-slot": "collapsible-content",
|
|
@@ -998,8 +1295,8 @@ function CollapsibleContent2({
|
|
|
998
1295
|
|
|
999
1296
|
// src/components/sources.tsx
|
|
1000
1297
|
import { BookIcon, ChevronDownIcon as ChevronDownIcon2 } from "lucide-react";
|
|
1001
|
-
import { Fragment as Fragment3, jsx as
|
|
1002
|
-
var Sources = ({ className, ...props }) => /* @__PURE__ */
|
|
1298
|
+
import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1299
|
+
var Sources = ({ className, ...props }) => /* @__PURE__ */ jsx15(
|
|
1003
1300
|
Collapsible,
|
|
1004
1301
|
{
|
|
1005
1302
|
className: cn("not-prose mb-4 text-primary text-xs", className),
|
|
@@ -1011,25 +1308,25 @@ var SourcesTrigger = ({
|
|
|
1011
1308
|
count,
|
|
1012
1309
|
children,
|
|
1013
1310
|
...props
|
|
1014
|
-
}) => /* @__PURE__ */
|
|
1311
|
+
}) => /* @__PURE__ */ jsx15(
|
|
1015
1312
|
CollapsibleTrigger2,
|
|
1016
1313
|
{
|
|
1017
1314
|
className: cn("flex items-center gap-2", className),
|
|
1018
1315
|
...props,
|
|
1019
|
-
children: children ?? /* @__PURE__ */
|
|
1020
|
-
/* @__PURE__ */
|
|
1316
|
+
children: children ?? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1317
|
+
/* @__PURE__ */ jsxs10("p", { className: "font-medium", children: [
|
|
1021
1318
|
"Used ",
|
|
1022
1319
|
count,
|
|
1023
1320
|
" sources"
|
|
1024
1321
|
] }),
|
|
1025
|
-
/* @__PURE__ */
|
|
1322
|
+
/* @__PURE__ */ jsx15(ChevronDownIcon2, { className: "h-4 w-4" })
|
|
1026
1323
|
] })
|
|
1027
1324
|
}
|
|
1028
1325
|
);
|
|
1029
1326
|
var SourcesContent = ({
|
|
1030
1327
|
className,
|
|
1031
1328
|
...props
|
|
1032
|
-
}) => /* @__PURE__ */
|
|
1329
|
+
}) => /* @__PURE__ */ jsx15(
|
|
1033
1330
|
CollapsibleContent2,
|
|
1034
1331
|
{
|
|
1035
1332
|
className: cn(
|
|
@@ -1040,7 +1337,7 @@ var SourcesContent = ({
|
|
|
1040
1337
|
...props
|
|
1041
1338
|
}
|
|
1042
1339
|
);
|
|
1043
|
-
var Source = ({ href, title, children, ...props }) => /* @__PURE__ */
|
|
1340
|
+
var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ jsx15(
|
|
1044
1341
|
"a",
|
|
1045
1342
|
{
|
|
1046
1343
|
className: "flex items-center gap-2",
|
|
@@ -1048,9 +1345,9 @@ var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ jsx13(
|
|
|
1048
1345
|
rel: "noreferrer",
|
|
1049
1346
|
target: "_blank",
|
|
1050
1347
|
...props,
|
|
1051
|
-
children: children ?? /* @__PURE__ */
|
|
1052
|
-
/* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1348
|
+
children: children ?? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1349
|
+
/* @__PURE__ */ jsx15(BookIcon, { className: "h-4 w-4" }),
|
|
1350
|
+
/* @__PURE__ */ jsx15("span", { className: "block font-medium", children: title })
|
|
1054
1351
|
] })
|
|
1055
1352
|
}
|
|
1056
1353
|
);
|
|
@@ -1058,8 +1355,8 @@ var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ jsx13(
|
|
|
1058
1355
|
// src/components/reasoning.tsx
|
|
1059
1356
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
1060
1357
|
import { BrainIcon, ChevronDownIcon as ChevronDownIcon3 } from "lucide-react";
|
|
1061
|
-
import { createContext as createContext2, memo as memo2, useContext as useContext2, useEffect as useEffect4, useState as
|
|
1062
|
-
import { Fragment as Fragment4, jsx as
|
|
1358
|
+
import { createContext as createContext2, memo as memo2, useContext as useContext2, useEffect as useEffect4, useState as useState4 } from "react";
|
|
1359
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1063
1360
|
var ReasoningContext = createContext2(null);
|
|
1064
1361
|
var useReasoning = () => {
|
|
1065
1362
|
const context = useContext2(ReasoningContext);
|
|
@@ -1090,8 +1387,8 @@ var Reasoning = memo2(
|
|
|
1090
1387
|
prop: durationProp,
|
|
1091
1388
|
defaultProp: void 0
|
|
1092
1389
|
});
|
|
1093
|
-
const [hasAutoClosed, setHasAutoClosed] =
|
|
1094
|
-
const [startTime, setStartTime] =
|
|
1390
|
+
const [hasAutoClosed, setHasAutoClosed] = useState4(false);
|
|
1391
|
+
const [startTime, setStartTime] = useState4(null);
|
|
1095
1392
|
useEffect4(() => {
|
|
1096
1393
|
if (isStreaming) {
|
|
1097
1394
|
if (startTime === null) {
|
|
@@ -1114,11 +1411,11 @@ var Reasoning = memo2(
|
|
|
1114
1411
|
const handleOpenChange = (newOpen) => {
|
|
1115
1412
|
setIsOpen(newOpen);
|
|
1116
1413
|
};
|
|
1117
|
-
return /* @__PURE__ */
|
|
1414
|
+
return /* @__PURE__ */ jsx16(
|
|
1118
1415
|
ReasoningContext.Provider,
|
|
1119
1416
|
{
|
|
1120
1417
|
value: { isStreaming, isOpen, setIsOpen, duration },
|
|
1121
|
-
children: /* @__PURE__ */
|
|
1418
|
+
children: /* @__PURE__ */ jsx16(
|
|
1122
1419
|
Collapsible,
|
|
1123
1420
|
{
|
|
1124
1421
|
className: cn("not-prose", className),
|
|
@@ -1134,15 +1431,15 @@ var Reasoning = memo2(
|
|
|
1134
1431
|
);
|
|
1135
1432
|
var getThinkingMessage = (isStreaming, duration) => {
|
|
1136
1433
|
if (isStreaming) {
|
|
1137
|
-
return /* @__PURE__ */
|
|
1434
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children: "Thinking..." });
|
|
1138
1435
|
}
|
|
1139
1436
|
if (duration === void 0) {
|
|
1140
|
-
return /* @__PURE__ */
|
|
1437
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children: "Thought process" });
|
|
1141
1438
|
}
|
|
1142
1439
|
if (duration === 0) {
|
|
1143
|
-
return /* @__PURE__ */
|
|
1440
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children: "Thought process" });
|
|
1144
1441
|
}
|
|
1145
|
-
return /* @__PURE__ */
|
|
1442
|
+
return /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
1146
1443
|
"Thought for ",
|
|
1147
1444
|
duration,
|
|
1148
1445
|
" seconds"
|
|
@@ -1151,7 +1448,7 @@ var getThinkingMessage = (isStreaming, duration) => {
|
|
|
1151
1448
|
var ReasoningTrigger = memo2(
|
|
1152
1449
|
({ className, children, ...props }) => {
|
|
1153
1450
|
const { isStreaming, isOpen, duration } = useReasoning();
|
|
1154
|
-
return /* @__PURE__ */
|
|
1451
|
+
return /* @__PURE__ */ jsx16(
|
|
1155
1452
|
CollapsibleTrigger2,
|
|
1156
1453
|
{
|
|
1157
1454
|
className: cn(
|
|
@@ -1159,10 +1456,10 @@ var ReasoningTrigger = memo2(
|
|
|
1159
1456
|
className
|
|
1160
1457
|
),
|
|
1161
1458
|
...props,
|
|
1162
|
-
children: children ?? /* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1459
|
+
children: children ?? /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
1460
|
+
/* @__PURE__ */ jsx16(BrainIcon, { className: "size-4 flex-shrink-0" }),
|
|
1164
1461
|
getThinkingMessage(isStreaming, duration),
|
|
1165
|
-
/* @__PURE__ */
|
|
1462
|
+
/* @__PURE__ */ jsx16(
|
|
1166
1463
|
ChevronDownIcon3,
|
|
1167
1464
|
{
|
|
1168
1465
|
className: cn(
|
|
@@ -1177,7 +1474,7 @@ var ReasoningTrigger = memo2(
|
|
|
1177
1474
|
}
|
|
1178
1475
|
);
|
|
1179
1476
|
var ReasoningContent = memo2(
|
|
1180
|
-
({ className, children, ...props }) => /* @__PURE__ */
|
|
1477
|
+
({ className, children, ...props }) => /* @__PURE__ */ jsx16(
|
|
1181
1478
|
CollapsibleContent2,
|
|
1182
1479
|
{
|
|
1183
1480
|
className: cn(
|
|
@@ -1186,7 +1483,7 @@ var ReasoningContent = memo2(
|
|
|
1186
1483
|
className
|
|
1187
1484
|
),
|
|
1188
1485
|
...props,
|
|
1189
|
-
children: /* @__PURE__ */
|
|
1486
|
+
children: /* @__PURE__ */ jsx16(Response, { className: "grid gap-2", children })
|
|
1190
1487
|
}
|
|
1191
1488
|
)
|
|
1192
1489
|
);
|
|
@@ -1195,8 +1492,8 @@ ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
|
1195
1492
|
ReasoningContent.displayName = "ReasoningContent";
|
|
1196
1493
|
|
|
1197
1494
|
// src/components/loader.tsx
|
|
1198
|
-
import { jsx as
|
|
1199
|
-
var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */
|
|
1495
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1496
|
+
var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs12(
|
|
1200
1497
|
"svg",
|
|
1201
1498
|
{
|
|
1202
1499
|
height: size,
|
|
@@ -1205,10 +1502,10 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1205
1502
|
viewBox: "0 0 16 16",
|
|
1206
1503
|
width: size,
|
|
1207
1504
|
children: [
|
|
1208
|
-
/* @__PURE__ */
|
|
1209
|
-
/* @__PURE__ */
|
|
1210
|
-
/* @__PURE__ */
|
|
1211
|
-
/* @__PURE__ */
|
|
1505
|
+
/* @__PURE__ */ jsx17("title", { children: "Loader" }),
|
|
1506
|
+
/* @__PURE__ */ jsxs12("g", { clipPath: "url(#clip0_2393_1490)", children: [
|
|
1507
|
+
/* @__PURE__ */ jsx17("path", { d: "M8 0V4", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1508
|
+
/* @__PURE__ */ jsx17(
|
|
1212
1509
|
"path",
|
|
1213
1510
|
{
|
|
1214
1511
|
d: "M8 16V12",
|
|
@@ -1217,7 +1514,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1217
1514
|
strokeWidth: "1.5"
|
|
1218
1515
|
}
|
|
1219
1516
|
),
|
|
1220
|
-
/* @__PURE__ */
|
|
1517
|
+
/* @__PURE__ */ jsx17(
|
|
1221
1518
|
"path",
|
|
1222
1519
|
{
|
|
1223
1520
|
d: "M3.29773 1.52783L5.64887 4.7639",
|
|
@@ -1226,7 +1523,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1226
1523
|
strokeWidth: "1.5"
|
|
1227
1524
|
}
|
|
1228
1525
|
),
|
|
1229
|
-
/* @__PURE__ */
|
|
1526
|
+
/* @__PURE__ */ jsx17(
|
|
1230
1527
|
"path",
|
|
1231
1528
|
{
|
|
1232
1529
|
d: "M12.7023 1.52783L10.3511 4.7639",
|
|
@@ -1235,7 +1532,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1235
1532
|
strokeWidth: "1.5"
|
|
1236
1533
|
}
|
|
1237
1534
|
),
|
|
1238
|
-
/* @__PURE__ */
|
|
1535
|
+
/* @__PURE__ */ jsx17(
|
|
1239
1536
|
"path",
|
|
1240
1537
|
{
|
|
1241
1538
|
d: "M12.7023 14.472L10.3511 11.236",
|
|
@@ -1244,7 +1541,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1244
1541
|
strokeWidth: "1.5"
|
|
1245
1542
|
}
|
|
1246
1543
|
),
|
|
1247
|
-
/* @__PURE__ */
|
|
1544
|
+
/* @__PURE__ */ jsx17(
|
|
1248
1545
|
"path",
|
|
1249
1546
|
{
|
|
1250
1547
|
d: "M3.29773 14.472L5.64887 11.236",
|
|
@@ -1253,7 +1550,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1253
1550
|
strokeWidth: "1.5"
|
|
1254
1551
|
}
|
|
1255
1552
|
),
|
|
1256
|
-
/* @__PURE__ */
|
|
1553
|
+
/* @__PURE__ */ jsx17(
|
|
1257
1554
|
"path",
|
|
1258
1555
|
{
|
|
1259
1556
|
d: "M15.6085 5.52783L11.8043 6.7639",
|
|
@@ -1262,7 +1559,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1262
1559
|
strokeWidth: "1.5"
|
|
1263
1560
|
}
|
|
1264
1561
|
),
|
|
1265
|
-
/* @__PURE__ */
|
|
1562
|
+
/* @__PURE__ */ jsx17(
|
|
1266
1563
|
"path",
|
|
1267
1564
|
{
|
|
1268
1565
|
d: "M0.391602 10.472L4.19583 9.23598",
|
|
@@ -1271,7 +1568,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1271
1568
|
strokeWidth: "1.5"
|
|
1272
1569
|
}
|
|
1273
1570
|
),
|
|
1274
|
-
/* @__PURE__ */
|
|
1571
|
+
/* @__PURE__ */ jsx17(
|
|
1275
1572
|
"path",
|
|
1276
1573
|
{
|
|
1277
1574
|
d: "M15.6085 10.4722L11.8043 9.2361",
|
|
@@ -1280,7 +1577,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1280
1577
|
strokeWidth: "1.5"
|
|
1281
1578
|
}
|
|
1282
1579
|
),
|
|
1283
|
-
/* @__PURE__ */
|
|
1580
|
+
/* @__PURE__ */ jsx17(
|
|
1284
1581
|
"path",
|
|
1285
1582
|
{
|
|
1286
1583
|
d: "M0.391602 5.52783L4.19583 6.7639",
|
|
@@ -1290,11 +1587,11 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ jsxs9(
|
|
|
1290
1587
|
}
|
|
1291
1588
|
)
|
|
1292
1589
|
] }),
|
|
1293
|
-
/* @__PURE__ */
|
|
1590
|
+
/* @__PURE__ */ jsx17("defs", { children: /* @__PURE__ */ jsx17("clipPath", { id: "clip0_2393_1490", children: /* @__PURE__ */ jsx17("rect", { fill: "white", height: "16", width: "16" }) }) })
|
|
1294
1591
|
]
|
|
1295
1592
|
}
|
|
1296
1593
|
);
|
|
1297
|
-
var Loader = ({ className, size = 16, ...props }) => /* @__PURE__ */
|
|
1594
|
+
var Loader = ({ className, size = 16, ...props }) => /* @__PURE__ */ jsx17(
|
|
1298
1595
|
"div",
|
|
1299
1596
|
{
|
|
1300
1597
|
className: cn(
|
|
@@ -1302,14 +1599,14 @@ var Loader = ({ className, size = 16, ...props }) => /* @__PURE__ */ jsx15(
|
|
|
1302
1599
|
className
|
|
1303
1600
|
),
|
|
1304
1601
|
...props,
|
|
1305
|
-
children: /* @__PURE__ */
|
|
1602
|
+
children: /* @__PURE__ */ jsx17(LoaderIcon, { size })
|
|
1306
1603
|
}
|
|
1307
1604
|
);
|
|
1308
1605
|
|
|
1309
1606
|
// src/ui/badge.tsx
|
|
1310
1607
|
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
1311
1608
|
import { cva as cva3 } from "class-variance-authority";
|
|
1312
|
-
import { jsx as
|
|
1609
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1313
1610
|
var badgeVariants = cva3(
|
|
1314
1611
|
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
|
1315
1612
|
{
|
|
@@ -1333,7 +1630,7 @@ function Badge({
|
|
|
1333
1630
|
...props
|
|
1334
1631
|
}) {
|
|
1335
1632
|
const Comp = asChild ? Slot2 : "span";
|
|
1336
|
-
return /* @__PURE__ */
|
|
1633
|
+
return /* @__PURE__ */ jsx18(
|
|
1337
1634
|
Comp,
|
|
1338
1635
|
{
|
|
1339
1636
|
"data-slot": "badge",
|
|
@@ -1355,14 +1652,14 @@ import {
|
|
|
1355
1652
|
import { isValidElement } from "react";
|
|
1356
1653
|
|
|
1357
1654
|
// src/components/code-block.tsx
|
|
1358
|
-
import { CheckIcon as
|
|
1359
|
-
import { createContext as createContext3, useContext as useContext3, useState as
|
|
1655
|
+
import { CheckIcon as CheckIcon4, CopyIcon as CopyIcon2 } from "lucide-react";
|
|
1656
|
+
import { createContext as createContext3, useContext as useContext3, useState as useState5 } from "react";
|
|
1360
1657
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
|
1361
1658
|
import {
|
|
1362
1659
|
oneDark,
|
|
1363
1660
|
oneLight
|
|
1364
1661
|
} from "react-syntax-highlighter/dist/esm/styles/prism";
|
|
1365
|
-
import { jsx as
|
|
1662
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1366
1663
|
var CodeBlockContext = createContext3({
|
|
1367
1664
|
code: ""
|
|
1368
1665
|
});
|
|
@@ -1373,7 +1670,7 @@ var CodeBlock = ({
|
|
|
1373
1670
|
className,
|
|
1374
1671
|
children,
|
|
1375
1672
|
...props
|
|
1376
|
-
}) => /* @__PURE__ */
|
|
1673
|
+
}) => /* @__PURE__ */ jsx19(CodeBlockContext.Provider, { value: { code }, children: /* @__PURE__ */ jsx19(
|
|
1377
1674
|
"div",
|
|
1378
1675
|
{
|
|
1379
1676
|
className: cn(
|
|
@@ -1381,8 +1678,8 @@ var CodeBlock = ({
|
|
|
1381
1678
|
className
|
|
1382
1679
|
),
|
|
1383
1680
|
...props,
|
|
1384
|
-
children: /* @__PURE__ */
|
|
1385
|
-
/* @__PURE__ */
|
|
1681
|
+
children: /* @__PURE__ */ jsxs13("div", { className: "relative max-h-96 overflow-y-auto", children: [
|
|
1682
|
+
/* @__PURE__ */ jsx19(
|
|
1386
1683
|
SyntaxHighlighter,
|
|
1387
1684
|
{
|
|
1388
1685
|
className: "overflow-hidden dark:hidden",
|
|
@@ -1408,7 +1705,7 @@ var CodeBlock = ({
|
|
|
1408
1705
|
children: code
|
|
1409
1706
|
}
|
|
1410
1707
|
),
|
|
1411
|
-
/* @__PURE__ */
|
|
1708
|
+
/* @__PURE__ */ jsx19(
|
|
1412
1709
|
SyntaxHighlighter,
|
|
1413
1710
|
{
|
|
1414
1711
|
className: "hidden overflow-hidden dark:block",
|
|
@@ -1434,36 +1731,42 @@ var CodeBlock = ({
|
|
|
1434
1731
|
children: code
|
|
1435
1732
|
}
|
|
1436
1733
|
),
|
|
1437
|
-
children && /* @__PURE__ */
|
|
1734
|
+
children && /* @__PURE__ */ jsx19("div", { className: "absolute top-2 right-2 flex items-center gap-2", children })
|
|
1438
1735
|
] })
|
|
1439
1736
|
}
|
|
1440
1737
|
) });
|
|
1441
1738
|
|
|
1442
1739
|
// src/components/tool.tsx
|
|
1443
|
-
import { jsx as
|
|
1444
|
-
var Tool = ({ className, ...props }) => /* @__PURE__ */
|
|
1740
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1741
|
+
var Tool = ({ className, ...props }) => /* @__PURE__ */ jsx20(
|
|
1445
1742
|
Collapsible,
|
|
1446
1743
|
{
|
|
1447
1744
|
className: cn("not-prose w-full rounded-md border border-[var(--chat-divider)]", className),
|
|
1448
1745
|
...props
|
|
1449
1746
|
}
|
|
1450
1747
|
);
|
|
1748
|
+
var STATUS_LABELS = {
|
|
1749
|
+
"input-streaming": "Pending",
|
|
1750
|
+
"input-available": "Running",
|
|
1751
|
+
"output-available": "Completed",
|
|
1752
|
+
"output-error": "Error",
|
|
1753
|
+
"approval-requested": "Awaiting approval",
|
|
1754
|
+
"approval-responded": "Approved",
|
|
1755
|
+
"output-denied": "Denied"
|
|
1756
|
+
};
|
|
1757
|
+
var STATUS_ICONS = {
|
|
1758
|
+
"input-streaming": /* @__PURE__ */ jsx20(CircleIcon2, { className: "size-4" }),
|
|
1759
|
+
"input-available": /* @__PURE__ */ jsx20(ClockIcon, { className: "size-4 animate-pulse" }),
|
|
1760
|
+
"output-available": /* @__PURE__ */ jsx20(CheckCircleIcon, { className: "size-4 text-green-600" }),
|
|
1761
|
+
"output-error": /* @__PURE__ */ jsx20(XCircleIcon, { className: "size-4 text-red-600" }),
|
|
1762
|
+
"approval-requested": /* @__PURE__ */ jsx20(ClockIcon, { className: "size-4 text-amber-600" }),
|
|
1763
|
+
"approval-responded": /* @__PURE__ */ jsx20(CheckCircleIcon, { className: "size-4 text-amber-600" }),
|
|
1764
|
+
"output-denied": /* @__PURE__ */ jsx20(XCircleIcon, { className: "size-4 text-muted-foreground" })
|
|
1765
|
+
};
|
|
1451
1766
|
var getStatusBadge = (status) => {
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
"output-available": "Completed",
|
|
1456
|
-
"output-error": "Error"
|
|
1457
|
-
};
|
|
1458
|
-
const icons = {
|
|
1459
|
-
"input-streaming": /* @__PURE__ */ jsx18(CircleIcon2, { className: "size-4" }),
|
|
1460
|
-
"input-available": /* @__PURE__ */ jsx18(ClockIcon, { className: "size-4 animate-pulse" }),
|
|
1461
|
-
"output-available": /* @__PURE__ */ jsx18(CheckCircleIcon, { className: "size-4 text-green-600" }),
|
|
1462
|
-
"output-error": /* @__PURE__ */ jsx18(XCircleIcon, { className: "size-4 text-red-600" })
|
|
1463
|
-
};
|
|
1464
|
-
return /* @__PURE__ */ jsxs11(Badge, { className: "gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
1465
|
-
icons[status],
|
|
1466
|
-
labels[status]
|
|
1767
|
+
return /* @__PURE__ */ jsxs14(Badge, { className: "gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
1768
|
+
STATUS_ICONS[status],
|
|
1769
|
+
STATUS_LABELS[status]
|
|
1467
1770
|
] });
|
|
1468
1771
|
};
|
|
1469
1772
|
var ToolHeader = ({
|
|
@@ -1473,7 +1776,7 @@ var ToolHeader = ({
|
|
|
1473
1776
|
toolName,
|
|
1474
1777
|
state,
|
|
1475
1778
|
...props
|
|
1476
|
-
}) => /* @__PURE__ */
|
|
1779
|
+
}) => /* @__PURE__ */ jsxs14(
|
|
1477
1780
|
CollapsibleTrigger2,
|
|
1478
1781
|
{
|
|
1479
1782
|
className: cn(
|
|
@@ -1482,16 +1785,16 @@ var ToolHeader = ({
|
|
|
1482
1785
|
),
|
|
1483
1786
|
...props,
|
|
1484
1787
|
children: [
|
|
1485
|
-
/* @__PURE__ */
|
|
1486
|
-
/* @__PURE__ */
|
|
1487
|
-
/* @__PURE__ */
|
|
1788
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
1789
|
+
/* @__PURE__ */ jsx20(WrenchIcon, { className: "size-4 text-muted-foreground" }),
|
|
1790
|
+
/* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: title ?? toolName ?? type.split("-").slice(1).join("-") }),
|
|
1488
1791
|
getStatusBadge(state)
|
|
1489
1792
|
] }),
|
|
1490
|
-
/* @__PURE__ */
|
|
1793
|
+
/* @__PURE__ */ jsx20(ChevronDownIcon4, { className: "size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" })
|
|
1491
1794
|
]
|
|
1492
1795
|
}
|
|
1493
1796
|
);
|
|
1494
|
-
var ToolContent = ({ className, ...props }) => /* @__PURE__ */
|
|
1797
|
+
var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx20(
|
|
1495
1798
|
CollapsibleContent2,
|
|
1496
1799
|
{
|
|
1497
1800
|
className: cn(
|
|
@@ -1501,9 +1804,9 @@ var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx18(
|
|
|
1501
1804
|
...props
|
|
1502
1805
|
}
|
|
1503
1806
|
);
|
|
1504
|
-
var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */
|
|
1505
|
-
/* @__PURE__ */
|
|
1506
|
-
/* @__PURE__ */
|
|
1807
|
+
var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */ jsxs14("div", { className: cn("space-y-2 overflow-hidden p-2", className), ...props, children: [
|
|
1808
|
+
/* @__PURE__ */ jsx20("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Parameters" }),
|
|
1809
|
+
/* @__PURE__ */ jsx20("div", { className: "rounded-md bg-muted/50", children: /* @__PURE__ */ jsx20(CodeBlock, { code: JSON.stringify(input, null, 2), language: "json" }) })
|
|
1507
1810
|
] });
|
|
1508
1811
|
var ToolOutput = ({
|
|
1509
1812
|
className,
|
|
@@ -1514,15 +1817,15 @@ var ToolOutput = ({
|
|
|
1514
1817
|
if (!(output || errorText)) {
|
|
1515
1818
|
return null;
|
|
1516
1819
|
}
|
|
1517
|
-
let Output = /* @__PURE__ */
|
|
1820
|
+
let Output = /* @__PURE__ */ jsx20("div", { children: output });
|
|
1518
1821
|
if (typeof output === "object" && !isValidElement(output)) {
|
|
1519
|
-
Output = /* @__PURE__ */
|
|
1822
|
+
Output = /* @__PURE__ */ jsx20(CodeBlock, { code: JSON.stringify(output, null, 2), language: "json" });
|
|
1520
1823
|
} else if (typeof output === "string") {
|
|
1521
|
-
Output = /* @__PURE__ */
|
|
1824
|
+
Output = /* @__PURE__ */ jsx20(CodeBlock, { code: output, language: "json" });
|
|
1522
1825
|
}
|
|
1523
|
-
return /* @__PURE__ */
|
|
1524
|
-
/* @__PURE__ */
|
|
1525
|
-
/* @__PURE__ */
|
|
1826
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("space-y-2 p-2", className), ...props, children: [
|
|
1827
|
+
/* @__PURE__ */ jsx20("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: errorText ? "Error" : "Result" }),
|
|
1828
|
+
/* @__PURE__ */ jsxs14(
|
|
1526
1829
|
"div",
|
|
1527
1830
|
{
|
|
1528
1831
|
className: cn(
|
|
@@ -1530,7 +1833,7 @@ var ToolOutput = ({
|
|
|
1530
1833
|
errorText ? "bg-destructive/10 text-destructive" : "bg-muted/50 text-foreground"
|
|
1531
1834
|
),
|
|
1532
1835
|
children: [
|
|
1533
|
-
errorText && /* @__PURE__ */
|
|
1836
|
+
errorText && /* @__PURE__ */ jsx20("div", { children: errorText }),
|
|
1534
1837
|
Output
|
|
1535
1838
|
]
|
|
1536
1839
|
}
|
|
@@ -1539,7 +1842,7 @@ var ToolOutput = ({
|
|
|
1539
1842
|
};
|
|
1540
1843
|
|
|
1541
1844
|
// src/components/suggestion2.tsx
|
|
1542
|
-
import { jsx as
|
|
1845
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1543
1846
|
function StarterMessages({
|
|
1544
1847
|
className,
|
|
1545
1848
|
prompts,
|
|
@@ -1547,7 +1850,7 @@ function StarterMessages({
|
|
|
1547
1850
|
...props
|
|
1548
1851
|
}) {
|
|
1549
1852
|
if (prompts.length === 0) return null;
|
|
1550
|
-
return /* @__PURE__ */
|
|
1853
|
+
return /* @__PURE__ */ jsx21(
|
|
1551
1854
|
"div",
|
|
1552
1855
|
{
|
|
1553
1856
|
className: cn(
|
|
@@ -1555,8 +1858,8 @@ function StarterMessages({
|
|
|
1555
1858
|
className
|
|
1556
1859
|
),
|
|
1557
1860
|
...props,
|
|
1558
|
-
children: prompts.map((prompt, index) => /* @__PURE__ */
|
|
1559
|
-
/* @__PURE__ */
|
|
1861
|
+
children: prompts.map((prompt, index) => /* @__PURE__ */ jsxs15("div", { children: [
|
|
1862
|
+
/* @__PURE__ */ jsx21(
|
|
1560
1863
|
StarterMessageItem,
|
|
1561
1864
|
{
|
|
1562
1865
|
prompt,
|
|
@@ -1566,7 +1869,7 @@ function StarterMessages({
|
|
|
1566
1869
|
index < prompts.length - 1 && // 1px-tall element used as a divider — same --chat-divider token
|
|
1567
1870
|
// every other separator in the widget uses, so consumers only
|
|
1568
1871
|
// need to override one variable to recolour all of them.
|
|
1569
|
-
/* @__PURE__ */
|
|
1872
|
+
/* @__PURE__ */ jsx21("div", { className: "h-px mx-3", style: { backgroundColor: "var(--chat-divider)" } })
|
|
1570
1873
|
] }, index))
|
|
1571
1874
|
}
|
|
1572
1875
|
);
|
|
@@ -1577,7 +1880,7 @@ function StarterMessageItem({
|
|
|
1577
1880
|
onClick,
|
|
1578
1881
|
...props
|
|
1579
1882
|
}) {
|
|
1580
|
-
return /* @__PURE__ */
|
|
1883
|
+
return /* @__PURE__ */ jsxs15(
|
|
1581
1884
|
"button",
|
|
1582
1885
|
{
|
|
1583
1886
|
type: "button",
|
|
@@ -1592,8 +1895,8 @@ function StarterMessageItem({
|
|
|
1592
1895
|
),
|
|
1593
1896
|
...props,
|
|
1594
1897
|
children: [
|
|
1595
|
-
/* @__PURE__ */
|
|
1596
|
-
prompt.subtitle && /* @__PURE__ */
|
|
1898
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[13px] text-[hsl(var(--chat-text)/0.7)]", children: prompt.title }),
|
|
1899
|
+
prompt.subtitle && /* @__PURE__ */ jsx21("span", { className: "block text-[11px] text-[hsl(var(--chat-text)/0.4)] mt-0.5", children: prompt.subtitle })
|
|
1597
1900
|
]
|
|
1598
1901
|
}
|
|
1599
1902
|
);
|
|
@@ -1601,7 +1904,7 @@ function StarterMessageItem({
|
|
|
1601
1904
|
|
|
1602
1905
|
// src/contexts/chat-storage-context.tsx
|
|
1603
1906
|
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1604
|
-
import { jsx as
|
|
1907
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1605
1908
|
var ChatStorageContext = createContext4({
|
|
1606
1909
|
storageKeyPrefix: ""
|
|
1607
1910
|
});
|
|
@@ -1610,19 +1913,19 @@ function ChatStorageProvider({
|
|
|
1610
1913
|
userId
|
|
1611
1914
|
}) {
|
|
1612
1915
|
const storageKeyPrefix = userId || "";
|
|
1613
|
-
return /* @__PURE__ */
|
|
1916
|
+
return /* @__PURE__ */ jsx22(ChatStorageContext.Provider, { value: { storageKeyPrefix }, children });
|
|
1614
1917
|
}
|
|
1615
1918
|
function useChatStorageKey() {
|
|
1616
1919
|
return useContext4(ChatStorageContext);
|
|
1617
1920
|
}
|
|
1618
1921
|
|
|
1619
1922
|
// src/components/interface.tsx
|
|
1620
|
-
import { jsx as
|
|
1923
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1621
1924
|
function ChatInterface({ id, initialMessages, config, onClose, headerActions } = {}) {
|
|
1622
1925
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
1623
1926
|
const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` : `chat-${key}`;
|
|
1624
1927
|
const themeMode = config?.theme?.mode || "light";
|
|
1625
|
-
const [input, setInput] =
|
|
1928
|
+
const [input, setInput] = useState6("");
|
|
1626
1929
|
const inputRef = useRef4(null);
|
|
1627
1930
|
const inputPlugins = useInputPlugins({
|
|
1628
1931
|
textareaRef: inputRef,
|
|
@@ -1630,26 +1933,26 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1630
1933
|
setValue: setInput,
|
|
1631
1934
|
plugins: config?.inputPlugins
|
|
1632
1935
|
});
|
|
1633
|
-
const [showHistory, setShowHistory] =
|
|
1634
|
-
const [conversations, setConversations] =
|
|
1635
|
-
const [loadingHistory, setLoadingHistory] =
|
|
1636
|
-
const [historyLoaded, setHistoryLoaded] =
|
|
1637
|
-
const [searchQuery, setSearchQuery] =
|
|
1638
|
-
const [uploadError, setUploadError] =
|
|
1936
|
+
const [showHistory, setShowHistory] = useState6(false);
|
|
1937
|
+
const [conversations, setConversations] = useState6([]);
|
|
1938
|
+
const [loadingHistory, setLoadingHistory] = useState6(false);
|
|
1939
|
+
const [historyLoaded, setHistoryLoaded] = useState6(false);
|
|
1940
|
+
const [searchQuery, setSearchQuery] = useState6("");
|
|
1941
|
+
const [uploadError, setUploadError] = useState6(null);
|
|
1639
1942
|
useEffect5(() => {
|
|
1640
1943
|
if (uploadError) {
|
|
1641
1944
|
const timeoutId = setTimeout(() => setUploadError(null), 5e3);
|
|
1642
1945
|
return () => clearTimeout(timeoutId);
|
|
1643
1946
|
}
|
|
1644
1947
|
}, [uploadError]);
|
|
1645
|
-
const [tabs, setTabs] =
|
|
1646
|
-
const [activeTabId, setActiveTabId] =
|
|
1647
|
-
const [initialTabCreated, setInitialTabCreated] =
|
|
1648
|
-
const [isInitializing, setIsInitializing] =
|
|
1649
|
-
const [isLoadingMessages, setIsLoadingMessages] =
|
|
1948
|
+
const [tabs, setTabs] = useState6([]);
|
|
1949
|
+
const [activeTabId, setActiveTabId] = useState6("");
|
|
1950
|
+
const [initialTabCreated, setInitialTabCreated] = useState6(false);
|
|
1951
|
+
const [isInitializing, setIsInitializing] = useState6(true);
|
|
1952
|
+
const [isLoadingMessages, setIsLoadingMessages] = useState6(false);
|
|
1650
1953
|
const lastSyncedTabId = useRef4("");
|
|
1651
1954
|
const hasInitialized = useRef4(false);
|
|
1652
|
-
const { messages, sendMessage, status, setMessages } = useChat({
|
|
1955
|
+
const { messages, sendMessage, status, setMessages, stop, regenerate, error, clearError } = useChat({
|
|
1653
1956
|
id: activeTabId || "temp-id",
|
|
1654
1957
|
transport: new DefaultChatTransport({
|
|
1655
1958
|
api: "/api/chat",
|
|
@@ -1696,8 +1999,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1696
1999
|
mediaType: uploadResult.mediaType,
|
|
1697
2000
|
size: uploadResult.size
|
|
1698
2001
|
};
|
|
1699
|
-
} catch (
|
|
1700
|
-
console.error(`Error uploading ${file.filename}:`,
|
|
2002
|
+
} catch (error2) {
|
|
2003
|
+
console.error(`Error uploading ${file.filename}:`, error2);
|
|
1701
2004
|
return null;
|
|
1702
2005
|
}
|
|
1703
2006
|
});
|
|
@@ -1714,10 +2017,10 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1714
2017
|
setUploadError(warnMsg);
|
|
1715
2018
|
console.warn(warnMsg);
|
|
1716
2019
|
}
|
|
1717
|
-
} catch (
|
|
2020
|
+
} catch (error2) {
|
|
1718
2021
|
const errorMsg = "Error uploading files. Please try again.";
|
|
1719
2022
|
setUploadError(errorMsg);
|
|
1720
|
-
console.error("Error in file upload process:",
|
|
2023
|
+
console.error("Error in file upload process:", error2);
|
|
1721
2024
|
return;
|
|
1722
2025
|
}
|
|
1723
2026
|
}
|
|
@@ -1738,12 +2041,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1738
2041
|
};
|
|
1739
2042
|
const AttachButton = () => {
|
|
1740
2043
|
const attachments = usePromptInputAttachments();
|
|
1741
|
-
return /* @__PURE__ */
|
|
2044
|
+
return /* @__PURE__ */ jsx23(
|
|
1742
2045
|
PromptInputButton,
|
|
1743
2046
|
{
|
|
1744
2047
|
variant: "ghost",
|
|
1745
2048
|
onClick: () => attachments.openFileDialog(),
|
|
1746
|
-
children: /* @__PURE__ */
|
|
2049
|
+
children: /* @__PURE__ */ jsx23(PlusIcon2, { className: "size-4" })
|
|
1747
2050
|
}
|
|
1748
2051
|
);
|
|
1749
2052
|
};
|
|
@@ -1766,8 +2069,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1766
2069
|
} else {
|
|
1767
2070
|
console.error("Error loading messages:", response.status, response.statusText);
|
|
1768
2071
|
}
|
|
1769
|
-
} catch (
|
|
1770
|
-
console.error("Error loading conversation:",
|
|
2072
|
+
} catch (error2) {
|
|
2073
|
+
console.error("Error loading conversation:", error2);
|
|
1771
2074
|
}
|
|
1772
2075
|
};
|
|
1773
2076
|
const generateUniqueTabId = () => {
|
|
@@ -1871,8 +2174,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1871
2174
|
const errorText = await response.text();
|
|
1872
2175
|
console.error("[ChatInterface] Error response:", errorText);
|
|
1873
2176
|
}
|
|
1874
|
-
} catch (
|
|
1875
|
-
console.error("[ChatInterface] Error fetching chat history:",
|
|
2177
|
+
} catch (error2) {
|
|
2178
|
+
console.error("[ChatInterface] Error fetching chat history:", error2);
|
|
1876
2179
|
} finally {
|
|
1877
2180
|
setLoadingHistory(false);
|
|
1878
2181
|
}
|
|
@@ -2005,22 +2308,27 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2005
2308
|
const renderMessages = () => messages.map((message, index) => {
|
|
2006
2309
|
const sourceParts = message.parts?.filter((part) => part.type === "source-url") || [];
|
|
2007
2310
|
const fileParts = message.parts?.filter((part) => part.type === "file") || [];
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2311
|
+
const isLastMessage = index === messages.length - 1;
|
|
2312
|
+
const isStreamingThisMessage = isLastMessage && message.role === "assistant" && status !== "ready";
|
|
2313
|
+
const showActions = message.role === "assistant" && !isStreamingThisMessage;
|
|
2314
|
+
const showRegenerate = showActions && isLastMessage && status === "ready";
|
|
2315
|
+
const messageText = showActions ? (message.parts ?? []).filter((p) => p.type === "text").map((p) => p.text).join("\n\n") : "";
|
|
2316
|
+
return /* @__PURE__ */ jsxs16("div", { className: index > 0 ? "mt-6" : "", children: [
|
|
2317
|
+
message.role === "assistant" && sourceParts.length > 0 && /* @__PURE__ */ jsxs16(Sources, { children: [
|
|
2318
|
+
/* @__PURE__ */ jsx23(SourcesTrigger, { count: sourceParts.length }),
|
|
2319
|
+
/* @__PURE__ */ jsx23(SourcesContent, { children: sourceParts.map((part, i) => /* @__PURE__ */ jsx23(
|
|
2012
2320
|
Source,
|
|
2013
2321
|
{
|
|
2014
2322
|
href: part.url,
|
|
2015
2323
|
title: part.url
|
|
2016
2324
|
},
|
|
2017
|
-
`${message.id}-${i}`
|
|
2018
|
-
) }
|
|
2325
|
+
`${message.id}-source-${i}`
|
|
2326
|
+
)) })
|
|
2019
2327
|
] }),
|
|
2020
|
-
fileParts.length > 0 && /* @__PURE__ */
|
|
2328
|
+
fileParts.length > 0 && /* @__PURE__ */ jsx23("div", { className: cn(
|
|
2021
2329
|
"flex mb-1",
|
|
2022
2330
|
message.role === "user" ? "justify-end" : "justify-start"
|
|
2023
|
-
), children: /* @__PURE__ */
|
|
2331
|
+
), children: /* @__PURE__ */ jsx23(
|
|
2024
2332
|
MessageAttachments,
|
|
2025
2333
|
{
|
|
2026
2334
|
attachments: fileParts.map((part) => ({
|
|
@@ -2031,14 +2339,14 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2031
2339
|
}))
|
|
2032
2340
|
}
|
|
2033
2341
|
) }),
|
|
2034
|
-
message.parts ? /* @__PURE__ */
|
|
2342
|
+
message.parts ? /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: message.parts.map((part, i) => {
|
|
2035
2343
|
switch (part.type) {
|
|
2036
2344
|
case "text":
|
|
2037
2345
|
const isTextStreaming = status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id;
|
|
2038
|
-
return /* @__PURE__ */
|
|
2346
|
+
return /* @__PURE__ */ jsx23(Fragment5, { children: /* @__PURE__ */ jsx23(Message, { from: message.role, children: /* @__PURE__ */ jsx23(MessageContent, { children: /* @__PURE__ */ jsx23(Response, { isStreaming: isTextStreaming, children: part.text }) }) }) }, `${message.id}-${i}`);
|
|
2039
2347
|
case "reasoning":
|
|
2040
2348
|
const isCurrentlyStreaming = status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id;
|
|
2041
|
-
return /* @__PURE__ */
|
|
2349
|
+
return /* @__PURE__ */ jsxs16(
|
|
2042
2350
|
Reasoning,
|
|
2043
2351
|
{
|
|
2044
2352
|
className: "w-full",
|
|
@@ -2046,8 +2354,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2046
2354
|
defaultOpen: false,
|
|
2047
2355
|
open: isCurrentlyStreaming ? true : void 0,
|
|
2048
2356
|
children: [
|
|
2049
|
-
/* @__PURE__ */
|
|
2050
|
-
/* @__PURE__ */
|
|
2357
|
+
/* @__PURE__ */ jsx23(ReasoningTrigger, {}),
|
|
2358
|
+
/* @__PURE__ */ jsx23(ReasoningContent, { children: part.text })
|
|
2051
2359
|
]
|
|
2052
2360
|
},
|
|
2053
2361
|
`${message.id}-${i}`
|
|
@@ -2055,8 +2363,24 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2055
2363
|
default:
|
|
2056
2364
|
if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
|
|
2057
2365
|
const toolPart = part;
|
|
2058
|
-
|
|
2059
|
-
|
|
2366
|
+
const resolvedToolName = toolPart.toolName ?? (part.type.startsWith("tool-") ? part.type.slice(5) : "");
|
|
2367
|
+
const customRenderer = config?.toolRenderers?.[resolvedToolName];
|
|
2368
|
+
if (customRenderer) {
|
|
2369
|
+
const rendered = customRenderer({
|
|
2370
|
+
type: part.type,
|
|
2371
|
+
toolName: resolvedToolName,
|
|
2372
|
+
toolCallId: toolPart.toolCallId,
|
|
2373
|
+
state: toolPart.state,
|
|
2374
|
+
input: toolPart.input,
|
|
2375
|
+
output: toolPart.output,
|
|
2376
|
+
errorText: toolPart.errorText
|
|
2377
|
+
});
|
|
2378
|
+
if (rendered !== null && rendered !== void 0) {
|
|
2379
|
+
return /* @__PURE__ */ jsx23(Fragment5, { children: rendered }, `${message.id}-${i}`);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
return /* @__PURE__ */ jsxs16(Tool, { children: [
|
|
2383
|
+
/* @__PURE__ */ jsx23(
|
|
2060
2384
|
ToolHeader,
|
|
2061
2385
|
{
|
|
2062
2386
|
type: part.type,
|
|
@@ -2064,9 +2388,9 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2064
2388
|
state: toolPart.state
|
|
2065
2389
|
}
|
|
2066
2390
|
),
|
|
2067
|
-
/* @__PURE__ */
|
|
2068
|
-
/* @__PURE__ */
|
|
2069
|
-
/* @__PURE__ */
|
|
2391
|
+
/* @__PURE__ */ jsxs16(ToolContent, { children: [
|
|
2392
|
+
/* @__PURE__ */ jsx23(ToolInput, { input: toolPart.input }),
|
|
2393
|
+
/* @__PURE__ */ jsx23(ToolOutput, { output: toolPart.output, errorText: toolPart.errorText })
|
|
2070
2394
|
] })
|
|
2071
2395
|
] }, `${message.id}-${i}`);
|
|
2072
2396
|
}
|
|
@@ -2074,7 +2398,14 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2074
2398
|
}
|
|
2075
2399
|
}) }) : (
|
|
2076
2400
|
/* Handle standard AI SDK messages with content or text property */
|
|
2077
|
-
/* @__PURE__ */
|
|
2401
|
+
/* @__PURE__ */ jsx23(Fragment5, { children: /* @__PURE__ */ jsx23(Message, { from: message.role, children: /* @__PURE__ */ jsx23(MessageContent, { children: /* @__PURE__ */ jsx23(Response, { children: message.content || message.text }) }) }) }, `${message.id}-content`)
|
|
2402
|
+
),
|
|
2403
|
+
showActions && /* @__PURE__ */ jsx23(
|
|
2404
|
+
MessageActions,
|
|
2405
|
+
{
|
|
2406
|
+
text: messageText,
|
|
2407
|
+
onRegenerate: showRegenerate && regenerate ? () => regenerate() : void 0
|
|
2408
|
+
}
|
|
2078
2409
|
)
|
|
2079
2410
|
] }, message.id);
|
|
2080
2411
|
});
|
|
@@ -2102,8 +2433,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2102
2433
|
setActiveTabId(selectedConversationId);
|
|
2103
2434
|
await loadConversation(selectedConversationId);
|
|
2104
2435
|
setShowHistory(false);
|
|
2105
|
-
} catch (
|
|
2106
|
-
console.error("Error loading conversation:",
|
|
2436
|
+
} catch (error2) {
|
|
2437
|
+
console.error("Error loading conversation:", error2);
|
|
2107
2438
|
}
|
|
2108
2439
|
};
|
|
2109
2440
|
const dropdownRef = useRef4(null);
|
|
@@ -2120,7 +2451,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2120
2451
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
2121
2452
|
};
|
|
2122
2453
|
}, [showHistory]);
|
|
2123
|
-
return /* @__PURE__ */
|
|
2454
|
+
return /* @__PURE__ */ jsx23("div", { className: cn("w-full h-full flex flex-col bg-white dark:bg-gray-900 overflow-hidden ring-1 ring-black/[0.02] dark:ring-white/[0.03]", themeMode === "dark" && "dark"), children: /* @__PURE__ */ jsxs16(
|
|
2124
2455
|
"div",
|
|
2125
2456
|
{
|
|
2126
2457
|
className: cn(
|
|
@@ -2128,11 +2459,11 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2128
2459
|
themeMode === "dark" && "dark"
|
|
2129
2460
|
),
|
|
2130
2461
|
children: [
|
|
2131
|
-
/* @__PURE__ */
|
|
2462
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 px-3 py-2 border-b backdrop-blur-sm relative z-20", style: {
|
|
2132
2463
|
borderColor: "var(--chat-divider)",
|
|
2133
2464
|
backgroundColor: "var(--chat-header-bg)"
|
|
2134
2465
|
}, children: [
|
|
2135
|
-
/* @__PURE__ */
|
|
2466
|
+
/* @__PURE__ */ jsx23("div", { className: "flex items-center gap-1 flex-1 min-w-0 overflow-x-auto scrollbar-hide py-0.5 scroll-smooth", children: tabs.map((tab, index) => /* @__PURE__ */ jsxs16(
|
|
2136
2467
|
"div",
|
|
2137
2468
|
{
|
|
2138
2469
|
className: "relative flex items-center gap-1.5 px-3 py-1.5 rounded-lg cursor-pointer transition-all duration-150 group flex-shrink-0 min-w-0",
|
|
@@ -2155,8 +2486,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2155
2486
|
switchToTab(tab.id);
|
|
2156
2487
|
},
|
|
2157
2488
|
children: [
|
|
2158
|
-
/* @__PURE__ */
|
|
2159
|
-
tabs.length > 1 && /* @__PURE__ */
|
|
2489
|
+
/* @__PURE__ */ jsx23("span", { className: "truncate max-w-28 text-[13px] font-medium transition-colors", children: tab.title }),
|
|
2490
|
+
tabs.length > 1 && /* @__PURE__ */ jsx23(
|
|
2160
2491
|
"button",
|
|
2161
2492
|
{
|
|
2162
2493
|
onClick: (e) => {
|
|
@@ -2175,15 +2506,15 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2175
2506
|
e.currentTarget.style.opacity = tab.isActive ? "0.6" : "0";
|
|
2176
2507
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
2177
2508
|
},
|
|
2178
|
-
children: /* @__PURE__ */
|
|
2509
|
+
children: /* @__PURE__ */ jsx23(XIcon3, { className: "h-3 w-3", strokeWidth: 2.5 })
|
|
2179
2510
|
}
|
|
2180
2511
|
)
|
|
2181
2512
|
]
|
|
2182
2513
|
},
|
|
2183
2514
|
tab.id
|
|
2184
2515
|
)) }),
|
|
2185
|
-
/* @__PURE__ */
|
|
2186
|
-
/* @__PURE__ */
|
|
2516
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-0.5 flex-shrink-0", children: [
|
|
2517
|
+
/* @__PURE__ */ jsx23(
|
|
2187
2518
|
"button",
|
|
2188
2519
|
{
|
|
2189
2520
|
onClick: createNewTab,
|
|
@@ -2200,11 +2531,11 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2200
2531
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
2201
2532
|
},
|
|
2202
2533
|
title: "New Chat",
|
|
2203
|
-
children: /* @__PURE__ */
|
|
2534
|
+
children: /* @__PURE__ */ jsx23(PlusIcon2, { className: "h-4 w-4", strokeWidth: 2 })
|
|
2204
2535
|
}
|
|
2205
2536
|
),
|
|
2206
|
-
/* @__PURE__ */
|
|
2207
|
-
/* @__PURE__ */
|
|
2537
|
+
/* @__PURE__ */ jsxs16("div", { className: "relative", ref: dropdownRef, children: [
|
|
2538
|
+
/* @__PURE__ */ jsx23(
|
|
2208
2539
|
"button",
|
|
2209
2540
|
{
|
|
2210
2541
|
onClick: () => setShowHistory(!showHistory),
|
|
@@ -2226,17 +2557,17 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2226
2557
|
}
|
|
2227
2558
|
},
|
|
2228
2559
|
title: "Chat History",
|
|
2229
|
-
children: /* @__PURE__ */
|
|
2560
|
+
children: /* @__PURE__ */ jsx23(HistoryIcon, { className: "h-4 w-4", strokeWidth: 2 })
|
|
2230
2561
|
}
|
|
2231
2562
|
),
|
|
2232
|
-
showHistory && /* @__PURE__ */
|
|
2563
|
+
showHistory && /* @__PURE__ */ jsxs16("div", { className: "absolute right-0 top-full mt-1.5 w-72 rounded-xl shadow-[0_4px_24px_rgba(0,0,0,0.08)] dark:shadow-[0_4px_24px_rgba(0,0,0,0.3)] z-50 animate-in fade-in slide-in-from-top-1 duration-150 overflow-hidden", style: {
|
|
2233
2564
|
backgroundColor: "hsl(var(--chat-background))",
|
|
2234
2565
|
border: `1px solid ${"var(--chat-divider)"}`
|
|
2235
2566
|
}, children: [
|
|
2236
|
-
/* @__PURE__ */
|
|
2567
|
+
/* @__PURE__ */ jsx23("div", { className: "p-2.5 border-b", style: {
|
|
2237
2568
|
borderColor: "var(--chat-divider)",
|
|
2238
2569
|
backgroundColor: "var(--chat-overlay)"
|
|
2239
|
-
}, children: /* @__PURE__ */
|
|
2570
|
+
}, children: /* @__PURE__ */ jsx23("div", { className: "relative", children: /* @__PURE__ */ jsx23(
|
|
2240
2571
|
"input",
|
|
2241
2572
|
{
|
|
2242
2573
|
type: "text",
|
|
@@ -2251,25 +2582,25 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2251
2582
|
}
|
|
2252
2583
|
}
|
|
2253
2584
|
) }) }),
|
|
2254
|
-
/* @__PURE__ */
|
|
2255
|
-
/* @__PURE__ */
|
|
2585
|
+
/* @__PURE__ */ jsx23("div", { className: "max-h-[300px] overflow-y-auto ai-assistant-scrollbar", children: loadingHistory ? /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx23("div", { className: "text-[13px]", style: { color: "hsl(var(--chat-text-muted))" }, children: "Loading..." }) }) : conversations.length === 0 ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
|
|
2586
|
+
/* @__PURE__ */ jsx23("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
|
|
2256
2587
|
backgroundColor: "hsl(var(--chat-surface))"
|
|
2257
|
-
}, children: /* @__PURE__ */
|
|
2258
|
-
/* @__PURE__ */
|
|
2259
|
-
/* @__PURE__ */
|
|
2260
|
-
] }) : groupedConversations.length === 0 ? /* @__PURE__ */
|
|
2261
|
-
/* @__PURE__ */
|
|
2588
|
+
}, children: /* @__PURE__ */ jsx23(MessageSquareIcon, { className: "h-5 w-5", style: { color: "hsl(var(--chat-text-subtle))" }, strokeWidth: 2 }) }),
|
|
2589
|
+
/* @__PURE__ */ jsx23("p", { className: "text-[13px] font-medium mb-0.5", style: { color: "hsl(var(--chat-text))" }, children: "No Conversations" }),
|
|
2590
|
+
/* @__PURE__ */ jsx23("p", { className: "text-[12px]", style: { color: "hsl(var(--chat-text-muted))" }, children: "Start a new chat to begin" })
|
|
2591
|
+
] }) : groupedConversations.length === 0 ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
|
|
2592
|
+
/* @__PURE__ */ jsx23("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
|
|
2262
2593
|
backgroundColor: "hsl(var(--chat-surface))"
|
|
2263
|
-
}, children: /* @__PURE__ */
|
|
2264
|
-
/* @__PURE__ */
|
|
2265
|
-
/* @__PURE__ */
|
|
2266
|
-
] }) : /* @__PURE__ */
|
|
2267
|
-
/* @__PURE__ */
|
|
2594
|
+
}, children: /* @__PURE__ */ jsx23(SearchIcon, { className: "h-5 w-5", style: { color: "hsl(var(--chat-text-subtle))" }, strokeWidth: 2 }) }),
|
|
2595
|
+
/* @__PURE__ */ jsx23("p", { className: "text-[13px] font-medium mb-0.5", style: { color: "hsl(var(--chat-text))" }, children: "No Results" }),
|
|
2596
|
+
/* @__PURE__ */ jsx23("p", { className: "text-[12px]", style: { color: "hsl(var(--chat-text-muted))" }, children: "Try a different search" })
|
|
2597
|
+
] }) : /* @__PURE__ */ jsx23("div", { className: "py-0.5", children: groupedConversations.map(([groupName, groupConversations]) => /* @__PURE__ */ jsxs16("div", { className: "mb-0.5", children: [
|
|
2598
|
+
/* @__PURE__ */ jsx23("div", { className: "px-2.5 py-1 sticky top-0 backdrop-blur-sm z-10", style: {
|
|
2268
2599
|
backgroundColor: "var(--chat-header-bg-strong)"
|
|
2269
|
-
}, children: /* @__PURE__ */
|
|
2270
|
-
/* @__PURE__ */
|
|
2600
|
+
}, children: /* @__PURE__ */ jsx23("h3", { className: "text-[10px] font-semibold uppercase tracking-wide", style: { color: "hsl(var(--chat-text-muted))" }, children: groupName }) }),
|
|
2601
|
+
/* @__PURE__ */ jsx23("div", { className: "px-1 space-y-0.5", children: groupConversations.map((conversation) => {
|
|
2271
2602
|
const isActiveConversation = activeTabId === conversation.id;
|
|
2272
|
-
return /* @__PURE__ */
|
|
2603
|
+
return /* @__PURE__ */ jsx23(
|
|
2273
2604
|
"button",
|
|
2274
2605
|
{
|
|
2275
2606
|
className: "w-full px-2 py-1 rounded-md transition-all duration-150 text-left group relative",
|
|
@@ -2287,12 +2618,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2287
2618
|
}
|
|
2288
2619
|
},
|
|
2289
2620
|
onClick: () => handleSelectConversation(conversation.id, conversation.title),
|
|
2290
|
-
children: /* @__PURE__ */
|
|
2291
|
-
/* @__PURE__ */
|
|
2621
|
+
children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1.5", children: [
|
|
2622
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx23("p", { className: "text-[12px] line-clamp-1 transition-colors leading-tight", style: {
|
|
2292
2623
|
fontWeight: isActiveConversation ? 500 : 400,
|
|
2293
2624
|
color: isActiveConversation ? "hsl(var(--chat-text))" : "hsl(var(--chat-text-strong))"
|
|
2294
2625
|
}, children: conversation.title }) }),
|
|
2295
|
-
/* @__PURE__ */
|
|
2626
|
+
/* @__PURE__ */ jsx23(
|
|
2296
2627
|
ChevronRightIcon2,
|
|
2297
2628
|
{
|
|
2298
2629
|
className: "h-3 w-3 transition-all duration-150 flex-shrink-0",
|
|
@@ -2312,7 +2643,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2312
2643
|
] })
|
|
2313
2644
|
] }),
|
|
2314
2645
|
headerActions,
|
|
2315
|
-
onClose && /* @__PURE__ */
|
|
2646
|
+
onClose && /* @__PURE__ */ jsx23(
|
|
2316
2647
|
"button",
|
|
2317
2648
|
{
|
|
2318
2649
|
onClick: onClose,
|
|
@@ -2329,21 +2660,21 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2329
2660
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
2330
2661
|
},
|
|
2331
2662
|
title: "Close Chat",
|
|
2332
|
-
children: /* @__PURE__ */
|
|
2663
|
+
children: /* @__PURE__ */ jsx23(XIcon3, { className: "h-4 w-4", strokeWidth: 2 })
|
|
2333
2664
|
}
|
|
2334
2665
|
)
|
|
2335
2666
|
] })
|
|
2336
2667
|
] }),
|
|
2337
|
-
/* @__PURE__ */
|
|
2338
|
-
/* @__PURE__ */
|
|
2668
|
+
/* @__PURE__ */ jsxs16(Conversation, { className: "flex-1 max-w-full ai-assistant-scrollbar", children: [
|
|
2669
|
+
/* @__PURE__ */ jsxs16(ConversationContent, { className: "max-w-[96%] mx-auto py-6", children: [
|
|
2339
2670
|
renderMessages(),
|
|
2340
|
-
status === "submitted" && /* @__PURE__ */
|
|
2671
|
+
status === "submitted" && /* @__PURE__ */ jsx23("div", { className: "mt-6", children: /* @__PURE__ */ jsx23(Message, { from: "assistant", children: /* @__PURE__ */ jsx23(MessageContent, { children: /* @__PURE__ */ jsx23(Loader, { size: 16 }) }) }) })
|
|
2341
2672
|
] }),
|
|
2342
|
-
/* @__PURE__ */
|
|
2673
|
+
/* @__PURE__ */ jsx23(ConversationScrollButton, {})
|
|
2343
2674
|
] }),
|
|
2344
|
-
/* @__PURE__ */
|
|
2345
|
-
uploadError && /* @__PURE__ */
|
|
2346
|
-
isInitializing || isLoadingMessages ? /* @__PURE__ */
|
|
2675
|
+
/* @__PURE__ */ jsxs16("div", { className: "px-5 pb-5", children: [
|
|
2676
|
+
uploadError && /* @__PURE__ */ jsx23("div", { className: "mb-3 px-4 py-3 bg-red-50 dark:bg-red-900/20 border border-red-200/60 dark:border-red-800/60 rounded-2xl text-sm text-red-700 dark:text-red-400 shadow-sm", children: uploadError }),
|
|
2677
|
+
isInitializing || isLoadingMessages ? /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-center py-8", role: "status", "aria-label": "Loading conversation", children: /* @__PURE__ */ jsx23("div", { className: "h-4 w-4 rounded-full border-2 border-current border-t-transparent animate-spin", style: { color: "hsl(var(--chat-text-muted))" } }) }) : messages.length === 0 && status !== "submitted" && config?.starterPrompts && /* @__PURE__ */ jsx23(
|
|
2347
2678
|
StarterMessages,
|
|
2348
2679
|
{
|
|
2349
2680
|
prompts: config.starterPrompts,
|
|
@@ -2352,27 +2683,67 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2352
2683
|
}
|
|
2353
2684
|
}
|
|
2354
2685
|
),
|
|
2355
|
-
/* @__PURE__ */
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2686
|
+
/* @__PURE__ */ jsx23(
|
|
2687
|
+
ChatErrorBanner,
|
|
2688
|
+
{
|
|
2689
|
+
error: error ?? null,
|
|
2690
|
+
canRetry: messages.some((m) => m.role === "user"),
|
|
2691
|
+
onRetry: () => {
|
|
2692
|
+
clearError?.();
|
|
2693
|
+
regenerate?.();
|
|
2694
|
+
},
|
|
2695
|
+
onDismiss: clearError
|
|
2696
|
+
}
|
|
2697
|
+
),
|
|
2698
|
+
inputPlugins.panel,
|
|
2699
|
+
/* @__PURE__ */ jsxs16(
|
|
2700
|
+
PromptInput,
|
|
2701
|
+
{
|
|
2702
|
+
onSubmit: handleSubmit,
|
|
2703
|
+
globalDrop: true,
|
|
2704
|
+
multiple: true,
|
|
2705
|
+
accept: config?.features?.fileUploadAccept ?? "image/*",
|
|
2706
|
+
maxFileSize: config?.features?.fileUploadMaxBytes,
|
|
2707
|
+
onError: (err) => {
|
|
2708
|
+
if (err.code === "max_file_size") {
|
|
2709
|
+
setUploadError(
|
|
2710
|
+
config?.features?.fileUploadMaxBytes ? `File too large (max ${Math.floor(
|
|
2711
|
+
config.features.fileUploadMaxBytes / 1024 / 1024
|
|
2712
|
+
)} MB).` : "File too large."
|
|
2713
|
+
);
|
|
2714
|
+
} else if (err.code === "accept") {
|
|
2715
|
+
setUploadError("That file type is not supported.");
|
|
2716
|
+
} else if (err.code === "max_files") {
|
|
2717
|
+
setUploadError("Too many files attached.");
|
|
2718
|
+
}
|
|
2719
|
+
},
|
|
2720
|
+
children: [
|
|
2721
|
+
/* @__PURE__ */ jsxs16(PromptInputBody, { children: [
|
|
2722
|
+
/* @__PURE__ */ jsx23(PromptInputAttachments, { children: (attachment) => /* @__PURE__ */ jsx23(PromptInputAttachment, { data: attachment }) }),
|
|
2723
|
+
/* @__PURE__ */ jsx23(
|
|
2724
|
+
PromptInputTextarea,
|
|
2725
|
+
{
|
|
2726
|
+
ref: inputRef,
|
|
2727
|
+
onChange: (e) => setInput(e.target.value),
|
|
2728
|
+
onKeyDown: inputPlugins.onKeyDown,
|
|
2729
|
+
value: input
|
|
2730
|
+
}
|
|
2731
|
+
)
|
|
2732
|
+
] }),
|
|
2733
|
+
/* @__PURE__ */ jsxs16(PromptInputToolbar, { children: [
|
|
2734
|
+
/* @__PURE__ */ jsx23(PromptInputTools, { children: config?.features?.fileUpload === true && /* @__PURE__ */ jsx23(AttachButton, {}) }),
|
|
2735
|
+
/* @__PURE__ */ jsx23(
|
|
2736
|
+
PromptInputSubmit,
|
|
2737
|
+
{
|
|
2738
|
+
disabled: status === "streaming" || status === "submitted" ? false : !input,
|
|
2739
|
+
status,
|
|
2740
|
+
onStop: stop
|
|
2741
|
+
}
|
|
2742
|
+
)
|
|
2743
|
+
] })
|
|
2744
|
+
]
|
|
2745
|
+
}
|
|
2746
|
+
)
|
|
2376
2747
|
] })
|
|
2377
2748
|
]
|
|
2378
2749
|
}
|
|
@@ -2418,7 +2789,7 @@ function toHslTripletIfHex(value) {
|
|
|
2418
2789
|
}
|
|
2419
2790
|
|
|
2420
2791
|
// src/ChatWidget.tsx
|
|
2421
|
-
import { jsx as
|
|
2792
|
+
import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2422
2793
|
function ChatWidget({
|
|
2423
2794
|
userId,
|
|
2424
2795
|
conversationId,
|
|
@@ -2435,14 +2806,15 @@ function ChatWidget({
|
|
|
2435
2806
|
headerActions,
|
|
2436
2807
|
open,
|
|
2437
2808
|
onOpenChange,
|
|
2438
|
-
inputPlugins
|
|
2809
|
+
inputPlugins,
|
|
2810
|
+
toolRenderers
|
|
2439
2811
|
}) {
|
|
2440
2812
|
const layout = display?.layout || "popup";
|
|
2441
2813
|
const isControlled = open !== void 0;
|
|
2442
2814
|
const showToggleButton = !isControlled && display?.showToggleButton !== false;
|
|
2443
2815
|
const resizable = layout === "popup" && display?.resizable !== false;
|
|
2444
2816
|
const size = display?.size || "default";
|
|
2445
|
-
const [internalIsOpen, setInternalIsOpen] =
|
|
2817
|
+
const [internalIsOpen, setInternalIsOpen] = useState7(
|
|
2446
2818
|
layout !== "popup" ? true : display?.defaultOpen || false
|
|
2447
2819
|
);
|
|
2448
2820
|
const isOpen = isControlled ? open : internalIsOpen;
|
|
@@ -2453,7 +2825,7 @@ function ChatWidget({
|
|
|
2453
2825
|
setInternalIsOpen(next);
|
|
2454
2826
|
}
|
|
2455
2827
|
};
|
|
2456
|
-
const [isResizing, setIsResizing] =
|
|
2828
|
+
const [isResizing, setIsResizing] = useState7(false);
|
|
2457
2829
|
const containerRef = useRef5(null);
|
|
2458
2830
|
const customStyles = useMemo4(() => {
|
|
2459
2831
|
const styles = {};
|
|
@@ -2511,18 +2883,19 @@ function ChatWidget({
|
|
|
2511
2883
|
theme,
|
|
2512
2884
|
features,
|
|
2513
2885
|
starterPrompts,
|
|
2514
|
-
inputPlugins
|
|
2515
|
-
|
|
2886
|
+
inputPlugins,
|
|
2887
|
+
toolRenderers
|
|
2888
|
+
}), [userId, model, systemPrompt, temperature, theme, features, starterPrompts, inputPlugins, toolRenderers]);
|
|
2516
2889
|
const togglePosition = display?.toggleButtonPosition || { bottom: "24px", right: "24px" };
|
|
2517
2890
|
const themeClass = theme?.mode === "dark" ? "dark" : "";
|
|
2518
2891
|
if (layout === "inline") {
|
|
2519
|
-
return /* @__PURE__ */
|
|
2892
|
+
return /* @__PURE__ */ jsx24(ChatStorageProvider, { userId, children: /* @__PURE__ */ jsx24(
|
|
2520
2893
|
"div",
|
|
2521
2894
|
{
|
|
2522
2895
|
ref: containerRef,
|
|
2523
2896
|
className: `chat-widget-container chat-widget-inline chat-widget-content ${themeClass} ${className || ""}`,
|
|
2524
2897
|
style: customStyles,
|
|
2525
|
-
children: /* @__PURE__ */
|
|
2898
|
+
children: /* @__PURE__ */ jsx24(
|
|
2526
2899
|
ChatInterface,
|
|
2527
2900
|
{
|
|
2528
2901
|
id: conversationId,
|
|
@@ -2536,13 +2909,13 @@ function ChatWidget({
|
|
|
2536
2909
|
) });
|
|
2537
2910
|
}
|
|
2538
2911
|
if (layout === "page") {
|
|
2539
|
-
return /* @__PURE__ */
|
|
2912
|
+
return /* @__PURE__ */ jsx24(ChatStorageProvider, { userId, children: /* @__PURE__ */ jsx24(
|
|
2540
2913
|
"div",
|
|
2541
2914
|
{
|
|
2542
2915
|
ref: containerRef,
|
|
2543
2916
|
className: `chat-widget-container chat-widget-page chat-widget-content ${themeClass} ${className || ""}`,
|
|
2544
2917
|
style: customStyles,
|
|
2545
|
-
children: /* @__PURE__ */
|
|
2918
|
+
children: /* @__PURE__ */ jsx24(
|
|
2546
2919
|
ChatInterface,
|
|
2547
2920
|
{
|
|
2548
2921
|
id: conversationId,
|
|
@@ -2555,18 +2928,18 @@ function ChatWidget({
|
|
|
2555
2928
|
}
|
|
2556
2929
|
) });
|
|
2557
2930
|
}
|
|
2558
|
-
return /* @__PURE__ */
|
|
2559
|
-
showToggleButton && !isOpen && /* @__PURE__ */
|
|
2931
|
+
return /* @__PURE__ */ jsxs17(ChatStorageProvider, { userId, children: [
|
|
2932
|
+
showToggleButton && !isOpen && /* @__PURE__ */ jsx24(
|
|
2560
2933
|
"button",
|
|
2561
2934
|
{
|
|
2562
2935
|
onClick: () => setIsOpen(true),
|
|
2563
2936
|
className: "fixed z-50 rounded-full bg-primary text-primary-foreground shadow-lg hover:opacity-90 transition-all p-4",
|
|
2564
2937
|
style: togglePosition,
|
|
2565
2938
|
"aria-label": "Open chat",
|
|
2566
|
-
children: /* @__PURE__ */
|
|
2939
|
+
children: /* @__PURE__ */ jsx24(MessageCircle, { className: "h-6 w-6" })
|
|
2567
2940
|
}
|
|
2568
2941
|
),
|
|
2569
|
-
isOpen && /* @__PURE__ */
|
|
2942
|
+
isOpen && /* @__PURE__ */ jsxs17(
|
|
2570
2943
|
"div",
|
|
2571
2944
|
{
|
|
2572
2945
|
ref: containerRef,
|
|
@@ -2575,7 +2948,7 @@ function ChatWidget({
|
|
|
2575
2948
|
"data-resizing": isResizing,
|
|
2576
2949
|
style: customStyles,
|
|
2577
2950
|
children: [
|
|
2578
|
-
resizable && /* @__PURE__ */
|
|
2951
|
+
resizable && /* @__PURE__ */ jsx24(
|
|
2579
2952
|
"div",
|
|
2580
2953
|
{
|
|
2581
2954
|
onMouseDown: handleMouseDown,
|
|
@@ -2583,7 +2956,7 @@ function ChatWidget({
|
|
|
2583
2956
|
"aria-label": "Resize chat widget"
|
|
2584
2957
|
}
|
|
2585
2958
|
),
|
|
2586
|
-
/* @__PURE__ */
|
|
2959
|
+
/* @__PURE__ */ jsx24("div", { className: "w-full h-full overflow-hidden", children: /* @__PURE__ */ jsx24(
|
|
2587
2960
|
ChatInterface,
|
|
2588
2961
|
{
|
|
2589
2962
|
id: conversationId,
|
|
@@ -2604,7 +2977,7 @@ function ChatWidget({
|
|
|
2604
2977
|
var ChatWidget_default = ChatWidget;
|
|
2605
2978
|
|
|
2606
2979
|
// src/hooks/use-chat-theme.ts
|
|
2607
|
-
import { useState as
|
|
2980
|
+
import { useState as useState8, useEffect as useEffect7 } from "react";
|
|
2608
2981
|
|
|
2609
2982
|
// src/utils/models.ts
|
|
2610
2983
|
var MODELS = [
|
|
@@ -2724,12 +3097,12 @@ var defaultThemeMode = "light";
|
|
|
2724
3097
|
function useChatTheme() {
|
|
2725
3098
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
2726
3099
|
const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` : "chat-";
|
|
2727
|
-
const [theme, setTheme] =
|
|
2728
|
-
const [conversationStarters, setConversationStarters] =
|
|
2729
|
-
const [model, setModel] =
|
|
2730
|
-
const [systemPrompt, setSystemPrompt] =
|
|
2731
|
-
const [temperature, setTemperature] =
|
|
2732
|
-
const [themeMode, setThemeMode] =
|
|
3100
|
+
const [theme, setTheme] = useState8(defaultTheme);
|
|
3101
|
+
const [conversationStarters, setConversationStarters] = useState8(defaultConversationStarters);
|
|
3102
|
+
const [model, setModel] = useState8(defaultModel);
|
|
3103
|
+
const [systemPrompt, setSystemPrompt] = useState8(defaultSystemPrompt);
|
|
3104
|
+
const [temperature, setTemperature] = useState8(defaultTemperature);
|
|
3105
|
+
const [themeMode, setThemeMode] = useState8(defaultThemeMode);
|
|
2733
3106
|
useEffect7(() => {
|
|
2734
3107
|
const savedTheme = localStorage.getItem(`${keyPrefix}theme`);
|
|
2735
3108
|
if (savedTheme) {
|
|
@@ -2920,10 +3293,10 @@ function useChatTheme() {
|
|
|
2920
3293
|
|
|
2921
3294
|
// src/ui/input.tsx
|
|
2922
3295
|
import * as React3 from "react";
|
|
2923
|
-
import { jsx as
|
|
3296
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2924
3297
|
var Input = React3.forwardRef(
|
|
2925
3298
|
({ className, type, ...props }, ref) => {
|
|
2926
|
-
return /* @__PURE__ */
|
|
3299
|
+
return /* @__PURE__ */ jsx25(
|
|
2927
3300
|
"input",
|
|
2928
3301
|
{
|
|
2929
3302
|
type,
|
|
@@ -2941,23 +3314,23 @@ Input.displayName = "Input";
|
|
|
2941
3314
|
|
|
2942
3315
|
// src/ui/dialog.tsx
|
|
2943
3316
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
2944
|
-
import { XIcon as
|
|
2945
|
-
import { jsx as
|
|
3317
|
+
import { XIcon as XIcon4 } from "lucide-react";
|
|
3318
|
+
import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2946
3319
|
function Dialog({
|
|
2947
3320
|
...props
|
|
2948
3321
|
}) {
|
|
2949
|
-
return /* @__PURE__ */
|
|
3322
|
+
return /* @__PURE__ */ jsx26(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
2950
3323
|
}
|
|
2951
3324
|
function DialogPortal({
|
|
2952
3325
|
...props
|
|
2953
3326
|
}) {
|
|
2954
|
-
return /* @__PURE__ */
|
|
3327
|
+
return /* @__PURE__ */ jsx26(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
2955
3328
|
}
|
|
2956
3329
|
function DialogOverlay({
|
|
2957
3330
|
className,
|
|
2958
3331
|
...props
|
|
2959
3332
|
}) {
|
|
2960
|
-
return /* @__PURE__ */
|
|
3333
|
+
return /* @__PURE__ */ jsx26(
|
|
2961
3334
|
DialogPrimitive.Overlay,
|
|
2962
3335
|
{
|
|
2963
3336
|
"data-slot": "dialog-overlay",
|
|
@@ -2975,9 +3348,9 @@ function DialogContent({
|
|
|
2975
3348
|
showCloseButton = true,
|
|
2976
3349
|
...props
|
|
2977
3350
|
}) {
|
|
2978
|
-
return /* @__PURE__ */
|
|
2979
|
-
/* @__PURE__ */
|
|
2980
|
-
/* @__PURE__ */
|
|
3351
|
+
return /* @__PURE__ */ jsxs18(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
3352
|
+
/* @__PURE__ */ jsx26(DialogOverlay, {}),
|
|
3353
|
+
/* @__PURE__ */ jsxs18(
|
|
2981
3354
|
DialogPrimitive.Content,
|
|
2982
3355
|
{
|
|
2983
3356
|
"data-slot": "dialog-content",
|
|
@@ -2988,14 +3361,14 @@ function DialogContent({
|
|
|
2988
3361
|
...props,
|
|
2989
3362
|
children: [
|
|
2990
3363
|
children,
|
|
2991
|
-
showCloseButton && /* @__PURE__ */
|
|
3364
|
+
showCloseButton && /* @__PURE__ */ jsxs18(
|
|
2992
3365
|
DialogPrimitive.Close,
|
|
2993
3366
|
{
|
|
2994
3367
|
"data-slot": "dialog-close",
|
|
2995
3368
|
className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
2996
3369
|
children: [
|
|
2997
|
-
/* @__PURE__ */
|
|
2998
|
-
/* @__PURE__ */
|
|
3370
|
+
/* @__PURE__ */ jsx26(XIcon4, {}),
|
|
3371
|
+
/* @__PURE__ */ jsx26("span", { className: "sr-only", children: "Close" })
|
|
2999
3372
|
]
|
|
3000
3373
|
}
|
|
3001
3374
|
)
|
|
@@ -3005,7 +3378,7 @@ function DialogContent({
|
|
|
3005
3378
|
] });
|
|
3006
3379
|
}
|
|
3007
3380
|
function DialogHeader({ className, ...props }) {
|
|
3008
|
-
return /* @__PURE__ */
|
|
3381
|
+
return /* @__PURE__ */ jsx26(
|
|
3009
3382
|
"div",
|
|
3010
3383
|
{
|
|
3011
3384
|
"data-slot": "dialog-header",
|
|
@@ -3018,7 +3391,7 @@ function DialogTitle({
|
|
|
3018
3391
|
className,
|
|
3019
3392
|
...props
|
|
3020
3393
|
}) {
|
|
3021
|
-
return /* @__PURE__ */
|
|
3394
|
+
return /* @__PURE__ */ jsx26(
|
|
3022
3395
|
DialogPrimitive.Title,
|
|
3023
3396
|
{
|
|
3024
3397
|
"data-slot": "dialog-title",
|
|
@@ -3031,7 +3404,7 @@ function DialogDescription({
|
|
|
3031
3404
|
className,
|
|
3032
3405
|
...props
|
|
3033
3406
|
}) {
|
|
3034
|
-
return /* @__PURE__ */
|
|
3407
|
+
return /* @__PURE__ */ jsx26(
|
|
3035
3408
|
DialogPrimitive.Description,
|
|
3036
3409
|
{
|
|
3037
3410
|
"data-slot": "dialog-description",
|
|
@@ -3052,6 +3425,11 @@ export {
|
|
|
3052
3425
|
Input,
|
|
3053
3426
|
StarterMessageItem,
|
|
3054
3427
|
StarterMessages,
|
|
3428
|
+
Tool,
|
|
3429
|
+
ToolContent,
|
|
3430
|
+
ToolHeader,
|
|
3431
|
+
ToolInput,
|
|
3432
|
+
ToolOutput,
|
|
3055
3433
|
ChatWidget_default as default,
|
|
3056
3434
|
fontOptions,
|
|
3057
3435
|
useChatStorageKey,
|