@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.js
CHANGED
|
@@ -43,6 +43,11 @@ __export(src_exports, {
|
|
|
43
43
|
Input: () => Input,
|
|
44
44
|
StarterMessageItem: () => StarterMessageItem,
|
|
45
45
|
StarterMessages: () => StarterMessages,
|
|
46
|
+
Tool: () => Tool,
|
|
47
|
+
ToolContent: () => ToolContent,
|
|
48
|
+
ToolHeader: () => ToolHeader,
|
|
49
|
+
ToolInput: () => ToolInput,
|
|
50
|
+
ToolOutput: () => ToolOutput,
|
|
46
51
|
default: () => ChatWidget_default,
|
|
47
52
|
fontOptions: () => fontOptions,
|
|
48
53
|
useChatStorageKey: () => useChatStorageKey,
|
|
@@ -51,7 +56,7 @@ __export(src_exports, {
|
|
|
51
56
|
module.exports = __toCommonJS(src_exports);
|
|
52
57
|
|
|
53
58
|
// src/ChatWidget.tsx
|
|
54
|
-
var
|
|
59
|
+
var import_react14 = require("react");
|
|
55
60
|
|
|
56
61
|
// src/ui/button.tsx
|
|
57
62
|
var import_react_slot = require("@radix-ui/react-slot");
|
|
@@ -259,13 +264,22 @@ function PromptInputAttachment({
|
|
|
259
264
|
...props
|
|
260
265
|
}) {
|
|
261
266
|
const attachments = usePromptInputAttachments();
|
|
267
|
+
const isImage = data.mediaType?.startsWith("image/") && !!data.url;
|
|
262
268
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
263
269
|
"div",
|
|
264
270
|
{
|
|
265
|
-
className: cn(
|
|
271
|
+
className: cn(
|
|
272
|
+
"group relative rounded-lg border",
|
|
273
|
+
// Images keep the square thumbnail. Other files use a wider
|
|
274
|
+
// pill-shaped chip showing icon + filename — without it,
|
|
275
|
+
// non-image attachments rendered as identical paperclip
|
|
276
|
+
// squares with no way to tell them apart.
|
|
277
|
+
isImage ? "h-14 w-14" : "h-14 max-w-[200px]",
|
|
278
|
+
className
|
|
279
|
+
),
|
|
266
280
|
...props,
|
|
267
281
|
children: [
|
|
268
|
-
|
|
282
|
+
isImage ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
269
283
|
"img",
|
|
270
284
|
{
|
|
271
285
|
alt: data.filename || "attachment",
|
|
@@ -274,7 +288,7 @@ function PromptInputAttachment({
|
|
|
274
288
|
src: data.url,
|
|
275
289
|
width: 56
|
|
276
290
|
}
|
|
277
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
291
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NonImageChip, { data }),
|
|
278
292
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
279
293
|
Button,
|
|
280
294
|
{
|
|
@@ -292,6 +306,34 @@ function PromptInputAttachment({
|
|
|
292
306
|
data.id
|
|
293
307
|
);
|
|
294
308
|
}
|
|
309
|
+
function NonImageChip({ data }) {
|
|
310
|
+
const { Icon: Icon2, label } = describeFile(data);
|
|
311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex size-full items-center gap-2 px-2.5", children: [
|
|
312
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon2, { className: "size-5 flex-shrink-0 text-muted-foreground" }),
|
|
313
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "min-w-0 flex flex-col leading-tight", children: [
|
|
314
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[12px] font-medium truncate", children: data.filename || "attachment" }),
|
|
315
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[10px] text-muted-foreground uppercase tracking-wide", children: label })
|
|
316
|
+
] })
|
|
317
|
+
] });
|
|
318
|
+
}
|
|
319
|
+
function describeFile(data) {
|
|
320
|
+
const mt = (data.mediaType || "").toLowerCase();
|
|
321
|
+
const ext = (data.filename || "").toLowerCase().split(".").pop() || "";
|
|
322
|
+
if (mt === "application/pdf" || ext === "pdf") return { Icon: import_lucide_react4.FileTextIcon, label: "PDF" };
|
|
323
|
+
if (mt.includes("spreadsheet") || mt.includes("excel") || ext === "xlsx" || ext === "xls" || ext === "csv" || ext === "tsv") {
|
|
324
|
+
return { Icon: import_lucide_react4.FileSpreadsheetIcon, label: ext.toUpperCase() || "Spreadsheet" };
|
|
325
|
+
}
|
|
326
|
+
if (mt.includes("presentation") || mt.includes("powerpoint") || ext === "pptx" || ext === "ppt") {
|
|
327
|
+
return { Icon: import_lucide_react4.PresentationIcon, label: ext.toUpperCase() || "Slides" };
|
|
328
|
+
}
|
|
329
|
+
if (mt.includes("wordprocessing") || mt.includes("msword") || ext === "docx" || ext === "doc") {
|
|
330
|
+
return { Icon: import_lucide_react4.FileTextIcon, label: ext.toUpperCase() || "Doc" };
|
|
331
|
+
}
|
|
332
|
+
if (mt.startsWith("text/") || ext === "txt" || ext === "md" || ext === "json") {
|
|
333
|
+
return { Icon: import_lucide_react4.FileTextIcon, label: ext.toUpperCase() || "Text" };
|
|
334
|
+
}
|
|
335
|
+
return { Icon: import_lucide_react4.FileIcon, label: ext.toUpperCase() || "File" };
|
|
336
|
+
}
|
|
295
337
|
function PromptInputAttachments({
|
|
296
338
|
className,
|
|
297
339
|
children,
|
|
@@ -356,10 +398,18 @@ var PromptInput = ({
|
|
|
356
398
|
if (!accept || accept.trim() === "") {
|
|
357
399
|
return true;
|
|
358
400
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
return
|
|
401
|
+
const tokens = accept.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean);
|
|
402
|
+
const fileType = (f.type || "").toLowerCase();
|
|
403
|
+
const fileName = f.name.toLowerCase();
|
|
404
|
+
return tokens.some((token) => {
|
|
405
|
+
if (token === "*/*") return true;
|
|
406
|
+
if (token.startsWith(".")) return fileName.endsWith(token);
|
|
407
|
+
if (token.endsWith("/*")) {
|
|
408
|
+
const prefix = token.slice(0, -1);
|
|
409
|
+
return fileType.startsWith(prefix);
|
|
410
|
+
}
|
|
411
|
+
return fileType === token;
|
|
412
|
+
});
|
|
363
413
|
},
|
|
364
414
|
[accept]
|
|
365
415
|
);
|
|
@@ -661,6 +711,8 @@ var PromptInputSubmit = ({
|
|
|
661
711
|
variant = "default",
|
|
662
712
|
size = "icon",
|
|
663
713
|
status,
|
|
714
|
+
onStop,
|
|
715
|
+
onClick,
|
|
664
716
|
children,
|
|
665
717
|
...props
|
|
666
718
|
}) => {
|
|
@@ -672,13 +724,22 @@ var PromptInputSubmit = ({
|
|
|
672
724
|
} else if (status === "error") {
|
|
673
725
|
Icon2 = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react4.XIcon, { className: "size-4" });
|
|
674
726
|
}
|
|
727
|
+
const isStopping = status === "streaming" && !!onStop;
|
|
675
728
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
676
729
|
Button,
|
|
677
730
|
{
|
|
678
731
|
className: cn("gap-1.5 rounded-lg", className),
|
|
679
732
|
size,
|
|
680
|
-
type: "submit",
|
|
733
|
+
type: isStopping ? "button" : "submit",
|
|
681
734
|
variant,
|
|
735
|
+
onClick: (e) => {
|
|
736
|
+
if (isStopping) {
|
|
737
|
+
e.preventDefault();
|
|
738
|
+
onStop();
|
|
739
|
+
}
|
|
740
|
+
onClick?.(e);
|
|
741
|
+
},
|
|
742
|
+
"aria-label": isStopping ? "Stop generating" : void 0,
|
|
682
743
|
...props,
|
|
683
744
|
children: children ?? Icon2
|
|
684
745
|
}
|
|
@@ -688,55 +749,75 @@ var PromptInputSubmit = ({
|
|
|
688
749
|
// src/components/message-attachments.tsx
|
|
689
750
|
var import_lucide_react5 = require("lucide-react");
|
|
690
751
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
752
|
+
function openAttachment(attachment) {
|
|
753
|
+
if (attachment.url.startsWith("data:")) {
|
|
754
|
+
const w = window.open("", "_blank");
|
|
755
|
+
if (w) {
|
|
756
|
+
w.document.write(
|
|
757
|
+
`<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>`
|
|
758
|
+
);
|
|
759
|
+
w.document.close();
|
|
760
|
+
}
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
window.open(attachment.url, "_blank");
|
|
764
|
+
}
|
|
765
|
+
function describeFile2(att) {
|
|
766
|
+
const mt = (att.mediaType || "").toLowerCase();
|
|
767
|
+
const ext = (att.filename || "").toLowerCase().split(".").pop() || "";
|
|
768
|
+
if (mt === "application/pdf" || ext === "pdf") return { Icon: import_lucide_react5.FileTextIcon, label: "PDF" };
|
|
769
|
+
if (mt.includes("spreadsheet") || mt.includes("excel") || ext === "xlsx" || ext === "xls" || ext === "csv" || ext === "tsv") {
|
|
770
|
+
return { Icon: import_lucide_react5.FileSpreadsheetIcon, label: ext.toUpperCase() || "Spreadsheet" };
|
|
771
|
+
}
|
|
772
|
+
if (mt.includes("presentation") || mt.includes("powerpoint") || ext === "pptx" || ext === "ppt") {
|
|
773
|
+
return { Icon: import_lucide_react5.PresentationIcon, label: ext.toUpperCase() || "Slides" };
|
|
774
|
+
}
|
|
775
|
+
if (mt.includes("wordprocessing") || mt.includes("msword") || ext === "docx" || ext === "doc") {
|
|
776
|
+
return { Icon: import_lucide_react5.FileTextIcon, label: ext.toUpperCase() || "Doc" };
|
|
777
|
+
}
|
|
778
|
+
if (mt.startsWith("text/") || ext === "txt" || ext === "md" || ext === "json") {
|
|
779
|
+
return { Icon: import_lucide_react5.FileTextIcon, label: ext.toUpperCase() || "Text" };
|
|
780
|
+
}
|
|
781
|
+
return { Icon: import_lucide_react5.FileIcon, label: ext.toUpperCase() || "File" };
|
|
782
|
+
}
|
|
691
783
|
function MessageAttachments({ attachments, className }) {
|
|
692
784
|
if (!attachments || attachments.length === 0) {
|
|
693
785
|
return null;
|
|
694
786
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
newWindow.document.write(`
|
|
700
|
-
<html>
|
|
701
|
-
<head><title>${attachment.filename}</title></head>
|
|
702
|
-
<body style="margin:0; padding:20px; background:#f5f5f5; display:flex; justify-content:center; align-items:center; min-height:100vh;">
|
|
703
|
-
<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);" />
|
|
704
|
-
</body>
|
|
705
|
-
</html>
|
|
706
|
-
`);
|
|
707
|
-
newWindow.document.close();
|
|
708
|
-
}
|
|
709
|
-
} else if (attachment.url.startsWith("blob:")) {
|
|
710
|
-
window.open(attachment.url, "_blank");
|
|
711
|
-
} else if (attachment.url.startsWith("http")) {
|
|
712
|
-
window.open(attachment.url, "_blank");
|
|
713
|
-
} else {
|
|
714
|
-
window.open(attachment.url, "_blank");
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn("flex flex-wrap gap-2", className), children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
718
|
-
"div",
|
|
719
|
-
{
|
|
720
|
-
className: "group relative h-14 w-14 rounded-lg",
|
|
721
|
-
children: attachment.mediaType.startsWith("image/") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn("flex flex-wrap gap-2", className), children: attachments.map((attachment, index) => {
|
|
788
|
+
const isImage = attachment.mediaType.startsWith("image/");
|
|
789
|
+
if (isImage) {
|
|
790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "group relative h-14 w-14 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
722
791
|
"img",
|
|
723
792
|
{
|
|
724
793
|
src: attachment.url,
|
|
725
794
|
alt: attachment.filename,
|
|
726
795
|
className: "size-full rounded-lg object-cover cursor-pointer hover:opacity-80 transition-opacity",
|
|
727
|
-
onClick: () =>
|
|
728
|
-
}
|
|
729
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
730
|
-
"div",
|
|
731
|
-
{
|
|
732
|
-
className: "flex size-full items-center justify-center text-muted-foreground cursor-pointer hover:bg-secondary/50 rounded-lg transition-colors",
|
|
733
|
-
onClick: () => handleAttachmentClick(attachment),
|
|
734
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react5.PaperclipIcon, { className: "size-4" })
|
|
796
|
+
onClick: () => openAttachment(attachment)
|
|
735
797
|
}
|
|
736
|
-
)
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
|
|
798
|
+
) }, index);
|
|
799
|
+
}
|
|
800
|
+
const { Icon: Icon2, label } = describeFile2(attachment);
|
|
801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
802
|
+
"button",
|
|
803
|
+
{
|
|
804
|
+
type: "button",
|
|
805
|
+
onClick: () => openAttachment(attachment),
|
|
806
|
+
className: cn(
|
|
807
|
+
"group flex items-center gap-2 px-2.5 h-14 rounded-lg border max-w-[220px]",
|
|
808
|
+
"hover:bg-[hsl(var(--chat-text)/0.04)] transition-colors text-left cursor-pointer"
|
|
809
|
+
),
|
|
810
|
+
children: [
|
|
811
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon2, { className: "size-5 flex-shrink-0 text-muted-foreground" }),
|
|
812
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "min-w-0 flex flex-col leading-tight", children: [
|
|
813
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-[12px] font-medium truncate", children: attachment.filename }),
|
|
814
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-[10px] text-muted-foreground uppercase tracking-wide", children: label })
|
|
815
|
+
] })
|
|
816
|
+
]
|
|
817
|
+
},
|
|
818
|
+
index
|
|
819
|
+
);
|
|
820
|
+
}) });
|
|
740
821
|
}
|
|
741
822
|
|
|
742
823
|
// src/components/input-plugin-popover.tsx
|
|
@@ -750,6 +831,7 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
750
831
|
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
751
832
|
const debounceRef = (0, import_react3.useRef)(null);
|
|
752
833
|
const requestIdRef = (0, import_react3.useRef)(0);
|
|
834
|
+
const sessionValidatedRef = (0, import_react3.useRef)(false);
|
|
753
835
|
const pluginsByTrigger = (0, import_react3.useMemo)(() => {
|
|
754
836
|
const map = /* @__PURE__ */ new Map();
|
|
755
837
|
for (const p of plugins ?? []) {
|
|
@@ -766,9 +848,14 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
766
848
|
return value.slice(active.triggerIndex + 1, cursor);
|
|
767
849
|
}, [active, value, textareaRef]);
|
|
768
850
|
(0, import_react3.useEffect)(() => {
|
|
769
|
-
if (!active)
|
|
770
|
-
|
|
771
|
-
|
|
851
|
+
if (!active) {
|
|
852
|
+
sessionValidatedRef.current = false;
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
if (value[active.triggerIndex] === active.plugin.trigger) {
|
|
856
|
+
sessionValidatedRef.current = true;
|
|
857
|
+
}
|
|
858
|
+
if (!sessionValidatedRef.current) return;
|
|
772
859
|
if (value[active.triggerIndex] !== active.plugin.trigger) {
|
|
773
860
|
setActive(null);
|
|
774
861
|
return;
|
|
@@ -776,7 +863,7 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
776
863
|
if (/\s/.test(query)) {
|
|
777
864
|
setActive(null);
|
|
778
865
|
}
|
|
779
|
-
}, [active, value, query
|
|
866
|
+
}, [active, value, query]);
|
|
780
867
|
(0, import_react3.useEffect)(() => {
|
|
781
868
|
if (!active) {
|
|
782
869
|
setItems([]);
|
|
@@ -784,13 +871,20 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
784
871
|
return;
|
|
785
872
|
}
|
|
786
873
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
787
|
-
setLoading(true);
|
|
788
874
|
const reqId = ++requestIdRef.current;
|
|
875
|
+
const result = active.plugin.fetch(query);
|
|
876
|
+
if (Array.isArray(result)) {
|
|
877
|
+
setItems(result);
|
|
878
|
+
setHighlight(0);
|
|
879
|
+
setLoading(false);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
setLoading(true);
|
|
789
883
|
debounceRef.current = setTimeout(async () => {
|
|
790
884
|
try {
|
|
791
|
-
const
|
|
885
|
+
const items2 = await result;
|
|
792
886
|
if (reqId !== requestIdRef.current) return;
|
|
793
|
-
setItems(
|
|
887
|
+
setItems(items2);
|
|
794
888
|
setHighlight(0);
|
|
795
889
|
} catch (err) {
|
|
796
890
|
console.error("[input-plugin] fetch failed:", err);
|
|
@@ -871,14 +965,8 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
871
965
|
},
|
|
872
966
|
[active, items, highlight, selectItem, close, pluginsByTrigger, value]
|
|
873
967
|
);
|
|
874
|
-
(0,
|
|
875
|
-
|
|
876
|
-
if (value[active.triggerIndex] !== active.plugin.trigger) {
|
|
877
|
-
close();
|
|
878
|
-
}
|
|
879
|
-
}, [value, active, close]);
|
|
880
|
-
const popover = active && (loading || items.length > 0 || active.plugin.emptyText) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
881
|
-
PluginPopover,
|
|
968
|
+
const panel = active ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
969
|
+
PluginPanel,
|
|
882
970
|
{
|
|
883
971
|
plugin: active.plugin,
|
|
884
972
|
items,
|
|
@@ -888,65 +976,271 @@ function useInputPlugins({ textareaRef, value, setValue, plugins }) {
|
|
|
888
976
|
onSelect: selectItem
|
|
889
977
|
}
|
|
890
978
|
) : null;
|
|
891
|
-
return { onKeyDown,
|
|
979
|
+
return { onKeyDown, panel, isOpen: !!active };
|
|
892
980
|
}
|
|
893
|
-
function
|
|
981
|
+
function PluginPanel({ plugin, items, loading, highlight, onHover, onSelect }) {
|
|
982
|
+
const viewportRef = (0, import_react3.useRef)(null);
|
|
983
|
+
const itemRefs = (0, import_react3.useRef)([]);
|
|
984
|
+
(0, import_react3.useEffect)(() => {
|
|
985
|
+
const btn = itemRefs.current[highlight];
|
|
986
|
+
const viewport = viewportRef.current;
|
|
987
|
+
if (!btn || !viewport) return;
|
|
988
|
+
const btnRect = btn.getBoundingClientRect();
|
|
989
|
+
const viewRect = viewport.getBoundingClientRect();
|
|
990
|
+
if (btnRect.top < viewRect.top) {
|
|
991
|
+
viewport.scrollTop -= viewRect.top - btnRect.top;
|
|
992
|
+
} else if (btnRect.bottom > viewRect.bottom) {
|
|
993
|
+
viewport.scrollTop += btnRect.bottom - viewRect.bottom;
|
|
994
|
+
}
|
|
995
|
+
}, [highlight]);
|
|
894
996
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
895
997
|
"div",
|
|
896
998
|
{
|
|
897
999
|
role: "listbox",
|
|
898
|
-
className:
|
|
899
|
-
"absolute bottom-full left-0 right-0 mb-2 z-30",
|
|
900
|
-
"rounded-md border border-border bg-popover text-popover-foreground shadow-md",
|
|
901
|
-
"max-h-64 overflow-y-auto"
|
|
902
|
-
),
|
|
1000
|
+
className: "rounded-t-xl bg-[hsl(var(--chat-background))] overflow-hidden mx-auto",
|
|
903
1001
|
onMouseDown: (e) => e.preventDefault(),
|
|
1002
|
+
style: {
|
|
1003
|
+
width: "96%",
|
|
1004
|
+
borderTop: "1px solid var(--chat-divider)",
|
|
1005
|
+
borderLeft: "1px solid var(--chat-divider)",
|
|
1006
|
+
borderRight: "1px solid var(--chat-divider)",
|
|
1007
|
+
// Pull down 1px so our bottom edge overlaps the form's top
|
|
1008
|
+
// border, removing the visible seam between the two surfaces.
|
|
1009
|
+
marginBottom: -1
|
|
1010
|
+
},
|
|
1011
|
+
children: [
|
|
1012
|
+
plugin.heading && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1013
|
+
"div",
|
|
1014
|
+
{
|
|
1015
|
+
className: "px-3 py-1.5 text-[11px] font-semibold uppercase tracking-wide",
|
|
1016
|
+
style: {
|
|
1017
|
+
color: "hsl(var(--chat-text)/0.5)",
|
|
1018
|
+
borderBottom: "1px solid var(--chat-divider)"
|
|
1019
|
+
},
|
|
1020
|
+
children: plugin.heading
|
|
1021
|
+
}
|
|
1022
|
+
),
|
|
1023
|
+
loading && items.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1024
|
+
"div",
|
|
1025
|
+
{
|
|
1026
|
+
className: "px-3 py-2 text-[13px]",
|
|
1027
|
+
style: { color: "hsl(var(--chat-text)/0.5)" },
|
|
1028
|
+
children: "Loading\u2026"
|
|
1029
|
+
}
|
|
1030
|
+
),
|
|
1031
|
+
!loading && items.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1032
|
+
"div",
|
|
1033
|
+
{
|
|
1034
|
+
className: "px-3 py-2 text-[13px]",
|
|
1035
|
+
style: { color: "hsl(var(--chat-text)/0.5)" },
|
|
1036
|
+
children: plugin.emptyText ?? "No results"
|
|
1037
|
+
}
|
|
1038
|
+
),
|
|
1039
|
+
items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1040
|
+
"div",
|
|
1041
|
+
{
|
|
1042
|
+
ref: viewportRef,
|
|
1043
|
+
className: "max-h-[200px] overflow-y-auto",
|
|
1044
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "py-1", children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
|
|
1045
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1046
|
+
"button",
|
|
1047
|
+
{
|
|
1048
|
+
ref: (el) => {
|
|
1049
|
+
itemRefs.current[idx] = el;
|
|
1050
|
+
},
|
|
1051
|
+
type: "button",
|
|
1052
|
+
role: "option",
|
|
1053
|
+
"aria-selected": idx === highlight,
|
|
1054
|
+
onMouseEnter: () => onHover(idx),
|
|
1055
|
+
onClick: () => onSelect(item),
|
|
1056
|
+
className: cn(
|
|
1057
|
+
"w-full text-left px-3 py-2",
|
|
1058
|
+
"flex items-center justify-between gap-3",
|
|
1059
|
+
"transition-colors duration-150 ease-out",
|
|
1060
|
+
"cursor-pointer"
|
|
1061
|
+
),
|
|
1062
|
+
style: {
|
|
1063
|
+
backgroundColor: idx === highlight ? "hsl(var(--chat-text)/0.06)" : "transparent"
|
|
1064
|
+
},
|
|
1065
|
+
children: [
|
|
1066
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1067
|
+
"span",
|
|
1068
|
+
{
|
|
1069
|
+
className: "text-[13px] truncate",
|
|
1070
|
+
style: { color: "hsl(var(--chat-text)/0.85)" },
|
|
1071
|
+
children: item.label
|
|
1072
|
+
}
|
|
1073
|
+
),
|
|
1074
|
+
item.sublabel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1075
|
+
"span",
|
|
1076
|
+
{
|
|
1077
|
+
className: "text-[11px] flex-shrink-0",
|
|
1078
|
+
style: { color: "hsl(var(--chat-text)/0.4)" },
|
|
1079
|
+
children: item.sublabel
|
|
1080
|
+
}
|
|
1081
|
+
)
|
|
1082
|
+
]
|
|
1083
|
+
}
|
|
1084
|
+
),
|
|
1085
|
+
idx < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1086
|
+
"div",
|
|
1087
|
+
{
|
|
1088
|
+
className: "h-px mx-3",
|
|
1089
|
+
style: { backgroundColor: "var(--chat-divider)" }
|
|
1090
|
+
}
|
|
1091
|
+
)
|
|
1092
|
+
] }, item.id)) })
|
|
1093
|
+
}
|
|
1094
|
+
)
|
|
1095
|
+
]
|
|
1096
|
+
}
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// src/components/chat-error-banner.tsx
|
|
1101
|
+
var import_lucide_react6 = require("lucide-react");
|
|
1102
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1103
|
+
function ChatErrorBanner({
|
|
1104
|
+
error,
|
|
1105
|
+
canRetry = true,
|
|
1106
|
+
onRetry,
|
|
1107
|
+
onDismiss
|
|
1108
|
+
}) {
|
|
1109
|
+
if (!error) return null;
|
|
1110
|
+
const friendly = friendlyErrorMessage(error);
|
|
1111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1112
|
+
"div",
|
|
1113
|
+
{
|
|
1114
|
+
role: "alert",
|
|
1115
|
+
className: "flex items-start gap-2 px-3 py-2 mb-2 rounded-lg text-[13px]",
|
|
1116
|
+
style: {
|
|
1117
|
+
backgroundColor: "hsl(var(--chat-text)/0.04)",
|
|
1118
|
+
border: "1px solid var(--chat-divider)"
|
|
1119
|
+
},
|
|
1120
|
+
title: error.message,
|
|
904
1121
|
children: [
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
1122
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1123
|
+
import_lucide_react6.AlertTriangleIcon,
|
|
1124
|
+
{
|
|
1125
|
+
className: "size-4 mt-0.5 flex-shrink-0",
|
|
1126
|
+
style: { color: "hsl(var(--chat-text)/0.6)" }
|
|
1127
|
+
}
|
|
1128
|
+
),
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { color: "hsl(var(--chat-text)/0.85)" }, children: friendly }) }),
|
|
1130
|
+
canRetry && onRetry && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
909
1131
|
"button",
|
|
910
1132
|
{
|
|
911
1133
|
type: "button",
|
|
912
|
-
|
|
913
|
-
"
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
]
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1134
|
+
onClick: onRetry,
|
|
1135
|
+
className: "text-[12px] font-medium underline-offset-2 hover:underline",
|
|
1136
|
+
style: { color: "hsl(var(--chat-text)/0.85)" },
|
|
1137
|
+
children: "Try again"
|
|
1138
|
+
}
|
|
1139
|
+
),
|
|
1140
|
+
onDismiss && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1141
|
+
"button",
|
|
1142
|
+
{
|
|
1143
|
+
type: "button",
|
|
1144
|
+
onClick: onDismiss,
|
|
1145
|
+
"aria-label": "Dismiss",
|
|
1146
|
+
className: "flex-shrink-0 -mr-1 -mt-0.5 p-1 rounded hover:bg-[hsl(var(--chat-text)/0.06)] transition-colors",
|
|
1147
|
+
style: { color: "hsl(var(--chat-text)/0.5)" },
|
|
1148
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react6.XIcon, { className: "size-3.5" })
|
|
1149
|
+
}
|
|
1150
|
+
)
|
|
928
1151
|
]
|
|
929
1152
|
}
|
|
930
1153
|
);
|
|
931
1154
|
}
|
|
1155
|
+
function friendlyErrorMessage(error) {
|
|
1156
|
+
const raw = error.message ?? "";
|
|
1157
|
+
if (/abort/i.test(raw)) return "Stopped.";
|
|
1158
|
+
if (/network|fetch|disconnect|ECONN/i.test(raw)) {
|
|
1159
|
+
return "Connection issue. Check your network and try again.";
|
|
1160
|
+
}
|
|
1161
|
+
if (/rate.?limit|429/i.test(raw)) {
|
|
1162
|
+
return "You're sending messages too fast. Wait a moment and try again.";
|
|
1163
|
+
}
|
|
1164
|
+
if (/timeout/i.test(raw)) return "The response took too long.";
|
|
1165
|
+
return "Something went wrong while generating the response.";
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// src/components/message-actions.tsx
|
|
1169
|
+
var import_react4 = require("react");
|
|
1170
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1171
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1172
|
+
function MessageActions({
|
|
1173
|
+
text,
|
|
1174
|
+
onRegenerate,
|
|
1175
|
+
regenerateDisabled,
|
|
1176
|
+
className
|
|
1177
|
+
}) {
|
|
1178
|
+
const [copied, setCopied] = (0, import_react4.useState)(false);
|
|
1179
|
+
const handleCopy = async () => {
|
|
1180
|
+
if (!text) return;
|
|
1181
|
+
try {
|
|
1182
|
+
await navigator.clipboard.writeText(text);
|
|
1183
|
+
setCopied(true);
|
|
1184
|
+
setTimeout(() => setCopied(false), 1500);
|
|
1185
|
+
} catch {
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1189
|
+
"div",
|
|
1190
|
+
{
|
|
1191
|
+
className: cn(
|
|
1192
|
+
"flex items-center gap-1 mt-1.5 -ml-1.5",
|
|
1193
|
+
// Pulled left a touch so the icons line up with the message
|
|
1194
|
+
// text edge instead of its padding box.
|
|
1195
|
+
className
|
|
1196
|
+
),
|
|
1197
|
+
children: [
|
|
1198
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ActionButton, { onClick: handleCopy, ariaLabel: "Copy message", children: copied ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react7.CheckIcon, { className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react7.CopyIcon, { className: "size-3.5" }) }),
|
|
1199
|
+
onRegenerate && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1200
|
+
ActionButton,
|
|
1201
|
+
{
|
|
1202
|
+
onClick: onRegenerate,
|
|
1203
|
+
disabled: regenerateDisabled,
|
|
1204
|
+
ariaLabel: "Regenerate response",
|
|
1205
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react7.RotateCcwIcon, { className: "size-3.5" })
|
|
1206
|
+
}
|
|
1207
|
+
)
|
|
1208
|
+
]
|
|
1209
|
+
}
|
|
1210
|
+
);
|
|
1211
|
+
}
|
|
1212
|
+
function ActionButton({ onClick, disabled, ariaLabel, children }) {
|
|
1213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1214
|
+
"button",
|
|
1215
|
+
{
|
|
1216
|
+
type: "button",
|
|
1217
|
+
onClick,
|
|
1218
|
+
disabled,
|
|
1219
|
+
"aria-label": ariaLabel,
|
|
1220
|
+
className: "p-1.5 rounded-md transition-colors hover:bg-[hsl(var(--chat-text)/0.06)] disabled:opacity-40 disabled:cursor-not-allowed",
|
|
1221
|
+
style: { color: "hsl(var(--chat-text)/0.55)" },
|
|
1222
|
+
children
|
|
1223
|
+
}
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
932
1226
|
|
|
933
1227
|
// src/components/interface.tsx
|
|
934
|
-
var import_react10 = require("react");
|
|
935
|
-
var import_lucide_react10 = require("lucide-react");
|
|
936
1228
|
var import_react11 = require("react");
|
|
937
|
-
var
|
|
1229
|
+
var import_lucide_react12 = require("lucide-react");
|
|
1230
|
+
var import_react12 = require("react");
|
|
1231
|
+
var import_react13 = require("@ai-sdk/react");
|
|
938
1232
|
var import_ai = require("ai");
|
|
939
1233
|
|
|
940
1234
|
// src/components/response.tsx
|
|
941
|
-
var
|
|
1235
|
+
var import_react6 = require("react");
|
|
942
1236
|
var import_streamdown = require("streamdown");
|
|
943
1237
|
|
|
944
1238
|
// src/hooks/use-code-scroll.ts
|
|
945
|
-
var
|
|
1239
|
+
var import_react5 = require("react");
|
|
946
1240
|
function useCodeBlockAutoScroll(isStreaming) {
|
|
947
|
-
const observerRef = (0,
|
|
948
|
-
const containerRef = (0,
|
|
949
|
-
(0,
|
|
1241
|
+
const observerRef = (0, import_react5.useRef)(null);
|
|
1242
|
+
const containerRef = (0, import_react5.useRef)(null);
|
|
1243
|
+
(0, import_react5.useEffect)(() => {
|
|
950
1244
|
if (!isStreaming || !containerRef.current) {
|
|
951
1245
|
if (observerRef.current) {
|
|
952
1246
|
observerRef.current.disconnect();
|
|
@@ -976,11 +1270,11 @@ function useCodeBlockAutoScroll(isStreaming) {
|
|
|
976
1270
|
}
|
|
977
1271
|
|
|
978
1272
|
// src/components/response.tsx
|
|
979
|
-
var
|
|
980
|
-
var Response = (0,
|
|
1273
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1274
|
+
var Response = (0, import_react6.memo)(
|
|
981
1275
|
({ className, isStreaming = false, ...props }) => {
|
|
982
1276
|
const containerRef = useCodeBlockAutoScroll(isStreaming);
|
|
983
|
-
return /* @__PURE__ */ (0,
|
|
1277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: containerRef, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
984
1278
|
import_streamdown.Streamdown,
|
|
985
1279
|
{
|
|
986
1280
|
className: cn(
|
|
@@ -997,16 +1291,16 @@ Response.displayName = "Response";
|
|
|
997
1291
|
|
|
998
1292
|
// src/ui/collapsible.tsx
|
|
999
1293
|
var CollapsiblePrimitive = __toESM(require("@radix-ui/react-collapsible"));
|
|
1000
|
-
var
|
|
1294
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1001
1295
|
function Collapsible({
|
|
1002
1296
|
...props
|
|
1003
1297
|
}) {
|
|
1004
|
-
return /* @__PURE__ */ (0,
|
|
1298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
|
|
1005
1299
|
}
|
|
1006
1300
|
function CollapsibleTrigger2({
|
|
1007
1301
|
...props
|
|
1008
1302
|
}) {
|
|
1009
|
-
return /* @__PURE__ */ (0,
|
|
1303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1010
1304
|
CollapsiblePrimitive.CollapsibleTrigger,
|
|
1011
1305
|
{
|
|
1012
1306
|
"data-slot": "collapsible-trigger",
|
|
@@ -1017,7 +1311,7 @@ function CollapsibleTrigger2({
|
|
|
1017
1311
|
function CollapsibleContent2({
|
|
1018
1312
|
...props
|
|
1019
1313
|
}) {
|
|
1020
|
-
return /* @__PURE__ */ (0,
|
|
1314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1021
1315
|
CollapsiblePrimitive.CollapsibleContent,
|
|
1022
1316
|
{
|
|
1023
1317
|
"data-slot": "collapsible-content",
|
|
@@ -1027,9 +1321,9 @@ function CollapsibleContent2({
|
|
|
1027
1321
|
}
|
|
1028
1322
|
|
|
1029
1323
|
// src/components/sources.tsx
|
|
1030
|
-
var
|
|
1031
|
-
var
|
|
1032
|
-
var Sources = ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
1324
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1325
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1326
|
+
var Sources = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1033
1327
|
Collapsible,
|
|
1034
1328
|
{
|
|
1035
1329
|
className: cn("not-prose mb-4 text-primary text-xs", className),
|
|
@@ -1041,25 +1335,25 @@ var SourcesTrigger = ({
|
|
|
1041
1335
|
count,
|
|
1042
1336
|
children,
|
|
1043
1337
|
...props
|
|
1044
|
-
}) => /* @__PURE__ */ (0,
|
|
1338
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1045
1339
|
CollapsibleTrigger2,
|
|
1046
1340
|
{
|
|
1047
1341
|
className: cn("flex items-center gap-2", className),
|
|
1048
1342
|
...props,
|
|
1049
|
-
children: children ?? /* @__PURE__ */ (0,
|
|
1050
|
-
/* @__PURE__ */ (0,
|
|
1343
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1344
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "font-medium", children: [
|
|
1051
1345
|
"Used ",
|
|
1052
1346
|
count,
|
|
1053
1347
|
" sources"
|
|
1054
1348
|
] }),
|
|
1055
|
-
/* @__PURE__ */ (0,
|
|
1349
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react8.ChevronDownIcon, { className: "h-4 w-4" })
|
|
1056
1350
|
] })
|
|
1057
1351
|
}
|
|
1058
1352
|
);
|
|
1059
1353
|
var SourcesContent = ({
|
|
1060
1354
|
className,
|
|
1061
1355
|
...props
|
|
1062
|
-
}) => /* @__PURE__ */ (0,
|
|
1356
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1063
1357
|
CollapsibleContent2,
|
|
1064
1358
|
{
|
|
1065
1359
|
className: cn(
|
|
@@ -1070,7 +1364,7 @@ var SourcesContent = ({
|
|
|
1070
1364
|
...props
|
|
1071
1365
|
}
|
|
1072
1366
|
);
|
|
1073
|
-
var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ (0,
|
|
1367
|
+
var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1074
1368
|
"a",
|
|
1075
1369
|
{
|
|
1076
1370
|
className: "flex items-center gap-2",
|
|
@@ -1078,21 +1372,21 @@ var Source = ({ href, title, children, ...props }) => /* @__PURE__ */ (0, import
|
|
|
1078
1372
|
rel: "noreferrer",
|
|
1079
1373
|
target: "_blank",
|
|
1080
1374
|
...props,
|
|
1081
|
-
children: children ?? /* @__PURE__ */ (0,
|
|
1082
|
-
/* @__PURE__ */ (0,
|
|
1083
|
-
/* @__PURE__ */ (0,
|
|
1375
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1376
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react8.BookIcon, { className: "h-4 w-4" }),
|
|
1377
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "block font-medium", children: title })
|
|
1084
1378
|
] })
|
|
1085
1379
|
}
|
|
1086
1380
|
);
|
|
1087
1381
|
|
|
1088
1382
|
// src/components/reasoning.tsx
|
|
1089
1383
|
var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state");
|
|
1090
|
-
var
|
|
1091
|
-
var
|
|
1092
|
-
var
|
|
1093
|
-
var ReasoningContext = (0,
|
|
1384
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1385
|
+
var import_react7 = require("react");
|
|
1386
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1387
|
+
var ReasoningContext = (0, import_react7.createContext)(null);
|
|
1094
1388
|
var useReasoning = () => {
|
|
1095
|
-
const context = (0,
|
|
1389
|
+
const context = (0, import_react7.useContext)(ReasoningContext);
|
|
1096
1390
|
if (!context) {
|
|
1097
1391
|
throw new Error("Reasoning components must be used within Reasoning");
|
|
1098
1392
|
}
|
|
@@ -1100,7 +1394,7 @@ var useReasoning = () => {
|
|
|
1100
1394
|
};
|
|
1101
1395
|
var AUTO_CLOSE_DELAY = 1e3;
|
|
1102
1396
|
var MS_IN_S = 1e3;
|
|
1103
|
-
var Reasoning = (0,
|
|
1397
|
+
var Reasoning = (0, import_react7.memo)(
|
|
1104
1398
|
({
|
|
1105
1399
|
className,
|
|
1106
1400
|
isStreaming = false,
|
|
@@ -1120,9 +1414,9 @@ var Reasoning = (0, import_react6.memo)(
|
|
|
1120
1414
|
prop: durationProp,
|
|
1121
1415
|
defaultProp: void 0
|
|
1122
1416
|
});
|
|
1123
|
-
const [hasAutoClosed, setHasAutoClosed] = (0,
|
|
1124
|
-
const [startTime, setStartTime] = (0,
|
|
1125
|
-
(0,
|
|
1417
|
+
const [hasAutoClosed, setHasAutoClosed] = (0, import_react7.useState)(false);
|
|
1418
|
+
const [startTime, setStartTime] = (0, import_react7.useState)(null);
|
|
1419
|
+
(0, import_react7.useEffect)(() => {
|
|
1126
1420
|
if (isStreaming) {
|
|
1127
1421
|
if (startTime === null) {
|
|
1128
1422
|
setStartTime(Date.now());
|
|
@@ -1132,7 +1426,7 @@ var Reasoning = (0, import_react6.memo)(
|
|
|
1132
1426
|
setStartTime(null);
|
|
1133
1427
|
}
|
|
1134
1428
|
}, [isStreaming, startTime, setDuration]);
|
|
1135
|
-
(0,
|
|
1429
|
+
(0, import_react7.useEffect)(() => {
|
|
1136
1430
|
if (defaultOpen && !isStreaming && isOpen && !hasAutoClosed && durationProp !== void 0) {
|
|
1137
1431
|
const timer = setTimeout(() => {
|
|
1138
1432
|
setIsOpen(false);
|
|
@@ -1144,11 +1438,11 @@ var Reasoning = (0, import_react6.memo)(
|
|
|
1144
1438
|
const handleOpenChange = (newOpen) => {
|
|
1145
1439
|
setIsOpen(newOpen);
|
|
1146
1440
|
};
|
|
1147
|
-
return /* @__PURE__ */ (0,
|
|
1441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1148
1442
|
ReasoningContext.Provider,
|
|
1149
1443
|
{
|
|
1150
1444
|
value: { isStreaming, isOpen, setIsOpen, duration },
|
|
1151
|
-
children: /* @__PURE__ */ (0,
|
|
1445
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1152
1446
|
Collapsible,
|
|
1153
1447
|
{
|
|
1154
1448
|
className: cn("not-prose", className),
|
|
@@ -1164,24 +1458,24 @@ var Reasoning = (0, import_react6.memo)(
|
|
|
1164
1458
|
);
|
|
1165
1459
|
var getThinkingMessage = (isStreaming, duration) => {
|
|
1166
1460
|
if (isStreaming) {
|
|
1167
|
-
return /* @__PURE__ */ (0,
|
|
1461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: "Thinking..." });
|
|
1168
1462
|
}
|
|
1169
1463
|
if (duration === void 0) {
|
|
1170
|
-
return /* @__PURE__ */ (0,
|
|
1464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: "Thought process" });
|
|
1171
1465
|
}
|
|
1172
1466
|
if (duration === 0) {
|
|
1173
|
-
return /* @__PURE__ */ (0,
|
|
1467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: "Thought process" });
|
|
1174
1468
|
}
|
|
1175
|
-
return /* @__PURE__ */ (0,
|
|
1469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1176
1470
|
"Thought for ",
|
|
1177
1471
|
duration,
|
|
1178
1472
|
" seconds"
|
|
1179
1473
|
] });
|
|
1180
1474
|
};
|
|
1181
|
-
var ReasoningTrigger = (0,
|
|
1475
|
+
var ReasoningTrigger = (0, import_react7.memo)(
|
|
1182
1476
|
({ className, children, ...props }) => {
|
|
1183
1477
|
const { isStreaming, isOpen, duration } = useReasoning();
|
|
1184
|
-
return /* @__PURE__ */ (0,
|
|
1478
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1185
1479
|
CollapsibleTrigger2,
|
|
1186
1480
|
{
|
|
1187
1481
|
className: cn(
|
|
@@ -1189,11 +1483,11 @@ var ReasoningTrigger = (0, import_react6.memo)(
|
|
|
1189
1483
|
className
|
|
1190
1484
|
),
|
|
1191
1485
|
...props,
|
|
1192
|
-
children: children ?? /* @__PURE__ */ (0,
|
|
1193
|
-
/* @__PURE__ */ (0,
|
|
1486
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1487
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react9.BrainIcon, { className: "size-4 flex-shrink-0" }),
|
|
1194
1488
|
getThinkingMessage(isStreaming, duration),
|
|
1195
|
-
/* @__PURE__ */ (0,
|
|
1196
|
-
|
|
1489
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1490
|
+
import_lucide_react9.ChevronDownIcon,
|
|
1197
1491
|
{
|
|
1198
1492
|
className: cn(
|
|
1199
1493
|
"size-4 flex-shrink-0 transition-transform ml-1",
|
|
@@ -1206,8 +1500,8 @@ var ReasoningTrigger = (0, import_react6.memo)(
|
|
|
1206
1500
|
);
|
|
1207
1501
|
}
|
|
1208
1502
|
);
|
|
1209
|
-
var ReasoningContent = (0,
|
|
1210
|
-
({ className, children, ...props }) => /* @__PURE__ */ (0,
|
|
1503
|
+
var ReasoningContent = (0, import_react7.memo)(
|
|
1504
|
+
({ className, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1211
1505
|
CollapsibleContent2,
|
|
1212
1506
|
{
|
|
1213
1507
|
className: cn(
|
|
@@ -1216,7 +1510,7 @@ var ReasoningContent = (0, import_react6.memo)(
|
|
|
1216
1510
|
className
|
|
1217
1511
|
),
|
|
1218
1512
|
...props,
|
|
1219
|
-
children: /* @__PURE__ */ (0,
|
|
1513
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Response, { className: "grid gap-2", children })
|
|
1220
1514
|
}
|
|
1221
1515
|
)
|
|
1222
1516
|
);
|
|
@@ -1225,8 +1519,8 @@ ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
|
1225
1519
|
ReasoningContent.displayName = "ReasoningContent";
|
|
1226
1520
|
|
|
1227
1521
|
// src/components/loader.tsx
|
|
1228
|
-
var
|
|
1229
|
-
var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0,
|
|
1522
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1523
|
+
var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1230
1524
|
"svg",
|
|
1231
1525
|
{
|
|
1232
1526
|
height: size,
|
|
@@ -1235,10 +1529,10 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1235
1529
|
viewBox: "0 0 16 16",
|
|
1236
1530
|
width: size,
|
|
1237
1531
|
children: [
|
|
1238
|
-
/* @__PURE__ */ (0,
|
|
1239
|
-
/* @__PURE__ */ (0,
|
|
1240
|
-
/* @__PURE__ */ (0,
|
|
1241
|
-
/* @__PURE__ */ (0,
|
|
1532
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("title", { children: "Loader" }),
|
|
1533
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("g", { clipPath: "url(#clip0_2393_1490)", children: [
|
|
1534
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M8 0V4", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
1535
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1242
1536
|
"path",
|
|
1243
1537
|
{
|
|
1244
1538
|
d: "M8 16V12",
|
|
@@ -1247,7 +1541,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1247
1541
|
strokeWidth: "1.5"
|
|
1248
1542
|
}
|
|
1249
1543
|
),
|
|
1250
|
-
/* @__PURE__ */ (0,
|
|
1544
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1251
1545
|
"path",
|
|
1252
1546
|
{
|
|
1253
1547
|
d: "M3.29773 1.52783L5.64887 4.7639",
|
|
@@ -1256,7 +1550,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1256
1550
|
strokeWidth: "1.5"
|
|
1257
1551
|
}
|
|
1258
1552
|
),
|
|
1259
|
-
/* @__PURE__ */ (0,
|
|
1553
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1260
1554
|
"path",
|
|
1261
1555
|
{
|
|
1262
1556
|
d: "M12.7023 1.52783L10.3511 4.7639",
|
|
@@ -1265,7 +1559,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1265
1559
|
strokeWidth: "1.5"
|
|
1266
1560
|
}
|
|
1267
1561
|
),
|
|
1268
|
-
/* @__PURE__ */ (0,
|
|
1562
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1269
1563
|
"path",
|
|
1270
1564
|
{
|
|
1271
1565
|
d: "M12.7023 14.472L10.3511 11.236",
|
|
@@ -1274,7 +1568,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1274
1568
|
strokeWidth: "1.5"
|
|
1275
1569
|
}
|
|
1276
1570
|
),
|
|
1277
|
-
/* @__PURE__ */ (0,
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1278
1572
|
"path",
|
|
1279
1573
|
{
|
|
1280
1574
|
d: "M3.29773 14.472L5.64887 11.236",
|
|
@@ -1283,7 +1577,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1283
1577
|
strokeWidth: "1.5"
|
|
1284
1578
|
}
|
|
1285
1579
|
),
|
|
1286
|
-
/* @__PURE__ */ (0,
|
|
1580
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1287
1581
|
"path",
|
|
1288
1582
|
{
|
|
1289
1583
|
d: "M15.6085 5.52783L11.8043 6.7639",
|
|
@@ -1292,7 +1586,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1292
1586
|
strokeWidth: "1.5"
|
|
1293
1587
|
}
|
|
1294
1588
|
),
|
|
1295
|
-
/* @__PURE__ */ (0,
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1296
1590
|
"path",
|
|
1297
1591
|
{
|
|
1298
1592
|
d: "M0.391602 10.472L4.19583 9.23598",
|
|
@@ -1301,7 +1595,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1301
1595
|
strokeWidth: "1.5"
|
|
1302
1596
|
}
|
|
1303
1597
|
),
|
|
1304
|
-
/* @__PURE__ */ (0,
|
|
1598
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1305
1599
|
"path",
|
|
1306
1600
|
{
|
|
1307
1601
|
d: "M15.6085 10.4722L11.8043 9.2361",
|
|
@@ -1310,7 +1604,7 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1310
1604
|
strokeWidth: "1.5"
|
|
1311
1605
|
}
|
|
1312
1606
|
),
|
|
1313
|
-
/* @__PURE__ */ (0,
|
|
1607
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1314
1608
|
"path",
|
|
1315
1609
|
{
|
|
1316
1610
|
d: "M0.391602 5.52783L4.19583 6.7639",
|
|
@@ -1320,11 +1614,11 @@ var LoaderIcon = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx
|
|
|
1320
1614
|
}
|
|
1321
1615
|
)
|
|
1322
1616
|
] }),
|
|
1323
|
-
/* @__PURE__ */ (0,
|
|
1617
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("clipPath", { id: "clip0_2393_1490", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("rect", { fill: "white", height: "16", width: "16" }) }) })
|
|
1324
1618
|
]
|
|
1325
1619
|
}
|
|
1326
1620
|
);
|
|
1327
|
-
var Loader = ({ className, size = 16, ...props }) => /* @__PURE__ */ (0,
|
|
1621
|
+
var Loader = ({ className, size = 16, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1328
1622
|
"div",
|
|
1329
1623
|
{
|
|
1330
1624
|
className: cn(
|
|
@@ -1332,14 +1626,14 @@ var Loader = ({ className, size = 16, ...props }) => /* @__PURE__ */ (0, import_
|
|
|
1332
1626
|
className
|
|
1333
1627
|
),
|
|
1334
1628
|
...props,
|
|
1335
|
-
children: /* @__PURE__ */ (0,
|
|
1629
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LoaderIcon, { size })
|
|
1336
1630
|
}
|
|
1337
1631
|
);
|
|
1338
1632
|
|
|
1339
1633
|
// src/ui/badge.tsx
|
|
1340
1634
|
var import_react_slot2 = require("@radix-ui/react-slot");
|
|
1341
1635
|
var import_class_variance_authority3 = require("class-variance-authority");
|
|
1342
|
-
var
|
|
1636
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1343
1637
|
var badgeVariants = (0, import_class_variance_authority3.cva)(
|
|
1344
1638
|
"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",
|
|
1345
1639
|
{
|
|
@@ -1363,7 +1657,7 @@ function Badge({
|
|
|
1363
1657
|
...props
|
|
1364
1658
|
}) {
|
|
1365
1659
|
const Comp = asChild ? import_react_slot2.Slot : "span";
|
|
1366
|
-
return /* @__PURE__ */ (0,
|
|
1660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1367
1661
|
Comp,
|
|
1368
1662
|
{
|
|
1369
1663
|
"data-slot": "badge",
|
|
@@ -1374,16 +1668,16 @@ function Badge({
|
|
|
1374
1668
|
}
|
|
1375
1669
|
|
|
1376
1670
|
// src/components/tool.tsx
|
|
1377
|
-
var
|
|
1378
|
-
var
|
|
1671
|
+
var import_lucide_react11 = require("lucide-react");
|
|
1672
|
+
var import_react9 = require("react");
|
|
1379
1673
|
|
|
1380
1674
|
// src/components/code-block.tsx
|
|
1381
|
-
var
|
|
1382
|
-
var
|
|
1675
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1676
|
+
var import_react8 = require("react");
|
|
1383
1677
|
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
1384
1678
|
var import_prism = require("react-syntax-highlighter/dist/esm/styles/prism");
|
|
1385
|
-
var
|
|
1386
|
-
var CodeBlockContext = (0,
|
|
1679
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1680
|
+
var CodeBlockContext = (0, import_react8.createContext)({
|
|
1387
1681
|
code: ""
|
|
1388
1682
|
});
|
|
1389
1683
|
var CodeBlock = ({
|
|
@@ -1393,7 +1687,7 @@ var CodeBlock = ({
|
|
|
1393
1687
|
className,
|
|
1394
1688
|
children,
|
|
1395
1689
|
...props
|
|
1396
|
-
}) => /* @__PURE__ */ (0,
|
|
1690
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CodeBlockContext.Provider, { value: { code }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1397
1691
|
"div",
|
|
1398
1692
|
{
|
|
1399
1693
|
className: cn(
|
|
@@ -1401,8 +1695,8 @@ var CodeBlock = ({
|
|
|
1401
1695
|
className
|
|
1402
1696
|
),
|
|
1403
1697
|
...props,
|
|
1404
|
-
children: /* @__PURE__ */ (0,
|
|
1405
|
-
/* @__PURE__ */ (0,
|
|
1698
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "relative max-h-96 overflow-y-auto", children: [
|
|
1699
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1406
1700
|
import_react_syntax_highlighter.Prism,
|
|
1407
1701
|
{
|
|
1408
1702
|
className: "overflow-hidden dark:hidden",
|
|
@@ -1428,7 +1722,7 @@ var CodeBlock = ({
|
|
|
1428
1722
|
children: code
|
|
1429
1723
|
}
|
|
1430
1724
|
),
|
|
1431
|
-
/* @__PURE__ */ (0,
|
|
1725
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1432
1726
|
import_react_syntax_highlighter.Prism,
|
|
1433
1727
|
{
|
|
1434
1728
|
className: "hidden overflow-hidden dark:block",
|
|
@@ -1454,36 +1748,42 @@ var CodeBlock = ({
|
|
|
1454
1748
|
children: code
|
|
1455
1749
|
}
|
|
1456
1750
|
),
|
|
1457
|
-
children && /* @__PURE__ */ (0,
|
|
1751
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "absolute top-2 right-2 flex items-center gap-2", children })
|
|
1458
1752
|
] })
|
|
1459
1753
|
}
|
|
1460
1754
|
) });
|
|
1461
1755
|
|
|
1462
1756
|
// src/components/tool.tsx
|
|
1463
|
-
var
|
|
1464
|
-
var Tool = ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
1757
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1758
|
+
var Tool = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1465
1759
|
Collapsible,
|
|
1466
1760
|
{
|
|
1467
1761
|
className: cn("not-prose w-full rounded-md border border-[var(--chat-divider)]", className),
|
|
1468
1762
|
...props
|
|
1469
1763
|
}
|
|
1470
1764
|
);
|
|
1765
|
+
var STATUS_LABELS = {
|
|
1766
|
+
"input-streaming": "Pending",
|
|
1767
|
+
"input-available": "Running",
|
|
1768
|
+
"output-available": "Completed",
|
|
1769
|
+
"output-error": "Error",
|
|
1770
|
+
"approval-requested": "Awaiting approval",
|
|
1771
|
+
"approval-responded": "Approved",
|
|
1772
|
+
"output-denied": "Denied"
|
|
1773
|
+
};
|
|
1774
|
+
var STATUS_ICONS = {
|
|
1775
|
+
"input-streaming": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.CircleIcon, { className: "size-4" }),
|
|
1776
|
+
"input-available": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.ClockIcon, { className: "size-4 animate-pulse" }),
|
|
1777
|
+
"output-available": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.CheckCircleIcon, { className: "size-4 text-green-600" }),
|
|
1778
|
+
"output-error": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.XCircleIcon, { className: "size-4 text-red-600" }),
|
|
1779
|
+
"approval-requested": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.ClockIcon, { className: "size-4 text-amber-600" }),
|
|
1780
|
+
"approval-responded": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.CheckCircleIcon, { className: "size-4 text-amber-600" }),
|
|
1781
|
+
"output-denied": /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.XCircleIcon, { className: "size-4 text-muted-foreground" })
|
|
1782
|
+
};
|
|
1471
1783
|
var getStatusBadge = (status) => {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
"output-available": "Completed",
|
|
1476
|
-
"output-error": "Error"
|
|
1477
|
-
};
|
|
1478
|
-
const icons = {
|
|
1479
|
-
"input-streaming": /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.CircleIcon, { className: "size-4" }),
|
|
1480
|
-
"input-available": /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.ClockIcon, { className: "size-4 animate-pulse" }),
|
|
1481
|
-
"output-available": /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.CheckCircleIcon, { className: "size-4 text-green-600" }),
|
|
1482
|
-
"output-error": /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react9.XCircleIcon, { className: "size-4 text-red-600" })
|
|
1483
|
-
};
|
|
1484
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Badge, { className: "gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
1485
|
-
icons[status],
|
|
1486
|
-
labels[status]
|
|
1784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Badge, { className: "gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
1785
|
+
STATUS_ICONS[status],
|
|
1786
|
+
STATUS_LABELS[status]
|
|
1487
1787
|
] });
|
|
1488
1788
|
};
|
|
1489
1789
|
var ToolHeader = ({
|
|
@@ -1493,7 +1793,7 @@ var ToolHeader = ({
|
|
|
1493
1793
|
toolName,
|
|
1494
1794
|
state,
|
|
1495
1795
|
...props
|
|
1496
|
-
}) => /* @__PURE__ */ (0,
|
|
1796
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1497
1797
|
CollapsibleTrigger2,
|
|
1498
1798
|
{
|
|
1499
1799
|
className: cn(
|
|
@@ -1502,16 +1802,16 @@ var ToolHeader = ({
|
|
|
1502
1802
|
),
|
|
1503
1803
|
...props,
|
|
1504
1804
|
children: [
|
|
1505
|
-
/* @__PURE__ */ (0,
|
|
1506
|
-
/* @__PURE__ */ (0,
|
|
1507
|
-
/* @__PURE__ */ (0,
|
|
1805
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1806
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.WrenchIcon, { className: "size-4 text-muted-foreground" }),
|
|
1807
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "font-medium text-sm", children: title ?? toolName ?? type.split("-").slice(1).join("-") }),
|
|
1508
1808
|
getStatusBadge(state)
|
|
1509
1809
|
] }),
|
|
1510
|
-
/* @__PURE__ */ (0,
|
|
1810
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.ChevronDownIcon, { className: "size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" })
|
|
1511
1811
|
]
|
|
1512
1812
|
}
|
|
1513
1813
|
);
|
|
1514
|
-
var ToolContent = ({ className, ...props }) => /* @__PURE__ */ (0,
|
|
1814
|
+
var ToolContent = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1515
1815
|
CollapsibleContent2,
|
|
1516
1816
|
{
|
|
1517
1817
|
className: cn(
|
|
@@ -1521,9 +1821,9 @@ var ToolContent = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_ru
|
|
|
1521
1821
|
...props
|
|
1522
1822
|
}
|
|
1523
1823
|
);
|
|
1524
|
-
var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */ (0,
|
|
1525
|
-
/* @__PURE__ */ (0,
|
|
1526
|
-
/* @__PURE__ */ (0,
|
|
1824
|
+
var ToolInput = ({ className, input, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("space-y-2 overflow-hidden p-2", className), ...props, children: [
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: "Parameters" }),
|
|
1826
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "rounded-md bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CodeBlock, { code: JSON.stringify(input, null, 2), language: "json" }) })
|
|
1527
1827
|
] });
|
|
1528
1828
|
var ToolOutput = ({
|
|
1529
1829
|
className,
|
|
@@ -1534,15 +1834,15 @@ var ToolOutput = ({
|
|
|
1534
1834
|
if (!(output || errorText)) {
|
|
1535
1835
|
return null;
|
|
1536
1836
|
}
|
|
1537
|
-
let Output = /* @__PURE__ */ (0,
|
|
1538
|
-
if (typeof output === "object" && !(0,
|
|
1539
|
-
Output = /* @__PURE__ */ (0,
|
|
1837
|
+
let Output = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: output });
|
|
1838
|
+
if (typeof output === "object" && !(0, import_react9.isValidElement)(output)) {
|
|
1839
|
+
Output = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CodeBlock, { code: JSON.stringify(output, null, 2), language: "json" });
|
|
1540
1840
|
} else if (typeof output === "string") {
|
|
1541
|
-
Output = /* @__PURE__ */ (0,
|
|
1841
|
+
Output = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CodeBlock, { code: output, language: "json" });
|
|
1542
1842
|
}
|
|
1543
|
-
return /* @__PURE__ */ (0,
|
|
1544
|
-
/* @__PURE__ */ (0,
|
|
1545
|
-
/* @__PURE__ */ (0,
|
|
1843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("space-y-2 p-2", className), ...props, children: [
|
|
1844
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h4", { className: "font-medium text-muted-foreground text-xs uppercase tracking-wide", children: errorText ? "Error" : "Result" }),
|
|
1845
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1546
1846
|
"div",
|
|
1547
1847
|
{
|
|
1548
1848
|
className: cn(
|
|
@@ -1550,7 +1850,7 @@ var ToolOutput = ({
|
|
|
1550
1850
|
errorText ? "bg-destructive/10 text-destructive" : "bg-muted/50 text-foreground"
|
|
1551
1851
|
),
|
|
1552
1852
|
children: [
|
|
1553
|
-
errorText && /* @__PURE__ */ (0,
|
|
1853
|
+
errorText && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: errorText }),
|
|
1554
1854
|
Output
|
|
1555
1855
|
]
|
|
1556
1856
|
}
|
|
@@ -1559,7 +1859,7 @@ var ToolOutput = ({
|
|
|
1559
1859
|
};
|
|
1560
1860
|
|
|
1561
1861
|
// src/components/suggestion2.tsx
|
|
1562
|
-
var
|
|
1862
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1563
1863
|
function StarterMessages({
|
|
1564
1864
|
className,
|
|
1565
1865
|
prompts,
|
|
@@ -1567,7 +1867,7 @@ function StarterMessages({
|
|
|
1567
1867
|
...props
|
|
1568
1868
|
}) {
|
|
1569
1869
|
if (prompts.length === 0) return null;
|
|
1570
|
-
return /* @__PURE__ */ (0,
|
|
1870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1571
1871
|
"div",
|
|
1572
1872
|
{
|
|
1573
1873
|
className: cn(
|
|
@@ -1575,8 +1875,8 @@ function StarterMessages({
|
|
|
1575
1875
|
className
|
|
1576
1876
|
),
|
|
1577
1877
|
...props,
|
|
1578
|
-
children: prompts.map((prompt, index) => /* @__PURE__ */ (0,
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
1878
|
+
children: prompts.map((prompt, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
1879
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1580
1880
|
StarterMessageItem,
|
|
1581
1881
|
{
|
|
1582
1882
|
prompt,
|
|
@@ -1586,7 +1886,7 @@ function StarterMessages({
|
|
|
1586
1886
|
index < prompts.length - 1 && // 1px-tall element used as a divider — same --chat-divider token
|
|
1587
1887
|
// every other separator in the widget uses, so consumers only
|
|
1588
1888
|
// need to override one variable to recolour all of them.
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1889
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-px mx-3", style: { backgroundColor: "var(--chat-divider)" } })
|
|
1590
1890
|
] }, index))
|
|
1591
1891
|
}
|
|
1592
1892
|
);
|
|
@@ -1597,7 +1897,7 @@ function StarterMessageItem({
|
|
|
1597
1897
|
onClick,
|
|
1598
1898
|
...props
|
|
1599
1899
|
}) {
|
|
1600
|
-
return /* @__PURE__ */ (0,
|
|
1900
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
1601
1901
|
"button",
|
|
1602
1902
|
{
|
|
1603
1903
|
type: "button",
|
|
@@ -1612,17 +1912,17 @@ function StarterMessageItem({
|
|
|
1612
1912
|
),
|
|
1613
1913
|
...props,
|
|
1614
1914
|
children: [
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
1616
|
-
prompt.subtitle && /* @__PURE__ */ (0,
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[13px] text-[hsl(var(--chat-text)/0.7)]", children: prompt.title }),
|
|
1916
|
+
prompt.subtitle && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block text-[11px] text-[hsl(var(--chat-text)/0.4)] mt-0.5", children: prompt.subtitle })
|
|
1617
1917
|
]
|
|
1618
1918
|
}
|
|
1619
1919
|
);
|
|
1620
1920
|
}
|
|
1621
1921
|
|
|
1622
1922
|
// src/contexts/chat-storage-context.tsx
|
|
1623
|
-
var
|
|
1624
|
-
var
|
|
1625
|
-
var ChatStorageContext = (0,
|
|
1923
|
+
var import_react10 = require("react");
|
|
1924
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1925
|
+
var ChatStorageContext = (0, import_react10.createContext)({
|
|
1626
1926
|
storageKeyPrefix: ""
|
|
1627
1927
|
});
|
|
1628
1928
|
function ChatStorageProvider({
|
|
@@ -1630,46 +1930,46 @@ function ChatStorageProvider({
|
|
|
1630
1930
|
userId
|
|
1631
1931
|
}) {
|
|
1632
1932
|
const storageKeyPrefix = userId || "";
|
|
1633
|
-
return /* @__PURE__ */ (0,
|
|
1933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ChatStorageContext.Provider, { value: { storageKeyPrefix }, children });
|
|
1634
1934
|
}
|
|
1635
1935
|
function useChatStorageKey() {
|
|
1636
|
-
return (0,
|
|
1936
|
+
return (0, import_react10.useContext)(ChatStorageContext);
|
|
1637
1937
|
}
|
|
1638
1938
|
|
|
1639
1939
|
// src/components/interface.tsx
|
|
1640
|
-
var
|
|
1940
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1641
1941
|
function ChatInterface({ id, initialMessages, config, onClose, headerActions } = {}) {
|
|
1642
1942
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
1643
1943
|
const storageKey = (key) => storageKeyPrefix ? `chat-${storageKeyPrefix}-${key}` : `chat-${key}`;
|
|
1644
1944
|
const themeMode = config?.theme?.mode || "light";
|
|
1645
|
-
const [input, setInput] = (0,
|
|
1646
|
-
const inputRef = (0,
|
|
1945
|
+
const [input, setInput] = (0, import_react11.useState)("");
|
|
1946
|
+
const inputRef = (0, import_react11.useRef)(null);
|
|
1647
1947
|
const inputPlugins = useInputPlugins({
|
|
1648
1948
|
textareaRef: inputRef,
|
|
1649
1949
|
value: input,
|
|
1650
1950
|
setValue: setInput,
|
|
1651
1951
|
plugins: config?.inputPlugins
|
|
1652
1952
|
});
|
|
1653
|
-
const [showHistory, setShowHistory] = (0,
|
|
1654
|
-
const [conversations, setConversations] = (0,
|
|
1655
|
-
const [loadingHistory, setLoadingHistory] = (0,
|
|
1656
|
-
const [historyLoaded, setHistoryLoaded] = (0,
|
|
1657
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
1658
|
-
const [uploadError, setUploadError] = (0,
|
|
1659
|
-
(0,
|
|
1953
|
+
const [showHistory, setShowHistory] = (0, import_react11.useState)(false);
|
|
1954
|
+
const [conversations, setConversations] = (0, import_react11.useState)([]);
|
|
1955
|
+
const [loadingHistory, setLoadingHistory] = (0, import_react11.useState)(false);
|
|
1956
|
+
const [historyLoaded, setHistoryLoaded] = (0, import_react11.useState)(false);
|
|
1957
|
+
const [searchQuery, setSearchQuery] = (0, import_react11.useState)("");
|
|
1958
|
+
const [uploadError, setUploadError] = (0, import_react11.useState)(null);
|
|
1959
|
+
(0, import_react11.useEffect)(() => {
|
|
1660
1960
|
if (uploadError) {
|
|
1661
1961
|
const timeoutId = setTimeout(() => setUploadError(null), 5e3);
|
|
1662
1962
|
return () => clearTimeout(timeoutId);
|
|
1663
1963
|
}
|
|
1664
1964
|
}, [uploadError]);
|
|
1665
|
-
const [tabs, setTabs] = (0,
|
|
1666
|
-
const [activeTabId, setActiveTabId] = (0,
|
|
1667
|
-
const [initialTabCreated, setInitialTabCreated] = (0,
|
|
1668
|
-
const [isInitializing, setIsInitializing] = (0,
|
|
1669
|
-
const [isLoadingMessages, setIsLoadingMessages] = (0,
|
|
1670
|
-
const lastSyncedTabId = (0,
|
|
1671
|
-
const hasInitialized = (0,
|
|
1672
|
-
const { messages, sendMessage, status, setMessages } = (0,
|
|
1965
|
+
const [tabs, setTabs] = (0, import_react11.useState)([]);
|
|
1966
|
+
const [activeTabId, setActiveTabId] = (0, import_react11.useState)("");
|
|
1967
|
+
const [initialTabCreated, setInitialTabCreated] = (0, import_react11.useState)(false);
|
|
1968
|
+
const [isInitializing, setIsInitializing] = (0, import_react11.useState)(true);
|
|
1969
|
+
const [isLoadingMessages, setIsLoadingMessages] = (0, import_react11.useState)(false);
|
|
1970
|
+
const lastSyncedTabId = (0, import_react11.useRef)("");
|
|
1971
|
+
const hasInitialized = (0, import_react11.useRef)(false);
|
|
1972
|
+
const { messages, sendMessage, status, setMessages, stop, regenerate, error, clearError } = (0, import_react13.useChat)({
|
|
1673
1973
|
id: activeTabId || "temp-id",
|
|
1674
1974
|
transport: new import_ai.DefaultChatTransport({
|
|
1675
1975
|
api: "/api/chat",
|
|
@@ -1716,8 +2016,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1716
2016
|
mediaType: uploadResult.mediaType,
|
|
1717
2017
|
size: uploadResult.size
|
|
1718
2018
|
};
|
|
1719
|
-
} catch (
|
|
1720
|
-
console.error(`Error uploading ${file.filename}:`,
|
|
2019
|
+
} catch (error2) {
|
|
2020
|
+
console.error(`Error uploading ${file.filename}:`, error2);
|
|
1721
2021
|
return null;
|
|
1722
2022
|
}
|
|
1723
2023
|
});
|
|
@@ -1734,10 +2034,10 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1734
2034
|
setUploadError(warnMsg);
|
|
1735
2035
|
console.warn(warnMsg);
|
|
1736
2036
|
}
|
|
1737
|
-
} catch (
|
|
2037
|
+
} catch (error2) {
|
|
1738
2038
|
const errorMsg = "Error uploading files. Please try again.";
|
|
1739
2039
|
setUploadError(errorMsg);
|
|
1740
|
-
console.error("Error in file upload process:",
|
|
2040
|
+
console.error("Error in file upload process:", error2);
|
|
1741
2041
|
return;
|
|
1742
2042
|
}
|
|
1743
2043
|
}
|
|
@@ -1758,12 +2058,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1758
2058
|
};
|
|
1759
2059
|
const AttachButton = () => {
|
|
1760
2060
|
const attachments = usePromptInputAttachments();
|
|
1761
|
-
return /* @__PURE__ */ (0,
|
|
2061
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1762
2062
|
PromptInputButton,
|
|
1763
2063
|
{
|
|
1764
2064
|
variant: "ghost",
|
|
1765
2065
|
onClick: () => attachments.openFileDialog(),
|
|
1766
|
-
children: /* @__PURE__ */ (0,
|
|
2066
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.PlusIcon, { className: "size-4" })
|
|
1767
2067
|
}
|
|
1768
2068
|
);
|
|
1769
2069
|
};
|
|
@@ -1786,8 +2086,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1786
2086
|
} else {
|
|
1787
2087
|
console.error("Error loading messages:", response.status, response.statusText);
|
|
1788
2088
|
}
|
|
1789
|
-
} catch (
|
|
1790
|
-
console.error("Error loading conversation:",
|
|
2089
|
+
} catch (error2) {
|
|
2090
|
+
console.error("Error loading conversation:", error2);
|
|
1791
2091
|
}
|
|
1792
2092
|
};
|
|
1793
2093
|
const generateUniqueTabId = () => {
|
|
@@ -1802,7 +2102,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1802
2102
|
}
|
|
1803
2103
|
return newTabId;
|
|
1804
2104
|
};
|
|
1805
|
-
const createNewTab = (0,
|
|
2105
|
+
const createNewTab = (0, import_react11.useCallback)(() => {
|
|
1806
2106
|
if (!initialTabCreated) {
|
|
1807
2107
|
console.warn("Cannot create new tab while initializing");
|
|
1808
2108
|
return;
|
|
@@ -1829,10 +2129,10 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1829
2129
|
setMessages([]);
|
|
1830
2130
|
setInput("");
|
|
1831
2131
|
}, [initialTabCreated]);
|
|
1832
|
-
const startNewConversation = (0,
|
|
2132
|
+
const startNewConversation = (0, import_react11.useCallback)(() => {
|
|
1833
2133
|
createNewTab();
|
|
1834
2134
|
}, [createNewTab]);
|
|
1835
|
-
(0,
|
|
2135
|
+
(0, import_react11.useEffect)(() => {
|
|
1836
2136
|
return () => {
|
|
1837
2137
|
};
|
|
1838
2138
|
}, []);
|
|
@@ -1891,23 +2191,23 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1891
2191
|
const errorText = await response.text();
|
|
1892
2192
|
console.error("[ChatInterface] Error response:", errorText);
|
|
1893
2193
|
}
|
|
1894
|
-
} catch (
|
|
1895
|
-
console.error("[ChatInterface] Error fetching chat history:",
|
|
2194
|
+
} catch (error2) {
|
|
2195
|
+
console.error("[ChatInterface] Error fetching chat history:", error2);
|
|
1896
2196
|
} finally {
|
|
1897
2197
|
setLoadingHistory(false);
|
|
1898
2198
|
}
|
|
1899
2199
|
};
|
|
1900
|
-
(0,
|
|
2200
|
+
(0, import_react11.useEffect)(() => {
|
|
1901
2201
|
if (showHistory && !historyLoaded && config?.userId) {
|
|
1902
2202
|
fetchConversations();
|
|
1903
2203
|
}
|
|
1904
2204
|
}, [showHistory, historyLoaded, config?.userId]);
|
|
1905
|
-
(0,
|
|
2205
|
+
(0, import_react11.useEffect)(() => {
|
|
1906
2206
|
if (!historyLoaded && config?.userId) {
|
|
1907
2207
|
fetchConversations();
|
|
1908
2208
|
}
|
|
1909
2209
|
}, [historyLoaded, config?.userId]);
|
|
1910
|
-
(0,
|
|
2210
|
+
(0, import_react11.useEffect)(() => {
|
|
1911
2211
|
if (tabs.length > 0) {
|
|
1912
2212
|
const timeoutId = setTimeout(() => {
|
|
1913
2213
|
localStorage.setItem(storageKey("tabs"), JSON.stringify(tabs));
|
|
@@ -1916,7 +2216,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1916
2216
|
return () => clearTimeout(timeoutId);
|
|
1917
2217
|
}
|
|
1918
2218
|
}, [tabs, activeTabId, storageKey]);
|
|
1919
|
-
(0,
|
|
2219
|
+
(0, import_react11.useEffect)(() => {
|
|
1920
2220
|
if (hasInitialized.current) return;
|
|
1921
2221
|
const loadInitialTabs = () => {
|
|
1922
2222
|
const savedTabs = localStorage.getItem(storageKey("tabs"));
|
|
@@ -1943,8 +2243,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1943
2243
|
}
|
|
1944
2244
|
hasInitialized.current = true;
|
|
1945
2245
|
}, []);
|
|
1946
|
-
const hasLoadedInitialMessages = (0,
|
|
1947
|
-
(0,
|
|
2246
|
+
const hasLoadedInitialMessages = (0, import_react11.useRef)(false);
|
|
2247
|
+
(0, import_react11.useEffect)(() => {
|
|
1948
2248
|
if (hasLoadedInitialMessages.current) return;
|
|
1949
2249
|
if (!config?.userId) return;
|
|
1950
2250
|
if (!activeTabId) return;
|
|
@@ -1957,14 +2257,14 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
1957
2257
|
}
|
|
1958
2258
|
})();
|
|
1959
2259
|
}, [config?.userId, activeTabId]);
|
|
1960
|
-
(0,
|
|
2260
|
+
(0, import_react11.useEffect)(() => {
|
|
1961
2261
|
if (isInitializing) return;
|
|
1962
2262
|
if (activeTabId && tabs.length > 0 && activeTabId !== lastSyncedTabId.current) {
|
|
1963
2263
|
lastSyncedTabId.current = activeTabId;
|
|
1964
2264
|
setInput("");
|
|
1965
2265
|
}
|
|
1966
2266
|
}, [activeTabId, isInitializing, tabs.length]);
|
|
1967
|
-
const groupedConversations = (0,
|
|
2267
|
+
const groupedConversations = (0, import_react11.useMemo)(() => {
|
|
1968
2268
|
const filtered = conversations.filter(
|
|
1969
2269
|
(conv) => searchQuery === "" || conv.title.toLowerCase().includes(searchQuery.toLowerCase())
|
|
1970
2270
|
);
|
|
@@ -2025,22 +2325,27 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2025
2325
|
const renderMessages = () => messages.map((message, index) => {
|
|
2026
2326
|
const sourceParts = message.parts?.filter((part) => part.type === "source-url") || [];
|
|
2027
2327
|
const fileParts = message.parts?.filter((part) => part.type === "file") || [];
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2328
|
+
const isLastMessage = index === messages.length - 1;
|
|
2329
|
+
const isStreamingThisMessage = isLastMessage && message.role === "assistant" && status !== "ready";
|
|
2330
|
+
const showActions = message.role === "assistant" && !isStreamingThisMessage;
|
|
2331
|
+
const showRegenerate = showActions && isLastMessage && status === "ready";
|
|
2332
|
+
const messageText = showActions ? (message.parts ?? []).filter((p) => p.type === "text").map((p) => p.text).join("\n\n") : "";
|
|
2333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: index > 0 ? "mt-6" : "", children: [
|
|
2334
|
+
message.role === "assistant" && sourceParts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Sources, { children: [
|
|
2335
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SourcesTrigger, { count: sourceParts.length }),
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SourcesContent, { children: sourceParts.map((part, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2032
2337
|
Source,
|
|
2033
2338
|
{
|
|
2034
2339
|
href: part.url,
|
|
2035
2340
|
title: part.url
|
|
2036
2341
|
},
|
|
2037
|
-
`${message.id}-${i}`
|
|
2038
|
-
) }
|
|
2342
|
+
`${message.id}-source-${i}`
|
|
2343
|
+
)) })
|
|
2039
2344
|
] }),
|
|
2040
|
-
fileParts.length > 0 && /* @__PURE__ */ (0,
|
|
2345
|
+
fileParts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn(
|
|
2041
2346
|
"flex mb-1",
|
|
2042
2347
|
message.role === "user" ? "justify-end" : "justify-start"
|
|
2043
|
-
), children: /* @__PURE__ */ (0,
|
|
2348
|
+
), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2044
2349
|
MessageAttachments,
|
|
2045
2350
|
{
|
|
2046
2351
|
attachments: fileParts.map((part) => ({
|
|
@@ -2051,14 +2356,14 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2051
2356
|
}))
|
|
2052
2357
|
}
|
|
2053
2358
|
) }),
|
|
2054
|
-
message.parts ? /* @__PURE__ */ (0,
|
|
2359
|
+
message.parts ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: message.parts.map((part, i) => {
|
|
2055
2360
|
switch (part.type) {
|
|
2056
2361
|
case "text":
|
|
2057
2362
|
const isTextStreaming = status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id;
|
|
2058
|
-
return /* @__PURE__ */ (0,
|
|
2363
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react12.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Message, { from: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MessageContent, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Response, { isStreaming: isTextStreaming, children: part.text }) }) }) }, `${message.id}-${i}`);
|
|
2059
2364
|
case "reasoning":
|
|
2060
2365
|
const isCurrentlyStreaming = status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id;
|
|
2061
|
-
return /* @__PURE__ */ (0,
|
|
2366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2062
2367
|
Reasoning,
|
|
2063
2368
|
{
|
|
2064
2369
|
className: "w-full",
|
|
@@ -2066,8 +2371,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2066
2371
|
defaultOpen: false,
|
|
2067
2372
|
open: isCurrentlyStreaming ? true : void 0,
|
|
2068
2373
|
children: [
|
|
2069
|
-
/* @__PURE__ */ (0,
|
|
2070
|
-
/* @__PURE__ */ (0,
|
|
2374
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReasoningTrigger, {}),
|
|
2375
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReasoningContent, { children: part.text })
|
|
2071
2376
|
]
|
|
2072
2377
|
},
|
|
2073
2378
|
`${message.id}-${i}`
|
|
@@ -2075,8 +2380,24 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2075
2380
|
default:
|
|
2076
2381
|
if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
|
|
2077
2382
|
const toolPart = part;
|
|
2078
|
-
|
|
2079
|
-
|
|
2383
|
+
const resolvedToolName = toolPart.toolName ?? (part.type.startsWith("tool-") ? part.type.slice(5) : "");
|
|
2384
|
+
const customRenderer = config?.toolRenderers?.[resolvedToolName];
|
|
2385
|
+
if (customRenderer) {
|
|
2386
|
+
const rendered = customRenderer({
|
|
2387
|
+
type: part.type,
|
|
2388
|
+
toolName: resolvedToolName,
|
|
2389
|
+
toolCallId: toolPart.toolCallId,
|
|
2390
|
+
state: toolPart.state,
|
|
2391
|
+
input: toolPart.input,
|
|
2392
|
+
output: toolPart.output,
|
|
2393
|
+
errorText: toolPart.errorText
|
|
2394
|
+
});
|
|
2395
|
+
if (rendered !== null && rendered !== void 0) {
|
|
2396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react12.Fragment, { children: rendered }, `${message.id}-${i}`);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tool, { children: [
|
|
2400
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2080
2401
|
ToolHeader,
|
|
2081
2402
|
{
|
|
2082
2403
|
type: part.type,
|
|
@@ -2084,9 +2405,9 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2084
2405
|
state: toolPart.state
|
|
2085
2406
|
}
|
|
2086
2407
|
),
|
|
2087
|
-
/* @__PURE__ */ (0,
|
|
2088
|
-
/* @__PURE__ */ (0,
|
|
2089
|
-
/* @__PURE__ */ (0,
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(ToolContent, { children: [
|
|
2409
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToolInput, { input: toolPart.input }),
|
|
2410
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToolOutput, { output: toolPart.output, errorText: toolPart.errorText })
|
|
2090
2411
|
] })
|
|
2091
2412
|
] }, `${message.id}-${i}`);
|
|
2092
2413
|
}
|
|
@@ -2094,7 +2415,14 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2094
2415
|
}
|
|
2095
2416
|
}) }) : (
|
|
2096
2417
|
/* Handle standard AI SDK messages with content or text property */
|
|
2097
|
-
/* @__PURE__ */ (0,
|
|
2418
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react12.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Message, { from: message.role, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MessageContent, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Response, { children: message.content || message.text }) }) }) }, `${message.id}-content`)
|
|
2419
|
+
),
|
|
2420
|
+
showActions && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2421
|
+
MessageActions,
|
|
2422
|
+
{
|
|
2423
|
+
text: messageText,
|
|
2424
|
+
onRegenerate: showRegenerate && regenerate ? () => regenerate() : void 0
|
|
2425
|
+
}
|
|
2098
2426
|
)
|
|
2099
2427
|
] }, message.id);
|
|
2100
2428
|
});
|
|
@@ -2122,12 +2450,12 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2122
2450
|
setActiveTabId(selectedConversationId);
|
|
2123
2451
|
await loadConversation(selectedConversationId);
|
|
2124
2452
|
setShowHistory(false);
|
|
2125
|
-
} catch (
|
|
2126
|
-
console.error("Error loading conversation:",
|
|
2453
|
+
} catch (error2) {
|
|
2454
|
+
console.error("Error loading conversation:", error2);
|
|
2127
2455
|
}
|
|
2128
2456
|
};
|
|
2129
|
-
const dropdownRef = (0,
|
|
2130
|
-
(0,
|
|
2457
|
+
const dropdownRef = (0, import_react11.useRef)(null);
|
|
2458
|
+
(0, import_react11.useEffect)(() => {
|
|
2131
2459
|
const handleClickOutside = (event) => {
|
|
2132
2460
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
2133
2461
|
setShowHistory(false);
|
|
@@ -2140,7 +2468,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2140
2468
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
2141
2469
|
};
|
|
2142
2470
|
}, [showHistory]);
|
|
2143
|
-
return /* @__PURE__ */ (0,
|
|
2471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2144
2472
|
"div",
|
|
2145
2473
|
{
|
|
2146
2474
|
className: cn(
|
|
@@ -2148,11 +2476,11 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2148
2476
|
themeMode === "dark" && "dark"
|
|
2149
2477
|
),
|
|
2150
2478
|
children: [
|
|
2151
|
-
/* @__PURE__ */ (0,
|
|
2479
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 border-b backdrop-blur-sm relative z-20", style: {
|
|
2152
2480
|
borderColor: "var(--chat-divider)",
|
|
2153
2481
|
backgroundColor: "var(--chat-header-bg)"
|
|
2154
2482
|
}, children: [
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2156
2484
|
"div",
|
|
2157
2485
|
{
|
|
2158
2486
|
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",
|
|
@@ -2175,8 +2503,8 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2175
2503
|
switchToTab(tab.id);
|
|
2176
2504
|
},
|
|
2177
2505
|
children: [
|
|
2178
|
-
/* @__PURE__ */ (0,
|
|
2179
|
-
tabs.length > 1 && /* @__PURE__ */ (0,
|
|
2506
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate max-w-28 text-[13px] font-medium transition-colors", children: tab.title }),
|
|
2507
|
+
tabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2180
2508
|
"button",
|
|
2181
2509
|
{
|
|
2182
2510
|
onClick: (e) => {
|
|
@@ -2195,15 +2523,15 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2195
2523
|
e.currentTarget.style.opacity = tab.isActive ? "0.6" : "0";
|
|
2196
2524
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
2197
2525
|
},
|
|
2198
|
-
children: /* @__PURE__ */ (0,
|
|
2526
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.XIcon, { className: "h-3 w-3", strokeWidth: 2.5 })
|
|
2199
2527
|
}
|
|
2200
2528
|
)
|
|
2201
2529
|
]
|
|
2202
2530
|
},
|
|
2203
2531
|
tab.id
|
|
2204
2532
|
)) }),
|
|
2205
|
-
/* @__PURE__ */ (0,
|
|
2206
|
-
/* @__PURE__ */ (0,
|
|
2533
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-0.5 flex-shrink-0", children: [
|
|
2534
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2207
2535
|
"button",
|
|
2208
2536
|
{
|
|
2209
2537
|
onClick: createNewTab,
|
|
@@ -2220,11 +2548,11 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2220
2548
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
2221
2549
|
},
|
|
2222
2550
|
title: "New Chat",
|
|
2223
|
-
children: /* @__PURE__ */ (0,
|
|
2551
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.PlusIcon, { className: "h-4 w-4", strokeWidth: 2 })
|
|
2224
2552
|
}
|
|
2225
2553
|
),
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2227
|
-
/* @__PURE__ */ (0,
|
|
2554
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative", ref: dropdownRef, children: [
|
|
2555
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2228
2556
|
"button",
|
|
2229
2557
|
{
|
|
2230
2558
|
onClick: () => setShowHistory(!showHistory),
|
|
@@ -2246,17 +2574,17 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2246
2574
|
}
|
|
2247
2575
|
},
|
|
2248
2576
|
title: "Chat History",
|
|
2249
|
-
children: /* @__PURE__ */ (0,
|
|
2577
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.HistoryIcon, { className: "h-4 w-4", strokeWidth: 2 })
|
|
2250
2578
|
}
|
|
2251
2579
|
),
|
|
2252
|
-
showHistory && /* @__PURE__ */ (0,
|
|
2580
|
+
showHistory && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: {
|
|
2253
2581
|
backgroundColor: "hsl(var(--chat-background))",
|
|
2254
2582
|
border: `1px solid ${"var(--chat-divider)"}`
|
|
2255
2583
|
}, children: [
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2584
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "p-2.5 border-b", style: {
|
|
2257
2585
|
borderColor: "var(--chat-divider)",
|
|
2258
2586
|
backgroundColor: "var(--chat-overlay)"
|
|
2259
|
-
}, children: /* @__PURE__ */ (0,
|
|
2587
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2260
2588
|
"input",
|
|
2261
2589
|
{
|
|
2262
2590
|
type: "text",
|
|
@@ -2271,25 +2599,25 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2271
2599
|
}
|
|
2272
2600
|
}
|
|
2273
2601
|
) }) }),
|
|
2274
|
-
/* @__PURE__ */ (0,
|
|
2275
|
-
/* @__PURE__ */ (0,
|
|
2602
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "max-h-[300px] overflow-y-auto ai-assistant-scrollbar", children: loadingHistory ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-[13px]", style: { color: "hsl(var(--chat-text-muted))" }, children: "Loading..." }) }) : conversations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
|
|
2603
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
|
|
2276
2604
|
backgroundColor: "hsl(var(--chat-surface))"
|
|
2277
|
-
}, children: /* @__PURE__ */ (0,
|
|
2278
|
-
/* @__PURE__ */ (0,
|
|
2279
|
-
/* @__PURE__ */ (0,
|
|
2280
|
-
] }) : groupedConversations.length === 0 ? /* @__PURE__ */ (0,
|
|
2281
|
-
/* @__PURE__ */ (0,
|
|
2605
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.MessageSquareIcon, { className: "h-5 w-5", style: { color: "hsl(var(--chat-text-subtle))" }, strokeWidth: 2 }) }),
|
|
2606
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[13px] font-medium mb-0.5", style: { color: "hsl(var(--chat-text))" }, children: "No Conversations" }),
|
|
2607
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[12px]", style: { color: "hsl(var(--chat-text-muted))" }, children: "Start a new chat to begin" })
|
|
2608
|
+
] }) : groupedConversations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 px-4 text-center", children: [
|
|
2609
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-12 h-12 rounded-full flex items-center justify-center mb-3", style: {
|
|
2282
2610
|
backgroundColor: "hsl(var(--chat-surface))"
|
|
2283
|
-
}, children: /* @__PURE__ */ (0,
|
|
2284
|
-
/* @__PURE__ */ (0,
|
|
2285
|
-
/* @__PURE__ */ (0,
|
|
2286
|
-
] }) : /* @__PURE__ */ (0,
|
|
2287
|
-
/* @__PURE__ */ (0,
|
|
2611
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.SearchIcon, { className: "h-5 w-5", style: { color: "hsl(var(--chat-text-subtle))" }, strokeWidth: 2 }) }),
|
|
2612
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[13px] font-medium mb-0.5", style: { color: "hsl(var(--chat-text))" }, children: "No Results" }),
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[12px]", style: { color: "hsl(var(--chat-text-muted))" }, children: "Try a different search" })
|
|
2614
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "py-0.5", children: groupedConversations.map(([groupName, groupConversations]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "mb-0.5", children: [
|
|
2615
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-2.5 py-1 sticky top-0 backdrop-blur-sm z-10", style: {
|
|
2288
2616
|
backgroundColor: "var(--chat-header-bg-strong)"
|
|
2289
|
-
}, children: /* @__PURE__ */ (0,
|
|
2290
|
-
/* @__PURE__ */ (0,
|
|
2617
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[10px] font-semibold uppercase tracking-wide", style: { color: "hsl(var(--chat-text-muted))" }, children: groupName }) }),
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-1 space-y-0.5", children: groupConversations.map((conversation) => {
|
|
2291
2619
|
const isActiveConversation = activeTabId === conversation.id;
|
|
2292
|
-
return /* @__PURE__ */ (0,
|
|
2620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2293
2621
|
"button",
|
|
2294
2622
|
{
|
|
2295
2623
|
className: "w-full px-2 py-1 rounded-md transition-all duration-150 text-left group relative",
|
|
@@ -2307,13 +2635,13 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2307
2635
|
}
|
|
2308
2636
|
},
|
|
2309
2637
|
onClick: () => handleSelectConversation(conversation.id, conversation.title),
|
|
2310
|
-
children: /* @__PURE__ */ (0,
|
|
2311
|
-
/* @__PURE__ */ (0,
|
|
2638
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2639
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[12px] line-clamp-1 transition-colors leading-tight", style: {
|
|
2312
2640
|
fontWeight: isActiveConversation ? 500 : 400,
|
|
2313
2641
|
color: isActiveConversation ? "hsl(var(--chat-text))" : "hsl(var(--chat-text-strong))"
|
|
2314
2642
|
}, children: conversation.title }) }),
|
|
2315
|
-
/* @__PURE__ */ (0,
|
|
2316
|
-
|
|
2643
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2644
|
+
import_lucide_react12.ChevronRightIcon,
|
|
2317
2645
|
{
|
|
2318
2646
|
className: "h-3 w-3 transition-all duration-150 flex-shrink-0",
|
|
2319
2647
|
style: {
|
|
@@ -2332,7 +2660,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2332
2660
|
] })
|
|
2333
2661
|
] }),
|
|
2334
2662
|
headerActions,
|
|
2335
|
-
onClose && /* @__PURE__ */ (0,
|
|
2663
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2336
2664
|
"button",
|
|
2337
2665
|
{
|
|
2338
2666
|
onClick: onClose,
|
|
@@ -2349,21 +2677,21 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2349
2677
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
2350
2678
|
},
|
|
2351
2679
|
title: "Close Chat",
|
|
2352
|
-
children: /* @__PURE__ */ (0,
|
|
2680
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.XIcon, { className: "h-4 w-4", strokeWidth: 2 })
|
|
2353
2681
|
}
|
|
2354
2682
|
)
|
|
2355
2683
|
] })
|
|
2356
2684
|
] }),
|
|
2357
|
-
/* @__PURE__ */ (0,
|
|
2358
|
-
/* @__PURE__ */ (0,
|
|
2685
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Conversation, { className: "flex-1 max-w-full ai-assistant-scrollbar", children: [
|
|
2686
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(ConversationContent, { className: "max-w-[96%] mx-auto py-6", children: [
|
|
2359
2687
|
renderMessages(),
|
|
2360
|
-
status === "submitted" && /* @__PURE__ */ (0,
|
|
2688
|
+
status === "submitted" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Message, { from: "assistant", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MessageContent, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Loader, { size: 16 }) }) }) })
|
|
2361
2689
|
] }),
|
|
2362
|
-
/* @__PURE__ */ (0,
|
|
2690
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ConversationScrollButton, {})
|
|
2363
2691
|
] }),
|
|
2364
|
-
/* @__PURE__ */ (0,
|
|
2365
|
-
uploadError && /* @__PURE__ */ (0,
|
|
2366
|
-
isInitializing || isLoadingMessages ? /* @__PURE__ */ (0,
|
|
2692
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "px-5 pb-5", children: [
|
|
2693
|
+
uploadError && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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 }),
|
|
2694
|
+
isInitializing || isLoadingMessages ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center justify-center py-8", role: "status", "aria-label": "Loading conversation", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(
|
|
2367
2695
|
StarterMessages,
|
|
2368
2696
|
{
|
|
2369
2697
|
prompts: config.starterPrompts,
|
|
@@ -2372,27 +2700,67 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2372
2700
|
}
|
|
2373
2701
|
}
|
|
2374
2702
|
),
|
|
2375
|
-
/* @__PURE__ */ (0,
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2703
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2704
|
+
ChatErrorBanner,
|
|
2705
|
+
{
|
|
2706
|
+
error: error ?? null,
|
|
2707
|
+
canRetry: messages.some((m) => m.role === "user"),
|
|
2708
|
+
onRetry: () => {
|
|
2709
|
+
clearError?.();
|
|
2710
|
+
regenerate?.();
|
|
2711
|
+
},
|
|
2712
|
+
onDismiss: clearError
|
|
2713
|
+
}
|
|
2714
|
+
),
|
|
2715
|
+
inputPlugins.panel,
|
|
2716
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2717
|
+
PromptInput,
|
|
2718
|
+
{
|
|
2719
|
+
onSubmit: handleSubmit,
|
|
2720
|
+
globalDrop: true,
|
|
2721
|
+
multiple: true,
|
|
2722
|
+
accept: config?.features?.fileUploadAccept ?? "image/*",
|
|
2723
|
+
maxFileSize: config?.features?.fileUploadMaxBytes,
|
|
2724
|
+
onError: (err) => {
|
|
2725
|
+
if (err.code === "max_file_size") {
|
|
2726
|
+
setUploadError(
|
|
2727
|
+
config?.features?.fileUploadMaxBytes ? `File too large (max ${Math.floor(
|
|
2728
|
+
config.features.fileUploadMaxBytes / 1024 / 1024
|
|
2729
|
+
)} MB).` : "File too large."
|
|
2730
|
+
);
|
|
2731
|
+
} else if (err.code === "accept") {
|
|
2732
|
+
setUploadError("That file type is not supported.");
|
|
2733
|
+
} else if (err.code === "max_files") {
|
|
2734
|
+
setUploadError("Too many files attached.");
|
|
2735
|
+
}
|
|
2736
|
+
},
|
|
2737
|
+
children: [
|
|
2738
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(PromptInputBody, { children: [
|
|
2739
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptInputAttachments, { children: (attachment) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptInputAttachment, { data: attachment }) }),
|
|
2740
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2741
|
+
PromptInputTextarea,
|
|
2742
|
+
{
|
|
2743
|
+
ref: inputRef,
|
|
2744
|
+
onChange: (e) => setInput(e.target.value),
|
|
2745
|
+
onKeyDown: inputPlugins.onKeyDown,
|
|
2746
|
+
value: input
|
|
2747
|
+
}
|
|
2748
|
+
)
|
|
2749
|
+
] }),
|
|
2750
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(PromptInputToolbar, { children: [
|
|
2751
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptInputTools, { children: config?.features?.fileUpload === true && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AttachButton, {}) }),
|
|
2752
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2753
|
+
PromptInputSubmit,
|
|
2754
|
+
{
|
|
2755
|
+
disabled: status === "streaming" || status === "submitted" ? false : !input,
|
|
2756
|
+
status,
|
|
2757
|
+
onStop: stop
|
|
2758
|
+
}
|
|
2759
|
+
)
|
|
2760
|
+
] })
|
|
2761
|
+
]
|
|
2762
|
+
}
|
|
2763
|
+
)
|
|
2396
2764
|
] })
|
|
2397
2765
|
]
|
|
2398
2766
|
}
|
|
@@ -2400,7 +2768,7 @@ function ChatInterface({ id, initialMessages, config, onClose, headerActions } =
|
|
|
2400
2768
|
}
|
|
2401
2769
|
|
|
2402
2770
|
// src/ChatWidget.tsx
|
|
2403
|
-
var
|
|
2771
|
+
var import_lucide_react13 = require("lucide-react");
|
|
2404
2772
|
|
|
2405
2773
|
// src/utils/color.ts
|
|
2406
2774
|
function toHslTripletIfHex(value) {
|
|
@@ -2438,7 +2806,7 @@ function toHslTripletIfHex(value) {
|
|
|
2438
2806
|
}
|
|
2439
2807
|
|
|
2440
2808
|
// src/ChatWidget.tsx
|
|
2441
|
-
var
|
|
2809
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2442
2810
|
function ChatWidget({
|
|
2443
2811
|
userId,
|
|
2444
2812
|
conversationId,
|
|
@@ -2455,14 +2823,15 @@ function ChatWidget({
|
|
|
2455
2823
|
headerActions,
|
|
2456
2824
|
open,
|
|
2457
2825
|
onOpenChange,
|
|
2458
|
-
inputPlugins
|
|
2826
|
+
inputPlugins,
|
|
2827
|
+
toolRenderers
|
|
2459
2828
|
}) {
|
|
2460
2829
|
const layout = display?.layout || "popup";
|
|
2461
2830
|
const isControlled = open !== void 0;
|
|
2462
2831
|
const showToggleButton = !isControlled && display?.showToggleButton !== false;
|
|
2463
2832
|
const resizable = layout === "popup" && display?.resizable !== false;
|
|
2464
2833
|
const size = display?.size || "default";
|
|
2465
|
-
const [internalIsOpen, setInternalIsOpen] = (0,
|
|
2834
|
+
const [internalIsOpen, setInternalIsOpen] = (0, import_react14.useState)(
|
|
2466
2835
|
layout !== "popup" ? true : display?.defaultOpen || false
|
|
2467
2836
|
);
|
|
2468
2837
|
const isOpen = isControlled ? open : internalIsOpen;
|
|
@@ -2473,9 +2842,9 @@ function ChatWidget({
|
|
|
2473
2842
|
setInternalIsOpen(next);
|
|
2474
2843
|
}
|
|
2475
2844
|
};
|
|
2476
|
-
const [isResizing, setIsResizing] = (0,
|
|
2477
|
-
const containerRef = (0,
|
|
2478
|
-
const customStyles = (0,
|
|
2845
|
+
const [isResizing, setIsResizing] = (0, import_react14.useState)(false);
|
|
2846
|
+
const containerRef = (0, import_react14.useRef)(null);
|
|
2847
|
+
const customStyles = (0, import_react14.useMemo)(() => {
|
|
2479
2848
|
const styles = {};
|
|
2480
2849
|
if (display?.width) {
|
|
2481
2850
|
styles["--chat-widget-width"] = display.width;
|
|
@@ -2494,14 +2863,14 @@ function ChatWidget({
|
|
|
2494
2863
|
}
|
|
2495
2864
|
return styles;
|
|
2496
2865
|
}, [display?.width, theme?.primaryColor, theme?.backgroundColor, theme?.textColor, theme?.tokens]);
|
|
2497
|
-
const handleMouseDown = (0,
|
|
2866
|
+
const handleMouseDown = (0, import_react14.useCallback)((e) => {
|
|
2498
2867
|
if (!resizable) return;
|
|
2499
2868
|
e.preventDefault();
|
|
2500
2869
|
setIsResizing(true);
|
|
2501
2870
|
document.body.style.cursor = "ew-resize";
|
|
2502
2871
|
document.body.style.userSelect = "none";
|
|
2503
2872
|
}, [resizable]);
|
|
2504
|
-
(0,
|
|
2873
|
+
(0, import_react14.useEffect)(() => {
|
|
2505
2874
|
if (!isResizing) return;
|
|
2506
2875
|
const handleMouseMove = (e) => {
|
|
2507
2876
|
if (!containerRef.current) return;
|
|
@@ -2523,7 +2892,7 @@ function ChatWidget({
|
|
|
2523
2892
|
document.removeEventListener("mouseup", handleMouseUp);
|
|
2524
2893
|
};
|
|
2525
2894
|
}, [isResizing]);
|
|
2526
|
-
const config = (0,
|
|
2895
|
+
const config = (0, import_react14.useMemo)(() => ({
|
|
2527
2896
|
userId,
|
|
2528
2897
|
model,
|
|
2529
2898
|
systemPrompt,
|
|
@@ -2531,18 +2900,19 @@ function ChatWidget({
|
|
|
2531
2900
|
theme,
|
|
2532
2901
|
features,
|
|
2533
2902
|
starterPrompts,
|
|
2534
|
-
inputPlugins
|
|
2535
|
-
|
|
2903
|
+
inputPlugins,
|
|
2904
|
+
toolRenderers
|
|
2905
|
+
}), [userId, model, systemPrompt, temperature, theme, features, starterPrompts, inputPlugins, toolRenderers]);
|
|
2536
2906
|
const togglePosition = display?.toggleButtonPosition || { bottom: "24px", right: "24px" };
|
|
2537
2907
|
const themeClass = theme?.mode === "dark" ? "dark" : "";
|
|
2538
2908
|
if (layout === "inline") {
|
|
2539
|
-
return /* @__PURE__ */ (0,
|
|
2909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatStorageProvider, { userId, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2540
2910
|
"div",
|
|
2541
2911
|
{
|
|
2542
2912
|
ref: containerRef,
|
|
2543
2913
|
className: `chat-widget-container chat-widget-inline chat-widget-content ${themeClass} ${className || ""}`,
|
|
2544
2914
|
style: customStyles,
|
|
2545
|
-
children: /* @__PURE__ */ (0,
|
|
2915
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2546
2916
|
ChatInterface,
|
|
2547
2917
|
{
|
|
2548
2918
|
id: conversationId,
|
|
@@ -2556,13 +2926,13 @@ function ChatWidget({
|
|
|
2556
2926
|
) });
|
|
2557
2927
|
}
|
|
2558
2928
|
if (layout === "page") {
|
|
2559
|
-
return /* @__PURE__ */ (0,
|
|
2929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatStorageProvider, { userId, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2560
2930
|
"div",
|
|
2561
2931
|
{
|
|
2562
2932
|
ref: containerRef,
|
|
2563
2933
|
className: `chat-widget-container chat-widget-page chat-widget-content ${themeClass} ${className || ""}`,
|
|
2564
2934
|
style: customStyles,
|
|
2565
|
-
children: /* @__PURE__ */ (0,
|
|
2935
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2566
2936
|
ChatInterface,
|
|
2567
2937
|
{
|
|
2568
2938
|
id: conversationId,
|
|
@@ -2575,18 +2945,18 @@ function ChatWidget({
|
|
|
2575
2945
|
}
|
|
2576
2946
|
) });
|
|
2577
2947
|
}
|
|
2578
|
-
return /* @__PURE__ */ (0,
|
|
2579
|
-
showToggleButton && !isOpen && /* @__PURE__ */ (0,
|
|
2948
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ChatStorageProvider, { userId, children: [
|
|
2949
|
+
showToggleButton && !isOpen && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2580
2950
|
"button",
|
|
2581
2951
|
{
|
|
2582
2952
|
onClick: () => setIsOpen(true),
|
|
2583
2953
|
className: "fixed z-50 rounded-full bg-primary text-primary-foreground shadow-lg hover:opacity-90 transition-all p-4",
|
|
2584
2954
|
style: togglePosition,
|
|
2585
2955
|
"aria-label": "Open chat",
|
|
2586
|
-
children: /* @__PURE__ */ (0,
|
|
2956
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.MessageCircle, { className: "h-6 w-6" })
|
|
2587
2957
|
}
|
|
2588
2958
|
),
|
|
2589
|
-
isOpen && /* @__PURE__ */ (0,
|
|
2959
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2590
2960
|
"div",
|
|
2591
2961
|
{
|
|
2592
2962
|
ref: containerRef,
|
|
@@ -2595,7 +2965,7 @@ function ChatWidget({
|
|
|
2595
2965
|
"data-resizing": isResizing,
|
|
2596
2966
|
style: customStyles,
|
|
2597
2967
|
children: [
|
|
2598
|
-
resizable && /* @__PURE__ */ (0,
|
|
2968
|
+
resizable && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2599
2969
|
"div",
|
|
2600
2970
|
{
|
|
2601
2971
|
onMouseDown: handleMouseDown,
|
|
@@ -2603,7 +2973,7 @@ function ChatWidget({
|
|
|
2603
2973
|
"aria-label": "Resize chat widget"
|
|
2604
2974
|
}
|
|
2605
2975
|
),
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2976
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-full h-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2607
2977
|
ChatInterface,
|
|
2608
2978
|
{
|
|
2609
2979
|
id: conversationId,
|
|
@@ -2624,7 +2994,7 @@ function ChatWidget({
|
|
|
2624
2994
|
var ChatWidget_default = ChatWidget;
|
|
2625
2995
|
|
|
2626
2996
|
// src/hooks/use-chat-theme.ts
|
|
2627
|
-
var
|
|
2997
|
+
var import_react15 = require("react");
|
|
2628
2998
|
|
|
2629
2999
|
// src/utils/models.ts
|
|
2630
3000
|
var MODELS = [
|
|
@@ -2744,13 +3114,13 @@ var defaultThemeMode = "light";
|
|
|
2744
3114
|
function useChatTheme() {
|
|
2745
3115
|
const { storageKeyPrefix } = useChatStorageKey();
|
|
2746
3116
|
const keyPrefix = storageKeyPrefix ? `chat-${storageKeyPrefix}-` : "chat-";
|
|
2747
|
-
const [theme, setTheme] = (0,
|
|
2748
|
-
const [conversationStarters, setConversationStarters] = (0,
|
|
2749
|
-
const [model, setModel] = (0,
|
|
2750
|
-
const [systemPrompt, setSystemPrompt] = (0,
|
|
2751
|
-
const [temperature, setTemperature] = (0,
|
|
2752
|
-
const [themeMode, setThemeMode] = (0,
|
|
2753
|
-
(0,
|
|
3117
|
+
const [theme, setTheme] = (0, import_react15.useState)(defaultTheme);
|
|
3118
|
+
const [conversationStarters, setConversationStarters] = (0, import_react15.useState)(defaultConversationStarters);
|
|
3119
|
+
const [model, setModel] = (0, import_react15.useState)(defaultModel);
|
|
3120
|
+
const [systemPrompt, setSystemPrompt] = (0, import_react15.useState)(defaultSystemPrompt);
|
|
3121
|
+
const [temperature, setTemperature] = (0, import_react15.useState)(defaultTemperature);
|
|
3122
|
+
const [themeMode, setThemeMode] = (0, import_react15.useState)(defaultThemeMode);
|
|
3123
|
+
(0, import_react15.useEffect)(() => {
|
|
2754
3124
|
const savedTheme = localStorage.getItem(`${keyPrefix}theme`);
|
|
2755
3125
|
if (savedTheme) {
|
|
2756
3126
|
try {
|
|
@@ -2838,7 +3208,7 @@ function useChatTheme() {
|
|
|
2838
3208
|
window.removeEventListener("chat-theme-mode-change", handleThemeModeChange);
|
|
2839
3209
|
};
|
|
2840
3210
|
}, [keyPrefix]);
|
|
2841
|
-
(0,
|
|
3211
|
+
(0, import_react15.useEffect)(() => {
|
|
2842
3212
|
localStorage.setItem(`${keyPrefix}theme`, JSON.stringify(theme));
|
|
2843
3213
|
const root = document.documentElement;
|
|
2844
3214
|
if (themeMode === "light") {
|
|
@@ -2854,23 +3224,23 @@ function useChatTheme() {
|
|
|
2854
3224
|
root.style.setProperty("--chat-font-size", `${theme.fontSize}px`);
|
|
2855
3225
|
window.dispatchEvent(new CustomEvent("chat-theme-change", { detail: theme }));
|
|
2856
3226
|
}, [theme, themeMode, keyPrefix]);
|
|
2857
|
-
(0,
|
|
3227
|
+
(0, import_react15.useEffect)(() => {
|
|
2858
3228
|
localStorage.setItem(`${keyPrefix}conversation-starters`, JSON.stringify(conversationStarters));
|
|
2859
3229
|
window.dispatchEvent(new CustomEvent("chat-starters-change", { detail: conversationStarters }));
|
|
2860
3230
|
}, [conversationStarters, keyPrefix]);
|
|
2861
|
-
(0,
|
|
3231
|
+
(0, import_react15.useEffect)(() => {
|
|
2862
3232
|
localStorage.setItem(`${keyPrefix}model`, model);
|
|
2863
3233
|
window.dispatchEvent(new CustomEvent("chat-model-change", { detail: model }));
|
|
2864
3234
|
}, [model, keyPrefix]);
|
|
2865
|
-
(0,
|
|
3235
|
+
(0, import_react15.useEffect)(() => {
|
|
2866
3236
|
localStorage.setItem(`${keyPrefix}system-prompt`, systemPrompt);
|
|
2867
3237
|
window.dispatchEvent(new CustomEvent("chat-system-prompt-change", { detail: systemPrompt }));
|
|
2868
3238
|
}, [systemPrompt, keyPrefix]);
|
|
2869
|
-
(0,
|
|
3239
|
+
(0, import_react15.useEffect)(() => {
|
|
2870
3240
|
localStorage.setItem(`${keyPrefix}temperature`, temperature.toString());
|
|
2871
3241
|
window.dispatchEvent(new CustomEvent("chat-temperature-change", { detail: temperature }));
|
|
2872
3242
|
}, [temperature, keyPrefix]);
|
|
2873
|
-
(0,
|
|
3243
|
+
(0, import_react15.useEffect)(() => {
|
|
2874
3244
|
localStorage.setItem(`${keyPrefix}theme-mode`, themeMode);
|
|
2875
3245
|
window.dispatchEvent(new CustomEvent("chat-theme-mode-change", { detail: themeMode }));
|
|
2876
3246
|
}, [themeMode, keyPrefix]);
|
|
@@ -2940,10 +3310,10 @@ function useChatTheme() {
|
|
|
2940
3310
|
|
|
2941
3311
|
// src/ui/input.tsx
|
|
2942
3312
|
var React3 = __toESM(require("react"));
|
|
2943
|
-
var
|
|
3313
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2944
3314
|
var Input = React3.forwardRef(
|
|
2945
3315
|
({ className, type, ...props }, ref) => {
|
|
2946
|
-
return /* @__PURE__ */ (0,
|
|
3316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2947
3317
|
"input",
|
|
2948
3318
|
{
|
|
2949
3319
|
type,
|
|
@@ -2961,23 +3331,23 @@ Input.displayName = "Input";
|
|
|
2961
3331
|
|
|
2962
3332
|
// src/ui/dialog.tsx
|
|
2963
3333
|
var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
|
|
2964
|
-
var
|
|
2965
|
-
var
|
|
3334
|
+
var import_lucide_react14 = require("lucide-react");
|
|
3335
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2966
3336
|
function Dialog({
|
|
2967
3337
|
...props
|
|
2968
3338
|
}) {
|
|
2969
|
-
return /* @__PURE__ */ (0,
|
|
3339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
2970
3340
|
}
|
|
2971
3341
|
function DialogPortal({
|
|
2972
3342
|
...props
|
|
2973
3343
|
}) {
|
|
2974
|
-
return /* @__PURE__ */ (0,
|
|
3344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
2975
3345
|
}
|
|
2976
3346
|
function DialogOverlay({
|
|
2977
3347
|
className,
|
|
2978
3348
|
...props
|
|
2979
3349
|
}) {
|
|
2980
|
-
return /* @__PURE__ */ (0,
|
|
3350
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2981
3351
|
DialogPrimitive.Overlay,
|
|
2982
3352
|
{
|
|
2983
3353
|
"data-slot": "dialog-overlay",
|
|
@@ -2995,9 +3365,9 @@ function DialogContent({
|
|
|
2995
3365
|
showCloseButton = true,
|
|
2996
3366
|
...props
|
|
2997
3367
|
}) {
|
|
2998
|
-
return /* @__PURE__ */ (0,
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3000
|
-
/* @__PURE__ */ (0,
|
|
3368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
3369
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogOverlay, {}),
|
|
3370
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3001
3371
|
DialogPrimitive.Content,
|
|
3002
3372
|
{
|
|
3003
3373
|
"data-slot": "dialog-content",
|
|
@@ -3008,14 +3378,14 @@ function DialogContent({
|
|
|
3008
3378
|
...props,
|
|
3009
3379
|
children: [
|
|
3010
3380
|
children,
|
|
3011
|
-
showCloseButton && /* @__PURE__ */ (0,
|
|
3381
|
+
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3012
3382
|
DialogPrimitive.Close,
|
|
3013
3383
|
{
|
|
3014
3384
|
"data-slot": "dialog-close",
|
|
3015
3385
|
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",
|
|
3016
3386
|
children: [
|
|
3017
|
-
/* @__PURE__ */ (0,
|
|
3018
|
-
/* @__PURE__ */ (0,
|
|
3387
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.XIcon, {}),
|
|
3388
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "sr-only", children: "Close" })
|
|
3019
3389
|
]
|
|
3020
3390
|
}
|
|
3021
3391
|
)
|
|
@@ -3025,7 +3395,7 @@ function DialogContent({
|
|
|
3025
3395
|
] });
|
|
3026
3396
|
}
|
|
3027
3397
|
function DialogHeader({ className, ...props }) {
|
|
3028
|
-
return /* @__PURE__ */ (0,
|
|
3398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3029
3399
|
"div",
|
|
3030
3400
|
{
|
|
3031
3401
|
"data-slot": "dialog-header",
|
|
@@ -3038,7 +3408,7 @@ function DialogTitle({
|
|
|
3038
3408
|
className,
|
|
3039
3409
|
...props
|
|
3040
3410
|
}) {
|
|
3041
|
-
return /* @__PURE__ */ (0,
|
|
3411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3042
3412
|
DialogPrimitive.Title,
|
|
3043
3413
|
{
|
|
3044
3414
|
"data-slot": "dialog-title",
|
|
@@ -3051,7 +3421,7 @@ function DialogDescription({
|
|
|
3051
3421
|
className,
|
|
3052
3422
|
...props
|
|
3053
3423
|
}) {
|
|
3054
|
-
return /* @__PURE__ */ (0,
|
|
3424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3055
3425
|
DialogPrimitive.Description,
|
|
3056
3426
|
{
|
|
3057
3427
|
"data-slot": "dialog-description",
|
|
@@ -3073,6 +3443,11 @@ function DialogDescription({
|
|
|
3073
3443
|
Input,
|
|
3074
3444
|
StarterMessageItem,
|
|
3075
3445
|
StarterMessages,
|
|
3446
|
+
Tool,
|
|
3447
|
+
ToolContent,
|
|
3448
|
+
ToolHeader,
|
|
3449
|
+
ToolInput,
|
|
3450
|
+
ToolOutput,
|
|
3076
3451
|
fontOptions,
|
|
3077
3452
|
useChatStorageKey,
|
|
3078
3453
|
useChatTheme
|