@copilotz/chat-ui 0.1.31 → 0.1.33

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,26 @@ 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",
36
+ voiceIdle: "Tap the mic to record",
37
+ voicePreparing: "Preparing microphone...",
38
+ voiceWaiting: "Waiting for speech...",
39
+ voiceListening: "Listening...",
40
+ voiceFinishing: "Finishing capture...",
41
+ voiceReview: "Ready to send",
42
+ voiceSending: "Sending...",
43
+ voiceStart: "Start recording",
44
+ voiceStop: "Stop recording",
45
+ voiceSendNow: "Send now",
46
+ voiceCancel: "Cancel",
47
+ voiceDiscard: "Delete recording",
48
+ voiceRecordAgain: "Record again",
49
+ voiceAutoSendIn: "Auto-sends in {{seconds}}s",
50
+ voiceTranscriptPending: "Transcript unavailable",
51
+ voicePermissionDenied: "Microphone access was denied.",
52
+ voiceCaptureError: "Unable to capture audio.",
33
53
  // Header labels
34
54
  exportData: "Export data",
35
55
  importData: "Import data",
@@ -92,6 +112,16 @@ var defaultChatConfig = {
92
112
  longMessageChunkChars: 12e3,
93
113
  renderUserMarkdown: true
94
114
  },
115
+ voiceCompose: {
116
+ enabled: false,
117
+ defaultMode: "text",
118
+ autoSendDelayMs: 5e3,
119
+ persistComposer: true,
120
+ showTranscriptPreview: true,
121
+ transcriptMode: "final-only",
122
+ maxRecordingMs: 6e4,
123
+ createProvider: void 0
124
+ },
95
125
  customComponent: {},
96
126
  headerActions: null
97
127
  };
@@ -114,6 +144,10 @@ function mergeConfig(_baseConfig, userConfig) {
114
144
  ...defaultChatConfig.ui,
115
145
  ...userConfig.ui
116
146
  },
147
+ voiceCompose: {
148
+ ...defaultChatConfig.voiceCompose,
149
+ ...userConfig.voiceCompose
150
+ },
117
151
  agentSelector: {
118
152
  ...defaultChatConfig.agentSelector,
119
153
  ...userConfig.agentSelector
@@ -732,7 +766,7 @@ var MediaRenderer = memo(function MediaRenderer2({ attachment }) {
732
766
  URL.revokeObjectURL(objectUrl);
733
767
  };
734
768
  }, [attachment.kind, attachment.dataUrl]);
