@copilotz/chat-ui 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/chat/ChatUI.tsx
2
- import { useState as useState8, useEffect as useEffect7, useRef as useRef4, useCallback as useCallback4 } from "react";
2
+ import { useState as useState8, useEffect as useEffect10, useRef as useRef7, useCallback as useCallback4 } from "react";
3
3
 
4
4
  // src/config/chatConfig.ts
5
5
  var defaultChatConfig = {
@@ -9,6 +9,11 @@ var defaultChatConfig = {
9
9
  title: "Chat Assistant",
10
10
  subtitle: "How can I help you today?"
11
11
  },
12
+ agentSelector: {
13
+ enabled: false,
14
+ label: "Select agent",
15
+ hideIfSingle: true
16
+ },
12
17
  labels: {
13
18
  inputPlaceholder: "Type your message...",
14
19
  sendButton: "Send",
@@ -101,6 +106,10 @@ function mergeConfig(_baseConfig, userConfig) {
101
106
  ...defaultChatConfig.ui,
102
107
  ...userConfig.ui
103
108
  },
109
+ agentSelector: {
110
+ ...defaultChatConfig.agentSelector,
111
+ ...userConfig.agentSelector
112
+ },
104
113
  customComponent: userConfig.customComponent || defaultChatConfig.customComponent,
105
114
  headerActions: userConfig.headerActions || defaultChatConfig.headerActions
106
115
  };
@@ -228,9 +237,10 @@ var configUtils = {
228
237
  };
229
238
 
230
239
  // src/components/chat/Message.tsx
231
- import { useState, useRef } from "react";
240
+ import { useState, useRef, memo, Component } from "react";
232
241
  import ReactMarkdown from "react-markdown";
233
242
  import remarkGfm from "remark-gfm";
243
+ import remarkBreaks from "remark-breaks";
234
244
  import rehypeHighlight from "rehype-highlight";
235
245
 
236
246
  // src/components/ui/button.tsx
@@ -521,7 +531,25 @@ import {
521
531
  ChevronDown
522
532
  } from "lucide-react";
523
533
  import { Fragment, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
524
- var ThinkingIndicator = ({ label = "Thinking..." }) => {
534
+ var MarkdownErrorBoundary = class extends Component {
535
+ constructor(props) {
536
+ super(props);
537
+ this.state = { hasError: false };
538
+ }
539
+ static getDerivedStateFromError(_error) {
540
+ return { hasError: true };
541
+ }
542
+ componentDidCatch(error, errorInfo) {
543
+ console.warn("[Markdown] Falling back to simple rendering due to:", error.message);
544
+ }
545
+ render() {
546
+ if (this.state.hasError) {
547
+ return this.props.fallback;
548
+ }
549
+ return this.props.children;
550
+ }
551
+ };
552
+ var ThinkingIndicator = memo(function ThinkingIndicator2({ label = "Thinking..." }) {
525
553
  return /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 py-2", children: [
526
554
  /* @__PURE__ */ jsxs2("div", { className: "flex gap-1", children: [
527
555
  /* @__PURE__ */ jsx7(
@@ -548,36 +576,61 @@ var ThinkingIndicator = ({ label = "Thinking..." }) => {
548
576
  ] }),
549
577
  /* @__PURE__ */ jsx7("span", { className: "text-sm text-muted-foreground animate-pulse", children: label })
550
578
  ] });
579
+ });
580
+ var markdownComponents = {
581
+ code: ({ node, className, children, ...props }) => {
582
+ const inline = props.inline;
583
+ const match = /language-(\w+)/.exec(className || "");
584
+ return !inline && match ? /* @__PURE__ */ jsx7("pre", { className: "relative", children: /* @__PURE__ */ jsx7("code", { className, ...props, children }) }) : /* @__PURE__ */ jsx7("code", { className: "bg-muted px-1 py-0.5 rounded text-sm", ...props, children });
585
+ }
551
586
  };
552
- var StreamingText = ({
587
+ var remarkPluginsWithGfm = [remarkGfm, remarkBreaks];
588
+ var remarkPluginsSimple = [remarkBreaks];
589
+ var rehypePluginsDefault = [rehypeHighlight];
590
+ var rehypePluginsEmpty = [];
591
+ var SimpleMarkdown = memo(function SimpleMarkdown2({
592
+ content,
593
+ isStreaming = false
594
+ }) {
595
+ return /* @__PURE__ */ jsx7(
596
+ ReactMarkdown,
597
+ {
598
+ remarkPlugins: remarkPluginsSimple,
599
+ rehypePlugins: isStreaming ? rehypePluginsEmpty : rehypePluginsDefault,
600
+ components: markdownComponents,
601
+ children: content
602
+ }
603
+ );
604
+ });
605
+ var FullMarkdown = memo(function FullMarkdown2({
606
+ content,
607
+ isStreaming = false
608
+ }) {
609
+ return /* @__PURE__ */ jsx7(
610
+ ReactMarkdown,
611
+ {
612
+ remarkPlugins: remarkPluginsWithGfm,
613
+ rehypePlugins: isStreaming ? rehypePluginsEmpty : rehypePluginsDefault,
614
+ components: markdownComponents,
615
+ children: content
616
+ }
617
+ );
618
+ });
619
+ var StreamingText = memo(function StreamingText2({
553
620
  content,
554
621
  isStreaming = false,
555
622
  thinkingLabel = "Thinking..."
556
- }) => {
623
+ }) {
557
624
  const hasContent = content.trim().length > 0;
558
625
  return /* @__PURE__ */ jsxs2("div", { className: "prose prose-sm max-w-none dark:prose-invert", children: [
559
- hasContent ? /* @__PURE__ */ jsx7(
560
- ReactMarkdown,
561
- {
562
- remarkPlugins: [remarkGfm],
563
- rehypePlugins: isStreaming ? [] : [rehypeHighlight],
564
- components: {
565
- code: ({ node, className, children, ...props }) => {
566
- const inline = props.inline;
567
- const match = /language-(\w+)/.exec(className || "");
568
- return !inline && match ? /* @__PURE__ */ jsx7("pre", { className: "relative", children: /* @__PURE__ */ jsx7("code", { className, ...props, children }) }) : /* @__PURE__ */ jsx7("code", { className: "bg-muted px-1 py-0.5 rounded text-sm", ...props, children });
569
- }
570
- },
571
- children: content
572
- }
573
- ) : isStreaming ? (
626
+ hasContent ? /* @__PURE__ */ jsx7(MarkdownErrorBoundary, { fallback: /* @__PURE__ */ jsx7(SimpleMarkdown, { content, isStreaming }), children: /* @__PURE__ */ jsx7(FullMarkdown, { content, isStreaming }) }) : isStreaming ? (
574
627
  // Show thinking indicator while waiting for first token
575
628
  /* @__PURE__ */ jsx7(ThinkingIndicator, { label: thinkingLabel })
576
629
  ) : null,
577
630
  isStreaming && hasContent && /* @__PURE__ */ jsx7("span", { className: "inline-block w-2 h-4 bg-primary animate-pulse ml-1" })
578
631
  ] });
579
- };
580
- var MediaRenderer = ({ attachment }) => {
632
+ });
633
+ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
581
634
  const [isPlaying, setIsPlaying] = useState(false);
582
635
  const audioRef = useRef(null);
583
636
  const videoRef = useRef(null);
@@ -651,8 +704,8 @@ var MediaRenderer = ({ attachment }) => {
651
704
  default:
652
705
  return null;
653
706
  }
654
- };
655
- var ToolCallsDisplay = ({ toolCalls, label }) => {
707
+ });
708
+ var ToolCallsDisplay = memo(function ToolCallsDisplay2({ toolCalls, label }) {
656
709
  const [expandedCall, setExpandedCall] = useState(null);
657
710
  const getStatusIcon = (status) => {
658
711
  switch (status) {
@@ -721,8 +774,48 @@ var ToolCallsDisplay = ({ toolCalls, label }) => {
721
774
  ] }, call.id);
722
775
  })
723
776
  ] });
