@copilotz/chat-ui 0.1.30 → 0.1.32

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
@@ -30,6 +30,23 @@ var defaultChatConfig = {
30
30
  attachFileTooltip: "Attach file",
31
31
  recordAudio: "Record Audio",
32
32
  recordAudioTooltip: "Record audio",
33
+ voiceEnter: "Voice input",
34
+ voiceExit: "Use keyboard",
35
+ voiceTitle: "Voice input",
36
+ voicePreparing: "Preparing microphone...",
37
+ voiceWaiting: "Waiting for speech...",
38
+ voiceListening: "Listening...",
39
+ voiceFinishing: "Finishing capture...",
40
+ voiceReview: "Ready to send",
41
+ voiceStart: "Start recording",
42
+ voiceStop: "Stop recording",
43
+ voiceSendNow: "Send now",
44
+ voiceCancel: "Cancel",
45
+ voiceRecordAgain: "Record again",
46
+ voiceAutoSendIn: "Auto-sends in {{seconds}}s",
47
+ voiceTranscriptPending: "Transcript unavailable",
48
+ voicePermissionDenied: "Microphone access was denied.",
49
+ voiceCaptureError: "Unable to capture audio.",
33
50
  // Header labels
34
51
  exportData: "Export data",
35
52
  importData: "Import data",
@@ -92,6 +109,15 @@ var defaultChatConfig = {
92
109
  longMessageChunkChars: 12e3,
93
110
  renderUserMarkdown: true
94
111
  },
112
+ voiceCompose: {
113
+ enabled: false,
114
+ autoSendDelayMs: 5e3,
115
+ persistComposer: true,
116
+ showTranscriptPreview: true,
117
+ transcriptMode: "final-only",
118
+ maxRecordingMs: 6e4,
119
+ createProvider: void 0
120
+ },
95
121
  customComponent: {},
96
122
  headerActions: null
97
123
  };
@@ -114,6 +140,10 @@ function mergeConfig(_baseConfig, userConfig) {
114
140
  ...defaultChatConfig.ui,
115
141
  ...userConfig.ui
116
142
  },
143
+ voiceCompose: {
144
+ ...defaultChatConfig.voiceCompose,
145
+ ...userConfig.voiceCompose
146
+ },
117
147
  agentSelector: {
118
148
  ...defaultChatConfig.agentSelector,
119
149
  ...userConfig.agentSelector
@@ -732,7 +762,7 @@ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
732
762
  URL.revokeObjectURL(objectUrl);
733
763
  };
734
764
  }, [attachment.kind, attachment.dataUrl]);
735
- const formatDuration = (ms) => {
765
+ const formatDuration2 = (ms) => {
736
766
  if (!ms) return "";
737
767
  const seconds = Math.floor(ms / 1e3);
738
768
  const minutes = Math.floor(seconds / 60);
@@ -2794,6 +2824,215 @@ function useChatUserContext() {
2794
2824
  return v;
2795
2825
  }
2796
2826
 
2827
+ // src/lib/voiceCompose.ts
2828
+ var AUDIO_MIME_TYPES = [
2829
+ "audio/webm;codecs=opus",
2830
+ "audio/webm",
2831
+ "audio/mp4",
2832
+ "audio/ogg;codecs=opus"
2833
+ ];
2834
+ var pickRecorderMimeType = () => {
2835
+ if (typeof MediaRecorder === "undefined") return void 0;
2836
+ for (const mimeType of AUDIO_MIME_TYPES) {
2837
+ if (typeof MediaRecorder.isTypeSupported === "function" && MediaRecorder.isTypeSupported(mimeType)) {
2838
+ return mimeType;
2839
+ }
2840
+ }
2841
+ return void 0;
2842
+ };
2843
+ var blobToDataUrl = (blob) => new Promise((resolve, reject) => {
2844
+ const reader = new FileReader();
2845
+ reader.onload = () => resolve(reader.result);
2846
+ reader.onerror = () => reject(reader.error ?? new Error("Failed to read recorded audio"));
2847
+ reader.readAsDataURL(blob);
2848
+ });
2849
+ var stopStream = (stream) => {
2850
+ if (!stream) return;
2851
+ stream.getTracks().forEach((track) => track.stop());
2852
+ };
2853
+ var closeAudioContext = async (audioContext) => {
2854
+ if (!audioContext) return;
2855
+ try {
2856
+ await audioContext.close();
2857
+ } catch {
2858
+ }
2859
+ };
2860
+ var emitDuration = (handlers, startedAt) => {
2861
+ handlers.onDurationChange?.(Math.max(0, Date.now() - startedAt));
2862
+ };
2863
+ var createManualVoiceProvider = async (handlers, options = {}) => {
2864
+ let mediaRecorder = null;
2865
+ let mediaStream = null;
2866
+ let audioContext = null;
2867
+ let analyser = null;
2868
+ let levelData = null;
2869
+ let levelFrame = 0;
2870
+ let durationTimer = null;
2871
+ let maxDurationTimer = null;
2872
+ let startedAt = 0;
2873
+ let shouldEmitSegment = true;
2874
+ let isStarting = false;
2875
+ const clearTimers = () => {
2876
+ if (durationTimer) {
2877
+ clearInterval(durationTimer);
2878
+ durationTimer = null;
2879
+ }
2880
+ if (maxDurationTimer) {
2881
+ clearTimeout(maxDurationTimer);
2882
+ maxDurationTimer = null;
2883
+ }
2884
+ };
2885
+ const stopLevelLoop = () => {
2886
+ if (levelFrame) {
2887
+ cancelAnimationFrame(levelFrame);
2888
+ levelFrame = 0;
2889
+ }
2890
+ handlers.onAudioLevelChange?.(0);
2891
+ };
2892
+ const startLevelLoop = () => {
2893
+ if (!analyser || !levelData) return;
2894
+ const tick = () => {
2895
+ if (!analyser || !levelData) return;
2896
+ analyser.getByteTimeDomainData(levelData);
2897
+ let sum = 0;
2898
+ for (let index = 0; index < levelData.length; index += 1) {
2899
+ const centered = (levelData[index] - 128) / 128;
2900
+ sum += centered * centered;
2901
+ }
2902
+ const rms = Math.sqrt(sum / levelData.length);
2903
+ handlers.onAudioLevelChange?.(Math.min(1, rms * 4));
2904
+ levelFrame = requestAnimationFrame(tick);
2905
+ };
2906
+ tick();
2907
+ };
2908
+ const cleanupActiveResources = async () => {
2909
+ clearTimers();
2910
+ stopLevelLoop();
2911
+ stopStream(mediaStream);
2912
+ mediaStream = null;
2913
+ analyser = null;
2914
+ levelData = null;
2915
+ await closeAudioContext(audioContext);
2916
+ audioContext = null;
2917
+ };
2918
+ const finalizeStop = async () => {
2919
+ mediaRecorder = null;
2920
+ isStarting = false;
2921
+ await cleanupActiveResources();
2922
+ };
2923
+ const start = async () => {
2924
+ if (isStarting || mediaRecorder?.state === "recording") {
2925
+ return;
2926
+ }
2927
+ if (!navigator.mediaDevices?.getUserMedia) {
2928
+ throw new Error("Audio capture is not supported in this browser");
2929
+ }
2930
+ if (typeof MediaRecorder === "undefined") {
2931
+ throw new Error("MediaRecorder is not supported in this browser");
2932
+ }
2933
+ isStarting = true;
2934
+ shouldEmitSegment = true;
2935
+ handlers.onTranscriptChange?.({});
2936
+ handlers.onDurationChange?.(0);
2937
+ handlers.onAudioLevelChange?.(0);
2938
+ handlers.onStateChange?.("preparing");
2939
+ try {
2940
+ mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
2941
+ const mimeType = pickRecorderMimeType();
2942
+ mediaRecorder = mimeType ? new MediaRecorder(mediaStream, { mimeType }) : new MediaRecorder(mediaStream);
2943
+ const chunks = [];
2944
+ mediaRecorder.ondataavailable = (event) => {
2945
+ if (event.data.size > 0) {
2946
+ chunks.push(event.data);
2947
+ }
2948
+ };
2949
+ mediaRecorder.onerror = (event) => {
2950
+ const error = event.error ?? new Error("Audio recorder failed");
2951
+ handlers.onError?.(error);
2952
+ };
2953
+ mediaRecorder.onstop = async () => {
2954
+ const durationMs = startedAt > 0 ? Math.max(0, Date.now() - startedAt) : 0;
2955
+ try {
2956
+ if (shouldEmitSegment && chunks.length > 0) {
2957
+ const blob = new Blob(chunks, {
2958
+ type: mediaRecorder?.mimeType || mimeType || "audio/webm"
2959
+ });
2960
+ const dataUrl = await blobToDataUrl(blob);
2961
+ handlers.onSegmentReady?.({
2962
+ attachment: {
2963
+ kind: "audio",
2964
+ dataUrl,
2965
+ mimeType: blob.type || "audio/webm",
2966
+ durationMs,
2967
+ fileName: `voice-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.webm`,
2968
+ size: blob.size
2969
+ },
2970
+ metadata: { source: "manual" }
2971
+ });
2972
+ } else {
2973
+ handlers.onStateChange?.("idle");
2974
+ }
2975
+ } catch (error) {
2976
+ handlers.onError?.(error);
2977
+ } finally {
2978
+ await finalizeStop();
2979
+ }
2980
+ };
2981
+ const AudioContextCtor = globalThis.AudioContext || globalThis.webkitAudioContext;
2982
+ if (AudioContextCtor) {
2983
+ audioContext = new AudioContextCtor();
2984
+ await audioContext.resume().catch(() => void 0);
2985
+ const sourceNode = audioContext.createMediaStreamSource(mediaStream);
2986
+ analyser = audioContext.createAnalyser();
2987
+ analyser.fftSize = 1024;
2988
+ levelData = new Uint8Array(analyser.fftSize);
2989
+ sourceNode.connect(analyser);
2990
+ startLevelLoop();
2991
+ }
2992
+ startedAt = Date.now();
2993
+ emitDuration(handlers, startedAt);
2994
+ durationTimer = setInterval(() => emitDuration(handlers, startedAt), 200);
2995
+ if (options.maxRecordingMs && options.maxRecordingMs > 0) {
2996
+ maxDurationTimer = setTimeout(() => {
2997
+ void stop();
2998
+ }, options.maxRecordingMs);
2999
+ }
3000
+ mediaRecorder.start();
3001
+ handlers.onStateChange?.("listening");
3002
+ } catch (error) {
3003
+ isStarting = false;
3004
+ await cleanupActiveResources();
3005
+ throw error;
3006
+ }
3007
+ };
3008
+ const stop = async () => {
3009
+ if (!mediaRecorder || mediaRecorder.state === "inactive") {
3010
+ return;
3011
+ }
3012
+ handlers.onStateChange?.("finishing");
3013
+ mediaRecorder.stop();
3014
+ };
3015
+ const cancel = async () => {
3016
+ shouldEmitSegment = false;
3017
+ if (mediaRecorder && mediaRecorder.state !== "inactive") {
3018
+ mediaRecorder.stop();
3019
+ return;
3020
+ }
3021
+ await finalizeStop();
3022
+ handlers.onStateChange?.("idle");
3023
+ };
3024
+ const destroy = async () => {
3025
+ await cancel();
3026
+ };
3027
+ return {
3028
+ start,
3029
+ stop,
3030
+ cancel,
3031
+ destroy
3032
+ };
3033
+ };
3034
+ var resolveVoiceProviderFactory = (createProvider) => createProvider ?? createManualVoiceProvider;
3035
+
2797
3036
  // src/components/ui/progress.tsx
2798
3037
  import * as ProgressPrimitive from "@radix-ui/react-progress";
2799
3038
  import { jsx as jsx20 } from "react/jsx-runtime";
@@ -2823,21 +3062,174 @@ function Progress({
2823
3062
  );
2824
3063
  }
2825
3064
 
3065
+ // src/components/chat/VoiceComposer.tsx
3066
+ import { Keyboard, Loader2, Mic, RotateCcw as RotateCcw2, Send, Square, X as X2 } from "lucide-react";
3067
+ import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3068
+ var formatDuration = (durationMs) => {
3069
+ const totalSeconds = Math.max(0, Math.floor(durationMs / 1e3));
3070
+ const minutes = Math.floor(totalSeconds / 60);
3071
+ const seconds = totalSeconds % 60;
3072
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
3073
+ };
3074
+ var interpolateSeconds = (label, seconds) => {
3075
+ if (!label) {
3076
+ return `Auto-sends in ${seconds}s`;
3077
+ }
3078
+ if (label.includes("{{seconds}}")) {
3079
+ return label.replace(/\{\{\s*seconds\s*\}\}/g, String(seconds));
3080
+ }
3081
+ return `${label} ${seconds}s`;
3082
+ };
3083
+ var resolveStateLabel = (state, labels, errorMessage) => {
3084
+ switch (state) {
3085
+ case "preparing":
3086
+ return labels?.voicePreparing || "Preparing microphone...";
3087
+ case "waiting_for_speech":
3088
+ return labels?.voiceWaiting || "Waiting for speech...";
3089
+ case "listening":
3090
+ return labels?.voiceListening || "Listening...";
3091
+ case "finishing":
3092
+ return labels?.voiceFinishing || "Finishing capture...";
3093
+ case "review":
3094
+ return labels?.voiceReview || "Ready to send";
3095
+ case "sending":
3096
+ return "Sending...";
3097
+ case "error":
3098
+ return errorMessage || labels?.voiceCaptureError || "Unable to capture audio.";
3099
+ case "idle":
3100
+ default:
3101
+ return labels?.voiceTitle || "Voice input";
3102
+ }
3103
+ };
3104
+ var resolveTranscriptText = (transcript, transcriptMode) => {
3105
+ if (transcriptMode === "none" || !transcript) {
3106
+ return null;
3107
+ }
3108
+ if (transcriptMode === "final-only") {
3109
+ return transcript.final?.trim() || null;
3110
+ }
3111
+ return transcript.final?.trim() || transcript.partial?.trim() || null;
3112
+ };
3113
+ var VoiceComposer = ({
3114
+ state,
3115
+ transcript,
3116
+ transcriptMode,
3117
+ showTranscriptPreview,
3118
+ durationMs,
3119
+ audioLevel,
3120
+ countdownMs,
3121
+ autoSendDelayMs,
3122
+ errorMessage,
3123
+ disabled = false,
3124
+ labels,
3125
+ onStart,
3126
+ onStop,
3127
+ onCancel,
3128
+ onSendNow,
3129
+ onRecordAgain,
3130
+ onExit
3131
+ }) => {
3132
+ const transcriptText = resolveTranscriptText(transcript, transcriptMode);
3133
+ const countdownSeconds = Math.max(1, Math.ceil(countdownMs / 1e3));
3134
+ const countdownValue = autoSendDelayMs > 0 ? Math.min(100, Math.max(0, (autoSendDelayMs - countdownMs) / autoSendDelayMs * 100)) : 100;
3135
+ const isBusy = state === "preparing" || state === "finishing" || state === "sending";
3136
+ const isCapturing = state === "waiting_for_speech" || state === "listening";
3137
+ const levelValue = isCapturing || state === "preparing" || state === "finishing" ? Math.max(8, Math.round(audioLevel * 100)) : 0;
3138
+ return /* @__PURE__ */ jsxs11("div", { className: "w-full md:min-w-3xl max-w-3xl rounded-xl border bg-background p-4 shadow-sm", children: [
3139
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-3", children: [
3140
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3141
+ /* @__PURE__ */ jsx21(Badge, { variant: "outline", children: labels?.voiceTitle || "Voice input" }),
3142
+ /* @__PURE__ */ jsx21("span", { className: "text-sm text-muted-foreground", children: resolveStateLabel(state, labels, errorMessage) })
3143
+ ] }),
3144
+ /* @__PURE__ */ jsxs11(
3145
+ Button,
3146
+ {
3147
+ type: "button",
3148
+ variant: "ghost",
3149
+ size: "sm",
3150
+ onClick: onExit,
3151
+ disabled: disabled || isBusy,
3152
+ children: [
3153
+ /* @__PURE__ */ jsx21(Keyboard, { className: "h-4 w-4" }),
3154
+ labels?.voiceExit || "Use keyboard"
3155
+ ]
3156
+ }
3157
+ )
3158
+ ] }),
3159
+ /* @__PURE__ */ jsxs11("div", { className: "mt-4 flex flex-col items-center gap-4 rounded-xl border border-dashed border-primary/30 bg-primary/5 px-4 py-6 text-center", children: [
3160
+ /* @__PURE__ */ jsx21("div", { className: "flex h-20 w-20 items-center justify-center rounded-full bg-primary/10", children: isBusy ? /* @__PURE__ */ jsx21(Loader2, { className: "h-8 w-8 animate-spin text-primary" }) : isCapturing ? /* @__PURE__ */ jsx21(Square, { className: "h-8 w-8 text-primary" }) : /* @__PURE__ */ jsx21(Mic, { className: "h-8 w-8 text-primary" }) }),
3161
+ /* @__PURE__ */ jsxs11("div", { className: "w-full max-w-md space-y-2", children: [
3162
+ /* @__PURE__ */ jsx21(Progress, { value: levelValue, className: "h-2" }),
3163
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
3164
+ /* @__PURE__ */ jsx21("span", { children: formatDuration(durationMs) }),
3165
+ /* @__PURE__ */ jsx21("span", { children: resolveStateLabel(state, labels, errorMessage) })
3166
+ ] })
3167
+ ] }),
3168
+ showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ jsx21("div", { className: "w-full max-w-md rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText })
3169
+ ] }),
3170
+ state === "review" && autoSendDelayMs > 0 && /* @__PURE__ */ jsxs11("div", { className: "mt-4 space-y-2", children: [
3171
+ /* @__PURE__ */ jsx21(Progress, { value: countdownValue, className: "h-2" }),
3172
+ /* @__PURE__ */ jsx21("div", { className: "text-center text-xs text-muted-foreground", children: interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds) })
3173
+ ] }),
3174
+ state === "error" && errorMessage && /* @__PURE__ */ jsx21("div", { className: "mt-4 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: errorMessage }),
3175
+ /* @__PURE__ */ jsxs11("div", { className: "mt-4 flex flex-wrap items-center justify-center gap-2", children: [
3176
+ state === "idle" && /* @__PURE__ */ jsxs11(Button, { type: "button", onClick: onStart, disabled, children: [
3177
+ /* @__PURE__ */ jsx21(Mic, { className: "h-4 w-4" }),
3178
+ labels?.voiceStart || "Start recording"
3179
+ ] }),
3180
+ isCapturing && /* @__PURE__ */ jsxs11(Fragment4, { children: [
3181
+ /* @__PURE__ */ jsxs11(Button, { type: "button", onClick: onStop, disabled, children: [
3182
+ /* @__PURE__ */ jsx21(Square, { className: "h-4 w-4" }),
3183
+ labels?.voiceStop || "Stop recording"
3184
+ ] }),
3185
+ /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "outline", onClick: onCancel, disabled, children: [
3186
+ /* @__PURE__ */ jsx21(X2, { className: "h-4 w-4" }),
3187
+ labels?.voiceCancel || "Cancel"
3188
+ ] })
3189
+ ] }),
3190
+ state === "review" && /* @__PURE__ */ jsxs11(Fragment4, { children: [
3191
+ /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "outline", onClick: onCancel, disabled, children: [
3192
+ /* @__PURE__ */ jsx21(X2, { className: "h-4 w-4" }),
3193
+ labels?.voiceCancel || "Cancel"
3194
+ ] }),
3195
+ /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "outline", onClick: onRecordAgain, disabled, children: [
3196
+ /* @__PURE__ */ jsx21(RotateCcw2, { className: "h-4 w-4" }),
3197
+ labels?.voiceRecordAgain || "Record again"
3198
+ ] }),
3199
+ /* @__PURE__ */ jsxs11(Button, { type: "button", onClick: onSendNow, disabled, children: [
3200
+ /* @__PURE__ */ jsx21(Send, { className: "h-4 w-4" }),
3201
+ labels?.voiceSendNow || "Send now"
3202
+ ] })
3203
+ ] }),
3204
+ state === "error" && /* @__PURE__ */ jsxs11(Fragment4, { children: [
3205
+ /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "outline", onClick: onCancel, disabled, children: [
3206
+ /* @__PURE__ */ jsx21(X2, { className: "h-4 w-4" }),
3207
+ labels?.voiceCancel || "Cancel"
3208
+ ] }),
3209
+ /* @__PURE__ */ jsxs11(Button, { type: "button", onClick: onRecordAgain, disabled, children: [
3210
+ /* @__PURE__ */ jsx21(RotateCcw2, { className: "h-4 w-4" }),
3211
+ labels?.voiceRecordAgain || "Record again"
3212
+ ] })
3213
+ ] })
3214
+ ] })
3215
+ ] });
3216
+ };
3217
+
2826
3218
  // src/components/chat/ChatInput.tsx