735
- const formatDuration = (ms) => {
769
+ const formatDuration2 = (ms) => {
736
770
  if (!ms) return "";
737
771
  const seconds = Math.floor(ms / 1e3);
738
772
  const minutes = Math.floor(seconds / 60);
@@ -2794,6 +2828,215 @@ function useChatUserContext() {
2794
2828
  return v;
2795
2829
  }
2796
2830
 
2831
+ // src/lib/voiceCompose.ts
2832
+ var AUDIO_MIME_TYPES = [
2833
+ "audio/webm;codecs=opus",
2834
+ "audio/webm",
2835
+ "audio/mp4",
2836
+ "audio/ogg;codecs=opus"
2837
+ ];
2838
+ var pickRecorderMimeType = () => {
2839
+ if (typeof MediaRecorder === "undefined") return void 0;
2840
+ for (const mimeType of AUDIO_MIME_TYPES) {
2841
+ if (typeof MediaRecorder.isTypeSupported === "function" && MediaRecorder.isTypeSupported(mimeType)) {
2842
+ return mimeType;
2843
+ }
2844
+ }
2845
+ return void 0;
2846
+ };
2847
+ var blobToDataUrl = (blob) => new Promise((resolve, reject) => {
2848
+ const reader = new FileReader();
2849
+ reader.onload = () => resolve(reader.result);
2850
+ reader.onerror = () => reject(reader.error ?? new Error("Failed to read recorded audio"));
2851
+ reader.readAsDataURL(blob);
2852
+ });
2853
+ var stopStream = (stream) => {
2854
+ if (!stream) return;
2855
+ stream.getTracks().forEach((track) => track.stop());
2856
+ };
2857
+ var closeAudioContext = async (audioContext) => {
2858
+ if (!audioContext) return;
2859
+ try {
2860
+ await audioContext.close();
2861
+ } catch {
2862
+ }
2863
+ };
2864
+ var emitDuration = (handlers, startedAt) => {
2865
+ handlers.onDurationChange?.(Math.max(0, Date.now() - startedAt));
2866
+ };
2867
+ var createManualVoiceProvider = async (handlers, options = {}) => {
2868
+ let mediaRecorder = null;
2869
+ let mediaStream = null;
2870
+ let audioContext = null;
2871
+ let analyser = null;
2872
+ let levelData = null;
2873
+ let levelFrame = 0;
2874
+ let durationTimer = null;
2875
+ let maxDurationTimer = null;
2876
+ let startedAt = 0;
2877
+ let shouldEmitSegment = true;
2878
+ let isStarting = false;
2879
+ const clearTimers = () => {
2880
+ if (durationTimer) {
2881
+ clearInterval(durationTimer);
2882
+ durationTimer = null;
2883
+ }
2884
+ if (maxDurationTimer) {
2885
+ clearTimeout(maxDurationTimer);
2886
+ maxDurationTimer = null;
2887
+ }
2888
+ };
2889
+ const stopLevelLoop = () => {
2890
+ if (levelFrame) {
2891
+ cancelAnimationFrame(levelFrame);
2892
+ levelFrame = 0;
2893
+ }
2894
+ handlers.onAudioLevelChange?.(0);
2895
+ };
2896
+ const startLevelLoop = () => {
2897
+ if (!analyser || !levelData) return;
2898
+ const tick = () => {
2899
+ if (!analyser || !levelData) return;
2900
+ analyser.getByteTimeDomainData(levelData);
2901
+ let sum = 0;
2902
+ for (let index = 0; index < levelData.length; index += 1) {
2903
+ const centered = (levelData[index] - 128) / 128;
2904
+ sum += centered * centered;
2905
+ }
2906
+ const rms = Math.sqrt(sum / levelData.length);
2907
+ handlers.onAudioLevelChange?.(Math.min(1, rms * 4));
2908
+ levelFrame = requestAnimationFrame(tick);
2909
+ };
2910
+ tick();
2911
+ };
2912
+ const cleanupActiveResources = async () => {
2913
+ clearTimers();
2914
+ stopLevelLoop();
2915
+ stopStream(mediaStream);
2916
+ mediaStream = null;
2917
+ analyser = null;
2918
+ levelData = null;
2919
+ await closeAudioContext(audioContext);
2920
+ audioContext = null;
2921
+ };
2922
+ const finalizeStop = async () => {
2923
+ mediaRecorder = null;
2924
+ isStarting = false;
2925
+ await cleanupActiveResources();
2926
+ };
2927
+ const start = async () => {
2928
+ if (isStarting || mediaRecorder?.state === "recording") {
2929
+ return;
2930
+ }
2931
+ if (!navigator.mediaDevices?.getUserMedia) {
2932
+ throw new Error("Audio capture is not supported in this browser");
2933
+ }
2934
+ if (typeof MediaRecorder === "undefined") {
2935
+ throw new Error("MediaRecorder is not supported in this browser");
2936
+ }
2937
+ isStarting = true;
2938
+ shouldEmitSegment = true;
2939
+ handlers.onTranscriptChange?.({});
2940
+ handlers.onDurationChange?.(0);
2941
+ handlers.onAudioLevelChange?.(0);
2942
+ handlers.onStateChange?.("preparing");
2943
+ try {
2944
+ mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
2945
+ const mimeType = pickRecorderMimeType();
2946
+ mediaRecorder = mimeType ? new MediaRecorder(mediaStream, { mimeType }) : new MediaRecorder(mediaStream);
2947
+ const chunks = [];
2948
+ mediaRecorder.ondataavailable = (event) => {
2949
+ if (event.data.size > 0) {
2950
+ chunks.push(event.data);
2951
+ }
2952
+ };
2953
+ mediaRecorder.onerror = (event) => {
2954
+ const error = event.error ?? new Error("Audio recorder failed");
2955
+ handlers.onError?.(error);
2956
+ };
2957
+ mediaRecorder.onstop = async () => {
2958
+ const durationMs = startedAt > 0 ? Math.max(0, Date.now() - startedAt) : 0;
2959
+ try {
2960
+ if (shouldEmitSegment && chunks.length > 0) {
2961
+ const blob = new Blob(chunks, {
2962
+ type: mediaRecorder?.mimeType || mimeType || "audio/webm"
2963
+ });
2964
+ const dataUrl = await blobToDataUrl(blob);
2965
+ handlers.onSegmentReady?.({
2966
+ attachment: {
2967
+ kind: "audio",
2968
+ dataUrl,
2969
+ mimeType: blob.type || "audio/webm",
2970
+ durationMs,
2971
+ fileName: `voice-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.webm`,
2972
+ size: blob.size
2973
+ },
2974
+ metadata: { source: "manual" }
2975
+ });
2976
+ } else {
2977
+ handlers.onStateChange?.("idle");
2978
+ }
2979
+ } catch (error) {
2980
+ handlers.onError?.(error);
2981
+ } finally {
2982
+ await finalizeStop();
2983
+ }
2984
+ };
2985
+ const AudioContextCtor = globalThis.AudioContext || globalThis.webkitAudioContext;
2986
+ if (AudioContextCtor) {
2987
+ audioContext = new AudioContextCtor();
2988
+ await audioContext.resume().catch(() => void 0);
2989
+ const sourceNode = audioContext.createMediaStreamSource(mediaStream);
2990
+ analyser = audioContext.createAnalyser();
2991
+ analyser.fftSize = 1024;
2992
+ levelData = new Uint8Array(analyser.fftSize);
2993
+ sourceNode.connect(analyser);
2994
+ startLevelLoop();
2995
+ }
2996
+ startedAt = Date.now();
2997
+ emitDuration(handlers, startedAt);
2998
+ durationTimer = setInterval(() => emitDuration(handlers, startedAt), 200);
2999
+ if (options.maxRecordingMs && options.maxRecordingMs > 0) {
3000
+ maxDurationTimer = setTimeout(() => {
3001
+ void stop();
3002
+ }, options.maxRecordingMs);
3003
+ }
3004
+ mediaRecorder.start();
3005
+ handlers.onStateChange?.("listening");
3006
+ } catch (error) {
3007
+ isStarting = false;
3008
+ await cleanupActiveResources();
3009
+ throw error;
3010
+ }
3011
+ };
3012
+ const stop = async () => {
3013
+ if (!mediaRecorder || mediaRecorder.state === "inactive") {
3014
+ return;
3015
+ }
3016
+ handlers.onStateChange?.("finishing");
3017
+ mediaRecorder.stop();
3018
+ };
3019
+ const cancel = async () => {
3020
+ shouldEmitSegment = false;
3021
+ if (mediaRecorder && mediaRecorder.state !== "inactive") {
3022
+ mediaRecorder.stop();
3023
+ return;
3024
+ }
3025
+ await finalizeStop();
3026
+ handlers.onStateChange?.("idle");
3027
+ };
3028
+ const destroy = async () => {
3029
+ await cancel();
3030
+ };
3031
+ return {
3032
+ start,
3033
+ stop,
3034
+ cancel,
3035
+ destroy
3036
+ };
3037
+ };
3038
+ var resolveVoiceProviderFactory = (createProvider) => createProvider ?? createManualVoiceProvider;
3039
+
2797
3040
  // src/components/ui/progress.tsx
2798
3041
  import * as ProgressPrimitive from "@radix-ui/react-progress";
2799
3042
  import { jsx as jsx20 } from "react/jsx-runtime";
@@ -2823,21 +3066,197 @@ function Progress({
2823
3066
  );
2824
3067
  }
2825
3068
 
3069
+ // src/components/chat/VoiceComposer.tsx
3070
+ import { Keyboard, Loader2, Mic, Send, Square, Trash2 as Trash23, X as X2 } from "lucide-react";
3071
+ import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3072
+ var formatDuration = (durationMs) => {
3073
+ const totalSeconds = Math.max(0, Math.floor(durationMs / 1e3));
3074
+ const minutes = Math.floor(totalSeconds / 60);
3075
+ const seconds = totalSeconds % 60;
3076
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
3077
+ };
3078
+ var interpolateSeconds = (label, seconds) => {
3079
+ if (!label) {
3080
+ return `Auto-sends in ${seconds}s`;
3081
+ }
3082
+ if (label.includes("{{seconds}}")) {
3083
+ return label.replace(/\{\{\s*seconds\s*\}\}/g, String(seconds));
3084
+ }
3085
+ return `${label} ${seconds}s`;
3086
+ };
3087
+ var resolveStateLabel = (state, labels, errorMessage) => {
3088
+ switch (state) {
3089
+ case "preparing":
3090
+ return labels?.voicePreparing || "Preparing microphone...";
3091
+ case "waiting_for_speech":
3092
+ return labels?.voiceWaiting || "Waiting for speech...";
3093
+ case "listening":
3094
+ return labels?.voiceListening || "Listening...";
3095
+ case "finishing":
3096
+ return labels?.voiceFinishing || "Finishing capture...";
3097
+ case "review":
3098
+ return labels?.voiceReview || "Ready to send";
3099
+ case "sending":
3100
+ return labels?.voiceSending || "Sending...";
3101
+ case "error":
3102
+ return errorMessage || labels?.voiceCaptureError || "Unable to capture audio.";
3103
+ case "idle":
3104
+ default:
3105
+ return labels?.voiceIdle || "Tap the mic to record";
3106
+ }
3107
+ };
3108
+ var resolveTranscriptText = (transcript, transcriptMode) => {
3109
+ if (transcriptMode === "none" || !transcript) {
3110
+ return null;
3111
+ }
3112
+ if (transcriptMode === "final-only") {
3113
+ return transcript.final?.trim() || null;
3114
+ }
3115
+ return transcript.final?.trim() || transcript.partial?.trim() || null;
3116
+ };
3117
+ var VoiceComposer = ({
3118
+ state,
3119
+ transcript,
3120
+ transcriptMode,
3121
+ showTranscriptPreview,
3122
+ attachment,
3123
+ durationMs,
3124
+ audioLevel,
3125
+ countdownMs,
3126
+ autoSendDelayMs,
3127
+ isAutoSendActive,
3128
+ errorMessage,
3129
+ disabled = false,
3130
+ labels,
3131
+ onStart,
3132
+ onStop,
3133
+ onCancelAutoSend,
3134
+ onDiscard,
3135
+ onRecordAgain,
3136
+ onSendNow,
3137
+ onExit
3138
+ }) => {
3139
+ const transcriptText = resolveTranscriptText(transcript, transcriptMode);
3140
+ const countdownSeconds = Math.max(1, Math.ceil(countdownMs / 1e3));
3141
+ const countdownValue = autoSendDelayMs > 0 ? Math.min(100, Math.max(0, (autoSendDelayMs - countdownMs) / autoSendDelayMs * 100)) : 100;
3142
+ const isBusy = state === "preparing" || state === "finishing" || state === "sending";
3143
+ const isCapturing = state === "waiting_for_speech" || state === "listening";
3144
+ const isReviewing = state === "review";
3145
+ const levelValue = isCapturing || state === "preparing" || state === "finishing" ? Math.max(8, Math.round(audioLevel * 100)) : 0;
3146
+ const headerLabel = state === "error" ? labels?.voiceCaptureError || "Unable to capture audio." : resolveStateLabel(state, labels, errorMessage);
3147
+ return /* @__PURE__ */ jsxs11("div", { className: "w-full max-w-3xl rounded-xl border bg-background p-3 shadow-sm sm:p-4 md:min-w-3xl", children: [
3148
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-2 sm:gap-3", children: [
3149
+ /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 items-center gap-2", children: [
3150
+ /* @__PURE__ */ jsx21(Badge, { variant: "outline", children: labels?.voiceTitle || "Voice" }),
3151
+ /* @__PURE__ */ jsx21("span", { className: "truncate text-xs sm:text-sm text-muted-foreground", children: headerLabel })
3152
+ ] }),
3153
+ /* @__PURE__ */ jsxs11(
3154
+ Button,
3155
+ {
3156
+ type: "button",
3157
+ variant: "ghost",
3158
+ size: "sm",
3159
+ className: "shrink-0 px-2 sm:px-3",
3160
+ onClick: onExit,
3161
+ disabled: disabled || isBusy,
3162
+ children: [
3163
+ /* @__PURE__ */ jsx21(Keyboard, { className: "h-4 w-4" }),
3164
+ /* @__PURE__ */ jsx21("span", { className: "hidden sm:inline", children: labels?.voiceExit || "Use keyboard" })
3165
+ ]
3166
+ }
3167
+ )
3168
+ ] }),
3169
+ !isReviewing ? /* @__PURE__ */ jsx21("div", { className: "mt-3 rounded-xl border border-dashed border-primary/30 bg-primary/5 px-3 py-3 text-center sm:px-4 sm:py-4", children: /* @__PURE__ */ jsxs11("div", { className: "mx-auto flex w-full max-w-sm flex-col items-center gap-3", children: [
3170
+ /* @__PURE__ */ jsx21(
3171
+ Button,
3172
+ {
3173
+ type: "button",
3174
+ size: "icon",
3175
+ variant: isCapturing ? "destructive" : "outline",
3176
+ className: `h-16 w-16 rounded-full sm:h-20 sm:w-20 ${isCapturing ? "bg-red-500 hover:bg-red-600 text-white border-red-500" : "border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700"}`,
3177
+ onClick: isCapturing ? onStop : onStart,
3178
+ disabled: disabled || isBusy,
3179
+ children: isBusy ? /* @__PURE__ */ jsx21(Loader2, { className: "h-7 w-7 animate-spin" }) : isCapturing ? /* @__PURE__ */ jsx21(Square, { className: "h-7 w-7" }) : /* @__PURE__ */ jsx21(Mic, { className: "h-7 w-7" })
3180
+ }
3181
+ ),
3182
+ /* @__PURE__ */ jsxs11("div", { className: "w-full space-y-2", children: [
3183
+ /* @__PURE__ */ jsx21(Progress, { value: levelValue, className: "h-2" }),
3184
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
3185
+ /* @__PURE__ */ jsx21("span", { children: formatDuration(durationMs) }),
3186
+ /* @__PURE__ */ jsx21("span", { children: isCapturing ? labels?.voiceStop || "Stop recording" : labels?.voiceStart || "Start recording" })
3187
+ ] })
3188
+ ] }),
3189
+ showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ jsx21("div", { className: "w-full rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText })
3190
+ ] }) }) : /* @__PURE__ */ jsxs11("div", { className: "mt-3 rounded-xl border bg-muted/20 p-3 sm:p-4", children: [
3191
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-start justify-between gap-2", children: [
3192
+ /* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
3193
+ /* @__PURE__ */ jsx21("div", { className: "text-sm font-medium text-foreground", children: labels?.voiceReview || "Ready to send" }),
3194
+ /* @__PURE__ */ jsx21("div", { className: "text-xs text-muted-foreground", children: formatDuration(durationMs) })
3195
+ ] }),
3196
+ /* @__PURE__ */ jsx21(
3197
+ Button,
3198
+ {
3199
+ type: "button",
3200
+ variant: "ghost",
3201
+ size: "icon",
3202
+ className: "h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive",
3203
+ onClick: onDiscard,
3204
+ disabled,
3205
+ "aria-label": labels?.voiceDiscard || "Delete recording",
3206
+ title: labels?.voiceDiscard || "Delete recording",
3207
+ children: /* @__PURE__ */ jsx21(Trash23, { className: "h-4 w-4" })
3208
+ }
3209
+ )
3210
+ ] }),
3211
+ attachment && /* @__PURE__ */ jsx21("div", { className: "mt-3 rounded-lg bg-background p-2", children: /* @__PURE__ */ jsx21("audio", { controls: true, preload: "metadata", className: "w-full", children: /* @__PURE__ */ jsx21("source", { src: attachment.dataUrl, type: attachment.mimeType }) }) }),
3212
+ showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ jsx21("div", { className: "mt-3 rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText }),
3213
+ isAutoSendActive && autoSendDelayMs > 0 && /* @__PURE__ */ jsxs11("div", { className: "mt-3 space-y-2", children: [
3214
+ /* @__PURE__ */ jsx21(Progress, { value: countdownValue, className: "h-2" }),
3215
+ /* @__PURE__ */ jsx21("div", { className: "text-center text-xs text-muted-foreground", children: interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds) })
3216
+ ] }),
3217
+ /* @__PURE__ */ jsxs11("div", { className: "mt-3 flex items-center justify-end gap-2", children: [
3218
+ isAutoSendActive && /* @__PURE__ */ jsxs11(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancelAutoSend, disabled, children: [
3219
+ /* @__PURE__ */ jsx21(X2, { className: "h-4 w-4" }),
3220
+ labels?.voiceCancel || "Cancel"
3221
+ ] }),
3222
+ !isAutoSendActive && /* @__PURE__ */ jsx21(
3223
+ Button,
3224
+ {
3225
+ type: "button",
3226
+ variant: "outline",
3227
+ size: "icon",
3228
+ onClick: onRecordAgain,
3229
+ disabled,
3230
+ "aria-label": labels?.voiceRecordAgain || "Record again",
3231
+ title: labels?.voiceRecordAgain || "Record again",
3232
+ children: /* @__PURE__ */ jsx21(Mic, { className: "h-4 w-4" })
3233
+ }
3234
+ ),
3235
+ /* @__PURE__ */ jsxs11(Button, { type: "button", size: "sm", onClick: onSendNow, disabled, children: [
3236
+ /* @__PURE__ */ jsx21(Send, { className: "h-4 w-4" }),
3237
+ labels?.voiceSendNow || "Send now"
3238
+ ] })
3239
+ ] })
3240
+ ] }),
3241
+ state === "error" && errorMessage && /* @__PURE__ */ jsx21("div", { className: "mt-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: errorMessage })
3242
+ ] });
3243
+ };
3244
+
2826
3245
  // src/components/chat/ChatInput.tsx