777
+ });
778
+ var arePropsEqual = (prevProps, nextProps) => {
779
+ if (prevProps.message.id !== nextProps.message.id) return false;
780
+ if (prevProps.message.content !== nextProps.message.content) return false;
781
+ if (prevProps.message.isStreaming !== nextProps.message.isStreaming) return false;
782
+ if (prevProps.message.isComplete !== nextProps.message.isComplete) return false;
783
+ if (prevProps.message.isEdited !== nextProps.message.isEdited) return false;
784
+ if (prevProps.message.timestamp !== nextProps.message.timestamp) return false;
785
+ if (prevProps.message.toolCalls !== nextProps.message.toolCalls) {
786
+ const prevCalls = prevProps.message.toolCalls;
787
+ const nextCalls = nextProps.message.toolCalls;
788
+ if (!prevCalls || !nextCalls || prevCalls.length !== nextCalls.length) return false;
789
+ for (let i = 0; i < prevCalls.length; i++) {
790
+ if (prevCalls[i].id !== nextCalls[i].id || prevCalls[i].status !== nextCalls[i].status || prevCalls[i].result !== nextCalls[i].result) {
791
+ return false;
792
+ }
793
+ }
794
+ }
795
+ if (prevProps.message.attachments !== nextProps.message.attachments) {
796
+ const prevAtt = prevProps.message.attachments;
797
+ const nextAtt = nextProps.message.attachments;
798
+ if (!prevAtt || !nextAtt || prevAtt.length !== nextAtt.length) return false;
799
+ }
800
+ if (prevProps.isUser !== nextProps.isUser) return false;
801
+ if (prevProps.userAvatar !== nextProps.userAvatar) return false;
802
+ if (prevProps.userName !== nextProps.userName) return false;
803
+ if (prevProps.assistantName !== nextProps.assistantName) return false;
804
+ if (prevProps.showTimestamp !== nextProps.showTimestamp) return false;
805
+ if (prevProps.showAvatar !== nextProps.showAvatar) return false;
806
+ if (prevProps.enableCopy !== nextProps.enableCopy) return false;
807
+ if (prevProps.enableEdit !== nextProps.enableEdit) return false;
808
+ if (prevProps.enableRegenerate !== nextProps.enableRegenerate) return false;
809
+ if (prevProps.enableToolCallsDisplay !== nextProps.enableToolCallsDisplay) return false;
810
+ if (prevProps.compactMode !== nextProps.compactMode) return false;
811
+ if (prevProps.className !== nextProps.className) return false;
812
+ if (prevProps.toolUsedLabel !== nextProps.toolUsedLabel) return false;
813
+ if (prevProps.thinkingLabel !== nextProps.thinkingLabel) return false;
814
+ if (prevProps.isGrouped !== nextProps.isGrouped) return false;
815
+ if (prevProps.assistantAvatar !== nextProps.assistantAvatar) return false;
816
+ return true;
724
817
  };