2827
3219
  import {
2828
- Send,
3220
+ Send as Send2,
2829
3221
  Paperclip,
2830
- Mic,
3222
+ Mic as Mic2,
2831
3223
  Image as Image2,
2832
3224
  Video,
2833
3225
  FileText,
2834
- X as X2,
2835
- Square,
3226
+ X as X3,
3227
+ Square as Square2,
2836
3228
  Play,
2837
3229
  Pause,
2838
- Loader2
3230
+ Loader2 as Loader22
2839
3231
  } from "lucide-react";
2840
- import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3232
+ import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
2841
3233
  var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }) {
2842
3234
  const guessTypeFromName = (name) => {
2843
3235
  const ext = (name || "").split(".").pop()?.toLowerCase();
@@ -2866,10 +3258,10 @@ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }
2866
3258
  };
2867
3259
  const getFileIcon = (type, name) => {
2868
3260
  const t = typeof type === "string" && type.length > 0 ? type : guessTypeFromName(name);
2869
- if (t.startsWith("image/")) return /* @__PURE__ */ jsx21(Image2, { className: "h-4 w-4" });
2870
- if (t.startsWith("video/")) return /* @__PURE__ */ jsx21(Video, { className: "h-4 w-4" });
2871
- if (t.startsWith("audio/")) return /* @__PURE__ */ jsx21(Mic, { className: "h-4 w-4" });
2872
- return /* @__PURE__ */ jsx21(FileText, { className: "h-4 w-4" });
3261
+ if (t.startsWith("image/")) return /* @__PURE__ */ jsx22(Image2, { className: "h-4 w-4" });
3262
+ if (t.startsWith("video/")) return /* @__PURE__ */ jsx22(Video, { className: "h-4 w-4" });
3263
+ if (t.startsWith("audio/")) return /* @__PURE__ */ jsx22(Mic2, { className: "h-4 w-4" });
3264
+ return /* @__PURE__ */ jsx22(FileText, { className: "h-4 w-4" });
2873
3265
  };
2874
3266
  const formatFileSize = (bytes) => {
2875
3267
  if (bytes === 0) return "0 Bytes";
@@ -2878,21 +3270,21 @@ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }
2878
3270
  const i = Math.floor(Math.log(bytes) / Math.log(k));
2879
3271
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
2880
3272
  };
2881
- return /* @__PURE__ */ jsx21(Card, { className: "relative", children: /* @__PURE__ */ jsx21(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-3", children: [
3273
+ return /* @__PURE__ */ jsx22(Card, { className: "relative", children: /* @__PURE__ */ jsx22(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3", children: [
2882
3274
  getFileIcon(file.type, file.name),
2883
- /* @__PURE__ */ jsxs11("div", { className: "flex-1 min-w-0", children: [
2884
- /* @__PURE__ */ jsx21("p", { className: "text-sm font-medium truncate", children: file.name }),
2885
- /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
2886
- /* @__PURE__ */ jsx21(Progress, { value: progress, className: "h-1 mt-1" })
3275
+ /* @__PURE__ */ jsxs12("div", { className: "flex-1 min-w-0", children: [
3276
+ /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium truncate", children: file.name }),
3277
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
3278
+ /* @__PURE__ */ jsx22(Progress, { value: progress, className: "h-1 mt-1" })
2887
3279
  ] }),
2888
- /* @__PURE__ */ jsx21(
3280
+ /* @__PURE__ */ jsx22(
2889
3281
  Button,
2890
3282
  {
2891
3283
  variant: "ghost",
2892
3284
  size: "icon",
2893
3285
  className: "h-6 w-6",
2894
3286
  onClick: onCancel,
2895
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3287
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
2896
3288
  }
2897
3289
  )
2898
3290
  ] }) }) });
@@ -2926,15 +3318,15 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2926
3318
  setIsPlaying(!isPlaying);
2927
3319
  }
2928
3320
  };
2929
- const formatDuration = (ms) => {
3321
+ const formatDuration2 = (ms) => {
2930
3322
  if (!ms) return "";
2931
3323
  const seconds = Math.floor(ms / 1e3);
2932
3324
  const minutes = Math.floor(seconds / 60);
2933
3325
  return `${minutes}:${(seconds % 60).toString().padStart(2, "0")}`;
2934
3326
  };
2935
- return /* @__PURE__ */ jsx21(Card, { className: "relative group", children: /* @__PURE__ */ jsxs11(CardContent, { className: "p-2", children: [
2936
- attachment.kind === "image" && /* @__PURE__ */ jsxs11("div", { className: "relative", children: [
2937
- /* @__PURE__ */ jsx21(
3327
+ return /* @__PURE__ */ jsx22(Card, { className: "relative group", children: /* @__PURE__ */ jsxs12(CardContent, { className: "p-2", children: [
3328
+ attachment.kind === "image" && /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
3329
+ /* @__PURE__ */ jsx22(
2938
3330
  "img",
2939
3331
  {
2940
3332
  src: attachment.dataUrl,
@@ -2942,19 +3334,19 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2942
3334
  className: "w-full h-20 object-cover rounded"
2943
3335
  }
2944
3336
  ),
2945
- /* @__PURE__ */ jsx21("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ jsx21(
3337
+ /* @__PURE__ */ jsx22("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ jsx22(
2946
3338
  Button,
2947
3339
  {
2948
3340
  variant: "destructive",
2949
3341
  size: "icon",
2950
3342
  className: "h-6 w-6",
2951
3343
  onClick: onRemove,
2952
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3344
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
2953
3345
  }
2954
3346
  ) })
2955
3347
  ] }),
2956
- attachment.kind === "video" && /* @__PURE__ */ jsxs11("div", { className: "relative", children: [
2957
- /* @__PURE__ */ jsx21(
3348
+ attachment.kind === "video" && /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
3349
+ /* @__PURE__ */ jsx22(
2958
3350
  "video",
2959
3351
  {
2960
3352
  src: attachment.dataUrl,
@@ -2963,34 +3355,34 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2963
3355
  muted: true
2964
3356
  }
2965
3357
  ),
2966
- /* @__PURE__ */ jsx21("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ jsx21(
3358
+ /* @__PURE__ */ jsx22("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ jsx22(
2967
3359
  Button,
2968
3360
  {
2969
3361
  variant: "destructive",
2970
3362
  size: "icon",
2971
3363
  className: "h-6 w-6",
2972
3364
  onClick: onRemove,
2973
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3365
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
2974
3366
  }
2975
3367
  ) }),
2976
- /* @__PURE__ */ jsx21(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration(attachment.durationMs) })
3368
+ /* @__PURE__ */ jsx22(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration2(attachment.durationMs) })
2977
3369
  ] }),
2978
- attachment.kind === "audio" && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 p-2", children: [
2979
- /* @__PURE__ */ jsx21(
3370
+ attachment.kind === "audio" && /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 p-2", children: [
3371
+ /* @__PURE__ */ jsx22(
2980
3372
  Button,
2981
3373
  {
2982
3374
  variant: "outline",
2983
3375
  size: "icon",
2984
3376
  className: "h-8 w-8",
2985
3377
  onClick: handlePlayPause,
2986
- children: isPlaying ? /* @__PURE__ */ jsx21(Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx21(Play, { className: "h-3 w-3" })
3378
+ children: isPlaying ? /* @__PURE__ */ jsx22(Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx22(Play, { className: "h-3 w-3" })
2987
3379
  }
2988
3380
  ),
2989
- /* @__PURE__ */ jsxs11("div", { className: "flex-1", children: [
2990
- /* @__PURE__ */ jsx21("p", { className: "text-xs font-medium", children: attachment.fileName || "\xC1udio" }),
2991
- /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: formatDuration(attachment.durationMs) })
3381
+ /* @__PURE__ */ jsxs12("div", { className: "flex-1", children: [
3382
+ /* @__PURE__ */ jsx22("p", { className: "text-xs font-medium", children: attachment.fileName || "\xC1udio" }),
3383
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: formatDuration2(attachment.durationMs) })
2992
3384
  ] }),
2993
- /* @__PURE__ */ jsx21(
3385
+ /* @__PURE__ */ jsx22(
2994
3386
  "audio",
2995
3387
  {
2996
3388
  ref: audioRef,
@@ -2998,21 +3390,21 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2998
3390
  onPause: () => setIsPlaying(false),
2999
3391
  onEnded: () => setIsPlaying(false),
3000
3392
  preload: "metadata",
3001
- children: /* @__PURE__ */ jsx21("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3393
+ children: /* @__PURE__ */ jsx22("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3002
3394
  }
3003
3395
  ),
3004
- /* @__PURE__ */ jsx21(
3396
+ /* @__PURE__ */ jsx22(
3005
3397
  Button,
3006
3398
  {
3007
3399
  variant: "ghost",
3008
3400
  size: "icon",
3009
3401
  className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
3010
3402
  onClick: onRemove,
3011
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3403
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
3012
3404
  }
3013
3405
  )
3014
3406
  ] }),
3015
- attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ jsx21("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ jsx21("p", { className: "truncate", children: attachment.fileName }) })
3407
+ attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ jsx22("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ jsx22("p", { className: "truncate", children: attachment.fileName }) })
3016
3408
  ] }) });
3017
3409
  });
3018
3410
  var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
@@ -3022,47 +3414,47 @@ var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecordin
3022
3414
  return `${mins}:${secs.toString().padStart(2, "0")}`;
3023
3415
  };
3024
3416
  if (!isRecording) {
3025
- return /* @__PURE__ */ jsxs11(Tooltip, { children: [
3026
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
3417
+ return /* @__PURE__ */ jsxs12(Tooltip, { children: [
3418
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3027
3419
  Button,
3028
3420
  {
3029
3421
  variant: "outline",
3030
3422
  size: "icon",
3031
3423
  onClick: onStartRecording,
3032
3424
  className: "h-10 w-10",
3033
- children: /* @__PURE__ */ jsx21(Mic, { className: "h-4 w-4" })
3425
+ children: /* @__PURE__ */ jsx22(Mic2, { className: "h-4 w-4" })
3034
3426
  }
3035
3427
  ) }),
3036
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3428
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3037
3429
  ] });
3038
3430
  }
3039
- return /* @__PURE__ */ jsx21(Card, { className: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950", children: /* @__PURE__ */ jsx21(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-3", children: [
3040
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3041
- /* @__PURE__ */ jsx21("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
3042
- /* @__PURE__ */ jsx21("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: "Gravando" })
3431
+ return /* @__PURE__ */ jsx22(Card, { className: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950", children: /* @__PURE__ */ jsx22(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3", children: [
3432
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
3433
+ /* @__PURE__ */ jsx22("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
3434
+ /* @__PURE__ */ jsx22("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: "Gravando" })
3043
3435
  ] }),
3044
- /* @__PURE__ */ jsx21(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
3045
- /* @__PURE__ */ jsxs11("div", { className: "flex gap-1 ml-auto", children: [
3046
- /* @__PURE__ */ jsxs11(
3436
+ /* @__PURE__ */ jsx22(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
3437
+ /* @__PURE__ */ jsxs12("div", { className: "flex gap-1 ml-auto", children: [
3438
+ /* @__PURE__ */ jsxs12(
3047
3439
  Button,
3048
3440
  {
3049
3441
  variant: "outline",
3050
3442
  size: "sm",
3051
3443
  onClick: onCancel,
3052
3444
  children: [
3053
- /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3 mr-1" }),
3445
+ /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3 mr-1" }),
3054
3446
  "Cancelar"
3055
3447
  ]
3056
3448
  }
3057
3449
  ),
3058
- /* @__PURE__ */ jsxs11(
3450
+ /* @__PURE__ */ jsxs12(
3059
3451
  Button,
3060
3452
  {
3061
3453
  variant: "default",
3062
3454
  size: "sm",
3063
3455
  onClick: onStopRecording,
3064
3456
  children: [
3065
- /* @__PURE__ */ jsx21(Square, { className: "h-3 w-3 mr-1" }),
3457
+ /* @__PURE__ */ jsx22(Square2, { className: "h-3 w-3 mr-1" }),
3066
3458
  "Parar"
3067
3459
  ]
3068
3460
  }
@@ -3070,6 +3462,16 @@ var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecordin
3070
3462
  ] })
3071
3463
  ] }) }) });
3072
3464
  });
3465
+ var resolveVoiceErrorMessage = (error, config) => {
3466
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
3467
+ return config?.labels?.voicePermissionDenied || "Microphone access was denied.";
3468
+ }
3469
+ if (error instanceof Error && error.message.trim().length > 0) {
3470
+ return error.message;
3471
+ }
3472
+ return config?.labels?.voiceCaptureError || "Unable to capture audio.";
3473
+ };
3474
+ var clearVoiceTranscript = () => ({});
3073
3475
  var ChatInput = memo2(function ChatInput2({
3074
3476
  value,
3075
3477
  onChange,
@@ -3093,12 +3495,27 @@ var ChatInput = memo2(function ChatInput2({
3093
3495
  const { setContext } = useChatUserContext();
3094
3496
  const [recordingDuration, setRecordingDuration] = useState6(0);
3095
3497
  const [uploadProgress, setUploadProgress] = useState6(/* @__PURE__ */ new Map());
3498
+ const [isVoiceComposerOpen, setIsVoiceComposerOpen] = useState6(false);
3499
+ const [voiceState, setVoiceState] = useState6("idle");
3500
+ const [voiceDraft, setVoiceDraft] = useState6(null);
3501
+ const [voiceTranscript, setVoiceTranscript] = useState6(clearVoiceTranscript);
3502
+ const [voiceDurationMs, setVoiceDurationMs] = useState6(0);
3503
+ const [voiceAudioLevel, setVoiceAudioLevel] = useState6(0);
3504
+ const [voiceCountdownMs, setVoiceCountdownMs] = useState6(0);
3505
+ const [voiceError, setVoiceError] = useState6(null);
3096
3506
  const textareaRef = useRef5(null);
3097
3507
  const fileInputRef = useRef5(null);
3098
3508
  const mediaRecorderRef = useRef5(null);
3099
3509
  const recordingStartTime = useRef5(0);
3100
3510
  const recordingInterval = useRef5(null);
3101
3511
  const mediaStreamRef = useRef5(null);
3512
+ const voiceProviderRef = useRef5(null);
3513
+ const voiceComposeEnabled = config?.voiceCompose?.enabled === true;
3514
+ const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5e3;
3515
+ const voicePersistComposer = config?.voiceCompose?.persistComposer ?? true;
3516
+ const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;
3517
+ const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? "final-only";
3518
+ const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;
3102
3519
  useEffect9(() => {
3103
3520
  return () => {
3104
3521
  if (mediaStreamRef.current) {
@@ -3107,6 +3524,10 @@ var ChatInput = memo2(function ChatInput2({
3107
3524
  if (recordingInterval.current) {
3108
3525
  clearInterval(recordingInterval.current);
3109
3526
  }
3527
+ if (voiceProviderRef.current) {
3528
+ void voiceProviderRef.current.destroy();
3529
+ voiceProviderRef.current = null;
3530
+ }
3110
3531
  };
3111
3532
  }, []);
3112
3533
  const handleSubmit = (e) => {
@@ -3283,13 +3704,149 @@ var ChatInput = memo2(function ChatInput2({
3283
3704
  }
3284
3705
  }
3285
3706
  };
3707
+ const resetVoiceComposerState = useCallback3((nextState = "idle") => {
3708
+ setVoiceState(nextState);
3709
+ setVoiceDraft(null);
3710
+ setVoiceTranscript(clearVoiceTranscript());
3711
+ setVoiceDurationMs(0);
3712
+ setVoiceAudioLevel(0);
3713
+ setVoiceCountdownMs(0);
3714
+ setVoiceError(null);
3715
+ }, []);
3716
+ const ensureVoiceProvider = useCallback3(async () => {
3717
+ if (voiceProviderRef.current) {
3718
+ return voiceProviderRef.current;
3719
+ }
3720
+ const createProvider = resolveVoiceProviderFactory(config?.voiceCompose?.createProvider);
3721
+ const provider = await createProvider({
3722
+ onStateChange: setVoiceState,
3723
+ onAudioLevelChange: setVoiceAudioLevel,
3724
+ onDurationChange: setVoiceDurationMs,
3725
+ onTranscriptChange: setVoiceTranscript,
3726
+ onSegmentReady: (segment) => {
3727
+ setVoiceDraft(segment);
3728
+ setVoiceTranscript(segment.transcript ?? clearVoiceTranscript());
3729
+ setVoiceDurationMs(segment.attachment.durationMs ?? 0);
3730
+ setVoiceAudioLevel(0);
3731
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3732
+ setVoiceError(null);
3733
+ setVoiceState("review");
3734
+ },
3735
+ onError: (error) => {
3736
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3737
+ setVoiceAudioLevel(0);
3738
+ setVoiceCountdownMs(0);
3739
+ setVoiceState("error");
3740
+ }
3741
+ }, {
3742
+ maxRecordingMs: voiceMaxRecordingMs
3743
+ });
3744
+ voiceProviderRef.current = provider;
3745
+ return provider;
3746
+ }, [config, voiceAutoSendDelayMs, voiceMaxRecordingMs]);
3747
+ const closeVoiceComposer = useCallback3(async () => {
3748
+ setIsVoiceComposerOpen(false);
3749
+ setVoiceError(null);
3750
+ setVoiceCountdownMs(0);
3751
+ setVoiceAudioLevel(0);
3752
+ setVoiceTranscript(clearVoiceTranscript());
3753
+ setVoiceDraft(null);
3754
+ setVoiceDurationMs(0);
3755
+ setVoiceState("idle");
3756
+ if (voiceProviderRef.current) {
3757
+ await voiceProviderRef.current.cancel();
3758
+ }
3759
+ }, []);
3760
+ const startVoiceCapture = useCallback3(async () => {
3761
+ if (disabled || isGenerating) {
3762
+ return;
3763
+ }
3764
+ setIsVoiceComposerOpen(true);
3765
+ setVoiceError(null);
3766
+ setVoiceDraft(null);
3767
+ setVoiceCountdownMs(0);
3768
+ setVoiceTranscript(clearVoiceTranscript());
3769
+ setVoiceAudioLevel(0);
3770
+ setVoiceDurationMs(0);
3771
+ try {
3772
+ const provider = await ensureVoiceProvider();
3773
+ await provider.start();
3774
+ } catch (error) {
3775
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3776
+ setVoiceState("error");
3777
+ }
3778
+ }, [disabled, isGenerating, ensureVoiceProvider, config]);
3779
+ const stopVoiceCapture = useCallback3(async () => {
3780
+ if (!voiceProviderRef.current) return;
3781
+ try {
3782
+ await voiceProviderRef.current.stop();
3783
+ } catch (error) {
3784
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3785
+ setVoiceState("error");
3786
+ }
3787
+ }, [config]);
3788
+ const cancelVoiceCapture = useCallback3(async () => {
3789
+ if (voiceProviderRef.current) {
3790
+ await voiceProviderRef.current.cancel();
3791
+ }
3792
+ resetVoiceComposerState("idle");
3793
+ }, [resetVoiceComposerState]);
3794
+ const finalizeVoiceComposerAfterSend = useCallback3(() => {
3795
+ if (voicePersistComposer) {
3796
+ resetVoiceComposerState("idle");
3797
+ setIsVoiceComposerOpen(true);
3798
+ return;
3799
+ }
3800
+ void closeVoiceComposer();
3801
+ }, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);
3802
+ const sendVoiceDraft = useCallback3(() => {
3803
+ if (!voiceDraft || disabled || isGenerating) {
3804
+ return;
3805
+ }
3806
+ setVoiceState("sending");
3807
+ setVoiceCountdownMs(0);
3808
+ onSubmit("", [...attachments, voiceDraft.attachment]);
3809
+ onChange("");
3810
+ onAttachmentsChange([]);
3811
+ finalizeVoiceComposerAfterSend();
3812
+ }, [
3813
+ voiceDraft,
3814
+ disabled,
3815
+ isGenerating,
3816
+ onSubmit,
3817
+ attachments,
3818
+ onChange,
3819
+ onAttachmentsChange,
3820
+ finalizeVoiceComposerAfterSend
3821
+ ]);
3822
+ const recordVoiceAgain = useCallback3(async () => {
3823
+ resetVoiceComposerState("idle");
3824
+ await startVoiceCapture();
3825
+ }, [resetVoiceComposerState, startVoiceCapture]);
3826
+ useEffect9(() => {
3827
+ if (voiceState !== "review" || !voiceDraft || voiceAutoSendDelayMs <= 0) {
3828
+ return;
3829
+ }
3830
+ const startedAt = Date.now();
3831
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3832
+ const timer = setInterval(() => {
3833
+ const remaining = Math.max(0, voiceAutoSendDelayMs - (Date.now() - startedAt));
3834
+ setVoiceCountdownMs(remaining);
3835
+ if (remaining <= 0) {
3836
+ clearInterval(timer);
3837
+ sendVoiceDraft();
3838
+ }
3839
+ }, 100);
3840
+ return () => clearInterval(timer);
3841
+ }, [voiceState, voiceDraft, voiceAutoSendDelayMs, sendVoiceDraft]);
3286
3842
  const removeAttachment = (index) => {
3287
3843
  const newAttachments = attachments.filter((_, i) => i !== index);
3288
3844
  onAttachmentsChange(newAttachments);
3289
3845
  };
3290
3846
  const canAddMoreAttachments = attachments.length < maxAttachments;
3291
- return /* @__PURE__ */ jsx21(TooltipProvider, { children: /* @__PURE__ */ jsx21("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ jsxs11("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
3292
- uploadProgress.size > 0 && /* @__PURE__ */ jsx21("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ jsx21(
3847
+ const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;
3848
+ return /* @__PURE__ */ jsx22(TooltipProvider, { children: /* @__PURE__ */ jsx22("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ jsxs12("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
3849
+ uploadProgress.size > 0 && /* @__PURE__ */ jsx22("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ jsx22(
3293
3850
  FileUploadItem,
3294
3851
  {
3295
3852
  file: { name: progress.fileName },
@@ -3304,7 +3861,7 @@ var ChatInput = memo2(function ChatInput2({
3304
3861
  },
3305
3862
  id
3306
3863
  )) }),
3307
- isRecording && /* @__PURE__ */ jsx21(
3864
+ isRecording && /* @__PURE__ */ jsx22(
3308
3865
  AudioRecorder,
3309
3866
  {
3310
3867
  isRecording,
@@ -3315,7 +3872,7 @@ var ChatInput = memo2(function ChatInput2({
3315
3872
  config
3316
3873
  }
3317
3874
  ),
3318
- attachments.length > 0 && /* @__PURE__ */ jsx21("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ jsx21(
3875
+ attachments.length > 0 && /* @__PURE__ */ jsx22("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ jsx22(
3319
3876
  AttachmentPreview,
3320
3877
  {
3321
3878
  attachment,
@@ -3323,15 +3880,46 @@ var ChatInput = memo2(function ChatInput2({
3323
3880
  },
3324
3881
  index
3325
3882
  )) }),
3326
- /* @__PURE__ */ jsx21("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ jsxs11(
3883
+ showVoiceComposer ? /* @__PURE__ */ jsx22("div", { className: "mb-1 flex justify-center", children: /* @__PURE__ */ jsx22(
3884
+ VoiceComposer,
3885
+ {
3886
+ state: voiceState,
3887
+ transcript: voiceTranscript,
3888
+ transcriptMode: voiceTranscriptMode,
3889
+ showTranscriptPreview: voiceShowTranscriptPreview,
3890
+ durationMs: voiceDurationMs,
3891
+ audioLevel: voiceAudioLevel,
3892
+ countdownMs: voiceCountdownMs,
3893
+ autoSendDelayMs: voiceAutoSendDelayMs,
3894
+ errorMessage: voiceError,
3895
+ disabled: disabled || isGenerating,
3896
+ labels: config?.labels,
3897
+ onStart: () => {
3898
+ void startVoiceCapture();
3899
+ },
3900
+ onStop: () => {
3901
+ void stopVoiceCapture();
3902
+ },
3903
+ onCancel: () => {
3904
+ void cancelVoiceCapture();
3905
+ },
3906
+ onSendNow: sendVoiceDraft,
3907
+ onRecordAgain: () => {
3908
+ void recordVoiceAgain();
3909
+ },
3910
+ onExit: () => {
3911
+ void closeVoiceComposer();
3912
+ }
3913
+ }
3914
+ ) }) : /* @__PURE__ */ jsx22("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ jsxs12(
3327
3915
  "div",
3328
3916
  {
3329
3917
  className: "flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl",
3330
3918
  onDrop: handleDrop,
3331
3919
  onDragOver: handleDragOver,
3332
3920
  children: [
3333
- enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ jsxs11(Fragment4, { children: [
3334
- /* @__PURE__ */ jsx21(
3921
+ enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ jsxs12(Fragment5, { children: [
3922
+ /* @__PURE__ */ jsx22(
3335
3923
  "input",
3336
3924
  {
3337
3925
  ref: fileInputRef,
@@ -3342,8 +3930,8 @@ var ChatInput = memo2(function ChatInput2({
3342
3930
  className: "hidden"
3343
3931
  }
3344
3932
  ),
3345
- /* @__PURE__ */ jsxs11(Tooltip, { children: [
3346
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
3933
+ /* @__PURE__ */ jsxs12(Tooltip, { children: [
3934
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3347
3935
  Button,
3348
3936
  {
3349
3937
  type: "button",
@@ -3356,13 +3944,13 @@ var ChatInput = memo2(function ChatInput2({
3356
3944
  fileInputRef.current?.click();
3357
3945
  },
3358
3946
  disabled,
3359
- children: /* @__PURE__ */ jsx21(Paperclip, { className: "h-4 w-4" })
3947
+ children: /* @__PURE__ */ jsx22(Paperclip, { className: "h-4 w-4" })
3360
3948
  }
3361
3949
  ) }),
3362
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.attachFileTooltip })
3950
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.attachFileTooltip })
3363
3951
  ] })
3364
3952
  ] }),
3365
- /* @__PURE__ */ jsx21("div", { className: "flex-1", children: /* @__PURE__ */ jsx21(
3953
+ /* @__PURE__ */ jsx22("div", { className: "flex-1", children: /* @__PURE__ */ jsx22(
3366
3954
  Textarea,
3367
3955
  {
3368
3956
  ref: textareaRef,
@@ -3375,7 +3963,23 @@ var ChatInput = memo2(function ChatInput2({
3375
3963
  rows: 1
3376
3964
  }
3377
3965
  ) }),
3378
- enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ jsx21(
3966
+ enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (voiceComposeEnabled ? /* @__PURE__ */ jsxs12(Tooltip, { children: [
3967
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3968
+ Button,
3969
+ {
3970
+ type: "button",
3971
+ variant: "outline",
3972
+ size: "icon",
3973
+ className: "h-10 w-10",
3974
+ onClick: () => {
3975
+ void startVoiceCapture();
3976
+ },
3977
+ disabled: disabled || isGenerating,
3978
+ children: /* @__PURE__ */ jsx22(Mic2, { className: "h-4 w-4" })
3979
+ }
3980
+ ) }),
3981
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip })
3982
+ ] }) : /* @__PURE__ */ jsx22(
3379
3983
  AudioRecorder,
3380
3984
  {
3381
3985
  isRecording,
@@ -3385,9 +3989,9 @@ var ChatInput = memo2(function ChatInput2({
3385
3989
  recordingDuration,
3386
3990
  config
3387
3991
  }
3388
- ),
3389
- isGenerating ? /* @__PURE__ */ jsxs11(Tooltip, { children: [
3390
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
3992
+ )),
3993
+ isGenerating ? /* @__PURE__ */ jsxs12(Tooltip, { children: [
3994
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3391
3995
  Button,
3392
3996
  {
3393
3997
  type: "button",
@@ -3395,36 +3999,36 @@ var ChatInput = memo2(function ChatInput2({
3395
3999
  size: "icon",
3396
4000
  className: "h-10 w-10",
3397
4001
  onClick: onStopGeneration,
3398
- children: /* @__PURE__ */ jsx21(Square, { className: "h-4 w-4" })
4002
+ children: /* @__PURE__ */ jsx22(Square2, { className: "h-4 w-4" })
3399
4003
  }
3400
4004
  ) }),
3401
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
3402
- ] }) : /* @__PURE__ */ jsxs11(Tooltip, { children: [
3403
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
4005
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
4006
+ ] }) : /* @__PURE__ */ jsxs12(Tooltip, { children: [
4007
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3404
4008
  Button,
3405
4009
  {
3406
4010
  type: "submit",
3407
4011
  size: "icon",
3408
4012
  className: "h-10 w-10",
3409
4013
  disabled: disabled || !value.trim() && attachments.length === 0,
3410
- children: disabled ? /* @__PURE__ */ jsx21(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx21(Send, { className: "h-4 w-4" })
4014
+ children: disabled ? /* @__PURE__ */ jsx22(Loader22, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx22(Send2, { className: "h-4 w-4" })
3411
4015
  }
3412
4016
  ) }),
3413
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.sendMessageTooltip })
4017
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.sendMessageTooltip })
3414
4018
  ] })
3415
4019
  ]
3416
4020
  }
3417
4021
  ) }),
3418
- /* @__PURE__ */ jsxs11("div", { className: "text-[10px] text-muted-foreground text-center", children: [
4022
+ /* @__PURE__ */ jsxs12("div", { className: "text-[10px] text-muted-foreground text-center", children: [
3419
4023
  window.innerWidth > 768 ? config?.labels?.inputHelpText : "",
3420
- attachments.length > 0 && /* @__PURE__ */ jsxs11(Fragment4, { children: [
4024
+ attachments.length > 0 && /* @__PURE__ */ jsxs12(Fragment5, { children: [
3421
4025
  " \u2022 ",
3422
4026
  attachments.length,
3423
4027
  "/",
3424
4028
  maxAttachments,
3425
4029
  " anexos"
3426
4030
  ] }),
3427
- config?.labels?.footerLabel && /* @__PURE__ */ jsxs11(Fragment4, { children: [
4031
+ config?.labels?.footerLabel && /* @__PURE__ */ jsxs12(Fragment5, { children: [
3428
4032
  " \u2022 ",
3429
4033
  config.labels.footerLabel
3430
4034
  ] })
@@ -3438,16 +4042,16 @@ import { useState as useState7 } from "react";
3438
4042
  // src/components/ui/scroll-area.tsx
3439
4043
  import * as React11 from "react";
3440
4044
  import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3441
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
4045
+ import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
3442
4046
  var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
3443
- return /* @__PURE__ */ jsxs12(
4047
+ return /* @__PURE__ */ jsxs13(
3444
4048
  ScrollAreaPrimitive.Root,
3445
4049
  {
3446
4050
  "data-slot": "scroll-area",
3447
4051
  className: cn("relative", className),
3448
4052
  ...props,
3449
4053
  children: [
3450
- /* @__PURE__ */ jsx22(
4054
+ /* @__PURE__ */ jsx23(
3451
4055
  ScrollAreaPrimitive.Viewport,
3452
4056
  {
3453
4057
  ref,
@@ -3461,8 +4065,8 @@ var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, o
3461
4065
  children
3462
4066
  }
3463
4067
  ),
3464
- /* @__PURE__ */ jsx22(ScrollBar, {}),
3465
- /* @__PURE__ */ jsx22(ScrollAreaPrimitive.Corner, {})
4068
+ /* @__PURE__ */ jsx23(ScrollBar, {}),
4069
+ /* @__PURE__ */ jsx23(ScrollAreaPrimitive.Corner, {})
3466
4070
  ]
3467
4071
  }
3468
4072
  );
@@ -3473,7 +4077,7 @@ function ScrollBar({
3473
4077
  orientation = "vertical",
3474
4078
  ...props
3475
4079
  }) {
3476
- return /* @__PURE__ */ jsx22(
4080
+ return /* @__PURE__ */ jsx23(
3477
4081
  ScrollAreaPrimitive.ScrollAreaScrollbar,
3478
4082
  {
3479
4083
  "data-slot": "scroll-area-scrollbar",
@@ -3485,7 +4089,7 @@ function ScrollBar({
3485
4089
  className
3486
4090
  ),
3487
4091
  ...props,
3488
- children: /* @__PURE__ */ jsx22(
4092
+ children: /* @__PURE__ */ jsx23(
3489
4093
  ScrollAreaPrimitive.ScrollAreaThumb,
3490
4094
  {
3491
4095
  "data-slot": "scroll-area-thumb",
@@ -3522,9 +4126,9 @@ import {
3522
4126
  Bot as Bot3,
3523
4127
  Pencil,
3524
4128
  Check as Check3,
3525
- X as X3
4129
+ X as X4
3526
4130
  } from "lucide-react";
3527
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
4131
+ import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
3528
4132
  var getInitials2 = (name, email) => {
3529
4133
  if (name) {
3530
4134
  return name.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase();
@@ -3538,29 +4142,29 @@ var getFieldIcon = (type, key) => {
3538
4142
  const iconClass = "h-4 w-4 text-muted-foreground";
3539
4143
  switch (type) {
3540
4144
  case "email":
3541
- return /* @__PURE__ */ jsx23(Mail, { className: iconClass });
4145
+ return /* @__PURE__ */ jsx24(Mail, { className: iconClass });
3542
4146
  case "phone":
3543
- return /* @__PURE__ */ jsx23(Phone, { className: iconClass });
4147
+ return /* @__PURE__ */ jsx24(Phone, { className: iconClass });
3544
4148
  case "url":
3545
- return /* @__PURE__ */ jsx23(Globe, { className: iconClass });
4149
+ return /* @__PURE__ */ jsx24(Globe, { className: iconClass });
3546
4150
  case "date":
3547
- return /* @__PURE__ */ jsx23(Calendar, { className: iconClass });
4151
+ return /* @__PURE__ */ jsx24(Calendar, { className: iconClass });
3548
4152
  }
3549
4153
  const lowerKey = key?.toLowerCase() || "";
3550
- if (lowerKey.includes("follower")) return /* @__PURE__ */ jsx23(Users, { className: iconClass });
3551
- if (lowerKey.includes("following")) return /* @__PURE__ */ jsx23(UserPlus, { className: iconClass });
3552
- if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ jsx23(Image3, { className: iconClass });
3553
- if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ jsx23(BadgeCheck, { className: iconClass });
3554
- if (lowerKey.includes("bio")) return /* @__PURE__ */ jsx23(FileText2, { className: iconClass });
3555
- if (lowerKey.includes("email")) return /* @__PURE__ */ jsx23(Mail, { className: iconClass });
3556
- if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ jsx23(Phone, { className: iconClass });
3557
- if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ jsx23(MapPin, { className: iconClass });
3558
- if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ jsx23(Building, { className: iconClass });
3559
- if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ jsx23(Briefcase, { className: iconClass });
3560
- if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ jsx23(Globe, { className: iconClass });
3561
- if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ jsx23(AtSign, { className: iconClass });
3562
- if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ jsx23(Calendar, { className: iconClass });
3563
- return /* @__PURE__ */ jsx23(User2, { className: iconClass });
4154
+ if (lowerKey.includes("follower")) return /* @__PURE__ */ jsx24(Users, { className: iconClass });
4155
+ if (lowerKey.includes("following")) return /* @__PURE__ */ jsx24(UserPlus, { className: iconClass });
4156
+ if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ jsx24(Image3, { className: iconClass });
4157
+ if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ jsx24(BadgeCheck, { className: iconClass });
4158
+ if (lowerKey.includes("bio")) return /* @__PURE__ */ jsx24(FileText2, { className: iconClass });
4159
+ if (lowerKey.includes("email")) return /* @__PURE__ */ jsx24(Mail, { className: iconClass });
4160
+ if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ jsx24(Phone, { className: iconClass });
4161
+ if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ jsx24(MapPin, { className: iconClass });
4162
+ if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ jsx24(Building, { className: iconClass });
4163
+ if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ jsx24(Briefcase, { className: iconClass });
4164
+ if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ jsx24(Globe, { className: iconClass });
4165
+ if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ jsx24(AtSign, { className: iconClass });
4166
+ if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ jsx24(Calendar, { className: iconClass });
4167
+ return /* @__PURE__ */ jsx24(User2, { className: iconClass });
3564
4168
  };
3565
4169
  var formatValue = (value, type, key) => {
3566
4170
  if (value === null || value === void 0) return "-";
@@ -3594,15 +4198,15 @@ var getMemoryCategoryIcon = (category) => {
3594
4198
  const iconClass = "h-4 w-4 text-muted-foreground";
3595
4199
  switch (category) {
3596
4200
  case "preference":
3597
- return /* @__PURE__ */ jsx23(Heart, { className: iconClass });
4201
+ return /* @__PURE__ */ jsx24(Heart, { className: iconClass });
3598
4202
  case "fact":
3599
- return /* @__PURE__ */ jsx23(Info, { className: iconClass });
4203
+ return /* @__PURE__ */ jsx24(Info, { className: iconClass });
3600
4204
  case "goal":
3601
- return /* @__PURE__ */ jsx23(Target, { className: iconClass });
4205
+ return /* @__PURE__ */ jsx24(Target, { className: iconClass });
3602
4206
  case "context":
3603
- return /* @__PURE__ */ jsx23(Lightbulb, { className: iconClass });
4207
+ return /* @__PURE__ */ jsx24(Lightbulb, { className: iconClass });
3604
4208
  default:
3605
- return /* @__PURE__ */ jsx23(Brain2, { className: iconClass });
4209
+ return /* @__PURE__ */ jsx24(Brain2, { className: iconClass });
3606
4210
  }
3607
4211
  };
3608
4212
  var getMemoryCategoryLabel = (category) => {
@@ -3672,66 +4276,66 @@ var UserProfile = ({
3672
4276
  const displayName = user?.name || user?.email?.split("@")[0] || "User";
3673
4277
  const initials = getInitials2(user?.name, user?.email);
3674
4278
  const normalizedFields = normalizeCustomFields(customFields);
3675
- return /* @__PURE__ */ jsx23(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs13(
4279
+ return /* @__PURE__ */ jsx24(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs14(
3676
4280
  SheetContent,
3677
4281
  {
3678
4282
  side: "right",
3679
4283
  className: cn("w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden", className),
3680
4284
  children: [
3681
- /* @__PURE__ */ jsx23(SheetHeader, { className: "px-6 py-4 border-b shrink-0", children: /* @__PURE__ */ jsx23("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx23(SheetTitle, { children: labels.title }) }) }),
3682
- /* @__PURE__ */ jsx23(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxs13("div", { className: "p-6 space-y-6", children: [
3683
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-center text-center space-y-4", children: [
3684
- /* @__PURE__ */ jsxs13(Avatar, { className: "h-24 w-24 shrink-0", children: [
3685
- user?.avatar && /* @__PURE__ */ jsx23(AvatarImage, { src: user.avatar, alt: displayName }),
3686
- /* @__PURE__ */ jsx23(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
4285
+ /* @__PURE__ */ jsx24(SheetHeader, { className: "px-6 py-4 border-b shrink-0", children: /* @__PURE__ */ jsx24("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx24(SheetTitle, { children: labels.title }) }) }),
4286
+ /* @__PURE__ */ jsx24(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxs14("div", { className: "p-6 space-y-6", children: [
4287
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center text-center space-y-4", children: [
4288
+ /* @__PURE__ */ jsxs14(Avatar, { className: "h-24 w-24 shrink-0", children: [
4289
+ user?.avatar && /* @__PURE__ */ jsx24(AvatarImage, { src: user.avatar, alt: displayName }),
4290
+ /* @__PURE__ */ jsx24(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
3687
4291
  ] }),
3688
- /* @__PURE__ */ jsxs13("div", { className: "w-full px-2", children: [
3689
- /* @__PURE__ */ jsx23("h2", { className: "text-xl font-semibold break-words", children: displayName }),
3690
- user?.email && /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
4292
+ /* @__PURE__ */ jsxs14("div", { className: "w-full px-2", children: [
4293
+ /* @__PURE__ */ jsx24("h2", { className: "text-xl font-semibold break-words", children: displayName }),
4294
+ user?.email && /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
3691
4295
  ] })
3692
4296
  ] }),
3693
- /* @__PURE__ */ jsx23(Separator, {}),
3694
- /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
3695
- /* @__PURE__ */ jsx23("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
3696
- /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3697
- /* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
3698
- /* @__PURE__ */ jsx23(User2, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
3699
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3700
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "Name" }),
3701
- /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium break-words", children: displayName })
4297
+ /* @__PURE__ */ jsx24(Separator, {}),
4298
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
4299
+ /* @__PURE__ */ jsx24("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
4300
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
4301
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4302
+ /* @__PURE__ */ jsx24(User2, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4303
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4304
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "Name" }),
4305
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium break-words", children: displayName })
3702
4306
  ] })
3703
4307
  ] }),
3704
- user?.email && /* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
3705
- /* @__PURE__ */ jsx23(AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
3706
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3707
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
3708
- /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium break-words", children: user.email })
4308
+ user?.email && /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4309
+ /* @__PURE__ */ jsx24(AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4310
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4311
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
4312
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium break-words", children: user.email })
3709
4313
  ] })
3710
4314
  ] }),
3711
- user?.id && user.id !== user?.name && user.id !== user?.email && /* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
3712
- /* @__PURE__ */ jsx23(User2, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
3713
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3714
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "ID" }),
3715
- /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium break-words", children: user.id })
4315
+ user?.id && user.id !== user?.name && user.id !== user?.email && /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4316
+ /* @__PURE__ */ jsx24(User2, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4317
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4318
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "ID" }),
4319
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium break-words", children: user.id })
3716
4320
  ] })
3717
4321
  ] })
3718
4322
  ] })
3719
4323
  ] }),
3720
- normalizedFields.length > 0 && /* @__PURE__ */ jsxs13(Fragment5, { children: [
3721
- /* @__PURE__ */ jsx23(Separator, {}),
3722
- /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
3723
- /* @__PURE__ */ jsx23("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
3724
- /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: normalizedFields.map((field) => {
4324
+ normalizedFields.length > 0 && /* @__PURE__ */ jsxs14(Fragment6, { children: [
4325
+ /* @__PURE__ */ jsx24(Separator, {}),
4326
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
4327
+ /* @__PURE__ */ jsx24("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
4328
+ /* @__PURE__ */ jsx24("div", { className: "space-y-2", children: normalizedFields.map((field) => {
3725
4329
  const isBioField = field.key.toLowerCase().includes("bio");
3726
- return /* @__PURE__ */ jsxs13(
4330
+ return /* @__PURE__ */ jsxs14(
3727
4331
  "div",
3728
4332
  {
3729
4333
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50",
3730
4334
  children: [
3731
- /* @__PURE__ */ jsx23("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
3732
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3733
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: field.label }),
3734
- /* @__PURE__ */ jsx23("p", { className: cn(
4335
+ /* @__PURE__ */ jsx24("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
4336
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4337
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: field.label }),
4338
+ /* @__PURE__ */ jsx24("p", { className: cn(
3735
4339
  "text-sm font-medium",
3736
4340
  isBioField ? "whitespace-pre-wrap break-words" : "break-words"
3737
4341
  ), children: formatValue(field.value, field.type, field.key) })
@@ -3743,26 +4347,26 @@ var UserProfile = ({
3743
4347
  }) })
3744
4348
  ] })
3745
4349
  ] }),
3746
- /* @__PURE__ */ jsx23(Separator, {}),
3747
- /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
3748
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
3749
- /* @__PURE__ */ jsxs13("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
3750
- /* @__PURE__ */ jsx23(Brain2, { className: "h-4 w-4" }),
4350
+ /* @__PURE__ */ jsx24(Separator, {}),
4351
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
4352
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
4353
+ /* @__PURE__ */ jsxs14("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
4354
+ /* @__PURE__ */ jsx24(Brain2, { className: "h-4 w-4" }),
3751
4355
  labels.memories
3752
4356
  ] }),
3753
- onAddMemory && /* @__PURE__ */ jsx23(
4357
+ onAddMemory && /* @__PURE__ */ jsx24(
3754
4358
  Button,
3755
4359
  {
3756
4360
  variant: "ghost",
3757
4361
  size: "sm",
3758
4362
  className: "h-7 px-2",
3759
4363
  onClick: () => setIsAddingMemory(true),
3760
- children: /* @__PURE__ */ jsx23(Plus3, { className: "h-4 w-4" })
4364
+ children: /* @__PURE__ */ jsx24(Plus3, { className: "h-4 w-4" })
3761
4365
  }
3762
4366
  )
3763
4367
  ] }),
3764
- isAddingMemory && onAddMemory && /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
3765
- /* @__PURE__ */ jsx23(
4368
+ isAddingMemory && onAddMemory && /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
4369
+ /* @__PURE__ */ jsx24(
3766
4370
  Input,
3767
4371
  {
3768
4372
  value: newMemoryContent,
@@ -3779,24 +4383,24 @@ var UserProfile = ({
3779
4383
  autoFocus: true
3780
4384
  }
3781
4385
  ),
3782
- /* @__PURE__ */ jsx23(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
4386
+ /* @__PURE__ */ jsx24(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
3783
4387
  ] }),
3784
- /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: memories.length === 0 ? /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground text-center py-4", children: labels.noMemories }) : memories.map((memory) => {
4388
+ /* @__PURE__ */ jsx24("div", { className: "space-y-2", children: memories.length === 0 ? /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground text-center py-4", children: labels.noMemories }) : memories.map((memory) => {
3785
4389
  const isEditing = editingMemoryId === memory.id;
3786
- return /* @__PURE__ */ jsxs13(
4390
+ return /* @__PURE__ */ jsxs14(
3787
4391
  "div",
3788
4392
  {
3789
4393
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
3790
4394
  children: [
3791
- /* @__PURE__ */ jsx23("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ jsx23(Bot3, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
3792
- /* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
3793
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 mb-0.5", children: [
3794
- /* @__PURE__ */ jsx23("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
3795
- /* @__PURE__ */ jsx23("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
3796
- /* @__PURE__ */ jsx23("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
4395
+ /* @__PURE__ */ jsx24("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ jsx24(Bot3, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
4396
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4397
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-0.5", children: [
4398
+ /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
4399
+ /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
4400
+ /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
3797
4401
  ] }),
3798
- isEditing ? /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3799
- /* @__PURE__ */ jsx23(
4402
+ isEditing ? /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
4403
+ /* @__PURE__ */ jsx24(
3800
4404
  Textarea,
3801
4405
  {
3802
4406
  value: editingMemoryContent,
@@ -3813,8 +4417,8 @@ var UserProfile = ({
3813
4417
  }
3814
4418
  }
3815
4419
  ),
3816
- /* @__PURE__ */ jsxs13("div", { className: "flex gap-1 justify-end", children: [
3817
- /* @__PURE__ */ jsxs13(
4420
+ /* @__PURE__ */ jsxs14("div", { className: "flex gap-1 justify-end", children: [
4421
+ /* @__PURE__ */ jsxs14(
3818
4422
  Button,
3819
4423
  {
3820
4424
  variant: "ghost",
@@ -3822,12 +4426,12 @@ var UserProfile = ({
3822
4426
  className: "h-7 px-2",
3823
4427
  onClick: handleCancelEdit,
3824
4428
  children: [
3825
- /* @__PURE__ */ jsx23(X3, { className: "h-3.5 w-3.5 mr-1" }),
4429
+ /* @__PURE__ */ jsx24(X4, { className: "h-3.5 w-3.5 mr-1" }),
3826
4430
  "Cancelar"
3827
4431
  ]
3828
4432
  }
3829
4433
  ),
3830
- /* @__PURE__ */ jsxs13(
4434
+ /* @__PURE__ */ jsxs14(
3831
4435
  Button,
3832
4436
  {
3833
4437
  size: "sm",
@@ -3835,33 +4439,33 @@ var UserProfile = ({
3835
4439
  onClick: handleSaveEdit,
3836
4440
  disabled: !editingMemoryContent.trim(),
3837
4441
  children: [
3838
- /* @__PURE__ */ jsx23(Check3, { className: "h-3.5 w-3.5 mr-1" }),
4442
+ /* @__PURE__ */ jsx24(Check3, { className: "h-3.5 w-3.5 mr-1" }),
3839
4443
  "Salvar"
3840
4444
  ]
3841
4445
  }
3842
4446
  )
3843
4447
  ] })
3844
- ] }) : /* @__PURE__ */ jsx23("p", { className: "text-sm break-words", children: memory.content })
4448
+ ] }) : /* @__PURE__ */ jsx24("p", { className: "text-sm break-words", children: memory.content })
3845
4449
  ] }),
3846
- !isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ jsxs13("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0", children: [
3847
- onUpdateMemory && /* @__PURE__ */ jsx23(
4450
+ !isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ jsxs14("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0", children: [
4451
+ onUpdateMemory && /* @__PURE__ */ jsx24(
3848
4452
  Button,
3849
4453
  {
3850
4454
  variant: "ghost",
3851
4455
  size: "icon",
3852
4456
  className: "h-7 w-7",
3853
4457
  onClick: () => handleStartEdit(memory),
3854
- children: /* @__PURE__ */ jsx23(Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
4458
+ children: /* @__PURE__ */ jsx24(Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
3855
4459
  }
3856
4460
  ),
3857
- onDeleteMemory && /* @__PURE__ */ jsx23(
4461
+ onDeleteMemory && /* @__PURE__ */ jsx24(
3858
4462
  Button,
3859
4463
  {
3860
4464
  variant: "ghost",
3861
4465
  size: "icon",
3862
4466
  className: "h-7 w-7",
3863
4467
  onClick: () => onDeleteMemory(memory.id),
3864
- children: /* @__PURE__ */ jsx23(Trash23, { className: "h-3.5 w-3.5 text-destructive" })
4468
+ children: /* @__PURE__ */ jsx24(Trash23, { className: "h-3.5 w-3.5 text-destructive" })
3865
4469
  }
3866
4470
  )
3867
4471
  ] })
@@ -3872,8 +4476,8 @@ var UserProfile = ({
3872
4476
  }) })
3873
4477
  ] })
3874
4478
  ] }) }),
3875
- /* @__PURE__ */ jsxs13("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
3876
- onEditProfile && /* @__PURE__ */ jsx23(
4479
+ /* @__PURE__ */ jsxs14("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
4480
+ onEditProfile && /* @__PURE__ */ jsx24(
3877
4481
  Button,
3878
4482
  {
3879
4483
  variant: "outline",
@@ -3882,7 +4486,7 @@ var UserProfile = ({
3882
4486
  children: "Edit Profile"
3883
4487
  }
3884
4488
  ),
3885
- onLogout && /* @__PURE__ */ jsx23(
4489
+ onLogout && /* @__PURE__ */ jsx24(
3886
4490
  Button,
3887
4491
  {
3888
4492
  variant: "destructive",
@@ -3899,7 +4503,7 @@ var UserProfile = ({
3899
4503
 
3900
4504
  // src/components/chat/ChatUI.tsx
3901
4505
  import { Sparkles, ArrowRight, MessageSquare, Lightbulb as Lightbulb2, Zap, HelpCircle } from "lucide-react";
3902
- import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
4506
+ import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
3903
4507
  var ChatUI = ({
3904
4508
  messages = [],
3905
4509
  threads = [],
@@ -4165,13 +4769,13 @@ var ChatUI = ({
4165
4769
  const SuggestionIconComponents = [MessageSquare, Lightbulb2, Zap, HelpCircle];
4166
4770
  const renderSuggestions = () => {
4167
4771
  if (messages.length > 0 || !suggestions.length) return null;
4168
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
4169
- /* @__PURE__ */ jsxs14("div", { className: "text-center mb-8", children: [
4170
- /* @__PURE__ */ jsx24("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__ */ jsx24(Sparkles, { className: "w-7 h-7 text-primary" }) }),
4171
- /* @__PURE__ */ jsx24("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
4172
- /* @__PURE__ */ jsx24("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
4772
+ return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
4773
+ /* @__PURE__ */ jsxs15("div", { className: "text-center mb-8", children: [
4774
+ /* @__PURE__ */ jsx25("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__ */ jsx25(Sparkles, { className: "w-7 h-7 text-primary" }) }),
4775
+ /* @__PURE__ */ jsx25("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
4776
+ /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
4173
4777
  ] }),
4174
- /* @__PURE__ */ jsx24("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs14(
4778
+ /* @__PURE__ */ jsx25("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs15(
4175
4779
  "button",
4176
4780
  {
4177
4781
  type: "button",
@@ -4180,10 +4784,10 @@ var ChatUI = ({
4180
4784
  children: [
4181
4785
  (() => {
4182
4786
  const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];
4183
- return /* @__PURE__ */ jsx24("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__ */ jsx24(IconComponent, { className: "h-4 w-4" }) });
4787
+ return /* @__PURE__ */ jsx25("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__ */ jsx25(IconComponent, { className: "h-4 w-4" }) });
4184
4788
  })(),
4185
- /* @__PURE__ */ jsx24("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
4186
- /* @__PURE__ */ jsx24(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" })
4789
+ /* @__PURE__ */ jsx25("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ jsx25("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
4790
+ /* @__PURE__ */ jsx25(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" })
4187
4791
  ]
4188
4792
  },
4189
4793
  index
@@ -4194,34 +4798,34 @@ var ChatUI = ({
4194
4798
  const items = messageSuggestions?.[messageId];
4195
4799
  if (!items || items.length === 0) return null;
4196
4800
  const inlineSuggestionOffsetClass = config.ui.showAvatars ? config.ui.compactMode ? "ml-9" : "ml-11" : "";
4197
- return /* @__PURE__ */ jsx24("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ jsxs14(
4801
+ return /* @__PURE__ */ jsx25("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ jsxs15(
4198
4802
  "button",
4199
4803
  {
4200
4804
  type: "button",
4201
4805
  onClick: () => handleSendMessage(suggestion),
4202
4806
  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",
4203
4807
  children: [
4204
- /* @__PURE__ */ jsx24(Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4205
- /* @__PURE__ */ jsx24("span", { className: "max-w-[200px] truncate", children: suggestion })
4808
+ /* @__PURE__ */ jsx25(Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4809
+ /* @__PURE__ */ jsx25("span", { className: "max-w-[200px] truncate", children: suggestion })
4206
4810
  ]
4207
4811
  },
4208
4812
  `${messageId}-suggestion-${index}`
4209
4813
  )) });
4210
4814
  };
4211
- const renderMessageLoadingSkeleton = () => /* @__PURE__ */ jsx24("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4815
+ const renderMessageLoadingSkeleton = () => /* @__PURE__ */ jsx25("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4212
4816
  const isUserRow = index % 2 === 1;
4213
- return /* @__PURE__ */ jsxs14(
4817
+ return /* @__PURE__ */ jsxs15(
4214
4818
  "div",
4215
4819
  {
4216
4820
  className: `flex gap-3 ${isUserRow ? "justify-end" : "justify-start"}`,
4217
4821
  children: [
4218
- !isUserRow && /* @__PURE__ */ jsx24(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
4219
- /* @__PURE__ */ jsxs14("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
4220
- /* @__PURE__ */ jsx24(Skeleton, { className: "h-4 w-24" }),
4221
- /* @__PURE__ */ jsx24(Skeleton, { className: "h-4 w-full" }),
4222
- /* @__PURE__ */ jsx24(Skeleton, { className: "h-4 w-[85%]" })
4822
+ !isUserRow && /* @__PURE__ */ jsx25(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
4823
+ /* @__PURE__ */ jsxs15("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
4824
+ /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-24" }),
4825
+ /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-full" }),
4826
+ /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-[85%]" })
4223
4827
  ] }),
4224
- isUserRow && /* @__PURE__ */ jsx24(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4828
+ isUserRow && /* @__PURE__ */ jsx25(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4225
4829
  ]
4226
4830
  },
4227
4831
  `message-skeleton-${index}`
@@ -4277,8 +4881,8 @@ var ChatUI = ({
4277
4881
  const shouldShowAgentSelector = Boolean(
4278
4882
  config.agentSelector?.enabled && onSelectAgent && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1)
4279
4883
  );
4280
- return /* @__PURE__ */ jsx24(TooltipProvider, { children: /* @__PURE__ */ jsx24(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ jsxs14("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
4281
- /* @__PURE__ */ jsx24(
4884
+ return /* @__PURE__ */ jsx25(TooltipProvider, { children: /* @__PURE__ */ jsx25(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ jsxs15("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
4885
+ /* @__PURE__ */ jsx25(
4282
4886
  Sidebar2,
4283
4887
  {
4284
4888
  threads,
@@ -4295,8 +4899,8 @@ var ChatUI = ({
4295
4899
  showThemeOptions: !!callbacks.onThemeChange
4296
4900
  }
4297
4901
  ),
4298
- /* @__PURE__ */ jsx24(SidebarInset, { children: /* @__PURE__ */ jsxs14("div", { className: "flex flex-col h-full min-h-0", children: [
4299
- /* @__PURE__ */ jsx24(
4902
+ /* @__PURE__ */ jsx25(SidebarInset, { children: /* @__PURE__ */ jsxs15("div", { className: "flex flex-col h-full min-h-0", children: [
4903
+ /* @__PURE__ */ jsx25(
4300
4904
  ChatHeader,
4301
4905
  {
4302
4906
  config,
@@ -4311,9 +4915,9 @@ var ChatUI = ({
4311
4915
  onSelectAgent
4312
4916
  }
4313
4917
  ),
4314
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
4315
- /* @__PURE__ */ jsxs14("div", { className: "flex-1 flex flex-col min-h-0", children: [
4316
- /* @__PURE__ */ jsx24(
4918
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
4919
+ /* @__PURE__ */ jsxs15("div", { className: "flex-1 flex flex-col min-h-0", children: [
4920
+ /* @__PURE__ */ jsx25(
4317
4921
  ScrollArea,
4318
4922
  {
4319
4923
  ref: scrollAreaRef,
@@ -4321,7 +4925,7 @@ var ChatUI = ({
4321
4925
  viewportClassName: "p-4 overscroll-contain",
4322
4926
  onScrollCapture: handleScroll,
4323
4927
  style: { contain: "strict" },
4324
- children: /* @__PURE__ */ jsx24("div", { className: "max-w-4xl mx-auto pb-4", children: isMessagesLoading ? renderMessageLoadingSkeleton() : messages.length === 0 ? renderSuggestions() : /* @__PURE__ */ jsx24(
4928
+ children: /* @__PURE__ */ jsx25("div", { className: "max-w-4xl mx-auto pb-4", children: isMessagesLoading ? renderMessageLoadingSkeleton() : messages.length === 0 ? renderSuggestions() : /* @__PURE__ */ jsx25(
4325
4929
  "div",
4326
4930
  {
4327
4931
  style: {
@@ -4333,7 +4937,7 @@ var ChatUI = ({
4333
4937
  const message = messages[virtualRow.index];
4334
4938
  const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;
4335
4939
  const isGrouped = prevMessage !== null && prevMessage.role === message.role;
4336
- return /* @__PURE__ */ jsx24(
4940
+ return /* @__PURE__ */ jsx25(
4337
4941
  "div",
4338
4942
  {
4339
4943
  "data-index": virtualRow.index,
@@ -4345,8 +4949,8 @@ var ChatUI = ({
4345
4949
  width: "100%",
4346
4950
  transform: `translateY(${virtualRow.start}px)`
4347
4951
  },
4348
- children: /* @__PURE__ */ jsxs14("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4349
- /* @__PURE__ */ jsx24(
4952
+ children: /* @__PURE__ */ jsxs15("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4953
+ /* @__PURE__ */ jsx25(
4350
4954
  Message,
4351
4955
  {
4352
4956
  message,
@@ -4365,7 +4969,7 @@ var ChatUI = ({
4365
4969
  ) })
4366
4970
  }
4367
4971
  ),
4368
- /* @__PURE__ */ jsx24("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ jsx24(
4972
+ /* @__PURE__ */ jsx25("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ jsx25(
4369
4973
  ChatInput,
4370
4974
  {
4371
4975
  value: inputValue,
@@ -4391,17 +4995,17 @@ var ChatUI = ({
4391
4995
  }
4392
4996
  ) })
4393
4997
  ] }),
4394
- config?.customComponent?.component && !isMobile && /* @__PURE__ */ jsx24(
4998
+ config?.customComponent?.component && !isMobile && /* @__PURE__ */ jsx25(
4395
4999
  "div",
4396
5000
  {
4397
5001
  className: `h-full transition-all duration-300 ease-in-out overflow-hidden ${state.showSidebar ? "w-80" : "w-0"}`,
4398
- children: state.showSidebar && /* @__PURE__ */ jsx24("div", { className: "flex flex-col h-full border-l bg-background animate-in slide-in-from-right-4 duration-300 w-80", children: renderCustomComponent() })
5002
+ children: state.showSidebar && /* @__PURE__ */ jsx25("div", { className: "flex flex-col h-full border-l bg-background animate-in slide-in-from-right-4 duration-300 w-80", children: renderCustomComponent() })
4399
5003
  }
4400
5004
  )
4401
5005
  ] })
4402
5006
  ] }) }),
4403
- isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ jsxs14("div", { className: "fixed inset-0 z-50", children: [
4404
- /* @__PURE__ */ jsx24(
5007
+ isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ jsxs15("div", { className: "fixed inset-0 z-50", children: [
5008
+ /* @__PURE__ */ jsx25(
4405
5009
  "div",
4406
5010
  {
4407
5011
  className: `absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${isCustomVisible ? "opacity-100" : "opacity-0"}`,
@@ -4409,16 +5013,16 @@ var ChatUI = ({
4409
5013
  onClick: closeSidebar
4410
5014
  }
4411
5015
  ),
4412
- /* @__PURE__ */ jsx24(
5016
+ /* @__PURE__ */ jsx25(
4413
5017
  "div",
4414
5018
  {
4415
5019
  className: `absolute top-0 right-0 h-full w-full bg-background transform-gpu transition-transform duration-200 ease-out ${isCustomVisible ? "translate-x-0" : "translate-x-full"}`,
4416
5020
  style: { willChange: "transform" },
4417
- children: /* @__PURE__ */ jsx24("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
5021
+ children: /* @__PURE__ */ jsx25("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
4418
5022
  }
4419
5023
  )
4420
5024
  ] }),
4421
- isUserProfileOpen && /* @__PURE__ */ jsx24(
5025
+ isUserProfileOpen && /* @__PURE__ */ jsx25(
4422
5026
  UserProfile,
4423
5027
  {
4424
5028
  isOpen: isUserProfileOpen,
@@ -4453,10 +5057,10 @@ import {
4453
5057
  Filter as Filter2,
4454
5058
  Calendar as Calendar2,
4455
5059
  Hash,
4456
- X as X4,
5060
+ X as X5,
4457
5061
  Check as Check4
4458
5062
  } from "lucide-react";
4459
- import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
5063
+ import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
4460
5064
  var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
4461
5065
  const [isEditing, setIsEditing] = useState9(false);
4462
5066
  const [editTitle, setEditTitle] = useState9(thread.title);
@@ -4485,9 +5089,9 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4485
5089
  handleCancelEdit();
4486
5090
  }
4487
5091
  };
4488
- return /* @__PURE__ */ jsx25(Card, { className: `cursor-pointer transition-all duration-200 hover:shadow-md py-0 ${isActive ? "ring-2 ring-primary bg-primary/5" : "hover:bg-muted/50"}`, children: /* @__PURE__ */ jsx25(CardContent, { className: "p-3 max-w-sm", children: /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-2", children: [
4489
- /* @__PURE__ */ jsx25("div", { className: "flex-1 min-w-0", onClick: onSelect, children: isEditing ? /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
4490
- /* @__PURE__ */ jsx25(
5092
+ return /* @__PURE__ */ jsx26(Card, { className: `cursor-pointer transition-all duration-200 hover:shadow-md py-0 ${isActive ? "ring-2 ring-primary bg-primary/5" : "hover:bg-muted/50"}`, children: /* @__PURE__ */ jsx26(CardContent, { className: "p-3 max-w-sm", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-2", children: [
5093
+ /* @__PURE__ */ jsx26("div", { className: "flex-1 min-w-0", onClick: onSelect, children: isEditing ? /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
5094
+ /* @__PURE__ */ jsx26(
4491
5095
  Input,
4492
5096
  {
4493
5097
  ref: inputRef,
@@ -4499,44 +5103,44 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4499
5103
  placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
4500
5104
  }
4501
5105
  ),
4502
- /* @__PURE__ */ jsx25(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx25(Check4, { className: "h-3 w-3" }) }),
4503
- /* @__PURE__ */ jsx25(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ jsx25(X4, { className: "h-3 w-3" }) })
4504
- ] }) : /* @__PURE__ */ jsxs15(Fragment6, { children: [
4505
- /* @__PURE__ */ jsx25("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
4506
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
4507
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1", children: [
4508
- /* @__PURE__ */ jsx25(Hash, { className: "h-3 w-3" }),
5106
+ /* @__PURE__ */ jsx26(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx26(Check4, { className: "h-3 w-3" }) }),
5107
+ /* @__PURE__ */ jsx26(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ jsx26(X5, { className: "h-3 w-3" }) })
5108
+ ] }) : /* @__PURE__ */ jsxs16(Fragment7, { children: [
5109
+ /* @__PURE__ */ jsx26("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
5110
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
5111
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
5112
+ /* @__PURE__ */ jsx26(Hash, { className: "h-3 w-3" }),
4509
5113
  thread.messageCount,
4510
5114
  " msgs"
4511
5115
  ] }),
4512
- /* @__PURE__ */ jsx25(Separator, { orientation: "vertical", className: "h-3" }),
4513
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1", children: [
4514
- /* @__PURE__ */ jsx25(Calendar2, { className: "h-3 w-3" }),
5116
+ /* @__PURE__ */ jsx26(Separator, { orientation: "vertical", className: "h-3" }),
5117
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
5118
+ /* @__PURE__ */ jsx26(Calendar2, { className: "h-3 w-3" }),
4515
5119
  formatDate(thread.updatedAt, config?.labels)
4516
5120
  ] }),
4517
- thread.isArchived && /* @__PURE__ */ jsxs15(Fragment6, { children: [
4518
- /* @__PURE__ */ jsx25(Separator, { orientation: "vertical", className: "h-3" }),
4519
- /* @__PURE__ */ jsxs15(Badge, { variant: "secondary", className: "text-xs", children: [
4520
- /* @__PURE__ */ jsx25(Archive2, { className: "h-2 w-2 mr-1" }),
5121
+ thread.isArchived && /* @__PURE__ */ jsxs16(Fragment7, { children: [
5122
+ /* @__PURE__ */ jsx26(Separator, { orientation: "vertical", className: "h-3" }),
5123
+ /* @__PURE__ */ jsxs16(Badge, { variant: "secondary", className: "text-xs", children: [
5124
+ /* @__PURE__ */ jsx26(Archive2, { className: "h-2 w-2 mr-1" }),
4521
5125
  config?.labels?.archiveThread || "Archived"
4522
5126
  ] })
4523
5127
  ] })
4524
5128
  ] })
4525
5129
  ] }) }),
4526
- !isEditing && /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
4527
- /* @__PURE__ */ jsx25(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 m-auto", children: /* @__PURE__ */ jsx25(MoreVertical2, { className: "h-3 w-3" }) }) }),
4528
- /* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", children: [
4529
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
4530
- /* @__PURE__ */ jsx25(Edit22, { className: "h-4 w-4 mr-2" }),
5130
+ !isEditing && /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
5131
+ /* @__PURE__ */ jsx26(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 m-auto", children: /* @__PURE__ */ jsx26(MoreVertical2, { className: "h-3 w-3" }) }) }),
5132
+ /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
5133
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
5134
+ /* @__PURE__ */ jsx26(Edit22, { className: "h-4 w-4 mr-2" }),
4531
5135
  config?.labels?.renameThread || "Rename"
4532
5136
  ] }),
4533
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: onArchive, children: [
4534
- /* @__PURE__ */ jsx25(Archive2, { className: "h-4 w-4 mr-2" }),
5137
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: onArchive, children: [
5138
+ /* @__PURE__ */ jsx26(Archive2, { className: "h-4 w-4 mr-2" }),
4535
5139
  thread.isArchived ? config?.labels?.unarchiveThread || "Unarchive" : config?.labels?.archiveThread || "Archive"
4536
5140
  ] }),
4537
- /* @__PURE__ */ jsx25(DropdownMenuSeparator, {}),
4538
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
4539
- /* @__PURE__ */ jsx25(Trash24, { className: "h-4 w-4 mr-2" }),
5141
+ /* @__PURE__ */ jsx26(DropdownMenuSeparator, {}),
5142
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
5143
+ /* @__PURE__ */ jsx26(Trash24, { className: "h-4 w-4 mr-2" }),
4540
5144
  config?.labels?.deleteThread || "Delete"
4541
5145
  ] })
4542
5146
  ] })
@@ -4551,17 +5155,17 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4551
5155
  setTitle("");
4552
5156
  setIsOpen(false);
4553
5157
  };
4554
- return /* @__PURE__ */ jsxs15(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
4555
- /* @__PURE__ */ jsx25(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(Button, { variant: "outline", className: "w-full", children: [
4556
- /* @__PURE__ */ jsx25(Plus4, { className: "h-4 w-4 mr-2" }),
5158
+ return /* @__PURE__ */ jsxs16(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
5159
+ /* @__PURE__ */ jsx26(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs16(Button, { variant: "outline", className: "w-full", children: [
5160
+ /* @__PURE__ */ jsx26(Plus4, { className: "h-4 w-4 mr-2" }),
4557
5161
  config?.labels?.createNewThread || "New Conversation"
4558
5162
  ] }) }),
4559
- /* @__PURE__ */ jsxs15(DialogContent, { children: [
4560
- /* @__PURE__ */ jsxs15(DialogHeader, { children: [
4561
- /* @__PURE__ */ jsx25(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
4562
- /* @__PURE__ */ jsx25(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
5163
+ /* @__PURE__ */ jsxs16(DialogContent, { children: [
5164
+ /* @__PURE__ */ jsxs16(DialogHeader, { children: [
5165
+ /* @__PURE__ */ jsx26(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
5166
+ /* @__PURE__ */ jsx26(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
4563
5167
  ] }),
4564
- /* @__PURE__ */ jsx25(
5168
+ /* @__PURE__ */ jsx26(
4565
5169
  Input,
4566
5170
  {
4567
5171
  value: title,
@@ -4571,9 +5175,9 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4571
5175
  autoFocus: true
4572
5176
  }
4573
5177
  ),
4574
- /* @__PURE__ */ jsxs15(DialogFooter, { children: [
4575
- /* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
4576
- /* @__PURE__ */ jsx25(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
5178
+ /* @__PURE__ */ jsxs16(DialogFooter, { children: [
5179
+ /* @__PURE__ */ jsx26(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
5180
+ /* @__PURE__ */ jsx26(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
4577
5181
  ] })
4578
5182
  ] })
4579
5183
  ] });
@@ -4627,20 +5231,20 @@ var ThreadManager = ({
4627
5231
  setDeleteThreadId(null);
4628
5232
  };
4629
5233
  if (!isOpen) return null;
4630
- return /* @__PURE__ */ jsx25(TooltipProvider, { children: /* @__PURE__ */ jsxs15("div", { className: `fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`, children: [
4631
- /* @__PURE__ */ jsx25("div", { className: "fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg", children: /* @__PURE__ */ jsxs15(Card, { className: "h-full border-0 rounded-none", children: [
4632
- /* @__PURE__ */ jsxs15(CardHeader, { className: "border-b", children: [
4633
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
4634
- /* @__PURE__ */ jsxs15(CardTitle, { className: "flex items-center gap-2", children: [
4635
- /* @__PURE__ */ jsx25(MessageSquare2, { className: "h-5 w-5" }),
5234
+ return /* @__PURE__ */ jsx26(TooltipProvider, { children: /* @__PURE__ */ jsxs16("div", { className: `fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`, children: [
5235
+ /* @__PURE__ */ jsx26("div", { className: "fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg", children: /* @__PURE__ */ jsxs16(Card, { className: "h-full border-0 rounded-none", children: [
5236
+ /* @__PURE__ */ jsxs16(CardHeader, { className: "border-b", children: [
5237
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
5238
+ /* @__PURE__ */ jsxs16(CardTitle, { className: "flex items-center gap-2", children: [
5239
+ /* @__PURE__ */ jsx26(MessageSquare2, { className: "h-5 w-5" }),
4636
5240
  config?.labels?.newChat || "Conversations"
4637
5241
  ] }),
4638
- /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx25(X4, { className: "h-4 w-4" }) })
5242
+ /* @__PURE__ */ jsx26(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx26(X5, { className: "h-4 w-4" }) })
4639
5243
  ] }),
4640
- /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
4641
- /* @__PURE__ */ jsxs15("div", { className: "relative", children: [
4642
- /* @__PURE__ */ jsx25(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
4643
- /* @__PURE__ */ jsx25(
5244
+ /* @__PURE__ */ jsxs16("div", { className: "space-y-3", children: [
5245
+ /* @__PURE__ */ jsxs16("div", { className: "relative", children: [
5246
+ /* @__PURE__ */ jsx26(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
5247
+ /* @__PURE__ */ jsx26(
4644
5248
  Input,
4645
5249
  {
4646
5250
  placeholder: config?.labels?.search || "Search conversations...",
@@ -4650,8 +5254,8 @@ var ThreadManager = ({
4650
5254
  }
4651
5255
  )
4652
5256
  ] }),
4653
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
4654
- /* @__PURE__ */ jsxs15(
5257
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
5258
+ /* @__PURE__ */ jsxs16(
4655
5259
  Button,
4656
5260
  {
4657
5261
  variant: "outline",
@@ -4659,12 +5263,12 @@ var ThreadManager = ({
4659
5263
  onClick: () => setShowArchived(!showArchived),
4660
5264
  className: "text-xs",
4661
5265
  children: [
4662
- /* @__PURE__ */ jsx25(Filter2, { className: "h-3 w-3 mr-1" }),
5266
+ /* @__PURE__ */ jsx26(Filter2, { className: "h-3 w-3 mr-1" }),
4663
5267
  showArchived ? config?.labels?.hideArchived || "Hide Archived" : config?.labels?.showArchived || "Show Archived"
4664
5268
  ]
4665
5269
  }
4666
5270
  ),
4667
- /* @__PURE__ */ jsxs15(Badge, { variant: "secondary", className: "text-xs", children: [
5271
+ /* @__PURE__ */ jsxs16(Badge, { variant: "secondary", className: "text-xs", children: [
4668
5272
  filteredThreads.length,
4669
5273
  " / ",
4670
5274
  threads.length
@@ -4672,14 +5276,14 @@ var ThreadManager = ({
4672
5276
  ] })
4673
5277
  ] })
4674
5278
  ] }),
4675
- /* @__PURE__ */ jsxs15(CardContent, { className: "p-0 flex-1", children: [
4676
- /* @__PURE__ */ jsx25("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ jsx25(CreateThreadDialog2, { onCreateThread, config }) }),
4677
- /* @__PURE__ */ jsx25(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ jsx25("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: [
4678
- /* @__PURE__ */ jsx25(MessageSquare2, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
4679
- /* @__PURE__ */ jsx25("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
4680
- ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ jsxs15("div", { children: [
4681
- /* @__PURE__ */ jsx25("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
4682
- /* @__PURE__ */ jsx25("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ jsx25(
5279
+ /* @__PURE__ */ jsxs16(CardContent, { className: "p-0 flex-1", children: [
5280
+ /* @__PURE__ */ jsx26("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ jsx26(CreateThreadDialog2, { onCreateThread, config }) }),
5281
+ /* @__PURE__ */ jsx26(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ jsx26("div", { className: "px-4 pb-4 space-y-4", children: Object.keys(groupedThreads).length === 0 ? /* @__PURE__ */ jsxs16("div", { className: "text-center py-8 text-muted-foreground", children: [
5282
+ /* @__PURE__ */ jsx26(MessageSquare2, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
5283
+ /* @__PURE__ */ jsx26("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
5284
+ ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ jsxs16("div", { children: [
5285
+ /* @__PURE__ */ jsx26("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
5286
+ /* @__PURE__ */ jsx26("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ jsx26(
4683
5287
  ThreadItem,
4684
5288
  {
4685
5289
  thread,
@@ -4695,14 +5299,14 @@ var ThreadManager = ({
4695
5299
  ] }, group)) }) })
4696
5300
  ] })
4697
5301
  ] }) }),
4698
- deleteThreadId && /* @__PURE__ */ jsx25(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs15(AlertDialogContent, { children: [
4699
- /* @__PURE__ */ jsxs15(AlertDialogHeader, { children: [
4700
- /* @__PURE__ */ jsx25(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
4701
- /* @__PURE__ */ jsx25(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
5302
+ deleteThreadId && /* @__PURE__ */ jsx26(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs16(AlertDialogContent, { children: [
5303
+ /* @__PURE__ */ jsxs16(AlertDialogHeader, { children: [
5304
+ /* @__PURE__ */ jsx26(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
5305
+ /* @__PURE__ */ jsx26(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
4702
5306
  ] }),
4703
- /* @__PURE__ */ jsxs15(AlertDialogFooter, { children: [
4704
- /* @__PURE__ */ jsx25(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
4705
- /* @__PURE__ */ jsx25(
5307
+ /* @__PURE__ */ jsxs16(AlertDialogFooter, { children: [
5308
+ /* @__PURE__ */ jsx26(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
5309
+ /* @__PURE__ */ jsx26(
4706
5310
  AlertDialogAction,
4707
5311
  {
4708
5312
  onClick: () => deleteThreadId && handleDeleteThread(deleteThreadId),