2827
3246
  import {
2828
- Send,
3247
+ Send as Send2,
2829
3248
  Paperclip,
2830
- Mic,
3249
+ Mic as Mic2,
2831
3250
  Image as Image2,
2832
3251
  Video,
2833
3252
  FileText,
2834
- X as X2,
2835
- Square,
3253
+ X as X3,
3254
+ Square as Square2,
2836
3255
  Play,
2837
3256
  Pause,
2838
- Loader2
3257
+ Loader2 as Loader22
2839
3258
  } from "lucide-react";
2840
- import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3259
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
2841
3260
  var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }) {
2842
3261
  const guessTypeFromName = (name) => {
2843
3262
  const ext = (name || "").split(".").pop()?.toLowerCase();
@@ -2866,10 +3285,10 @@ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }
2866
3285
  };
2867
3286
  const getFileIcon = (type, name) => {
2868
3287
  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" });
3288
+ if (t.startsWith("image/")) return /* @__PURE__ */ jsx22(Image2, { className: "h-4 w-4" });
3289
+ if (t.startsWith("video/")) return /* @__PURE__ */ jsx22(Video, { className: "h-4 w-4" });
3290
+ if (t.startsWith("audio/")) return /* @__PURE__ */ jsx22(Mic2, { className: "h-4 w-4" });
3291
+ return /* @__PURE__ */ jsx22(FileText, { className: "h-4 w-4" });
2873
3292
  };
2874
3293
  const formatFileSize = (bytes) => {
2875
3294
  if (bytes === 0) return "0 Bytes";
@@ -2878,21 +3297,21 @@ var FileUploadItem = memo2(function FileUploadItem2({ file, progress, onCancel }
2878
3297
  const i = Math.floor(Math.log(bytes) / Math.log(k));
2879
3298
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
2880
3299
  };
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: [
3300
+ 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
3301
  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" })
3302
+ /* @__PURE__ */ jsxs12("div", { className: "flex-1 min-w-0", children: [
3303
+ /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium truncate", children: file.name }),
3304
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
3305
+ /* @__PURE__ */ jsx22(Progress, { value: progress, className: "h-1 mt-1" })
2887
3306
  ] }),
2888
- /* @__PURE__ */ jsx21(
3307
+ /* @__PURE__ */ jsx22(
2889
3308
  Button,
2890
3309
  {
2891
3310
  variant: "ghost",
2892
3311
  size: "icon",
2893
3312
  className: "h-6 w-6",
2894
3313
  onClick: onCancel,
2895
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3314
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
2896
3315
  }
2897
3316
  )
2898
3317
  ] }) }) });
@@ -2926,35 +3345,35 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2926
3345
  setIsPlaying(!isPlaying);
2927
3346
  }
2928
3347
  };
2929
- const formatDuration = (ms) => {
3348
+ const formatDuration2 = (ms) => {
2930
3349
  if (!ms) return "";
2931
3350
  const seconds = Math.floor(ms / 1e3);
2932
3351
  const minutes = Math.floor(seconds / 60);
2933
3352
  return `${minutes}:${(seconds % 60).toString().padStart(2, "0")}`;
2934
3353
  };
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(
3354
+ return /* @__PURE__ */ jsx22(Card, { className: "relative group", children: /* @__PURE__ */ jsxs12(CardContent, { className: "p-2", children: [
3355
+ attachment.kind === "image" && /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
3356
+ /* @__PURE__ */ jsx22(
2938
3357
  "img",
2939
3358
  {
2940
3359
  src: attachment.dataUrl,
2941
- alt: attachment.fileName || "Anexo",
3360
+ alt: attachment.fileName || "Attachment",
2942
3361
  className: "w-full h-20 object-cover rounded"
2943
3362
  }
2944
3363
  ),
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(
3364
+ /* @__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
3365
  Button,
2947
3366
  {
2948
3367
  variant: "destructive",
2949
3368
  size: "icon",
2950
3369
  className: "h-6 w-6",
2951
3370
  onClick: onRemove,
2952
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3371
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
2953
3372
  }
2954
3373
  ) })
2955
3374
  ] }),
2956
- attachment.kind === "video" && /* @__PURE__ */ jsxs11("div", { className: "relative", children: [
2957
- /* @__PURE__ */ jsx21(
3375
+ attachment.kind === "video" && /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
3376
+ /* @__PURE__ */ jsx22(
2958
3377
  "video",
2959
3378
  {
2960
3379
  src: attachment.dataUrl,
@@ -2963,34 +3382,34 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2963
3382
  muted: true
2964
3383
  }
2965
3384
  ),
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(
3385
+ /* @__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
3386
  Button,
2968
3387
  {
2969
3388
  variant: "destructive",
2970
3389
  size: "icon",
2971
3390
  className: "h-6 w-6",
2972
3391
  onClick: onRemove,
2973
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3392
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
2974
3393
  }
2975
3394
  ) }),
2976
- /* @__PURE__ */ jsx21(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration(attachment.durationMs) })
3395
+ /* @__PURE__ */ jsx22(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration2(attachment.durationMs) })
2977
3396
  ] }),
2978
- attachment.kind === "audio" && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 p-2", children: [
2979
- /* @__PURE__ */ jsx21(
3397
+ attachment.kind === "audio" && /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 p-2", children: [
3398
+ /* @__PURE__ */ jsx22(
2980
3399
  Button,
2981
3400
  {
2982
3401
  variant: "outline",
2983
3402
  size: "icon",
2984
3403
  className: "h-8 w-8",
2985
3404
  onClick: handlePlayPause,
2986
- children: isPlaying ? /* @__PURE__ */ jsx21(Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx21(Play, { className: "h-3 w-3" })
3405
+ children: isPlaying ? /* @__PURE__ */ jsx22(Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx22(Play, { className: "h-3 w-3" })
2987
3406
  }
2988
3407
  ),
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) })
3408
+ /* @__PURE__ */ jsxs12("div", { className: "flex-1", children: [
3409
+ /* @__PURE__ */ jsx22("p", { className: "text-xs font-medium", children: attachment.fileName || "Audio" }),
3410
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: formatDuration2(attachment.durationMs) })
2992
3411
  ] }),
2993
- /* @__PURE__ */ jsx21(
3412
+ /* @__PURE__ */ jsx22(
2994
3413
  "audio",
2995
3414
  {
2996
3415
  ref: audioRef,
@@ -2998,21 +3417,21 @@ var AttachmentPreview = memo2(function AttachmentPreview2({ attachment, onRemove
2998
3417
  onPause: () => setIsPlaying(false),
2999
3418
  onEnded: () => setIsPlaying(false),
3000
3419
  preload: "metadata",
3001
- children: /* @__PURE__ */ jsx21("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3420
+ children: /* @__PURE__ */ jsx22("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3002
3421
  }
3003
3422
  ),
3004
- /* @__PURE__ */ jsx21(
3423
+ /* @__PURE__ */ jsx22(
3005
3424
  Button,
3006
3425
  {
3007
3426
  variant: "ghost",
3008
3427
  size: "icon",
3009
3428
  className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
3010
3429
  onClick: onRemove,
3011
- children: /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3" })
3430
+ children: /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3" })
3012
3431
  }
3013
3432
  )
3014
3433
  ] }),
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 }) })
3434
+ 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
3435
  ] }) });
3017
3436
  });
3018
3437
  var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
@@ -3022,61 +3441,71 @@ var AudioRecorder = memo2(function AudioRecorder2({ isRecording, onStartRecordin
3022
3441
  return `${mins}:${secs.toString().padStart(2, "0")}`;
3023
3442
  };
3024
3443
  if (!isRecording) {
3025
- return /* @__PURE__ */ jsxs11(Tooltip, { children: [
3026
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
3444
+ return /* @__PURE__ */ jsxs12(Tooltip, { children: [
3445
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3027
3446
  Button,
3028
3447
  {
3029
3448
  variant: "outline",
3030
3449
  size: "icon",
3031
3450
  onClick: onStartRecording,
3032
3451
  className: "h-10 w-10",
3033
- children: /* @__PURE__ */ jsx21(Mic, { className: "h-4 w-4" })
3452
+ children: /* @__PURE__ */ jsx22(Mic2, { className: "h-4 w-4" })
3034
3453
  }
3035
3454
  ) }),
3036
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3455
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3037
3456
  ] });
3038
3457
  }
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" })
3458
+ 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: [
3459
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
3460
+ /* @__PURE__ */ jsx22("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
3461
+ /* @__PURE__ */ jsx22("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: config?.labels?.voiceListening || "Recording" })
3043
3462
  ] }),
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(
3463
+ /* @__PURE__ */ jsx22(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
3464
+ /* @__PURE__ */ jsxs12("div", { className: "flex gap-1 ml-auto", children: [
3465
+ /* @__PURE__ */ jsxs12(
3047
3466
  Button,
3048
3467
  {
3049
3468
  variant: "outline",
3050
3469
  size: "sm",
3051
3470
  onClick: onCancel,
3052
3471
  children: [
3053
- /* @__PURE__ */ jsx21(X2, { className: "h-3 w-3 mr-1" }),
3054
- "Cancelar"
3472
+ /* @__PURE__ */ jsx22(X3, { className: "h-3 w-3 mr-1" }),
3473
+ config?.labels?.cancel || "Cancel"
3055
3474
  ]
3056
3475
  }
3057
3476
  ),
3058
- /* @__PURE__ */ jsxs11(
3477
+ /* @__PURE__ */ jsxs12(
3059
3478
  Button,
3060
3479
  {
3061
3480
  variant: "default",
3062
3481
  size: "sm",
3063
3482
  onClick: onStopRecording,
3064
3483
  children: [
3065
- /* @__PURE__ */ jsx21(Square, { className: "h-3 w-3 mr-1" }),
3066
- "Parar"
3484
+ /* @__PURE__ */ jsx22(Square2, { className: "h-3 w-3 mr-1" }),
3485
+ config?.labels?.voiceStop || "Stop"
3067
3486
  ]
3068
3487
  }
3069
3488
  )
3070
3489
  ] })
3071
3490
  ] }) }) });
3072
3491
  });
3492
+ var resolveVoiceErrorMessage = (error, config) => {
3493
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
3494
+ return config?.labels?.voicePermissionDenied || "Microphone access was denied.";
3495
+ }
3496
+ if (error instanceof Error && error.message.trim().length > 0) {
3497
+ return error.message;
3498
+ }
3499
+ return config?.labels?.voiceCaptureError || "Unable to capture audio.";
3500
+ };
3501
+ var clearVoiceTranscript = () => ({});
3073
3502
  var ChatInput = memo2(function ChatInput2({
3074
3503
  value,
3075
3504
  onChange,
3076
3505
  onSubmit,
3077
3506
  attachments,
3078
3507
  onAttachmentsChange,
3079
- placeholder = "Digite sua mensagem...",
3508
+ placeholder = "Type your message...",
3080
3509
  disabled = false,
3081
3510
  isGenerating = false,
3082
3511
  onStopGeneration,
@@ -3089,16 +3518,35 @@ var ChatInput = memo2(function ChatInput2({
3089
3518
  className = "",
3090
3519
  config
3091
3520
  }) {
3521
+ const voiceComposeEnabled = config?.voiceCompose?.enabled === true;
3522
+ const voiceDefaultMode = config?.voiceCompose?.defaultMode ?? "text";
3523
+ const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5e3;
3524
+ const voicePersistComposer = config?.voiceCompose?.persistComposer ?? true;
3525
+ const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;
3526
+ const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? "final-only";
3527
+ const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;
3092
3528
  const [isRecording, setIsRecording] = useState6(false);
3093
3529
  const { setContext } = useChatUserContext();
3094
3530
  const [recordingDuration, setRecordingDuration] = useState6(0);
3095
3531
  const [uploadProgress, setUploadProgress] = useState6(/* @__PURE__ */ new Map());
3532
+ const [isVoiceComposerOpen, setIsVoiceComposerOpen] = useState6(
3533
+ () => voiceComposeEnabled && voiceDefaultMode === "voice"
3534
+ );
3535
+ const [voiceState, setVoiceState] = useState6("idle");
3536
+ const [voiceDraft, setVoiceDraft] = useState6(null);
3537
+ const [voiceTranscript, setVoiceTranscript] = useState6(clearVoiceTranscript);
3538
+ const [voiceDurationMs, setVoiceDurationMs] = useState6(0);
3539
+ const [voiceAudioLevel, setVoiceAudioLevel] = useState6(0);
3540
+ const [voiceCountdownMs, setVoiceCountdownMs] = useState6(0);
3541
+ const [isVoiceAutoSendActive, setIsVoiceAutoSendActive] = useState6(false);
3542
+ const [voiceError, setVoiceError] = useState6(null);
3096
3543
  const textareaRef = useRef5(null);
3097
3544
  const fileInputRef = useRef5(null);
3098
3545
  const mediaRecorderRef = useRef5(null);
3099
3546
  const recordingStartTime = useRef5(0);
3100
3547
  const recordingInterval = useRef5(null);
3101
3548
  const mediaStreamRef = useRef5(null);
3549
+ const voiceProviderRef = useRef5(null);
3102
3550
  useEffect9(() => {
3103
3551
  return () => {
3104
3552
  if (mediaStreamRef.current) {
@@ -3107,6 +3555,10 @@ var ChatInput = memo2(function ChatInput2({
3107
3555
  if (recordingInterval.current) {
3108
3556
  clearInterval(recordingInterval.current);
3109
3557
  }
3558
+ if (voiceProviderRef.current) {
3559
+ void voiceProviderRef.current.destroy();
3560
+ voiceProviderRef.current = null;
3561
+ }
3110
3562
  };
3111
3563
  }, []);
3112
3564
  const handleSubmit = (e) => {
@@ -3124,7 +3576,7 @@ var ChatInput = memo2(function ChatInput2({
3124
3576
  };
3125
3577
  const processFile = async (file) => {
3126
3578
  if (file.size > maxFileSize) {
3127
- alert(`Arquivo muito grande. M\xE1ximo permitido: ${Math.round(maxFileSize / 1024 / 1024)}MB`);
3579
+ alert(`File too large. Max allowed: ${Math.round(maxFileSize / 1024 / 1024)}MB`);
3128
3580
  return null;
3129
3581
  }
3130
3582
  const fileId = `${Date.now()}_${Math.random().toString(36).slice(2)}`;
@@ -3183,7 +3635,7 @@ var ChatInput = memo2(function ChatInput2({
3183
3635
  newMap.delete(fileId);
3184
3636
  return newMap;
3185
3637
  });
3186
- alert("Erro ao processar arquivo");
3638
+ alert("Failed to process file");
3187
3639
  return null;
3188
3640
  }
3189
3641
  };
@@ -3258,7 +3710,7 @@ var ChatInput = memo2(function ChatInput2({
3258
3710
  }, 1e3);
3259
3711
  } catch (error) {
3260
3712
  console.error("Error starting recording:", error);
3261
- alert("N\xE3o foi poss\xEDvel acessar o microfone");
3713
+ alert(config?.labels?.voicePermissionDenied || "Microphone access was denied.");
3262
3714
  }
3263
3715
  };
3264
3716
  const stopRecording = () => {
@@ -3283,13 +3735,154 @@ var ChatInput = memo2(function ChatInput2({
3283
3735
  }
3284
3736
  }
3285
3737
  };
3738
+ const resetVoiceComposerState = useCallback3((nextState = "idle") => {
3739
+ setVoiceState(nextState);
3740
+ setVoiceDraft(null);
3741
+ setVoiceTranscript(clearVoiceTranscript());
3742
+ setVoiceDurationMs(0);
3743
+ setVoiceAudioLevel(0);
3744
+ setVoiceCountdownMs(0);
3745
+ setIsVoiceAutoSendActive(false);
3746
+ setVoiceError(null);
3747
+ }, []);
3748
+ const ensureVoiceProvider = useCallback3(async () => {
3749
+ if (voiceProviderRef.current) {
3750
+ return voiceProviderRef.current;
3751
+ }
3752
+ const createProvider = resolveVoiceProviderFactory(config?.voiceCompose?.createProvider);
3753
+ const provider = await createProvider({
3754
+ onStateChange: setVoiceState,
3755
+ onAudioLevelChange: setVoiceAudioLevel,
3756
+ onDurationChange: setVoiceDurationMs,
3757
+ onTranscriptChange: setVoiceTranscript,
3758
+ onSegmentReady: (segment) => {
3759
+ setVoiceDraft(segment);
3760
+ setVoiceTranscript(segment.transcript ?? clearVoiceTranscript());
3761
+ setVoiceDurationMs(segment.attachment.durationMs ?? 0);
3762
+ setVoiceAudioLevel(0);
3763
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3764
+ setIsVoiceAutoSendActive(voiceAutoSendDelayMs > 0);
3765
+ setVoiceError(null);
3766
+ setVoiceState("review");
3767
+ },
3768
+ onError: (error) => {
3769
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3770
+ setVoiceAudioLevel(0);
3771
+ setVoiceCountdownMs(0);
3772
+ setIsVoiceAutoSendActive(false);
3773
+ setVoiceState("error");
3774
+ }
3775
+ }, {
3776
+ maxRecordingMs: voiceMaxRecordingMs
3777
+ });
3778
+ voiceProviderRef.current = provider;
3779
+ return provider;
3780
+ }, [config, voiceAutoSendDelayMs, voiceMaxRecordingMs]);
3781
+ const closeVoiceComposer = useCallback3(async () => {
3782
+ setIsVoiceComposerOpen(false);
3783
+ setVoiceError(null);
3784
+ setVoiceCountdownMs(0);
3785
+ setVoiceAudioLevel(0);
3786
+ setVoiceTranscript(clearVoiceTranscript());
3787
+ setVoiceDraft(null);
3788
+ setVoiceDurationMs(0);
3789
+ setVoiceState("idle");
3790
+ if (voiceProviderRef.current) {
3791
+ await voiceProviderRef.current.cancel();
3792
+ }
3793
+ }, []);
3794
+ const startVoiceCapture = useCallback3(async () => {
3795
+ if (disabled || isGenerating) {
3796
+ return;
3797
+ }
3798
+ setIsVoiceComposerOpen(true);
3799
+ setVoiceError(null);
3800
+ setVoiceDraft(null);
3801
+ setVoiceCountdownMs(0);
3802
+ setVoiceTranscript(clearVoiceTranscript());
3803
+ setVoiceAudioLevel(0);
3804
+ setVoiceDurationMs(0);
3805
+ setIsVoiceAutoSendActive(false);
3806
+ try {
3807
+ const provider = await ensureVoiceProvider();
3808
+ await provider.start();
3809
+ } catch (error) {
3810
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3811
+ setVoiceState("error");
3812
+ }
3813
+ }, [disabled, isGenerating, ensureVoiceProvider, config]);
3814
+ const stopVoiceCapture = useCallback3(async () => {
3815
+ if (!voiceProviderRef.current) return;
3816
+ try {
3817
+ await voiceProviderRef.current.stop();
3818
+ } catch (error) {
3819
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3820
+ setVoiceState("error");
3821
+ }
3822
+ }, [config]);
3823
+ const cancelVoiceCapture = useCallback3(async () => {
3824
+ if (voiceProviderRef.current) {
3825
+ await voiceProviderRef.current.cancel();
3826
+ }
3827
+ resetVoiceComposerState("idle");
3828
+ }, [resetVoiceComposerState]);
3829
+ const finalizeVoiceComposerAfterSend = useCallback3(() => {
3830
+ if (voicePersistComposer) {
3831
+ resetVoiceComposerState("idle");
3832
+ setIsVoiceComposerOpen(true);
3833
+ return;
3834
+ }
3835
+ void closeVoiceComposer();
3836
+ }, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);
3837
+ const sendVoiceDraft = useCallback3(() => {
3838
+ if (!voiceDraft || disabled || isGenerating) {
3839
+ return;
3840
+ }
3841
+ setVoiceState("sending");
3842
+ setVoiceCountdownMs(0);
3843
+ setIsVoiceAutoSendActive(false);
3844
+ onSubmit("", [...attachments, voiceDraft.attachment]);
3845
+ onChange("");
3846
+ onAttachmentsChange([]);
3847
+ finalizeVoiceComposerAfterSend();
3848
+ }, [
3849
+ voiceDraft,
3850
+ disabled,
3851
+ isGenerating,
3852
+ onSubmit,
3853
+ attachments,
3854
+ onChange,
3855
+ onAttachmentsChange,
3856
+ finalizeVoiceComposerAfterSend
3857
+ ]);
3858
+ const cancelVoiceAutoSend = useCallback3(() => {
3859
+ setVoiceCountdownMs(0);
3860
+ setIsVoiceAutoSendActive(false);
3861
+ }, []);
3862
+ useEffect9(() => {
3863
+ if (voiceState !== "review" || !voiceDraft || voiceAutoSendDelayMs <= 0 || !isVoiceAutoSendActive) {
3864
+ return;
3865
+ }
3866
+ const startedAt = Date.now();
3867
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3868
+ const timer = setInterval(() => {
3869
+ const remaining = Math.max(0, voiceAutoSendDelayMs - (Date.now() - startedAt));
3870
+ setVoiceCountdownMs(remaining);
3871
+ if (remaining <= 0) {
3872
+ clearInterval(timer);
3873
+ sendVoiceDraft();
3874
+ }
3875
+ }, 100);
3876
+ return () => clearInterval(timer);
3877
+ }, [voiceState, voiceDraft, voiceAutoSendDelayMs, isVoiceAutoSendActive, sendVoiceDraft]);
3286
3878
  const removeAttachment = (index) => {
3287
3879
  const newAttachments = attachments.filter((_, i) => i !== index);
3288
3880
  onAttachmentsChange(newAttachments);
3289
3881
  };
3290
3882
  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(
3883
+ const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;
3884
+ 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: [
3885
+ uploadProgress.size > 0 && /* @__PURE__ */ jsx22("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ jsx22(
3293
3886
  FileUploadItem,
3294
3887
  {
3295
3888
  file: { name: progress.fileName },
@@ -3304,7 +3897,7 @@ var ChatInput = memo2(function ChatInput2({
3304
3897
  },
3305
3898
  id
3306
3899
  )) }),
3307
- isRecording && /* @__PURE__ */ jsx21(
3900
+ isRecording && /* @__PURE__ */ jsx22(
3308
3901
  AudioRecorder,
3309
3902
  {
3310
3903
  isRecording,
@@ -3315,7 +3908,7 @@ var ChatInput = memo2(function ChatInput2({
3315
3908
  config
3316
3909
  }
3317
3910
  ),
3318
- attachments.length > 0 && /* @__PURE__ */ jsx21("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ jsx21(
3911
+ attachments.length > 0 && /* @__PURE__ */ jsx22("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ jsx22(
3319
3912
  AttachmentPreview,
3320
3913
  {
3321
3914
  attachment,
@@ -3323,15 +3916,51 @@ var ChatInput = memo2(function ChatInput2({
3323
3916
  },
3324
3917
  index
3325
3918
  )) }),
3326
- /* @__PURE__ */ jsx21("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ jsxs11(
3919
+ showVoiceComposer ? /* @__PURE__ */ jsx22("div", { className: "mb-1 flex justify-center", children: /* @__PURE__ */ jsx22(
3920
+ VoiceComposer,
3921
+ {
3922
+ state: voiceState,
3923
+ transcript: voiceTranscript,
3924
+ transcriptMode: voiceTranscriptMode,
3925
+ showTranscriptPreview: voiceShowTranscriptPreview,
3926
+ attachment: voiceDraft?.attachment ?? null,
3927
+ durationMs: voiceDurationMs,
3928
+ audioLevel: voiceAudioLevel,
3929
+ countdownMs: voiceCountdownMs,
3930
+ autoSendDelayMs: voiceAutoSendDelayMs,
3931
+ isAutoSendActive: isVoiceAutoSendActive,
3932
+ errorMessage: voiceError,
3933
+ disabled: disabled || isGenerating,
3934
+ labels: config?.labels,
3935
+ onStart: () => {
3936
+ void startVoiceCapture();
3937
+ },
3938
+ onStop: () => {
3939
+ void stopVoiceCapture();
3940
+ },
3941
+ onCancelAutoSend: () => {
3942
+ cancelVoiceAutoSend();
3943
+ },
3944
+ onDiscard: () => {
3945
+ void cancelVoiceCapture();
3946
+ },
3947
+ onRecordAgain: () => {
3948
+ void startVoiceCapture();
3949
+ },
3950
+ onSendNow: sendVoiceDraft,
3951
+ onExit: () => {
3952
+ void closeVoiceComposer();
3953
+ }
3954
+ }
3955
+ ) }) : /* @__PURE__ */ jsx22("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ jsxs12(
3327
3956
  "div",
3328
3957
  {
3329
3958
  className: "flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl",
3330
3959
  onDrop: handleDrop,
3331
3960
  onDragOver: handleDragOver,
3332
3961
  children: [
3333
- enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ jsxs11(Fragment4, { children: [
3334
- /* @__PURE__ */ jsx21(
3962
+ enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ jsxs12(Fragment4, { children: [
3963
+ /* @__PURE__ */ jsx22(
3335
3964
  "input",
3336
3965
  {
3337
3966
  ref: fileInputRef,
@@ -3342,8 +3971,8 @@ var ChatInput = memo2(function ChatInput2({
3342
3971
  className: "hidden"
3343
3972
  }
3344
3973
  ),
3345
- /* @__PURE__ */ jsxs11(Tooltip, { children: [
3346
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
3974
+ /* @__PURE__ */ jsxs12(Tooltip, { children: [
3975
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3347
3976
  Button,
3348
3977
  {
3349
3978
  type: "button",
@@ -3356,13 +3985,13 @@ var ChatInput = memo2(function ChatInput2({
3356
3985
  fileInputRef.current?.click();
3357
3986
  },
3358
3987
  disabled,
3359
- children: /* @__PURE__ */ jsx21(Paperclip, { className: "h-4 w-4" })
3988
+ children: /* @__PURE__ */ jsx22(Paperclip, { className: "h-4 w-4" })
3360
3989
  }
3361
3990
  ) }),
3362
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.attachFileTooltip })
3991
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.attachFileTooltip })
3363
3992
  ] })
3364
3993
  ] }),
3365
- /* @__PURE__ */ jsx21("div", { className: "flex-1", children: /* @__PURE__ */ jsx21(
3994
+ /* @__PURE__ */ jsx22("div", { className: "flex-1", children: /* @__PURE__ */ jsx22(
3366
3995
  Textarea,
3367
3996
  {
3368
3997
  ref: textareaRef,
@@ -3375,7 +4004,23 @@ var ChatInput = memo2(function ChatInput2({
3375
4004
  rows: 1
3376
4005
  }
3377
4006
  ) }),
3378
- enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ jsx21(
4007
+ enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (voiceComposeEnabled ? /* @__PURE__ */ jsxs12(Tooltip, { children: [
4008
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
4009
+ Button,
4010
+ {
4011
+ type: "button",
4012
+ variant: "outline",
4013
+ size: "icon",
4014
+ className: "h-10 w-10",
4015
+ onClick: () => {
4016
+ void startVoiceCapture();
4017
+ },
4018
+ disabled: disabled || isGenerating,
4019
+ children: /* @__PURE__ */ jsx22(Mic2, { className: "h-4 w-4" })
4020
+ }
4021
+ ) }),
4022
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip })
4023
+ ] }) : /* @__PURE__ */ jsx22(
3379
4024
  AudioRecorder,
3380
4025
  {
3381
4026
  isRecording,
@@ -3385,9 +4030,9 @@ var ChatInput = memo2(function ChatInput2({
3385
4030
  recordingDuration,
3386
4031
  config
3387
4032
  }
3388
- ),
3389
- isGenerating ? /* @__PURE__ */ jsxs11(Tooltip, { children: [
3390
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
4033
+ )),
4034
+ isGenerating ? /* @__PURE__ */ jsxs12(Tooltip, { children: [
4035
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3391
4036
  Button,
3392
4037
  {
3393
4038
  type: "button",
@@ -3395,36 +4040,36 @@ var ChatInput = memo2(function ChatInput2({
3395
4040
  size: "icon",
3396
4041
  className: "h-10 w-10",
3397
4042
  onClick: onStopGeneration,
3398
- children: /* @__PURE__ */ jsx21(Square, { className: "h-4 w-4" })
4043
+ children: /* @__PURE__ */ jsx22(Square2, { className: "h-4 w-4" })
3399
4044
  }
3400
4045
  ) }),
3401
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
3402
- ] }) : /* @__PURE__ */ jsxs11(Tooltip, { children: [
3403
- /* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
4046
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
4047
+ ] }) : /* @__PURE__ */ jsxs12(Tooltip, { children: [
4048
+ /* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3404
4049
  Button,
3405
4050
  {
3406
4051
  type: "submit",
3407
4052
  size: "icon",
3408
4053
  className: "h-10 w-10",
3409
4054
  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" })
4055
+ children: disabled ? /* @__PURE__ */ jsx22(Loader22, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx22(Send2, { className: "h-4 w-4" })
3411
4056
  }
3412
4057
  ) }),
3413
- /* @__PURE__ */ jsx21(TooltipContent, { children: config?.labels?.sendMessageTooltip })
4058
+ /* @__PURE__ */ jsx22(TooltipContent, { children: config?.labels?.sendMessageTooltip })
3414
4059
  ] })
3415
4060
  ]
3416
4061
  }
3417
4062
  ) }),
3418
- /* @__PURE__ */ jsxs11("div", { className: "text-[10px] text-muted-foreground text-center", children: [
4063
+ /* @__PURE__ */ jsxs12("div", { className: "text-[10px] text-muted-foreground text-center", children: [
3419
4064
  window.innerWidth > 768 ? config?.labels?.inputHelpText : "",
3420
- attachments.length > 0 && /* @__PURE__ */ jsxs11(Fragment4, { children: [
4065
+ attachments.length > 0 && /* @__PURE__ */ jsxs12(Fragment4, { children: [
3421
4066
  " \u2022 ",
3422
4067
  attachments.length,
3423
4068
  "/",
3424
4069
  maxAttachments,
3425
4070
  " anexos"
3426
4071
  ] }),
3427
- config?.labels?.footerLabel && /* @__PURE__ */ jsxs11(Fragment4, { children: [
4072
+ config?.labels?.footerLabel && /* @__PURE__ */ jsxs12(Fragment4, { children: [
3428
4073
  " \u2022 ",
3429
4074
  config.labels.footerLabel
3430
4075
  ] })
@@ -3438,16 +4083,16 @@ import { useState as useState7 } from "react";
3438
4083
  // src/components/ui/scroll-area.tsx
3439
4084
  import * as React11 from "react";
3440
4085
  import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3441
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
4086
+ import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
3442
4087
  var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
3443
- return /* @__PURE__ */ jsxs12(
4088
+ return /* @__PURE__ */ jsxs13(
3444
4089
  ScrollAreaPrimitive.Root,
3445
4090
  {
3446
4091
  "data-slot": "scroll-area",
3447
4092
  className: cn("relative", className),
3448
4093
  ...props,
3449
4094
  children: [
3450
- /* @__PURE__ */ jsx22(
4095
+ /* @__PURE__ */ jsx23(
3451
4096
  ScrollAreaPrimitive.Viewport,
3452
4097
  {
3453
4098
  ref,
@@ -3461,8 +4106,8 @@ var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, o
3461
4106
  children
3462
4107
  }
3463
4108
  ),
3464
- /* @__PURE__ */ jsx22(ScrollBar, {}),
3465
- /* @__PURE__ */ jsx22(ScrollAreaPrimitive.Corner, {})
4109
+ /* @__PURE__ */ jsx23(ScrollBar, {}),
4110
+ /* @__PURE__ */ jsx23(ScrollAreaPrimitive.Corner, {})
3466
4111
  ]
3467
4112
  }
3468
4113
  );
@@ -3473,7 +4118,7 @@ function ScrollBar({
3473
4118
  orientation = "vertical",
3474
4119
  ...props
3475
4120
  }) {
3476
- return /* @__PURE__ */ jsx22(
4121
+ return /* @__PURE__ */ jsx23(
3477
4122
  ScrollAreaPrimitive.ScrollAreaScrollbar,
3478
4123
  {
3479
4124
  "data-slot": "scroll-area-scrollbar",
@@ -3485,7 +4130,7 @@ function ScrollBar({
3485
4130
  className
3486
4131
  ),
3487
4132
  ...props,
3488
- children: /* @__PURE__ */ jsx22(
4133
+ children: /* @__PURE__ */ jsx23(
3489
4134
  ScrollAreaPrimitive.ScrollAreaThumb,
3490
4135
  {
3491
4136
  "data-slot": "scroll-area-thumb",
@@ -3514,7 +4159,7 @@ import {
3514
4159
  FileText as FileText2,
3515
4160
  Brain as Brain2,
3516
4161
  Plus as Plus3,
3517
- Trash2 as Trash23,
4162
+ Trash2 as Trash24,
3518
4163
  Target,
3519
4164
  Lightbulb,
3520
4165
  Info,
@@ -3522,9 +4167,9 @@ import {
3522
4167
  Bot as Bot3,
3523
4168
  Pencil,
3524
4169
  Check as Check3,
3525
- X as X3
4170
+ X as X4
3526
4171
  } from "lucide-react";
3527
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
4172
+ import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
3528
4173
  var getInitials2 = (name, email) => {
3529
4174
  if (name) {
3530
4175
  return name.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase();
@@ -3538,29 +4183,29 @@ var getFieldIcon = (type, key) => {
3538
4183
  const iconClass = "h-4 w-4 text-muted-foreground";
3539
4184
  switch (type) {
3540
4185
  case "email":
3541
- return /* @__PURE__ */ jsx23(Mail, { className: iconClass });
4186
+ return /* @__PURE__ */ jsx24(Mail, { className: iconClass });
3542
4187
  case "phone":
3543
- return /* @__PURE__ */ jsx23(Phone, { className: iconClass });
4188
+ return /* @__PURE__ */ jsx24(Phone, { className: iconClass });
3544
4189
  case "url":
3545
- return /* @__PURE__ */ jsx23(Globe, { className: iconClass });
4190
+ return /* @__PURE__ */ jsx24(Globe, { className: iconClass });
3546
4191
  case "date":
3547
- return /* @__PURE__ */ jsx23(Calendar, { className: iconClass });
4192
+ return /* @__PURE__ */ jsx24(Calendar, { className: iconClass });
3548
4193
  }
3549
4194
  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 });
4195
+ if (lowerKey.includes("follower")) return /* @__PURE__ */ jsx24(Users, { className: iconClass });
4196
+ if (lowerKey.includes("following")) return /* @__PURE__ */ jsx24(UserPlus, { className: iconClass });
4197
+ if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ jsx24(Image3, { className: iconClass });
4198
+ if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ jsx24(BadgeCheck, { className: iconClass });
4199
+ if (lowerKey.includes("bio")) return /* @__PURE__ */ jsx24(FileText2, { className: iconClass });
4200
+ if (lowerKey.includes("email")) return /* @__PURE__ */ jsx24(Mail, { className: iconClass });
4201
+ if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ jsx24(Phone, { className: iconClass });
4202
+ if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ jsx24(MapPin, { className: iconClass });
4203
+ if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ jsx24(Building, { className: iconClass });
4204
+ if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ jsx24(Briefcase, { className: iconClass });
4205
+ if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ jsx24(Globe, { className: iconClass });
4206
+ if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ jsx24(AtSign, { className: iconClass });
4207
+ if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ jsx24(Calendar, { className: iconClass });
4208
+ return /* @__PURE__ */ jsx24(User2, { className: iconClass });
3564
4209
  };
3565
4210
  var formatValue = (value, type, key) => {
3566
4211
  if (value === null || value === void 0) return "-";
@@ -3594,15 +4239,15 @@ var getMemoryCategoryIcon = (category) => {
3594
4239
  const iconClass = "h-4 w-4 text-muted-foreground";
3595
4240
  switch (category) {
3596
4241
  case "preference":
3597
- return /* @__PURE__ */ jsx23(Heart, { className: iconClass });
4242
+ return /* @__PURE__ */ jsx24(Heart, { className: iconClass });
3598
4243
  case "fact":
3599
- return /* @__PURE__ */ jsx23(Info, { className: iconClass });
4244
+ return /* @__PURE__ */ jsx24(Info, { className: iconClass });
3600
4245
  case "goal":
3601
- return /* @__PURE__ */ jsx23(Target, { className: iconClass });
4246
+ return /* @__PURE__ */ jsx24(Target, { className: iconClass });
3602
4247
  case "context":
3603
- return /* @__PURE__ */ jsx23(Lightbulb, { className: iconClass });
4248
+ return /* @__PURE__ */ jsx24(Lightbulb, { className: iconClass });
3604
4249
  default:
3605
- return /* @__PURE__ */ jsx23(Brain2, { className: iconClass });
4250
+ return /* @__PURE__ */ jsx24(Brain2, { className: iconClass });
3606
4251
  }
3607
4252
  };
3608
4253
  var getMemoryCategoryLabel = (category) => {
@@ -3672,66 +4317,66 @@ var UserProfile = ({
3672
4317
  const displayName = user?.name || user?.email?.split("@")[0] || "User";
3673
4318
  const initials = getInitials2(user?.name, user?.email);
3674
4319
  const normalizedFields = normalizeCustomFields(customFields);
3675
- return /* @__PURE__ */ jsx23(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs13(
4320
+ return /* @__PURE__ */ jsx24(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs14(
3676
4321
  SheetContent,
3677
4322
  {
3678
4323
  side: "right",
3679
4324
  className: cn("w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden", className),
3680
4325
  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 })
4326
+ /* @__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 }) }) }),
4327
+ /* @__PURE__ */ jsx24(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxs14("div", { className: "p-6 space-y-6", children: [
4328
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center text-center space-y-4", children: [
4329
+ /* @__PURE__ */ jsxs14(Avatar, { className: "h-24 w-24 shrink-0", children: [
4330
+ user?.avatar && /* @__PURE__ */ jsx24(AvatarImage, { src: user.avatar, alt: displayName }),
4331
+ /* @__PURE__ */ jsx24(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
3687
4332
  ] }),
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 })
4333
+ /* @__PURE__ */ jsxs14("div", { className: "w-full px-2", children: [
4334
+ /* @__PURE__ */ jsx24("h2", { className: "text-xl font-semibold break-words", children: displayName }),
4335
+ user?.email && /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
3691
4336
  ] })
3692
4337
  ] }),
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 })
4338
+ /* @__PURE__ */ jsx24(Separator, {}),
4339
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
4340
+ /* @__PURE__ */ jsx24("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
4341
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
4342
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4343
+ /* @__PURE__ */ jsx24(User2, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4344
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4345
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "Name" }),
4346
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium break-words", children: displayName })
3702
4347
  ] })
3703
4348
  ] }),
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 })
4349
+ user?.email && /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4350
+ /* @__PURE__ */ jsx24(AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4351
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4352
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
4353
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium break-words", children: user.email })
3709
4354
  ] })
3710
4355
  ] }),
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 })
4356
+ 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: [
4357
+ /* @__PURE__ */ jsx24(User2, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4358
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4359
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "ID" }),
4360
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium break-words", children: user.id })
3716
4361
  ] })
3717
4362
  ] })
3718
4363
  ] })
3719
4364
  ] }),
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) => {
4365
+ normalizedFields.length > 0 && /* @__PURE__ */ jsxs14(Fragment5, { children: [
4366
+ /* @__PURE__ */ jsx24(Separator, {}),
4367
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
4368
+ /* @__PURE__ */ jsx24("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
4369
+ /* @__PURE__ */ jsx24("div", { className: "space-y-2", children: normalizedFields.map((field) => {
3725
4370
  const isBioField = field.key.toLowerCase().includes("bio");
3726
- return /* @__PURE__ */ jsxs13(
4371
+ return /* @__PURE__ */ jsxs14(
3727
4372
  "div",
3728
4373
  {
3729
4374
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50",
3730
4375
  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(
4376
+ /* @__PURE__ */ jsx24("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
4377
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4378
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: field.label }),
4379
+ /* @__PURE__ */ jsx24("p", { className: cn(
3735
4380
  "text-sm font-medium",
3736
4381
  isBioField ? "whitespace-pre-wrap break-words" : "break-words"
3737
4382
  ), children: formatValue(field.value, field.type, field.key) })
@@ -3743,26 +4388,26 @@ var UserProfile = ({
3743
4388
  }) })
3744
4389
  ] })
3745
4390
  ] }),
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" }),
4391
+ /* @__PURE__ */ jsx24(Separator, {}),
4392
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
4393
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between", children: [
4394
+ /* @__PURE__ */ jsxs14("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
4395
+ /* @__PURE__ */ jsx24(Brain2, { className: "h-4 w-4" }),
3751
4396
  labels.memories
3752
4397
  ] }),
3753
- onAddMemory && /* @__PURE__ */ jsx23(
4398
+ onAddMemory && /* @__PURE__ */ jsx24(
3754
4399
  Button,
3755
4400
  {
3756
4401
  variant: "ghost",
3757
4402
  size: "sm",
3758
4403
  className: "h-7 px-2",
3759
4404
  onClick: () => setIsAddingMemory(true),
3760
- children: /* @__PURE__ */ jsx23(Plus3, { className: "h-4 w-4" })
4405
+ children: /* @__PURE__ */ jsx24(Plus3, { className: "h-4 w-4" })
3761
4406
  }
3762
4407
  )
3763
4408
  ] }),
3764
- isAddingMemory && onAddMemory && /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
3765
- /* @__PURE__ */ jsx23(
4409
+ isAddingMemory && onAddMemory && /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
4410
+ /* @__PURE__ */ jsx24(
3766
4411
  Input,
3767
4412
  {
3768
4413
  value: newMemoryContent,
@@ -3779,24 +4424,24 @@ var UserProfile = ({
3779
4424
  autoFocus: true
3780
4425
  }
3781
4426
  ),
3782
- /* @__PURE__ */ jsx23(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
4427
+ /* @__PURE__ */ jsx24(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
3783
4428
  ] }),
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) => {
4429
+ /* @__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
4430
  const isEditing = editingMemoryId === memory.id;
3786
- return /* @__PURE__ */ jsxs13(
4431
+ return /* @__PURE__ */ jsxs14(
3787
4432
  "div",
3788
4433
  {
3789
4434
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
3790
4435
  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" })
4436
+ /* @__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) }),
4437
+ /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
4438
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-0.5", children: [
4439
+ /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
4440
+ /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
4441
+ /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
3797
4442
  ] }),
3798
- isEditing ? /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
3799
- /* @__PURE__ */ jsx23(
4443
+ isEditing ? /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
4444
+ /* @__PURE__ */ jsx24(
3800
4445
  Textarea,
3801
4446
  {
3802
4447
  value: editingMemoryContent,
@@ -3813,8 +4458,8 @@ var UserProfile = ({
3813
4458
  }
3814
4459
  }
3815
4460
  ),
3816
- /* @__PURE__ */ jsxs13("div", { className: "flex gap-1 justify-end", children: [
3817
- /* @__PURE__ */ jsxs13(
4461
+ /* @__PURE__ */ jsxs14("div", { className: "flex gap-1 justify-end", children: [
4462
+ /* @__PURE__ */ jsxs14(
3818
4463
  Button,
3819
4464
  {
3820
4465
  variant: "ghost",
@@ -3822,12 +4467,12 @@ var UserProfile = ({
3822
4467
  className: "h-7 px-2",
3823
4468
  onClick: handleCancelEdit,
3824
4469
  children: [
3825
- /* @__PURE__ */ jsx23(X3, { className: "h-3.5 w-3.5 mr-1" }),
4470
+ /* @__PURE__ */ jsx24(X4, { className: "h-3.5 w-3.5 mr-1" }),
3826
4471
  "Cancelar"
3827
4472
  ]
3828
4473
  }
3829
4474
  ),
3830
- /* @__PURE__ */ jsxs13(
4475
+ /* @__PURE__ */ jsxs14(
3831
4476
  Button,
3832
4477
  {
3833
4478
  size: "sm",
@@ -3835,33 +4480,33 @@ var UserProfile = ({
3835
4480
  onClick: handleSaveEdit,
3836
4481
  disabled: !editingMemoryContent.trim(),
3837
4482
  children: [
3838
- /* @__PURE__ */ jsx23(Check3, { className: "h-3.5 w-3.5 mr-1" }),
4483
+ /* @__PURE__ */ jsx24(Check3, { className: "h-3.5 w-3.5 mr-1" }),
3839
4484
  "Salvar"
3840
4485
  ]
3841
4486
  }
3842
4487
  )
3843
4488
  ] })
3844
- ] }) : /* @__PURE__ */ jsx23("p", { className: "text-sm break-words", children: memory.content })
4489
+ ] }) : /* @__PURE__ */ jsx24("p", { className: "text-sm break-words", children: memory.content })
3845
4490
  ] }),
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(
4491
+ !isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ jsxs14("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0", children: [
4492
+ onUpdateMemory && /* @__PURE__ */ jsx24(
3848
4493
  Button,
3849
4494
  {
3850
4495
  variant: "ghost",
3851
4496
  size: "icon",
3852
4497
  className: "h-7 w-7",
3853
4498
  onClick: () => handleStartEdit(memory),
3854
- children: /* @__PURE__ */ jsx23(Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
4499
+ children: /* @__PURE__ */ jsx24(Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
3855
4500
  }
3856
4501
  ),
3857
- onDeleteMemory && /* @__PURE__ */ jsx23(
4502
+ onDeleteMemory && /* @__PURE__ */ jsx24(
3858
4503
  Button,
3859
4504
  {
3860
4505
  variant: "ghost",
3861
4506
  size: "icon",
3862
4507
  className: "h-7 w-7",
3863
4508
  onClick: () => onDeleteMemory(memory.id),
3864
- children: /* @__PURE__ */ jsx23(Trash23, { className: "h-3.5 w-3.5 text-destructive" })
4509
+ children: /* @__PURE__ */ jsx24(Trash24, { className: "h-3.5 w-3.5 text-destructive" })
3865
4510
  }
3866
4511
  )
3867
4512
  ] })
@@ -3872,8 +4517,8 @@ var UserProfile = ({
3872
4517
  }) })
3873
4518
  ] })
3874
4519
  ] }) }),
3875
- /* @__PURE__ */ jsxs13("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
3876
- onEditProfile && /* @__PURE__ */ jsx23(
4520
+ /* @__PURE__ */ jsxs14("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
4521
+ onEditProfile && /* @__PURE__ */ jsx24(
3877
4522
  Button,
3878
4523
  {
3879
4524
  variant: "outline",
@@ -3882,7 +4527,7 @@ var UserProfile = ({
3882
4527
  children: "Edit Profile"
3883
4528
  }
3884
4529
  ),
3885
- onLogout && /* @__PURE__ */ jsx23(
4530
+ onLogout && /* @__PURE__ */ jsx24(
3886
4531
  Button,
3887
4532
  {
3888
4533
  variant: "destructive",
@@ -3899,7 +4544,7 @@ var UserProfile = ({
3899
4544
 
3900
4545
  // src/components/chat/ChatUI.tsx
3901
4546
  import { Sparkles, ArrowRight, MessageSquare, Lightbulb as Lightbulb2, Zap, HelpCircle } from "lucide-react";
3902
- import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
4547
+ import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
3903
4548
  var ChatUI = ({
3904
4549
  messages = [],
3905
4550
  threads = [],
@@ -4165,13 +4810,13 @@ var ChatUI = ({
4165
4810
  const SuggestionIconComponents = [MessageSquare, Lightbulb2, Zap, HelpCircle];
4166
4811
  const renderSuggestions = () => {
4167
4812
  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 })
4813
+ return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
4814
+ /* @__PURE__ */ jsxs15("div", { className: "text-center mb-8", children: [
4815
+ /* @__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" }) }),
4816
+ /* @__PURE__ */ jsx25("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
4817
+ /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
4173
4818
  ] }),
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(
4819
+ /* @__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
4820
  "button",
4176
4821
  {
4177
4822
  type: "button",
@@ -4180,10 +4825,10 @@ var ChatUI = ({
4180
4825
  children: [
4181
4826
  (() => {
4182
4827
  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" }) });
4828
+ 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
4829
  })(),
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" })
4830
+ /* @__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 }) }),
4831
+ /* @__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
4832
  ]
4188
4833
  },
4189
4834
  index
@@ -4194,34 +4839,34 @@ var ChatUI = ({
4194
4839
  const items = messageSuggestions?.[messageId];
4195
4840
  if (!items || items.length === 0) return null;
4196
4841
  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(
4842
+ return /* @__PURE__ */ jsx25("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ jsxs15(
4198
4843
  "button",
4199
4844
  {
4200
4845
  type: "button",
4201
4846
  onClick: () => handleSendMessage(suggestion),
4202
4847
  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
4848
  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 })
4849
+ /* @__PURE__ */ jsx25(Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4850
+ /* @__PURE__ */ jsx25("span", { className: "max-w-[200px] truncate", children: suggestion })
4206
4851
  ]
4207
4852
  },
4208
4853
  `${messageId}-suggestion-${index}`
4209
4854
  )) });
4210
4855
  };
4211
- const renderMessageLoadingSkeleton = () => /* @__PURE__ */ jsx24("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4856
+ const renderMessageLoadingSkeleton = () => /* @__PURE__ */ jsx25("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4212
4857
  const isUserRow = index % 2 === 1;
4213
- return /* @__PURE__ */ jsxs14(
4858
+ return /* @__PURE__ */ jsxs15(
4214
4859
  "div",
4215
4860
  {
4216
4861
  className: `flex gap-3 ${isUserRow ? "justify-end" : "justify-start"}`,
4217
4862
  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%]" })
4863
+ !isUserRow && /* @__PURE__ */ jsx25(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
4864
+ /* @__PURE__ */ jsxs15("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
4865
+ /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-24" }),
4866
+ /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-full" }),
4867
+ /* @__PURE__ */ jsx25(Skeleton, { className: "h-4 w-[85%]" })
4223
4868
  ] }),
4224
- isUserRow && /* @__PURE__ */ jsx24(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4869
+ isUserRow && /* @__PURE__ */ jsx25(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4225
4870
  ]
4226
4871
  },
4227
4872
  `message-skeleton-${index}`
@@ -4277,8 +4922,8 @@ var ChatUI = ({
4277
4922
  const shouldShowAgentSelector = Boolean(
4278
4923
  config.agentSelector?.enabled && onSelectAgent && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1)
4279
4924
  );
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(
4925
+ 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: [
4926
+ /* @__PURE__ */ jsx25(
4282
4927
  Sidebar2,
4283
4928
  {
4284
4929
  threads,
@@ -4295,8 +4940,8 @@ var ChatUI = ({
4295
4940
  showThemeOptions: !!callbacks.onThemeChange
4296
4941
  }
4297
4942
  ),
4298
- /* @__PURE__ */ jsx24(SidebarInset, { children: /* @__PURE__ */ jsxs14("div", { className: "flex flex-col h-full min-h-0", children: [
4299
- /* @__PURE__ */ jsx24(
4943
+ /* @__PURE__ */ jsx25(SidebarInset, { children: /* @__PURE__ */ jsxs15("div", { className: "flex flex-col h-full min-h-0", children: [
4944
+ /* @__PURE__ */ jsx25(
4300
4945
  ChatHeader,
4301
4946
  {
4302
4947
  config,
@@ -4311,9 +4956,9 @@ var ChatUI = ({
4311
4956
  onSelectAgent
4312
4957
  }
4313
4958
  ),
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(
4959
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
4960
+ /* @__PURE__ */ jsxs15("div", { className: "flex-1 flex flex-col min-h-0", children: [
4961
+ /* @__PURE__ */ jsx25(
4317
4962
  ScrollArea,
4318
4963
  {
4319
4964
  ref: scrollAreaRef,
@@ -4321,7 +4966,7 @@ var ChatUI = ({
4321
4966
  viewportClassName: "p-4 overscroll-contain",
4322
4967
  onScrollCapture: handleScroll,
4323
4968
  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(
4969
+ children: /* @__PURE__ */ jsx25("div", { className: "max-w-4xl mx-auto pb-4", children: isMessagesLoading ? renderMessageLoadingSkeleton() : messages.length === 0 ? renderSuggestions() : /* @__PURE__ */ jsx25(
4325
4970
  "div",
4326
4971
  {
4327
4972
  style: {
@@ -4333,7 +4978,7 @@ var ChatUI = ({
4333
4978
  const message = messages[virtualRow.index];
4334
4979
  const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;
4335
4980
  const isGrouped = prevMessage !== null && prevMessage.role === message.role;
4336
- return /* @__PURE__ */ jsx24(
4981
+ return /* @__PURE__ */ jsx25(
4337
4982
  "div",
4338
4983
  {
4339
4984
  "data-index": virtualRow.index,
@@ -4345,8 +4990,8 @@ var ChatUI = ({
4345
4990
  width: "100%",
4346
4991
  transform: `translateY(${virtualRow.start}px)`
4347
4992
  },
4348
- children: /* @__PURE__ */ jsxs14("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4349
- /* @__PURE__ */ jsx24(
4993
+ children: /* @__PURE__ */ jsxs15("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4994
+ /* @__PURE__ */ jsx25(
4350
4995
  Message,
4351
4996
  {
4352
4997
  message,
@@ -4365,7 +5010,7 @@ var ChatUI = ({
4365
5010
  ) })
4366
5011
  }
4367
5012
  ),
4368
- /* @__PURE__ */ jsx24("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ jsx24(
5013
+ /* @__PURE__ */ jsx25("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ jsx25(
4369
5014
  ChatInput,
4370
5015
  {
4371
5016
  value: inputValue,
@@ -4391,17 +5036,17 @@ var ChatUI = ({
4391
5036
  }
4392
5037
  ) })
4393
5038
  ] }),
4394
- config?.customComponent?.component && !isMobile && /* @__PURE__ */ jsx24(
5039
+ config?.customComponent?.component && !isMobile && /* @__PURE__ */ jsx25(
4395
5040
  "div",
4396
5041
  {
4397
5042
  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() })
5043
+ 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
5044
  }
4400
5045
  )
4401
5046
  ] })
4402
5047
  ] }) }),
4403
- isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ jsxs14("div", { className: "fixed inset-0 z-50", children: [
4404
- /* @__PURE__ */ jsx24(
5048
+ isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ jsxs15("div", { className: "fixed inset-0 z-50", children: [
5049
+ /* @__PURE__ */ jsx25(
4405
5050
  "div",
4406
5051
  {
4407
5052
  className: `absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${isCustomVisible ? "opacity-100" : "opacity-0"}`,
@@ -4409,16 +5054,16 @@ var ChatUI = ({
4409
5054
  onClick: closeSidebar
4410
5055
  }
4411
5056
  ),
4412
- /* @__PURE__ */ jsx24(
5057
+ /* @__PURE__ */ jsx25(
4413
5058
  "div",
4414
5059
  {
4415
5060
  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
5061
  style: { willChange: "transform" },
4417
- children: /* @__PURE__ */ jsx24("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
5062
+ children: /* @__PURE__ */ jsx25("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
4418
5063
  }
4419
5064
  )
4420
5065
  ] }),
4421
- isUserProfileOpen && /* @__PURE__ */ jsx24(
5066
+ isUserProfileOpen && /* @__PURE__ */ jsx25(
4422
5067
  UserProfile,
4423
5068
  {
4424
5069
  isOpen: isUserProfileOpen,
@@ -4447,16 +5092,16 @@ import {
4447
5092
  MessageSquare as MessageSquare2,
4448
5093
  MoreVertical as MoreVertical2,
4449
5094
  Edit2 as Edit22,
4450
- Trash2 as Trash24,
5095
+ Trash2 as Trash25,
4451
5096
  Archive as Archive2,
4452
5097
  Search as Search2,
4453
5098
  Filter as Filter2,
4454
5099
  Calendar as Calendar2,
4455
5100
  Hash,
4456
- X as X4,
5101
+ X as X5,
4457
5102
  Check as Check4
4458
5103
  } from "lucide-react";
4459
- import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
5104
+ import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
4460
5105
  var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
4461
5106
  const [isEditing, setIsEditing] = useState9(false);
4462
5107
  const [editTitle, setEditTitle] = useState9(thread.title);
@@ -4485,9 +5130,9 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4485
5130
  handleCancelEdit();
4486
5131
  }
4487
5132
  };
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(
5133
+ 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: [
5134
+ /* @__PURE__ */ jsx26("div", { className: "flex-1 min-w-0", onClick: onSelect, children: isEditing ? /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
5135
+ /* @__PURE__ */ jsx26(
4491
5136
  Input,
4492
5137
  {
4493
5138
  ref: inputRef,
@@ -4499,44 +5144,44 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4499
5144
  placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
4500
5145
  }
4501
5146
  ),
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" }),
5147
+ /* @__PURE__ */ jsx26(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ jsx26(Check4, { className: "h-3 w-3" }) }),
5148
+ /* @__PURE__ */ jsx26(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ jsx26(X5, { className: "h-3 w-3" }) })
5149
+ ] }) : /* @__PURE__ */ jsxs16(Fragment6, { children: [
5150
+ /* @__PURE__ */ jsx26("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
5151
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
5152
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
5153
+ /* @__PURE__ */ jsx26(Hash, { className: "h-3 w-3" }),
4509
5154
  thread.messageCount,
4510
5155
  " msgs"
4511
5156
  ] }),
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" }),
5157
+ /* @__PURE__ */ jsx26(Separator, { orientation: "vertical", className: "h-3" }),
5158
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
5159
+ /* @__PURE__ */ jsx26(Calendar2, { className: "h-3 w-3" }),
4515
5160
  formatDate(thread.updatedAt, config?.labels)
4516
5161
  ] }),
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" }),
5162
+ thread.isArchived && /* @__PURE__ */ jsxs16(Fragment6, { children: [
5163
+ /* @__PURE__ */ jsx26(Separator, { orientation: "vertical", className: "h-3" }),
5164
+ /* @__PURE__ */ jsxs16(Badge, { variant: "secondary", className: "text-xs", children: [
5165
+ /* @__PURE__ */ jsx26(Archive2, { className: "h-2 w-2 mr-1" }),
4521
5166
  config?.labels?.archiveThread || "Archived"
4522
5167
  ] })
4523
5168
  ] })
4524
5169
  ] })
4525
5170
  ] }) }),
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" }),
5171
+ !isEditing && /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
5172
+ /* @__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" }) }) }),
5173
+ /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", children: [
5174
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
5175
+ /* @__PURE__ */ jsx26(Edit22, { className: "h-4 w-4 mr-2" }),
4531
5176
  config?.labels?.renameThread || "Rename"
4532
5177
  ] }),
4533
- /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: onArchive, children: [
4534
- /* @__PURE__ */ jsx25(Archive2, { className: "h-4 w-4 mr-2" }),
5178
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: onArchive, children: [
5179
+ /* @__PURE__ */ jsx26(Archive2, { className: "h-4 w-4 mr-2" }),
4535
5180
  thread.isArchived ? config?.labels?.unarchiveThread || "Unarchive" : config?.labels?.archiveThread || "Archive"
4536
5181
  ] }),
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" }),
5182
+ /* @__PURE__ */ jsx26(DropdownMenuSeparator, {}),
5183
+ /* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
5184
+ /* @__PURE__ */ jsx26(Trash25, { className: "h-4 w-4 mr-2" }),
4540
5185
  config?.labels?.deleteThread || "Delete"
4541
5186
  ] })
4542
5187
  ] })
@@ -4551,17 +5196,17 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4551
5196
  setTitle("");
4552
5197
  setIsOpen(false);
4553
5198
  };
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" }),
5199
+ return /* @__PURE__ */ jsxs16(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
5200
+ /* @__PURE__ */ jsx26(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs16(Button, { variant: "outline", className: "w-full", children: [
5201
+ /* @__PURE__ */ jsx26(Plus4, { className: "h-4 w-4 mr-2" }),
4557
5202
  config?.labels?.createNewThread || "New Conversation"
4558
5203
  ] }) }),
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." })
5204
+ /* @__PURE__ */ jsxs16(DialogContent, { children: [
5205
+ /* @__PURE__ */ jsxs16(DialogHeader, { children: [
5206
+ /* @__PURE__ */ jsx26(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
5207
+ /* @__PURE__ */ jsx26(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
4563
5208
  ] }),
4564
- /* @__PURE__ */ jsx25(
5209
+ /* @__PURE__ */ jsx26(
4565
5210
  Input,
4566
5211
  {
4567
5212
  value: title,
@@ -4571,9 +5216,9 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4571
5216
  autoFocus: true
4572
5217
  }
4573
5218
  ),
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" })
5219
+ /* @__PURE__ */ jsxs16(DialogFooter, { children: [
5220
+ /* @__PURE__ */ jsx26(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
5221
+ /* @__PURE__ */ jsx26(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
4577
5222
  ] })
4578
5223
  ] })
4579
5224
  ] });
@@ -4627,20 +5272,20 @@ var ThreadManager = ({
4627
5272
  setDeleteThreadId(null);
4628
5273
  };
4629
5274
  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" }),
5275
+ return /* @__PURE__ */ jsx26(TooltipProvider, { children: /* @__PURE__ */ jsxs16("div", { className: `fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`, children: [
5276
+ /* @__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: [
5277
+ /* @__PURE__ */ jsxs16(CardHeader, { className: "border-b", children: [
5278
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
5279
+ /* @__PURE__ */ jsxs16(CardTitle, { className: "flex items-center gap-2", children: [
5280
+ /* @__PURE__ */ jsx26(MessageSquare2, { className: "h-5 w-5" }),
4636
5281
  config?.labels?.newChat || "Conversations"
4637
5282
  ] }),
4638
- /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx25(X4, { className: "h-4 w-4" }) })
5283
+ /* @__PURE__ */ jsx26(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx26(X5, { className: "h-4 w-4" }) })
4639
5284
  ] }),
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(
5285
+ /* @__PURE__ */ jsxs16("div", { className: "space-y-3", children: [
5286
+ /* @__PURE__ */ jsxs16("div", { className: "relative", children: [
5287
+ /* @__PURE__ */ jsx26(Search2, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
5288
+ /* @__PURE__ */ jsx26(
4644
5289
  Input,
4645
5290
  {
4646
5291
  placeholder: config?.labels?.search || "Search conversations...",
@@ -4650,8 +5295,8 @@ var ThreadManager = ({
4650
5295
  }
4651
5296
  )
4652
5297
  ] }),
4653
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
4654
- /* @__PURE__ */ jsxs15(
5298
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
5299
+ /* @__PURE__ */ jsxs16(
4655
5300
  Button,
4656
5301
  {
4657
5302
  variant: "outline",
@@ -4659,12 +5304,12 @@ var ThreadManager = ({
4659
5304
  onClick: () => setShowArchived(!showArchived),
4660
5305
  className: "text-xs",
4661
5306
  children: [
4662
- /* @__PURE__ */ jsx25(Filter2, { className: "h-3 w-3 mr-1" }),
5307
+ /* @__PURE__ */ jsx26(Filter2, { className: "h-3 w-3 mr-1" }),
4663
5308
  showArchived ? config?.labels?.hideArchived || "Hide Archived" : config?.labels?.showArchived || "Show Archived"
4664
5309
  ]
4665
5310
  }
4666
5311
  ),
4667
- /* @__PURE__ */ jsxs15(Badge, { variant: "secondary", className: "text-xs", children: [
5312
+ /* @__PURE__ */ jsxs16(Badge, { variant: "secondary", className: "text-xs", children: [
4668
5313
  filteredThreads.length,
4669
5314
  " / ",
4670
5315
  threads.length
@@ -4672,14 +5317,14 @@ var ThreadManager = ({
4672
5317
  ] })
4673
5318
  ] })
4674
5319
  ] }),
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(
5320
+ /* @__PURE__ */ jsxs16(CardContent, { className: "p-0 flex-1", children: [
5321
+ /* @__PURE__ */ jsx26("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ jsx26(CreateThreadDialog2, { onCreateThread, config }) }),
5322
+ /* @__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: [
5323
+ /* @__PURE__ */ jsx26(MessageSquare2, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
5324
+ /* @__PURE__ */ jsx26("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
5325
+ ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ jsxs16("div", { children: [
5326
+ /* @__PURE__ */ jsx26("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
5327
+ /* @__PURE__ */ jsx26("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ jsx26(
4683
5328
  ThreadItem,
4684
5329
  {
4685
5330
  thread,
@@ -4695,14 +5340,14 @@ var ThreadManager = ({
4695
5340
  ] }, group)) }) })
4696
5341
  ] })
4697
5342
  ] }) }),
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." })
5343
+ deleteThreadId && /* @__PURE__ */ jsx26(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ jsxs16(AlertDialogContent, { children: [
5344
+ /* @__PURE__ */ jsxs16(AlertDialogHeader, { children: [
5345
+ /* @__PURE__ */ jsx26(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
5346
+ /* @__PURE__ */ jsx26(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
4702
5347
  ] }),
4703
- /* @__PURE__ */ jsxs15(AlertDialogFooter, { children: [
4704
- /* @__PURE__ */ jsx25(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
4705
- /* @__PURE__ */ jsx25(
5348
+ /* @__PURE__ */ jsxs16(AlertDialogFooter, { children: [
5349
+ /* @__PURE__ */ jsx26(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
5350
+ /* @__PURE__ */ jsx26(
4706
5351
  AlertDialogAction,
4707
5352
  {
4708
5353
  onClick: () => deleteThreadId && handleDeleteThread(deleteThreadId),