725
- var Message = ({
818
+ var Message = memo(({
726
819
  message,
727
820
  isUser,
728
821
  userAvatar,
@@ -739,7 +832,8 @@ var Message = ({
739
832
  onAction,
740
833
  className = "",
741
834
  toolUsedLabel,
742
- thinkingLabel = "Thinking..."
835
+ thinkingLabel = "Thinking...",
836
+ isGrouped = false
743
837
  }) => {
744
838
  const [isEditing, setIsEditing] = useState(false);
745
839
  const [editContent, setEditContent] = useState(message.content);
@@ -789,7 +883,7 @@ var Message = ({
789
883
  onMouseEnter: () => setShowActions(true),
790
884
  onMouseLeave: () => setShowActions(false),
791
885
  children: [
792
- /* @__PURE__ */ jsxs2("div", { className: `flex gap-3 ${messageIsUser ? "flex-row-reverse" : "flex-row"} w-full mb-1`, children: [
886
+ !isGrouped && /* @__PURE__ */ jsxs2("div", { className: `flex gap-3 ${messageIsUser ? "flex-row-reverse" : "flex-row"} w-full mb-1`, children: [
793
887
  showAvatar && /* @__PURE__ */ jsx7("div", { className: `flex-shrink-0 ${compactMode ? "mt-1" : "mt-0"}`, children: /* @__PURE__ */ jsx7(Avatar, { className: compactMode ? "h-6 w-6" : "h-8 w-8", children: messageIsUser ? /* @__PURE__ */ jsxs2(Fragment, { children: [
794
888
  /* @__PURE__ */ jsx7(AvatarImage, { src: userAvatar, alt: userName }),
795
889
  /* @__PURE__ */ jsx7(AvatarFallback, { className: "bg-primary text-primary-foreground", children: userName.charAt(0).toUpperCase() })
@@ -800,7 +894,7 @@ var Message = ({
800
894
  message.isEdited && /* @__PURE__ */ jsx7(Badge, { variant: "outline", className: "text-xs", children: "editado" })
801
895
  ] })
802
896
  ] }),
803
- /* @__PURE__ */ jsx7("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"}`, children: /* @__PURE__ */ jsxs2("div", { className: `relative inline-flex flex-col ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-[85%]"}`, children: [
897
+ /* @__PURE__ */ jsx7("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${isGrouped && showAvatar && !messageIsUser ? compactMode ? "ml-9" : "ml-11" : ""} ${isGrouped && showAvatar && messageIsUser ? compactMode ? "mr-9" : "mr-11" : ""}`, children: /* @__PURE__ */ jsxs2("div", { className: `relative inline-flex flex-col ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-[85%]"}`, children: [
804
898
  isEditing ? /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
805
899
  /* @__PURE__ */ jsx7(
806
900
  Textarea,
@@ -878,10 +972,10 @@ var Message = ({
878
972
  ]
879
973
  }
880
974
  ) });
881
- };
975
+ }, arePropsEqual);
882
976
 
883
977
  // src/components/chat/Sidebar.tsx
884
- import { useState as useState4, useRef as useRef2, useEffect as useEffect4 } from "react";
978
+ import { useState as useState4, useRef as useRef5, useEffect as useEffect7 } from "react";
885
979
 
886
980
  // src/components/ui/input.tsx
887
981
  import { jsx as jsx8 } from "react/jsx-runtime";
@@ -903,7 +997,7 @@ function Input({ className, type, ...props }) {
903
997
  }
904
998
 
905
999
  // src/components/ui/sidebar.tsx
906
- import * as React3 from "react";
1000
+ import * as React4 from "react";
907
1001
  import { Slot as Slot3 } from "@radix-ui/react-slot";
908
1002
  import { cva as cva3 } from "class-variance-authority";
909
1003
  import { PanelLeftIcon } from "lucide-react";
@@ -911,18 +1005,26 @@ import { PanelLeftIcon } from "lucide-react";
911
1005
  // src/hooks/use-mobile.ts
912
1006
  import * as React2 from "react";
913
1007
  var MOBILE_BREAKPOINT = 768;
1008
+ function getInitialIsMobile() {
1009
+ if (typeof window === "undefined") return false;
1010
+ return window.innerWidth < MOBILE_BREAKPOINT;
1011
+ }
914
1012
  function useIsMobile() {
915
- const [isMobile, setIsMobile] = React2.useState(void 0);
1013
+ const [isMobile, setIsMobile] = React2.useState(getInitialIsMobile);
916
1014
  React2.useEffect(() => {
917
1015
  const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
918
1016
  const onChange = () => {
919
1017
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
920
1018
  };
921
1019
  mql.addEventListener("change", onChange);
1020
+ window.addEventListener("resize", onChange);
922
1021
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
923
- return () => mql.removeEventListener("change", onChange);
1022
+ return () => {
1023
+ mql.removeEventListener("change", onChange);
1024
+ window.removeEventListener("resize", onChange);
1025
+ };
924
1026
  }, []);
925
- return !!isMobile;
1027
+ return isMobile;
926
1028
  }
927
1029
 
928
1030
  // src/components/ui/separator.tsx
@@ -950,11 +1052,30 @@ function Separator({
950
1052
  }
951
1053
 
952
1054
  // src/components/ui/sheet.tsx
1055
+ import * as React3 from "react";
953
1056
  import * as SheetPrimitive from "@radix-ui/react-dialog";
954
1057
  import { XIcon } from "lucide-react";
955
1058
  import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
956
- function Sheet({ ...props }) {
957
- return /* @__PURE__ */ jsx10(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
1059
+ function cleanupBodyStyles() {
1060
+ if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
1061
+ document.body.style.pointerEvents = "";
1062
+ }
1063
+ }
1064
+ function Sheet({ open, onOpenChange, ...props }) {
1065
+ const prevOpenRef = React3.useRef(open);
1066
+ React3.useEffect(() => {
1067
+ if (prevOpenRef.current === true && open === false) {
1068
+ const timeout = setTimeout(cleanupBodyStyles, 350);
1069
+ return () => clearTimeout(timeout);
1070
+ }
1071
+ prevOpenRef.current = open;
1072
+ }, [open]);
1073
+ React3.useEffect(() => {
1074
+ return () => {
1075
+ cleanupBodyStyles();
1076
+ };
1077
+ }, []);
1078
+ return /* @__PURE__ */ jsx10(SheetPrimitive.Root, { "data-slot": "sheet", open, onOpenChange, ...props });
958
1079
  }
959
1080
  function SheetPortal({
960
1081
  ...props
@@ -970,7 +1091,10 @@ function SheetOverlay({
970
1091
  {
971
1092
  "data-slot": "sheet-overlay",
972
1093
  className: cn(
973
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1094
+ "fixed inset-0 z-50 bg-black/50",
1095
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
1096
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
1097
+ "data-[state=closed]:pointer-events-none",
974
1098
  className
975
1099
  ),
976
1100
  ...props
@@ -989,6 +1113,7 @@ function SheetContent({
989
1113
  SheetPrimitive.Content,
990
1114
  {
991
1115
  "data-slot": "sheet-content",
1116
+ "aria-describedby": void 0,
992
1117
  className: cn(
993
1118
  "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
994
1119
  side === "right" && "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
@@ -1054,9 +1179,9 @@ var SIDEBAR_WIDTH = "16rem";
1054
1179
  var SIDEBAR_WIDTH_MOBILE = "18rem";
1055
1180
  var SIDEBAR_WIDTH_ICON = "3rem";
1056
1181
  var SIDEBAR_KEYBOARD_SHORTCUT = "b";
1057
- var SidebarContext = React3.createContext(null);
1182
+ var SidebarContext = React4.createContext(null);
1058
1183
  function useSidebar() {
1059
- const context = React3.useContext(SidebarContext);
1184
+ const context = React4.useContext(SidebarContext);
1060
1185
  if (!context) {
1061
1186
  throw new Error("useSidebar must be used within a SidebarProvider.");
1062
1187
  }
@@ -1072,10 +1197,10 @@ function SidebarProvider({
1072
1197
  ...props
1073
1198
  }) {
1074
1199
  const isMobile = useIsMobile();
1075
- const [openMobile, setOpenMobile] = React3.useState(false);
1076
- const [_open, _setOpen] = React3.useState(defaultOpen);
1200
+ const [openMobile, setOpenMobile] = React4.useState(false);
1201
+ const [_open, _setOpen] = React4.useState(defaultOpen);
1077
1202
  const open = openProp ?? _open;
1078
- const setOpen = React3.useCallback(
1203
+ const setOpen = React4.useCallback(
1079
1204
  (value) => {
1080
1205
  const openState = typeof value === "function" ? value(open) : value;
1081
1206
  if (setOpenProp) {
@@ -1087,10 +1212,10 @@ function SidebarProvider({
1087
1212
  },
1088
1213
  [setOpenProp, open]
1089
1214
  );
1090
- const toggleSidebar = React3.useCallback(() => {
1215
+ const toggleSidebar = React4.useCallback(() => {
1091
1216
  return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
1092
1217
  }, [isMobile, setOpen, setOpenMobile]);
1093
- React3.useEffect(() => {
1218
+ React4.useEffect(() => {
1094
1219
  const handleKeyDown = (event) => {
1095
1220
  if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
1096
1221
  event.preventDefault();
@@ -1101,7 +1226,7 @@ function SidebarProvider({
1101
1226
  return () => window.removeEventListener("keydown", handleKeyDown);
1102
1227
  }, [toggleSidebar]);
1103
1228
  const state = open ? "expanded" : "collapsed";
1104
- const contextValue = React3.useMemo(
1229
+ const contextValue = React4.useMemo(
1105
1230
  () => ({
1106
1231
  state,
1107
1232
  open,
@@ -1176,12 +1301,29 @@ function Sidebar({
1176
1301
  }
1177
1302
  ) });
1178
1303
  }
1304
+ const isCollapsed = state === "collapsed";
1305
+ const currentCollapsible = isCollapsed ? collapsible : "";
1306
+ const getGapWidth = () => {
1307
+ if (currentCollapsible === "offcanvas") return "0px";
1308
+ if (currentCollapsible === "icon") return SIDEBAR_WIDTH_ICON;
1309
+ return SIDEBAR_WIDTH;
1310
+ };
1311
+ const getContainerWidth = () => {
1312
+ if (currentCollapsible === "icon") return SIDEBAR_WIDTH_ICON;
1313
+ return SIDEBAR_WIDTH;
1314
+ };
1315
+ const getContainerOffset = () => {
1316
+ if (currentCollapsible === "offcanvas") {
1317
+ return side === "left" ? `calc(${SIDEBAR_WIDTH} * -1)` : `calc(${SIDEBAR_WIDTH} * -1)`;
1318
+ }
1319
+ return "0";
1320
+ };
1179
1321
  return /* @__PURE__ */ jsxs4(
1180
1322
  "div",
1181
1323
  {
1182
- className: "group peer text-sidebar-foreground hidden md:block",
1324
+ className: "group peer text-sidebar-foreground",
1183
1325
  "data-state": state,
1184
- "data-collapsible": state === "collapsed" ? collapsible : "",
1326
+ "data-collapsible": currentCollapsible,
1185
1327
  "data-variant": variant,
1186
1328
  "data-side": side,
1187
1329
  "data-slot": "sidebar",
@@ -1191,11 +1333,10 @@ function Sidebar({
1191
1333
  {
1192
1334
  "data-slot": "sidebar-gap",
1193
1335
  className: cn(
1194
- "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
1195
- "group-data-[collapsible=offcanvas]:w-0",
1196
- "group-data-[side=right]:rotate-180",
1197
- variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
1198
- )
1336
+ "relative bg-transparent transition-[width] duration-200 ease-linear",
1337
+ "group-data-[side=right]:rotate-180"
1338
+ ),
1339
+ style: { width: getGapWidth() }
1199
1340
  }
1200
1341
  ),
1201
1342
  /* @__PURE__ */ jsx11(
@@ -1203,12 +1344,16 @@ function Sidebar({
1203
1344
  {
1204
1345
  "data-slot": "sidebar-container",
1205
1346
  className: cn(
1206
- "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
1207
- side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
1347
+ "fixed inset-y-0 z-10 h-screen transition-[left,right,width] duration-200 ease-linear",
1208
1348
  // Adjust the padding for floating and inset variants.
1209
- variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
1349
+ variant === "floating" || variant === "inset" ? "p-2" : side === "left" ? "border-r" : "border-l",
1210
1350
  className
1211
1351
  ),
1352
+ style: {
1353
+ display: "flex",
1354
+ width: getContainerWidth(),
1355
+ [side === "left" ? "left" : "right"]: getContainerOffset()
1356
+ },
1212
1357
  ...props,
1213
1358
  children: /* @__PURE__ */ jsx11(
1214
1359
  "div",
@@ -1231,6 +1376,15 @@ function SidebarTrigger({
1231
1376
  ...props
1232
1377
  }) {
1233
1378
  const { toggleSidebar } = useSidebar();
1379
+ const handleActivation = React4.useCallback((event) => {
1380
+ if (event.type === "touchend") {
1381
+ event.preventDefault();
1382
+ }
1383
+ if ("onClick" in event && onClick) {
1384
+ onClick(event);
1385
+ }
1386
+ toggleSidebar();
1387
+ }, [onClick, toggleSidebar]);
1234
1388
  return /* @__PURE__ */ jsxs4(
1235
1389
  Button,
1236
1390
  {
@@ -1239,10 +1393,8 @@ function SidebarTrigger({
1239
1393
  variant: "ghost",
1240
1394
  size: "icon",
1241
1395
  className: cn("size-7", className),
1242
- onClick: (event) => {
1243
- onClick?.(event);
1244
- toggleSidebar();
1245
- },
1396
+ onClick: handleActivation,
1397
+ onTouchEnd: handleActivation,
1246
1398
  ...props,
1247
1399
  children: [
1248
1400
  /* @__PURE__ */ jsx11(PanelLeftIcon, {}),
@@ -1484,13 +1636,34 @@ function SidebarMenuAction({
1484
1636
  }
1485
1637
 
1486
1638
  // src/components/ui/dialog.tsx
1639
+ import * as React5 from "react";
1487
1640
  import * as DialogPrimitive from "@radix-ui/react-dialog";
1488
1641
  import { XIcon as XIcon2 } from "lucide-react";
1489
1642
  import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
1643
+ function cleanupBodyStyles2() {
1644
+ if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
1645
+ document.body.style.pointerEvents = "";
1646
+ }
1647
+ }
1490
1648
  function Dialog({
1649
+ open,
1650
+ onOpenChange,
1491
1651
  ...props
1492
1652
  }) {
1493
- return /* @__PURE__ */ jsx12(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
1653
+ const prevOpenRef = React5.useRef(open);
1654
+ React5.useEffect(() => {
1655
+ if (prevOpenRef.current === true && open === false) {
1656
+ const timeout = setTimeout(cleanupBodyStyles2, 250);
1657
+ return () => clearTimeout(timeout);
1658
+ }
1659
+ prevOpenRef.current = open;
1660
+ }, [open]);
1661
+ React5.useEffect(() => {
1662
+ return () => {
1663
+ cleanupBodyStyles2();
1664
+ };
1665
+ }, []);
1666
+ return /* @__PURE__ */ jsx12(DialogPrimitive.Root, { "data-slot": "dialog", open, onOpenChange, ...props });
1494
1667
  }
1495
1668
  function DialogTrigger({
1496
1669
  ...props
@@ -1511,7 +1684,10 @@ function DialogOverlay({
1511
1684
  {
1512
1685
  "data-slot": "dialog-overlay",
1513
1686
  className: cn(
1514
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1687
+ "fixed inset-0 z-50 bg-black/50",
1688
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
1689
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
1690
+ "data-[state=closed]:pointer-events-none",
1515
1691
  className
1516
1692
  ),
1517
1693
  ...props
@@ -1530,6 +1706,7 @@ function DialogContent({
1530
1706
  DialogPrimitive.Content,
1531
1707
  {
1532
1708
  "data-slot": "dialog-content",
1709
+ "aria-describedby": void 0,
1533
1710
  className: cn(
1534
1711
  "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
1535
1712
  className
@@ -1604,12 +1781,33 @@ function DialogDescription({
1604
1781
  }
1605
1782
 
1606
1783
  // src/components/ui/alert-dialog.tsx
1784
+ import * as React6 from "react";
1607
1785
  import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
1608
1786
  import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
1787
+ function cleanupBodyStyles3() {
1788
+ if (typeof document !== "undefined" && document.body.style.pointerEvents === "none") {
1789
+ document.body.style.pointerEvents = "";
1790
+ }
1791
+ }
1609
1792
  function AlertDialog({
1793
+ open,
1794
+ onOpenChange,
1610
1795
  ...props
1611
1796
  }) {
1612
- return /* @__PURE__ */ jsx13(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
1797
+ const prevOpenRef = React6.useRef(open);
1798
+ React6.useEffect(() => {
1799
+ if (prevOpenRef.current === true && open === false) {
1800
+ const timeout = setTimeout(cleanupBodyStyles3, 250);
1801
+ return () => clearTimeout(timeout);
1802
+ }
1803
+ prevOpenRef.current = open;
1804
+ }, [open]);
1805
+ React6.useEffect(() => {
1806
+ return () => {
1807
+ cleanupBodyStyles3();
1808
+ };
1809
+ }, []);
1810
+ return /* @__PURE__ */ jsx13(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", open, onOpenChange, ...props });
1613
1811
  }
1614
1812
  function AlertDialogPortal({
1615
1813
  ...props
@@ -1625,7 +1823,10 @@ function AlertDialogOverlay({
1625
1823
  {
1626
1824
  "data-slot": "alert-dialog-overlay",
1627
1825
  className: cn(
1628
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1826
+ "fixed inset-0 z-50 bg-black/50",
1827
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
1828
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
1829
+ "data-[state=closed]:pointer-events-none",
1629
1830
  className
1630
1831
  ),
1631
1832
  ...props
@@ -1829,7 +2030,8 @@ import {
1829
2030
  Trash2,
1830
2031
  Archive,
1831
2032
  Search,
1832
- Filter
2033
+ Filter,
2034
+ Bot
1833
2035
  } from "lucide-react";
1834
2036
 
1835
2037
  // src/components/chat/UserMenu.tsx
@@ -2044,9 +2246,9 @@ var Sidebar2 = ({
2044
2246
  const [deleteThreadId, setDeleteThreadId] = useState4(null);
2045
2247
  const [editingThreadId, setEditingThreadId] = useState4(null);
2046
2248
  const [editTitle, setEditTitle] = useState4("");
2047
- const inputRef = useRef2(null);
2249
+ const inputRef = useRef5(null);
2048
2250
  const { setOpen } = useSidebar();
2049
- useEffect4(() => {
2251
+ useEffect7(() => {
2050
2252
  if (editingThreadId && inputRef.current) {
2051
2253
  inputRef.current.focus();
2052
2254
  inputRef.current.select();
@@ -2099,6 +2301,13 @@ var Sidebar2 = ({
2099
2301
  };
2100
2302
  return /* @__PURE__ */ jsxs9(Sidebar, { collapsible: "icon", ...props, children: [
2101
2303
  /* @__PURE__ */ jsxs9(SidebarHeader, { children: [
2304
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 px-2 py-3", children: [
2305
+ /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center shrink-0", children: config.branding?.logo || /* @__PURE__ */ jsx16(Avatar, { className: "h-8 w-8", children: /* @__PURE__ */ jsx16(AvatarFallback, { className: "bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx16(Bot, { className: "h-4 w-4" }) }) }) }),
2306
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-col min-w-0 group-data-[collapsible=icon]:hidden", children: [
2307
+ /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold truncate", children: config.branding?.title || "Chat" }),
2308
+ config.branding?.subtitle && /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground truncate", children: config.branding.subtitle })
2309
+ ] })
2310
+ ] }),
2102
2311
  onCreateThread && /* @__PURE__ */ jsx16(
2103
2312
  CreateThreadDialog,
2104
2313
  {
@@ -2118,7 +2327,7 @@ var Sidebar2 = ({
2118
2327
  ) }) })
2119
2328
  }
2120
2329
  ),
2121
- /* @__PURE__ */ jsxs9("div", { className: "px-2 py-1 mt-6", children: [
2330
+ /* @__PURE__ */ jsxs9("div", { className: "px-2 py-1 mt-4", children: [
2122
2331
  /* @__PURE__ */ jsxs9("div", { className: "relative group-data-[collapsible=icon]:hidden", children: [
2123
2332
  /* @__PURE__ */ jsx16(Search, { className: "pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50" }),
2124
2333
  /* @__PURE__ */ jsx16(
@@ -2233,7 +2442,7 @@ var Sidebar2 = ({
2233
2442
  }
2234
2443
  ) }),
2235
2444
  /* @__PURE__ */ jsx16(SidebarRail, {}),
2236
- /* @__PURE__ */ jsx16(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs9(AlertDialogContent, { children: [
2445
+ deleteThreadId && /* @__PURE__ */ jsx16(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs9(AlertDialogContent, { children: [
2237
2446
  /* @__PURE__ */ jsxs9(AlertDialogHeader, { children: [
2238
2447
  /* @__PURE__ */ jsx16(AlertDialogTitle, { children: config.labels?.deleteConfirmTitle || "Delete Conversation" }),
2239
2448
  /* @__PURE__ */ jsx16(AlertDialogDescription, { children: config.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
@@ -2254,9 +2463,9 @@ var Sidebar2 = ({
2254
2463
  };
2255
2464
 
2256
2465
  // src/components/chat/ChatHeader.tsx
2257
- import React5 from "react";
2466
+ import React8 from "react";
2258
2467
  import {
2259
- Bot,
2468
+ Bot as Bot2,
2260
2469
  MoreVertical,
2261
2470
  Download,
2262
2471
  Upload,
@@ -2264,7 +2473,9 @@ import {
2264
2473
  Plus as Plus2,
2265
2474
  Menu,
2266
2475
  Moon as Moon2,
2267
- Sun as Sun2
2476
+ Sun as Sun2,
2477
+ ChevronDown as ChevronDown2,
2478
+ Check as Check2
2268
2479
  } from "lucide-react";
2269
2480
  import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
2270
2481
  var ChatHeader = ({
@@ -2278,13 +2489,17 @@ var ChatHeader = ({
2278
2489
  onClearAll,
2279
2490
  showCustomComponentButton,
2280
2491
  isMobile,
2492
+ showAgentSelector = false,
2493
+ agentOptions = [],
2494
+ selectedAgentId = null,
2495
+ onSelectAgent,
2281
2496
  className = ""
2282
2497
  }) => {
2283
- const [isDarkMode, setIsDarkMode] = React5.useState(() => {
2498
+ const [isDarkMode, setIsDarkMode] = React8.useState(() => {
2284
2499
  if (typeof window === "undefined") return false;
2285
2500
  return document.documentElement.classList.contains("dark");
2286
2501
  });
2287
- React5.useEffect(() => {
2502
+ React8.useEffect(() => {
2288
2503
  const observer = new MutationObserver(() => {
2289
2504
  setIsDarkMode(document.documentElement.classList.contains("dark"));
2290
2505
  });
@@ -2328,22 +2543,64 @@ var ChatHeader = ({
2328
2543
  };
2329
2544
  input.click();
2330
2545
  };
2546
+ const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;
2547
+ const agentPlaceholder = config.agentSelector?.label || "Select agent";
2331
2548
  return /* @__PURE__ */ jsx17(
2332
2549
  Card,
2333
2550
  {
2334
2551
  "data-chat-header": true,
2335
2552
  className: `py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 ${className}`,
2336
2553
  style: isMobile ? { paddingTop: "env(safe-area-inset-top)" } : void 0,
2337
- children: /* @__PURE__ */ jsx17(CardHeader, { className: "p-2", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between", children: [
2338
- /* @__PURE__ */ jsx17("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxs10(Tooltip, { children: [
2339
- /* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx17(SidebarTrigger, { className: "-ml-1" }) }),
2340
- /* @__PURE__ */ jsx17(TooltipContent, { children: config.labels?.sidebarToggle || "Toggle Sidebar" })
2341
- ] }) }),
2342
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3 flex-1 justify-center", children: [
2343
- config.branding?.logo || /* @__PURE__ */ jsx17(Avatar, { className: "h-8 w-8", children: /* @__PURE__ */ jsx17(AvatarFallback, { children: /* @__PURE__ */ jsx17(Bot, { className: "h-4 w-4" }) }) }),
2344
- /* @__PURE__ */ jsx17("div", { className: "text-center hidden md:block", children: /* @__PURE__ */ jsx17(CardTitle, { className: "text-sm font-medium", children: config.branding?.title || "Chat Assistant" }) }),
2345
- /* @__PURE__ */ jsx17("div", { className: "md:hidden text-sm font-medium truncate max-w-[150px]", children: currentThreadTitle || config.branding?.title || "Chat" })
2554
+ children: /* @__PURE__ */ jsx17(CardHeader, { className: "p-2", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-2", children: [
2555
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
2556
+ /* @__PURE__ */ jsxs10(Tooltip, { children: [
2557
+ /* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx17(SidebarTrigger, { className: "-ml-1" }) }),
2558
+ /* @__PURE__ */ jsx17(TooltipContent, { children: config.labels?.sidebarToggle || "Toggle Sidebar" })
2559
+ ] }),
2560
+ showAgentSelector && /* @__PURE__ */ jsxs10(DropdownMenu, { children: [
2561
+ /* @__PURE__ */ jsx17(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
2562
+ Button,
2563
+ {
2564
+ variant: "ghost",
2565
+ className: "h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50",
2566
+ children: [
2567
+ selectedAgent?.avatarUrl ? /* @__PURE__ */ jsxs10(Avatar, { className: "h-5 w-5", children: [
2568
+ /* @__PURE__ */ jsx17(AvatarImage, { src: selectedAgent.avatarUrl, alt: selectedAgent.name }),
2569
+ /* @__PURE__ */ jsx17(AvatarFallback, { className: "text-[10px]", children: selectedAgent.name.charAt(0).toUpperCase() })
2570
+ ] }) : null,
2571
+ /* @__PURE__ */ jsx17("span", { className: "max-w-[200px] truncate", children: selectedAgent?.name || agentPlaceholder }),
2572
+ /* @__PURE__ */ jsx17(ChevronDown2, { className: "h-4 w-4 opacity-50" })
2573
+ ]
2574
+ }
2575
+ ) }),
2576
+ /* @__PURE__ */ jsx17(DropdownMenuContent, { align: "start", className: "w-[280px]", children: agentOptions.map((agent) => {
2577
+ const isSelected = agent.id === selectedAgentId;
2578
+ return /* @__PURE__ */ jsxs10(
2579
+ DropdownMenuItem,
2580
+ {
2581
+ onClick: () => onSelectAgent?.(agent.id),
2582
+ className: "flex items-start gap-3 p-3 cursor-pointer",
2583
+ children: [
2584
+ agent.avatarUrl ? /* @__PURE__ */ jsxs10(Avatar, { className: "h-6 w-6 mt-0.5 shrink-0", children: [
2585
+ /* @__PURE__ */ jsx17(AvatarImage, { src: agent.avatarUrl, alt: agent.name }),
2586
+ /* @__PURE__ */ jsx17(AvatarFallback, { className: "text-[10px]", children: agent.name.charAt(0).toUpperCase() })
2587
+ ] }) : /* @__PURE__ */ jsx17("div", { className: "h-6 w-6 mt-0.5 shrink-0 flex items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx17(Bot2, { className: "h-3.5 w-3.5 text-primary" }) }),
2588
+ /* @__PURE__ */ jsxs10("div", { className: "flex-1 min-w-0", children: [
2589
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
2590
+ /* @__PURE__ */ jsx17("span", { className: "font-medium text-sm", children: agent.name }),
2591
+ isSelected && /* @__PURE__ */ jsx17(Check2, { className: "h-4 w-4 text-primary shrink-0" })
2592
+ ] }),
2593
+ agent.description && /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground mt-0.5 line-clamp-2", children: agent.description })
2594
+ ] })
2595
+ ]
2596
+ },
2597
+ agent.id
2598
+ );
2599
+ }) })
2600
+ ] }),
2601
+ !showAgentSelector && isMobile && /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium truncate max-w-[150px] ml-2", children: currentThreadTitle || config.branding?.title || "Chat" })
2346
2602
  ] }),
2603
+ /* @__PURE__ */ jsx17("div", { className: "flex-1" }),
2347
2604
  /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
2348
2605
  showCustomComponentButton && config.customComponent && /* @__PURE__ */ jsxs10(Tooltip, { children: [
2349
2606
  /* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx17(
@@ -2408,10 +2665,10 @@ var ChatHeader = ({
2408
2665
  };
2409
2666
 
2410
2667
  // src/components/chat/ChatInput.tsx
2411
- import { useState as useState6, useRef as useRef3, useCallback as useCallback3, useEffect as useEffect6 } from "react";
2668
+ import { useState as useState6, useRef as useRef6, useCallback as useCallback3, useEffect as useEffect9, memo as memo2 } from "react";
2412
2669
 
2413
2670
  // src/components/chat/UserContext.tsx
2414
- import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo2, useState as useState5 } from "react";
2671
+ import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo2, useState as useState5 } from "react";
2415
2672
  import { jsx as jsx18 } from "react/jsx-runtime";
2416
2673
  var Ctx = createContext2(void 0);
2417
2674
  var ChatUserContextProvider = ({ children, initial }) => {
@@ -2419,7 +2676,7 @@ var ChatUserContextProvider = ({ children, initial }) => {
2419
2676
  updatedAt: Date.now(),
2420
2677
  ...initial ?? {}
2421
2678
  }));
2422
- useEffect5(() => {
2679
+ useEffect8(() => {
2423
2680
  if (!initial) return;
2424
2681
  setCtx((prev) => ({
2425
2682
  ...prev,
@@ -2490,7 +2747,7 @@ import {
2490
2747
  Loader2
2491
2748
  } from "lucide-react";
2492
2749
  import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
2493
- var FileUploadItem = ({ file, progress, onCancel }) => {
2750
+ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }) {
2494
2751
  const guessTypeFromName = (name) => {
2495
2752
  const ext = (name || "").split(".").pop()?.toLowerCase();
2496
2753
  switch (ext) {
@@ -2548,10 +2805,10 @@ var FileUploadItem = ({ file, progress, onCancel }) => {
2548
2805
  }
2549
2806
  )
2550
2807
  ] }) }) });
2551
- };
2552
- var AttachmentPreview = ({ attachment, onRemove }) => {
2808
+ });
2809
+ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove }) {
2553
2810
  const [isPlaying, setIsPlaying] = useState6(false);
2554
- const audioRef = useRef3(null);
2811
+ const audioRef = useRef6(null);
2555
2812
  const handlePlayPause = () => {
2556
2813
  if (audioRef.current) {
2557
2814
  if (isPlaying) {
@@ -2649,8 +2906,8 @@ var AttachmentPreview = ({ attachment, onRemove }) => {
2649
2906
  ] }),
2650
2907
  attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ jsx20("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ jsx20("p", { className: "truncate", children: attachment.fileName }) })
2651
2908
  ] }) });
2652
- };
2653
- var AudioRecorder = ({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) => {
2909
+ });
2910
+ var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
2654
2911
  const formatTime = (seconds) => {
2655
2912
  const mins = Math.floor(seconds / 60);
2656
2913
  const secs = seconds % 60;
@@ -2704,8 +2961,8 @@ var AudioRecorder = ({ isRecording, onStartRecording, onStopRecording, onCancel,
2704
2961
  )
2705
2962
  ] })
2706
2963
  ] }) }) });
2707
- };
2708
- var ChatInput = ({
2964
+ });
2965
+ var ChatInput = memo2(function ChatInput2({
2709
2966
  value,
2710
2967
  onChange,
2711
2968
  onSubmit,
@@ -2723,18 +2980,18 @@ var ChatInput = ({
2723
2980
  acceptedFileTypes = ["image/*", "video/*", "audio/*"],
2724
2981
  className = "",
2725
2982
  config
2726
- }) => {
2983
+ }) {
2727
2984
  const [isRecording, setIsRecording] = useState6(false);
2728
2985
  const { setContext } = useChatUserContext();
2729
2986
  const [recordingDuration, setRecordingDuration] = useState6(0);
2730
2987
  const [uploadProgress, setUploadProgress] = useState6(/* @__PURE__ */ new Map());
2731
- const textareaRef = useRef3(null);
2732
- const fileInputRef = useRef3(null);
2733
- const mediaRecorderRef = useRef3(null);
2734
- const recordingStartTime = useRef3(0);
2735
- const recordingInterval = useRef3(null);
2736
- const mediaStreamRef = useRef3(null);
2737
- useEffect6(() => {
2988
+ const textareaRef = useRef6(null);
2989
+ const fileInputRef = useRef6(null);
2990
+ const mediaRecorderRef = useRef6(null);
2991
+ const recordingStartTime = useRef6(0);
2992
+ const recordingInterval = useRef6(null);
2993
+ const mediaStreamRef = useRef6(null);
2994
+ useEffect9(() => {
2738
2995
  return () => {
2739
2996
  if (mediaStreamRef.current) {
2740
2997
  mediaStreamRef.current.getTracks().forEach((track) => track.stop());
@@ -3065,16 +3322,16 @@ var ChatInput = ({
3065
3322
  ] })
3066
3323
  ] })
3067
3324
  ] }) }) });
3068
- };
3325
+ });
3069
3326
 
3070
3327
  // src/components/chat/UserProfile.tsx
3071
3328
  import { useState as useState7 } from "react";
3072
3329
 
3073
3330
  // src/components/ui/scroll-area.tsx
3074
- import * as React8 from "react";
3331
+ import * as React11 from "react";
3075
3332
  import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3076
3333
  import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
3077
- var ScrollArea = React8.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
3334
+ var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
3078
3335
  return /* @__PURE__ */ jsxs12(
3079
3336
  ScrollAreaPrimitive.Root,
3080
3337
  {
@@ -3154,9 +3411,9 @@ import {
3154
3411
  Lightbulb,
3155
3412
  Info,
3156
3413
  Heart,
3157
- Bot as Bot2,
3414
+ Bot as Bot3,
3158
3415
  Pencil,
3159
- Check as Check2,
3416
+ Check as Check3,
3160
3417
  X as X3
3161
3418
  } from "lucide-react";
3162
3419
  import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -3423,7 +3680,7 @@ var UserProfile = ({
3423
3680
  {
3424
3681
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
3425
3682
  children: [
3426
- /* @__PURE__ */ jsx22("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ jsx22(Bot2, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
3683
+ /* @__PURE__ */ jsx22("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ jsx22(Bot3, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
3427
3684
  /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3428
3685
  /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 mb-0.5", children: [
3429
3686
  /* @__PURE__ */ jsx22("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
@@ -3470,7 +3727,7 @@ var UserProfile = ({
3470
3727
  onClick: handleSaveEdit,
3471
3728
  disabled: !editingMemoryContent.trim(),
3472
3729
  children: [
3473
- /* @__PURE__ */ jsx22(Check2, { className: "h-3.5 w-3.5 mr-1" }),
3730
+ /* @__PURE__ */ jsx22(Check3, { className: "h-3.5 w-3.5 mr-1" }),
3474
3731
  "Salvar"
3475
3732
  ]
3476
3733
  }
@@ -3533,7 +3790,7 @@ var UserProfile = ({
3533
3790
  };
3534
3791
 
3535
3792
  // src/components/chat/ChatUI.tsx
3536
- import { Sparkles } from "lucide-react";
3793
+ import { Sparkles, ArrowRight, MessageSquare, Lightbulb as Lightbulb2, Zap, HelpCircle } from "lucide-react";
3537
3794
  import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
3538
3795
  var ChatUI = ({
3539
3796
  messages = [],
@@ -3546,10 +3803,16 @@ var ChatUI = ({
3546
3803
  user,
3547
3804
  assistant,
3548
3805
  suggestions = [],
3806
+ messageSuggestions = {},
3807
+ agentOptions = [],
3808
+ selectedAgentId = null,
3809
+ onSelectAgent,
3549
3810
  className = "",
3550
3811
  onAddMemory,
3551
3812
  onUpdateMemory,
3552
- onDeleteMemory
3813
+ onDeleteMemory,
3814
+ initialInput,
3815
+ onInitialInputConsumed
3553
3816
  }) => {
3554
3817
  const config = mergeConfig(defaultChatConfig, userConfig);
3555
3818
  const [isMobile, setIsMobile] = useState8(false);
@@ -3567,9 +3830,9 @@ var ChatUI = ({
3567
3830
  }
3568
3831
  return false;
3569
3832
  };
3833
+ const [inputValue, setInputValue] = useState8("");
3834
+ const [attachments, setAttachments] = useState8([]);
3570
3835
  const [state, setState] = useState8({
3571
- input: "",
3572
- attachments: [],
3573
3836
  isRecording: false,
3574
3837
  selectedThreadId: currentThreadId,
3575
3838
  isAtBottom: true,
@@ -3581,23 +3844,48 @@ var ChatUI = ({
3581
3844
  isSidebarCollapsed: false
3582
3845
  // No longer used for main sidebar
3583
3846
  });
3584
- useEffect7(() => {
3847
+ useEffect10(() => {
3585
3848
  if (currentThreadId !== state.selectedThreadId) {
3586
3849
  setState((prev) => ({ ...prev, selectedThreadId: currentThreadId }));
3587
3850
  }
3588
3851
  }, [currentThreadId]);
3589
- const messagesEndRef = useRef4(null);
3590
- const scrollAreaRef = useRef4(null);
3852
+ const initialInputApplied = useRef7(false);
3853
+ const initialInputConsumedRef = useRef7(false);
3854
+ useEffect10(() => {
3855
+ if (initialInput && !initialInputApplied.current) {
3856
+ setInputValue(initialInput);
3857
+ initialInputApplied.current = true;
3858
+ }
3859
+ }, [initialInput]);
3860
+ const messagesEndRef = useRef7(null);
3861
+ const scrollAreaRef = useRef7(null);
3862
+ const stateRef = useRef7(state);
3863
+ const inputValueRef = useRef7(inputValue);
3864
+ const attachmentsRef = useRef7(attachments);
3865
+ useEffect10(() => {
3866
+ stateRef.current = state;
3867
+ }, [state]);
3868
+ useEffect10(() => {
3869
+ inputValueRef.current = inputValue;
3870
+ }, [inputValue]);
3871
+ useEffect10(() => {
3872
+ attachmentsRef.current = attachments;
3873
+ }, [attachments]);
3591
3874
  const [isCustomMounted, setIsCustomMounted] = useState8(false);
3592
3875
  const [isCustomVisible, setIsCustomVisible] = useState8(false);
3593
3876
  const createStateCallback = useCallback4(
3594
3877
  (setter) => ({
3595
3878
  setState: (newState) => setter?.(newState),
3596
- getState: () => state
3879
+ getState: () => ({
3880
+ ...stateRef.current,
3881
+ input: inputValueRef.current,
3882
+ attachments: attachmentsRef.current
3883
+ })
3597
3884
  }),
3598
- [state]
3885
+ []
3886
+ // No dependencies - uses refs for latest state
3599
3887
  );
3600
- useEffect7(() => {
3888
+ useEffect10(() => {
3601
3889
  const checkMobile = () => {
3602
3890
  setIsMobile(globalThis.innerWidth < 1024);
3603
3891
  };
@@ -3605,7 +3893,7 @@ var ChatUI = ({
3605
3893
  globalThis.addEventListener("resize", checkMobile);
3606
3894
  return () => globalThis.removeEventListener("resize", checkMobile);
3607
3895
  }, []);
3608
- useEffect7(() => {
3896
+ useEffect10(() => {
3609
3897
  if (!isMobile || !config.customComponent?.component) return;
3610
3898
  if (state.showSidebar) {
3611
3899
  setIsCustomMounted(true);
@@ -3616,7 +3904,7 @@ var ChatUI = ({
3616
3904
  return () => clearTimeout(t);
3617
3905
  }
3618
3906
  }, [state.showSidebar, isMobile, config.customComponent]);
3619
- useEffect7(() => {
3907
+ useEffect10(() => {
3620
3908
  if (!state.isAtBottom) return;
3621
3909
  const viewport = scrollAreaRef.current;
3622
3910
  if (!viewport) return;
@@ -3632,15 +3920,16 @@ var ChatUI = ({
3632
3920
  const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;
3633
3921
  setState((prev) => ({ ...prev, isAtBottom }));
3634
3922
  }, []);
3635
- const handleSendMessage = useCallback4((content, attachments = []) => {
3636
- if (!content.trim() && attachments.length === 0) return;
3637
- callbacks.onSendMessage?.(content, attachments, createStateCallback());
3638
- setState((prev) => ({
3639
- ...prev,
3640
- input: "",
3641
- attachments: []
3642
- }));
3643
- }, [callbacks, createStateCallback]);
3923
+ const handleSendMessage = useCallback4((content, messageAttachments = []) => {
3924
+ if (!content.trim() && messageAttachments.length === 0) return;
3925
+ callbacks.onSendMessage?.(content, messageAttachments, createStateCallback());
3926
+ if (initialInputApplied.current && !initialInputConsumedRef.current) {
3927
+ initialInputConsumedRef.current = true;
3928
+ onInitialInputConsumed?.();
3929
+ }
3930
+ setInputValue("");
3931
+ setAttachments([]);
3932
+ }, [callbacks, createStateCallback, onInitialInputConsumed]);
3644
3933
  const handleMessageAction = useCallback4((event) => {
3645
3934
  const { action, messageId, content } = event;
3646
3935
  switch (action) {
@@ -3661,7 +3950,7 @@ var ChatUI = ({
3661
3950
  }
3662
3951
  }, [callbacks, createStateCallback]);
3663
3952
  const handleCreateThread = useCallback4((title) => {
3664
- callbacks.onCreateThread?.(title, createStateCallback(setState));
3953
+ callbacks.onCreateThread?.(title, createStateCallback());
3665
3954
  }, [callbacks, createStateCallback]);
3666
3955
  const handleSelectThread = useCallback4((threadId) => {
3667
3956
  callbacks.onSelectThread?.(threadId, createStateCallback());
@@ -3686,23 +3975,54 @@ var ChatUI = ({
3686
3975
  }
3687
3976
  return component;
3688
3977
  }, [config?.customComponent?.component, closeSidebar, isMobile]);
3978
+ const SuggestionIconComponents = [MessageSquare, Lightbulb2, Zap, HelpCircle];
3689
3979
  const renderSuggestions = () => {
3690
3980
  if (messages.length > 0 || !suggestions.length) return null;
3691
- return /* @__PURE__ */ jsxs14("div", { className: "text-center py-8", children: [
3692
- /* @__PURE__ */ jsx23("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary/10 mb-4", children: /* @__PURE__ */ jsx23(Sparkles, { className: "w-8 h-8 text-primary" }) }),
3693
- /* @__PURE__ */ jsx23("h3", { className: "text-lg font-semibold mb-2", children: config.branding.title }),
3694
- /* @__PURE__ */ jsx23("p", { className: "text-muted-foreground mb-6", children: config.branding.subtitle }),
3695
- /* @__PURE__ */ jsx23("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3 max-w-2xl mx-auto", children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsx23(
3696
- Card,
3981
+ return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
3982
+ /* @__PURE__ */ jsxs14("div", { className: "text-center mb-8", children: [
3983
+ /* @__PURE__ */ jsx23("div", { className: "inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-primary/20 to-primary/5 mb-4 shadow-sm", children: /* @__PURE__ */ jsx23(Sparkles, { className: "w-7 h-7 text-primary" }) }),
3984
+ /* @__PURE__ */ jsx23("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
3985
+ /* @__PURE__ */ jsx23("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
3986
+ ] }),
3987
+ /* @__PURE__ */ jsx23("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs14(
3988
+ "button",
3697
3989
  {
3698
- className: "cursor-pointer hover:bg-muted/50 transition-colors",
3990
+ type: "button",
3699
3991
  onClick: () => handleSendMessage(suggestion),
3700
- children: /* @__PURE__ */ jsx23(CardContent, { className: "p-4 text-left", children: /* @__PURE__ */ jsx23("p", { className: "text-sm", children: suggestion }) })
3992
+ className: "group relative flex items-start gap-3 p-4 text-left rounded-xl border bg-card hover:bg-accent/50 hover:border-accent transition-all duration-200 hover:shadow-sm",
3993
+ children: [
3994
+ (() => {
3995
+ const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];
3996
+ return /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary shrink-0 group-hover:bg-primary/15 transition-colors", children: /* @__PURE__ */ jsx23(IconComponent, { className: "h-4 w-4" }) });
3997
+ })(),
3998
+ /* @__PURE__ */ jsx23("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
3999
+ /* @__PURE__ */ jsx23(ArrowRight, { className: "absolute right-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
4000
+ ]
3701
4001
  },
3702
4002
  index
3703
4003
  )) })
3704
4004
  ] });
3705
4005
  };
4006
+ const renderInlineSuggestions = (messageId) => {
4007
+ const items = messageSuggestions?.[messageId];
4008
+ if (!items || items.length === 0) return null;
4009
+ return /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-2 mt-2 ml-11", children: items.map((suggestion, index) => /* @__PURE__ */ jsxs14(
4010
+ "button",
4011
+ {
4012
+ type: "button",
4013
+ onClick: () => handleSendMessage(suggestion),
4014
+ className: "group inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-border bg-background hover:bg-accent hover:border-accent-foreground/20 transition-all duration-150 text-foreground/80 hover:text-foreground",
4015
+ children: [
4016
+ /* @__PURE__ */ jsx23(Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4017
+ /* @__PURE__ */ jsx23("span", { className: "max-w-[200px] truncate", children: suggestion })
4018
+ ]
4019
+ },
4020
+ `${messageId}-suggestion-${index}`
4021
+ )) });
4022
+ };
4023
+ const shouldShowAgentSelector = Boolean(
4024
+ config.agentSelector?.enabled && onSelectAgent && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1)
4025
+ );
3706
4026
  return /* @__PURE__ */ jsx23(TooltipProvider, { children: /* @__PURE__ */ jsx23(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ jsxs14("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
3707
4027
  /* @__PURE__ */ jsx23(
3708
4028
  Sidebar2,
@@ -3743,7 +4063,11 @@ var ChatUI = ({
3743
4063
  isMobile,
3744
4064
  onCustomComponentToggle: () => setState((prev) => ({ ...prev, showSidebar: !prev.showSidebar })),
3745
4065
  onNewThread: handleCreateThread,
3746
- showCustomComponentButton: !!config?.customComponent?.component
4066
+ showCustomComponentButton: !!config?.customComponent?.component,
4067
+ showAgentSelector: shouldShowAgentSelector,
4068
+ agentOptions,
4069
+ selectedAgentId,
4070
+ onSelectAgent
3747
4071
  }
3748
4072
  ),
3749
4073
  /* @__PURE__ */ jsxs14("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
@@ -3757,27 +4081,34 @@ var ChatUI = ({
3757
4081
  onScrollCapture: handleScroll,
3758
4082
  children: /* @__PURE__ */ jsxs14("div", { className: "max-w-4xl mx-auto space-y-4 pb-4", children: [
3759
4083
  renderSuggestions(),
3760
- messages.map((message) => /* @__PURE__ */ jsx23(
3761
- Message,
3762
- {
3763
- message,
3764
- userAvatar: user?.avatar,
3765
- userName: user?.name,
3766
- assistantAvatar: assistant?.avatar,
3767
- assistantName: assistant?.name,
3768
- showTimestamp: config.ui.showTimestamps,
3769
- showAvatar: config.ui.showAvatars,
3770
- enableCopy: config.features.enableMessageCopy,
3771
- enableEdit: config.features.enableMessageEditing,
3772
- enableRegenerate: config.features.enableRegeneration,
3773
- enableToolCallsDisplay: config.features.enableToolCallsDisplay,
3774
- compactMode: config.ui.compactMode,
3775
- onAction: handleMessageAction,
3776
- toolUsedLabel: config.labels.toolUsed,
3777
- thinkingLabel: config.labels.thinking
3778
- },
3779
- message.id
3780
- )),
4084
+ messages.map((message, index) => {
4085
+ const prevMessage = index > 0 ? messages[index - 1] : null;
4086
+ const isGrouped = prevMessage !== null && prevMessage.role === message.role;
4087
+ return /* @__PURE__ */ jsxs14("div", { className: isGrouped ? "space-y-1 -mt-2" : "space-y-2", children: [
4088
+ /* @__PURE__ */ jsx23(
4089
+ Message,
4090
+ {
4091
+ message,
4092
+ userAvatar: user?.avatar,
4093
+ userName: user?.name,
4094
+ assistantAvatar: assistant?.avatar,
4095
+ assistantName: assistant?.name,
4096
+ showTimestamp: config.ui.showTimestamps,
4097
+ showAvatar: config.ui.showAvatars,
4098
+ enableCopy: config.features.enableMessageCopy,
4099
+ enableEdit: config.features.enableMessageEditing,
4100
+ enableRegenerate: config.features.enableRegeneration,
4101
+ enableToolCallsDisplay: config.features.enableToolCallsDisplay,
4102
+ compactMode: config.ui.compactMode,
4103
+ onAction: handleMessageAction,
4104
+ toolUsedLabel: config.labels.toolUsed,
4105
+ thinkingLabel: config.labels.thinking,
4106
+ isGrouped
4107
+ }
4108
+ ),
4109
+ message.role === "assistant" && renderInlineSuggestions(message.id)
4110
+ ] }, message.id);
4111
+ }),
3781
4112
  /* @__PURE__ */ jsx23("div", { ref: messagesEndRef })
3782
4113
  ] })
3783
4114
  }
@@ -3785,11 +4116,17 @@ var ChatUI = ({
3785
4116
  /* @__PURE__ */ jsx23("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ jsx23(
3786
4117
  ChatInput,
3787
4118
  {
3788
- value: state.input,
3789
- onChange: (value) => setState((prev) => ({ ...prev, input: value })),
4119
+ value: inputValue,
4120
+ onChange: (value) => {
4121
+ setInputValue(value);
4122
+ if (initialInputApplied.current && !initialInputConsumedRef.current) {
4123
+ initialInputConsumedRef.current = true;
4124
+ onInitialInputConsumed?.();
4125
+ }
4126
+ },
3790
4127
  onSubmit: handleSendMessage,
3791
- attachments: state.attachments,
3792
- onAttachmentsChange: (attachments) => setState((prev) => ({ ...prev, attachments })),
4128
+ attachments,
4129
+ onAttachmentsChange: setAttachments,
3793
4130
  placeholder: config.labels.inputPlaceholder,
3794
4131
  disabled: false,
3795
4132
  isGenerating,
@@ -3829,7 +4166,7 @@ var ChatUI = ({
3829
4166
  }
3830
4167
  )
3831
4168
  ] }),
3832
- /* @__PURE__ */ jsx23(
4169
+ isUserProfileOpen && /* @__PURE__ */ jsx23(
3833
4170
  UserProfile,
3834
4171
  {
3835
4172
  isOpen: isUserProfileOpen,
@@ -3852,10 +4189,10 @@ var ChatUI = ({
3852
4189
  };
3853
4190
 
3854
4191
  // src/components/chat/ThreadManager.tsx
3855
- import { useState as useState9, useRef as useRef5, useEffect as useEffect8 } from "react";
4192
+ import { useState as useState9, useRef as useRef8, useEffect as useEffect11 } from "react";
3856
4193
  import {
3857
4194
  Plus as Plus4,
3858
- MessageSquare,
4195
+ MessageSquare as MessageSquare2,
3859
4196
  MoreVertical as MoreVertical2,
3860
4197
  Edit2 as Edit22,
3861
4198
  Trash2 as Trash24,
@@ -3865,14 +4202,14 @@ import {
3865
4202
  Calendar as Calendar2,
3866
4203
  Hash,
3867
4204
  X as X4,
3868
- Check as Check3
4205
+ Check as Check4
3869
4206
  } from "lucide-react";
3870
4207
  import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
3871
4208
  var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
3872
4209
  const [isEditing, setIsEditing] = useState9(false);
3873
4210
  const [editTitle, setEditTitle] = useState9(thread.title);
3874
- const inputRef = useRef5(null);
3875
- useEffect8(() => {
4211
+ const inputRef = useRef8(null);
4212
+ useEffect11(() => {
3876
4213
  if (isEditing && inputRef.current) {
3877
4214
  inputRef.current.focus();
3878
4215
  inputRef.current.select();
@@ -3910,7 +4247,7 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
3910
4247
  placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
3911
4248
  }
3912
4249
  ),
3913
- /* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx24(Check3, { className: "h-3 w-3" }) }),
4250
+ /* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx24(Check4, { className: "h-3 w-3" }) }),
3914
4251
  /* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ jsx24(X4, { className: "h-3 w-3" }) })
3915
4252
  ] }) : /* @__PURE__ */ jsxs15(Fragment6, { children: [
3916
4253
  /* @__PURE__ */ jsx24("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
@@ -4043,7 +4380,7 @@ var ThreadManager = ({
4043
4380
  /* @__PURE__ */ jsxs15(CardHeader, { className: "border-b", children: [
4044
4381
  /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
4045
4382
  /* @__PURE__ */ jsxs15(CardTitle, { className: "flex items-center gap-2", children: [
4046
- /* @__PURE__ */ jsx24(MessageSquare, { className: "h-5 w-5" }),
4383
+ /* @__PURE__ */ jsx24(MessageSquare2, { className: "h-5 w-5" }),
4047
4384
  config?.labels?.newChat || "Conversations"
4048
4385
  ] }),
4049
4386
  /* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx24(X4, { className: "h-4 w-4" }) })
@@ -4086,7 +4423,7 @@ var ThreadManager = ({
4086
4423
  /* @__PURE__ */ jsxs15(CardContent, { className: "p-0 flex-1", children: [
4087
4424
  /* @__PURE__ */ jsx24("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ jsx24(CreateThreadDialog2, { onCreateThread, config }) }),
4088
4425
  /* @__PURE__ */ jsx24(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ jsx24("div", { className: "px-4 pb-4 space-y-4", children: Object.keys(groupedThreads).length === 0 ? /* @__PURE__ */ jsxs15("div", { className: "text-center py-8 text-muted-foreground", children: [
4089
- /* @__PURE__ */ jsx24(MessageSquare, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
4426
+ /* @__PURE__ */ jsx24(MessageSquare2, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
4090
4427
  /* @__PURE__ */ jsx24("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
4091
4428
  ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ jsxs15("div", { children: [
4092
4429
  /* @__PURE__ */ jsx24("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
@@ -4106,7 +4443,7 @@ var ThreadManager = ({
4106
4443
  ] }, group)) }) })
4107
4444
  ] })
4108
4445
  ] }) }),
4109
- /* @__PURE__ */ jsx24(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs15(AlertDialogContent, { children: [
4446
+ deleteThreadId && /* @__PURE__ */ jsx24(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs15(AlertDialogContent, { children: [
4110
4447
  /* @__PURE__ */ jsxs15(AlertDialogHeader, { children: [
4111
4448
  /* @__PURE__ */ jsx24(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
4112
4449
  /* @__PURE__ */ jsx24(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })