@copilotz/chat-ui 0.1.10 → 0.1.12

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.cts CHANGED
@@ -592,6 +592,7 @@ declare const configUtils: {
592
592
 
593
593
  declare function cn(...inputs: ClassValue[]): string;
594
594
  declare const formatDate: (timestamp: number, labels?: ChatConfig["labels"]) => string;
595
+ declare const createObjectUrlFromDataUrl: (dataUrl: string) => string | null;
595
596
 
596
597
  declare const chatUtils: {
597
598
  generateId: () => string;
@@ -602,4 +603,4 @@ declare const chatUtils: {
602
603
  generateThreadTitle: (firstMessage: string) => string;
603
604
  };
604
605
 
605
- export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
606
+ export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, createObjectUrlFromDataUrl, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
package/dist/index.d.ts CHANGED
@@ -592,6 +592,7 @@ declare const configUtils: {
592
592
 
593
593
  declare function cn(...inputs: ClassValue[]): string;
594
594
  declare const formatDate: (timestamp: number, labels?: ChatConfig["labels"]) => string;
595
+ declare const createObjectUrlFromDataUrl: (dataUrl: string) => string | null;
595
596
 
596
597
  declare const chatUtils: {
597
598
  generateId: () => string;
@@ -602,4 +603,4 @@ declare const chatUtils: {
602
603
  generateThreadTitle: (firstMessage: string) => string;
603
604
  };
604
605
 
605
- export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
606
+ export { type AgentOption, type ChatCallbacks, type ChatConfig, ChatHeader, type ChatHeaderConfig, type ChatHeaderProps, ChatInput, type ChatMessage, type ChatState, type ChatThread, ChatUI, type ChatUserContext, ChatUserContextProvider, type ChatV2Props, type CustomField, type FileUploadProgress, type MediaAttachment, type MemoryItem, Message, type MessageAction, type MessageActionEvent, Sidebar, type SidebarConfig, type SidebarProps, type StateCallback, type StreamingUpdate, ThreadManager, type ToolCall, type UserCustomField, UserMenu, type UserMenuCallbacks, type UserMenuConfig, type UserMenuProps, type UserMenuUser, UserProfile, type UserProfileConfig, type UserProfileProps, type UserProfileUser, chatConfigPresets, chatUtils, cn, configUtils, createObjectUrlFromDataUrl, defaultChatConfig, featureFlags, formatDate, mergeConfig, themeUtils, useChatUserContext, validateConfig };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/chat/ChatUI.tsx
2
- import { useState as useState8, useEffect as useEffect9, useRef as useRef7, useCallback as useCallback4, useMemo as useMemo4 } from "react";
2
+ import { useState as useState8, useEffect as useEffect10, useRef as useRef6, useCallback as useCallback4, useMemo as useMemo4 } from "react";
3
3
  import { useVirtualizer } from "@tanstack/react-virtual";
4
4
 
5
5
  // src/config/chatConfig.ts
@@ -245,7 +245,7 @@ var configUtils = {
245
245
  };
246
246
 
247
247
  // src/components/chat/Message.tsx
248
- import React, { useState, useRef, useMemo, memo } from "react";
248
+ import React, { useState, useMemo, useEffect, memo } from "react";
249
249
  import ReactMarkdown from "react-markdown";
250
250
  import remarkGfm from "remark-gfm";
251
251
  import rehypeHighlight from "rehype-highlight";
@@ -278,6 +278,24 @@ var formatDate = (timestamp, labels) => {
278
278
  });
279
279
  }
280
280
  };
281
+ var createObjectUrlFromDataUrl = (dataUrl) => {
282
+ const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);
283
+ if (!match) {
284
+ return null;
285
+ }
286
+ try {
287
+ const [, mimeType, base64] = match;
288
+ const binary = atob(base64);
289
+ const bytes = new Uint8Array(binary.length);
290
+ for (let i = 0; i < binary.length; i += 1) {
291
+ bytes[i] = binary.charCodeAt(i);
292
+ }
293
+ const blob = new Blob([bytes], { type: mimeType || "application/octet-stream" });
294
+ return URL.createObjectURL(blob);
295
+ } catch {
296
+ return null;
297
+ }
298
+ };
281
299
 
282
300
  // src/components/ui/button.tsx
283
301
  import { jsx } from "react/jsx-runtime";
@@ -668,26 +686,22 @@ var StreamingText = memo(function StreamingText2({
668
686
  ] });
669
687
  });
670
688
  var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
671
- const [isPlaying, setIsPlaying] = useState(false);
672
- const audioRef = useRef(null);
673
- const videoRef = useRef(null);
674
- const togglePlayback = () => {
675
- if (attachment.kind === "audio" && audioRef.current) {
676
- if (isPlaying) {
677
- audioRef.current.pause();
678
- } else {
679
- audioRef.current.play();
680
- }
681
- setIsPlaying(!isPlaying);
682
- } else if (attachment.kind === "video" && videoRef.current) {
683
- if (isPlaying) {
684
- videoRef.current.pause();
685
- } else {
686
- videoRef.current.play();
687
- }
688
- setIsPlaying(!isPlaying);
689
+ const [audioPlaybackSrc, setAudioPlaybackSrc] = useState(attachment.dataUrl);
690
+ useEffect(() => {
691
+ if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
692
+ setAudioPlaybackSrc(attachment.dataUrl);
693
+ return;
689
694
  }
690
- };
695
+ const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
696
+ if (!objectUrl) {
697
+ setAudioPlaybackSrc(attachment.dataUrl);
698
+ return;
699
+ }
700
+ setAudioPlaybackSrc(objectUrl);
701
+ return () => {
702
+ URL.revokeObjectURL(objectUrl);
703
+ };
704
+ }, [attachment.kind, attachment.dataUrl]);
691
705
  const formatDuration = (ms) => {
692
706
  if (!ms) return "";
693
707
  const seconds = Math.floor(ms / 1e3);
@@ -712,13 +726,10 @@ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
712
726
  return /* @__PURE__ */ jsx7("div", { className: "flex w-full max-w-md py-0 min-w-64 items-center gap-3", children: /* @__PURE__ */ jsx7(
713
727
  "audio",
714
728
  {
715
- ref: audioRef,
716
- src: attachment.dataUrl,
717
- onPlay: () => setIsPlaying(true),
718
- onPause: () => setIsPlaying(false),
719
- onEnded: () => setIsPlaying(false),
720
729
  className: "w-full mt-2",
721
- controls: true
730
+ preload: "metadata",
731
+ controls: true,
732
+ children: /* @__PURE__ */ jsx7("source", { src: audioPlaybackSrc, type: attachment.mimeType })
722
733
  }
723
734
  ) });
724
735
  case "video":
@@ -726,14 +737,10 @@ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
726
737
  /* @__PURE__ */ jsx7(
727
738
  "video",
728
739
  {
729
- ref: videoRef,
730
740
  src: attachment.dataUrl,
731
741
  poster: attachment.poster,
732
742
  controls: true,
733
- className: "w-full h-auto",
734
- onPlay: () => setIsPlaying(true),
735
- onPause: () => setIsPlaying(false),
736
- onEnded: () => setIsPlaying(false)
743
+ className: "w-full h-auto"
737
744
  }
738
745
  ),
739
746
  attachment.fileName && /* @__PURE__ */ jsx7("div", { className: "absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2", children: attachment.fileName })
@@ -889,6 +896,7 @@ var Message = memo(({
889
896
  contentVisibility: "auto",
890
897
  containIntrinsicSize: "1px 400px"
891
898
  } : void 0;
899
+ const horizontalOffsetClass = showAvatar ? messageIsUser ? compactMode ? "mr-9" : "mr-11" : compactMode ? "ml-9" : "ml-11" : "";
892
900
  const handleCopy = async () => {
893
901
  try {
894
902
  await navigator.clipboard.writeText(message.content);
@@ -944,7 +952,7 @@ var Message = memo(({
944
952
  message.isEdited && /* @__PURE__ */ jsx7(Badge, { variant: "outline", className: "text-xs", children: "editado" })
945
953
  ] })
946
954
  ] }),
947
- /* @__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 overflow-hidden text-left ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-full"}`, children: [
955
+ /* @__PURE__ */ jsx7("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${horizontalOffsetClass}`, children: /* @__PURE__ */ jsxs2("div", { className: `relative inline-flex flex-col overflow-hidden text-left ${messageIsUser ? "rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]" : "max-w-full"}`, children: [
948
956
  isEditing ? /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
949
957
  /* @__PURE__ */ jsx7(
950
958
  Textarea,
@@ -1040,7 +1048,7 @@ var Message = memo(({
1040
1048
  }, arePropsEqual);
1041
1049
 
1042
1050
  // src/components/chat/Sidebar.tsx
1043
- import { useState as useState4, useRef as useRef5, useEffect as useEffect6 } from "react";
1051
+ import { useState as useState4, useRef as useRef4, useEffect as useEffect7 } from "react";
1044
1052
 
1045
1053
  // src/components/ui/input.tsx
1046
1054
  import { jsx as jsx8 } from "react/jsx-runtime";
@@ -2289,9 +2297,9 @@ var Sidebar2 = ({
2289
2297
  const [deleteThreadId, setDeleteThreadId] = useState4(null);
2290
2298
  const [editingThreadId, setEditingThreadId] = useState4(null);
2291
2299
  const [editTitle, setEditTitle] = useState4("");
2292
- const inputRef = useRef5(null);
2300
+ const inputRef = useRef4(null);
2293
2301
  const { setOpen } = useSidebar();
2294
- useEffect6(() => {
2302
+ useEffect7(() => {
2295
2303
  if (editingThreadId && inputRef.current) {
2296
2304
  inputRef.current.focus();
2297
2305
  inputRef.current.select();
@@ -2708,10 +2716,10 @@ var ChatHeader = ({
2708
2716
  };
2709
2717
 
2710
2718
  // src/components/chat/ChatInput.tsx
2711
- import { useState as useState6, useRef as useRef6, useCallback as useCallback3, useEffect as useEffect8, memo as memo2 } from "react";
2719
+ import { useState as useState6, useRef as useRef5, useCallback as useCallback3, useEffect as useEffect9, memo as memo2 } from "react";
2712
2720
 
2713
2721
  // src/components/chat/UserContext.tsx
2714
- import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect7, useMemo as useMemo3, useState as useState5 } from "react";
2722
+ import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect as useEffect8, useMemo as useMemo3, useState as useState5 } from "react";
2715
2723
  import { jsx as jsx19 } from "react/jsx-runtime";
2716
2724
  var Ctx = createContext2(void 0);
2717
2725
  var ChatUserContextProvider = ({ children, initial }) => {
@@ -2719,7 +2727,7 @@ var ChatUserContextProvider = ({ children, initial }) => {
2719
2727
  updatedAt: Date.now(),
2720
2728
  ...initial ?? {}
2721
2729
  }));
2722
- useEffect7(() => {
2730
+ useEffect8(() => {
2723
2731
  if (!initial) return;
2724
2732
  setCtx((prev) => ({
2725
2733
  ...prev,
@@ -2785,8 +2793,8 @@ import {
2785
2793
  FileText,
2786
2794
  X as X2,
2787
2795
  Square,
2788
- Play as Play2,
2789
- Pause as Pause2,
2796
+ Play,
2797
+ Pause,
2790
2798
  Loader2
2791
2799
  } from "lucide-react";
2792
2800
  import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
@@ -2851,7 +2859,23 @@ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }
2851
2859
  });
2852
2860
  var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove }) {
2853
2861
  const [isPlaying, setIsPlaying] = useState6(false);
2854
- const audioRef = useRef6(null);
2862
+ const [audioPlaybackSrc, setAudioPlaybackSrc] = useState6(attachment.dataUrl);
2863
+ const audioRef = useRef5(null);
2864
+ useEffect9(() => {
2865
+ if (attachment.kind !== "audio" || !attachment.dataUrl.startsWith("data:")) {
2866
+ setAudioPlaybackSrc(attachment.dataUrl);
2867
+ return;
2868
+ }
2869
+ const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);
2870
+ if (!objectUrl) {
2871
+ setAudioPlaybackSrc(attachment.dataUrl);
2872
+ return;
2873
+ }
2874
+ setAudioPlaybackSrc(objectUrl);
2875
+ return () => {
2876
+ URL.revokeObjectURL(objectUrl);
2877
+ };
2878
+ }, [attachment.kind, attachment.dataUrl]);
2855
2879
  const handlePlayPause = () => {
2856
2880
  if (audioRef.current) {
2857
2881
  if (isPlaying) {
@@ -2919,7 +2943,7 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2919
2943
  size: "icon",
2920
2944
  className: "h-8 w-8",
2921
2945
  onClick: handlePlayPause,
2922
- children: isPlaying ? /* @__PURE__ */ jsx21(Pause2, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx21(Play2, { className: "h-3 w-3" })
2946
+ children: isPlaying ? /* @__PURE__ */ jsx21(Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx21(Play, { className: "h-3 w-3" })
2923
2947
  }
2924
2948
  ),
2925
2949
  /* @__PURE__ */ jsxs11("div", { className: "flex-1", children: [
@@ -2930,10 +2954,11 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2930
2954
  "audio",
2931
2955
  {
2932
2956
  ref: audioRef,
2933
- src: attachment.dataUrl,
2934
2957
  onPlay: () => setIsPlaying(true),
2935
2958
  onPause: () => setIsPlaying(false),
2936
- onEnded: () => setIsPlaying(false)
2959
+ onEnded: () => setIsPlaying(false),
2960
+ preload: "metadata",
2961
+ children: /* @__PURE__ */ jsx21("source", { src: audioPlaybackSrc, type: attachment.mimeType })
2937
2962
  }
2938
2963
  ),
2939
2964
  /* @__PURE__ */ jsx21(
@@ -3028,13 +3053,13 @@ var ChatInput = memo2(function ChatInput2({
3028
3053
  const { setContext } = useChatUserContext();
3029
3054
  const [recordingDuration, setRecordingDuration] = useState6(0);
3030
3055
  const [uploadProgress, setUploadProgress] = useState6(/* @__PURE__ */ new Map());
3031
- const textareaRef = useRef6(null);
3032
- const fileInputRef = useRef6(null);
3033
- const mediaRecorderRef = useRef6(null);
3034
- const recordingStartTime = useRef6(0);
3035
- const recordingInterval = useRef6(null);
3036
- const mediaStreamRef = useRef6(null);
3037
- useEffect8(() => {
3056
+ const textareaRef = useRef5(null);
3057
+ const fileInputRef = useRef5(null);
3058
+ const mediaRecorderRef = useRef5(null);
3059
+ const recordingStartTime = useRef5(0);
3060
+ const recordingInterval = useRef5(null);
3061
+ const mediaStreamRef = useRef5(null);
3062
+ useEffect9(() => {
3038
3063
  return () => {
3039
3064
  if (mediaStreamRef.current) {
3040
3065
  mediaStreamRef.current.getTracks().forEach((track) => track.stop());
@@ -3892,30 +3917,30 @@ var ChatUI = ({
3892
3917
  isSidebarCollapsed: false
3893
3918
  // No longer used for main sidebar
3894
3919
  });
3895
- useEffect9(() => {
3920
+ useEffect10(() => {
3896
3921
  if (currentThreadId !== state.selectedThreadId) {
3897
3922
  setState((prev) => ({ ...prev, selectedThreadId: currentThreadId }));
3898
3923
  }
3899
3924
  }, [currentThreadId]);
3900
- const initialInputApplied = useRef7(false);
3901
- const initialInputConsumedRef = useRef7(false);
3902
- useEffect9(() => {
3925
+ const initialInputApplied = useRef6(false);
3926
+ const initialInputConsumedRef = useRef6(false);
3927
+ useEffect10(() => {
3903
3928
  if (initialInput && !initialInputApplied.current) {
3904
3929
  setInputValue(initialInput);
3905
3930
  initialInputApplied.current = true;
3906
3931
  }
3907
3932
  }, [initialInput]);
3908
- const scrollAreaRef = useRef7(null);
3909
- const stateRef = useRef7(state);
3910
- const inputValueRef = useRef7(inputValue);
3911
- const attachmentsRef = useRef7(attachments);
3912
- useEffect9(() => {
3933
+ const scrollAreaRef = useRef6(null);
3934
+ const stateRef = useRef6(state);
3935
+ const inputValueRef = useRef6(inputValue);
3936
+ const attachmentsRef = useRef6(attachments);
3937
+ useEffect10(() => {
3913
3938
  stateRef.current = state;
3914
3939
  }, [state]);
3915
- useEffect9(() => {
3940
+ useEffect10(() => {
3916
3941
  inputValueRef.current = inputValue;
3917
3942
  }, [inputValue]);
3918
- useEffect9(() => {
3943
+ useEffect10(() => {
3919
3944
  attachmentsRef.current = attachments;
3920
3945
  }, [attachments]);
3921
3946
  const [isCustomMounted, setIsCustomMounted] = useState8(false);
@@ -3938,7 +3963,7 @@ var ChatUI = ({
3938
3963
  []
3939
3964
  // No dependencies - uses refs for latest state
3940
3965
  );
3941
- useEffect9(() => {
3966
+ useEffect10(() => {
3942
3967
  const checkMobile = () => {
3943
3968
  setIsMobile(globalThis.innerWidth < 1024);
3944
3969
  };
@@ -3946,7 +3971,7 @@ var ChatUI = ({
3946
3971
  globalThis.addEventListener("resize", checkMobile);
3947
3972
  return () => globalThis.removeEventListener("resize", checkMobile);
3948
3973
  }, []);
3949
- useEffect9(() => {
3974
+ useEffect10(() => {
3950
3975
  if (!isMobile || !config.customComponent?.component) return;
3951
3976
  if (state.showSidebar) {
3952
3977
  setIsCustomMounted(true);
@@ -3957,8 +3982,8 @@ var ChatUI = ({
3957
3982
  return () => clearTimeout(t);
3958
3983
  }
3959
3984
  }, [state.showSidebar, isMobile, config.customComponent]);
3960
- const prevMessageCountRef = useRef7(0);
3961
- useEffect9(() => {
3985
+ const prevMessageCountRef = useRef6(0);
3986
+ useEffect10(() => {
3962
3987
  if (messages.length === 0) {
3963
3988
  prevMessageCountRef.current = 0;
3964
3989
  return;
@@ -3984,10 +4009,10 @@ var ChatUI = ({
3984
4009
  }
3985
4010
  });
3986
4011
  }, [messages, state.isAtBottom, virtualizer]);
3987
- useEffect9(() => {
4012
+ useEffect10(() => {
3988
4013
  virtualizer.measure();
3989
4014
  }, [expandedMessageIds, virtualizer]);
3990
- useEffect9(() => {
4015
+ useEffect10(() => {
3991
4016
  const validMessageIds = new Set(messages.map((message) => message.id));
3992
4017
  setExpandedMessageIds((prev) => {
3993
4018
  const activeIds = Object.keys(prev);
@@ -4109,7 +4134,8 @@ var ChatUI = ({
4109
4134
  const renderInlineSuggestions = (messageId) => {
4110
4135
  const items = messageSuggestions?.[messageId];
4111
4136
  if (!items || items.length === 0) return null;
4112
- return /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-2 mt-2 ml-11", children: items.map((suggestion, index) => /* @__PURE__ */ jsxs14(
4137
+ const inlineSuggestionOffsetClass = config.ui.showAvatars ? config.ui.compactMode ? "ml-9" : "ml-11" : "";
4138
+ return /* @__PURE__ */ jsx24("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ jsxs14(
4113
4139
  "button",
4114
4140
  {
4115
4141
  type: "button",
@@ -4369,7 +4395,7 @@ var ChatUI = ({
4369
4395
  };
4370
4396
 
4371
4397
  // src/components/chat/ThreadManager.tsx
4372
- import { useState as useState9, useRef as useRef8, useEffect as useEffect10 } from "react";
4398
+ import { useState as useState9, useRef as useRef7, useEffect as useEffect11 } from "react";
4373
4399
  import {
4374
4400
  Plus as Plus4,
4375
4401
  MessageSquare as MessageSquare2,
@@ -4388,8 +4414,8 @@ import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-r
4388
4414
  var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
4389
4415
  const [isEditing, setIsEditing] = useState9(false);
4390
4416
  const [editTitle, setEditTitle] = useState9(thread.title);
4391
- const inputRef = useRef8(null);
4392
- useEffect10(() => {
4417
+ const inputRef = useRef7(null);
4418
+ useEffect11(() => {
4393
4419
  if (isEditing && inputRef.current) {
4394
4420
  inputRef.current.focus();
4395
4421
  inputRef.current.select();
@@ -4683,6 +4709,7 @@ export {
4683
4709
  chatUtils,
4684
4710
  cn,
4685
4711
  configUtils,
4712
+ createObjectUrlFromDataUrl,
4686
4713
  defaultChatConfig,
4687
4714
  featureFlags,
4688
4715
  formatDate,