@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.cjs CHANGED
@@ -86,6 +86,26 @@ var defaultChatConfig = {
86
86
  attachFileTooltip: "Attach file",
87
87
  recordAudio: "Record Audio",
88
88
  recordAudioTooltip: "Record audio",
89
+ voiceEnter: "Voice input",
90
+ voiceExit: "Use keyboard",
91
+ voiceTitle: "Voice",
92
+ voiceIdle: "Tap the mic to record",
93
+ voicePreparing: "Preparing microphone...",
94
+ voiceWaiting: "Waiting for speech...",
95
+ voiceListening: "Listening...",
96
+ voiceFinishing: "Finishing capture...",
97
+ voiceReview: "Ready to send",
98
+ voiceSending: "Sending...",
99
+ voiceStart: "Start recording",
100
+ voiceStop: "Stop recording",
101
+ voiceSendNow: "Send now",
102
+ voiceCancel: "Cancel",
103
+ voiceDiscard: "Delete recording",
104
+ voiceRecordAgain: "Record again",
105
+ voiceAutoSendIn: "Auto-sends in {{seconds}}s",
106
+ voiceTranscriptPending: "Transcript unavailable",
107
+ voicePermissionDenied: "Microphone access was denied.",
108
+ voiceCaptureError: "Unable to capture audio.",
89
109
  // Header labels
90
110
  exportData: "Export data",
91
111
  importData: "Import data",
@@ -148,6 +168,16 @@ var defaultChatConfig = {
148
168
  longMessageChunkChars: 12e3,
149
169
  renderUserMarkdown: true
150
170
  },
171
+ voiceCompose: {
172
+ enabled: false,
173
+ defaultMode: "text",
174
+ autoSendDelayMs: 5e3,
175
+ persistComposer: true,
176
+ showTranscriptPreview: true,
177
+ transcriptMode: "final-only",
178
+ maxRecordingMs: 6e4,
179
+ createProvider: void 0
180
+ },
151
181
  customComponent: {},
152
182
  headerActions: null
153
183
  };
@@ -170,6 +200,10 @@ function mergeConfig(_baseConfig, userConfig) {
170
200
  ...defaultChatConfig.ui,
171
201
  ...userConfig.ui
172
202
  },
203
+ voiceCompose: {
204
+ ...defaultChatConfig.voiceCompose,
205
+ ...userConfig.voiceCompose
206
+ },
173
207
  agentSelector: {
174
208
  ...defaultChatConfig.agentSelector,
175
209
  ...userConfig.agentSelector
@@ -777,7 +811,7 @@ var MediaRenderer = (0, import_react.memo)(function MediaRenderer2({ attachment
777
811
  URL.revokeObjectURL(objectUrl);
778
812
  };
779
813
  }, [attachment.kind, attachment.dataUrl]);
780
- const formatDuration = (ms) => {
814
+ const formatDuration2 = (ms) => {
781
815
  if (!ms) return "";
782
816
  const seconds = Math.floor(ms / 1e3);
783
817
  const minutes = Math.floor(seconds / 60);
@@ -2810,6 +2844,215 @@ function useChatUserContext() {
2810
2844
  return v;
2811
2845
  }
2812
2846
 
2847
+ // src/lib/voiceCompose.ts
2848
+ var AUDIO_MIME_TYPES = [
2849
+ "audio/webm;codecs=opus",
2850
+ "audio/webm",
2851
+ "audio/mp4",
2852
+ "audio/ogg;codecs=opus"
2853
+ ];
2854
+ var pickRecorderMimeType = () => {
2855
+ if (typeof MediaRecorder === "undefined") return void 0;
2856
+ for (const mimeType of AUDIO_MIME_TYPES) {
2857
+ if (typeof MediaRecorder.isTypeSupported === "function" && MediaRecorder.isTypeSupported(mimeType)) {
2858
+ return mimeType;
2859
+ }
2860
+ }
2861
+ return void 0;
2862
+ };
2863
+ var blobToDataUrl = (blob) => new Promise((resolve, reject) => {
2864
+ const reader = new FileReader();
2865
+ reader.onload = () => resolve(reader.result);
2866
+ reader.onerror = () => reject(reader.error ?? new Error("Failed to read recorded audio"));
2867
+ reader.readAsDataURL(blob);
2868
+ });
2869
+ var stopStream = (stream) => {
2870
+ if (!stream) return;
2871
+ stream.getTracks().forEach((track) => track.stop());
2872
+ };
2873
+ var closeAudioContext = async (audioContext) => {
2874
+ if (!audioContext) return;
2875
+ try {
2876
+ await audioContext.close();
2877
+ } catch {
2878
+ }
2879
+ };
2880
+ var emitDuration = (handlers, startedAt) => {
2881
+ handlers.onDurationChange?.(Math.max(0, Date.now() - startedAt));
2882
+ };
2883
+ var createManualVoiceProvider = async (handlers, options = {}) => {
2884
+ let mediaRecorder = null;
2885
+ let mediaStream = null;
2886
+ let audioContext = null;
2887
+ let analyser = null;
2888
+ let levelData = null;
2889
+ let levelFrame = 0;
2890
+ let durationTimer = null;
2891
+ let maxDurationTimer = null;
2892
+ let startedAt = 0;
2893
+ let shouldEmitSegment = true;
2894
+ let isStarting = false;
2895
+ const clearTimers = () => {
2896
+ if (durationTimer) {
2897
+ clearInterval(durationTimer);
2898
+ durationTimer = null;
2899
+ }
2900
+ if (maxDurationTimer) {
2901
+ clearTimeout(maxDurationTimer);
2902
+ maxDurationTimer = null;
2903
+ }
2904
+ };
2905
+ const stopLevelLoop = () => {
2906
+ if (levelFrame) {
2907
+ cancelAnimationFrame(levelFrame);
2908
+ levelFrame = 0;
2909
+ }
2910
+ handlers.onAudioLevelChange?.(0);
2911
+ };
2912
+ const startLevelLoop = () => {
2913
+ if (!analyser || !levelData) return;
2914
+ const tick = () => {
2915
+ if (!analyser || !levelData) return;
2916
+ analyser.getByteTimeDomainData(levelData);
2917
+ let sum = 0;
2918
+ for (let index = 0; index < levelData.length; index += 1) {
2919
+ const centered = (levelData[index] - 128) / 128;
2920
+ sum += centered * centered;
2921
+ }
2922
+ const rms = Math.sqrt(sum / levelData.length);
2923
+ handlers.onAudioLevelChange?.(Math.min(1, rms * 4));
2924
+ levelFrame = requestAnimationFrame(tick);
2925
+ };
2926
+ tick();
2927
+ };
2928
+ const cleanupActiveResources = async () => {
2929
+ clearTimers();
2930
+ stopLevelLoop();
2931
+ stopStream(mediaStream);
2932
+ mediaStream = null;
2933
+ analyser = null;
2934
+ levelData = null;
2935
+ await closeAudioContext(audioContext);
2936
+ audioContext = null;
2937
+ };
2938
+ const finalizeStop = async () => {
2939
+ mediaRecorder = null;
2940
+ isStarting = false;
2941
+ await cleanupActiveResources();
2942
+ };
2943
+ const start = async () => {
2944
+ if (isStarting || mediaRecorder?.state === "recording") {
2945
+ return;
2946
+ }
2947
+ if (!navigator.mediaDevices?.getUserMedia) {
2948
+ throw new Error("Audio capture is not supported in this browser");
2949
+ }
2950
+ if (typeof MediaRecorder === "undefined") {
2951
+ throw new Error("MediaRecorder is not supported in this browser");
2952
+ }
2953
+ isStarting = true;
2954
+ shouldEmitSegment = true;
2955
+ handlers.onTranscriptChange?.({});
2956
+ handlers.onDurationChange?.(0);
2957
+ handlers.onAudioLevelChange?.(0);
2958
+ handlers.onStateChange?.("preparing");
2959
+ try {
2960
+ mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
2961
+ const mimeType = pickRecorderMimeType();
2962
+ mediaRecorder = mimeType ? new MediaRecorder(mediaStream, { mimeType }) : new MediaRecorder(mediaStream);
2963
+ const chunks = [];
2964
+ mediaRecorder.ondataavailable = (event) => {
2965
+ if (event.data.size > 0) {
2966
+ chunks.push(event.data);
2967
+ }
2968
+ };
2969
+ mediaRecorder.onerror = (event) => {
2970
+ const error = event.error ?? new Error("Audio recorder failed");
2971
+ handlers.onError?.(error);
2972
+ };
2973
+ mediaRecorder.onstop = async () => {
2974
+ const durationMs = startedAt > 0 ? Math.max(0, Date.now() - startedAt) : 0;
2975
+ try {
2976
+ if (shouldEmitSegment && chunks.length > 0) {
2977
+ const blob = new Blob(chunks, {
2978
+ type: mediaRecorder?.mimeType || mimeType || "audio/webm"
2979
+ });
2980
+ const dataUrl = await blobToDataUrl(blob);
2981
+ handlers.onSegmentReady?.({
2982
+ attachment: {
2983
+ kind: "audio",
2984
+ dataUrl,
2985
+ mimeType: blob.type || "audio/webm",
2986
+ durationMs,
2987
+ fileName: `voice-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.webm`,
2988
+ size: blob.size
2989
+ },
2990
+ metadata: { source: "manual" }
2991
+ });
2992
+ } else {
2993
+ handlers.onStateChange?.("idle");
2994
+ }
2995
+ } catch (error) {
2996
+ handlers.onError?.(error);
2997
+ } finally {
2998
+ await finalizeStop();
2999
+ }
3000
+ };
3001
+ const AudioContextCtor = globalThis.AudioContext || globalThis.webkitAudioContext;
3002
+ if (AudioContextCtor) {
3003
+ audioContext = new AudioContextCtor();
3004
+ await audioContext.resume().catch(() => void 0);
3005
+ const sourceNode = audioContext.createMediaStreamSource(mediaStream);
3006
+ analyser = audioContext.createAnalyser();
3007
+ analyser.fftSize = 1024;
3008
+ levelData = new Uint8Array(analyser.fftSize);
3009
+ sourceNode.connect(analyser);
3010
+ startLevelLoop();
3011
+ }
3012
+ startedAt = Date.now();
3013
+ emitDuration(handlers, startedAt);
3014
+ durationTimer = setInterval(() => emitDuration(handlers, startedAt), 200);
3015
+ if (options.maxRecordingMs && options.maxRecordingMs > 0) {
3016
+ maxDurationTimer = setTimeout(() => {
3017
+ void stop();
3018
+ }, options.maxRecordingMs);
3019
+ }
3020
+ mediaRecorder.start();
3021
+ handlers.onStateChange?.("listening");
3022
+ } catch (error) {
3023
+ isStarting = false;
3024
+ await cleanupActiveResources();
3025
+ throw error;
3026
+ }
3027
+ };
3028
+ const stop = async () => {
3029
+ if (!mediaRecorder || mediaRecorder.state === "inactive") {
3030
+ return;
3031
+ }
3032
+ handlers.onStateChange?.("finishing");
3033
+ mediaRecorder.stop();
3034
+ };
3035
+ const cancel = async () => {
3036
+ shouldEmitSegment = false;
3037
+ if (mediaRecorder && mediaRecorder.state !== "inactive") {
3038
+ mediaRecorder.stop();
3039
+ return;
3040
+ }
3041
+ await finalizeStop();
3042
+ handlers.onStateChange?.("idle");
3043
+ };
3044
+ const destroy = async () => {
3045
+ await cancel();
3046
+ };
3047
+ return {
3048
+ start,
3049
+ stop,
3050
+ cancel,
3051
+ destroy
3052
+ };
3053
+ };
3054
+ var resolveVoiceProviderFactory = (createProvider) => createProvider ?? createManualVoiceProvider;
3055
+
2813
3056
  // src/components/ui/progress.tsx
2814
3057
  var ProgressPrimitive = __toESM(require("@radix-ui/react-progress"), 1);
2815
3058
  var import_jsx_runtime20 = require("react/jsx-runtime");
@@ -2839,9 +3082,185 @@ function Progress({
2839
3082
  );
2840
3083
  }
2841
3084
 
2842
- // src/components/chat/ChatInput.tsx
3085
+ // src/components/chat/VoiceComposer.tsx
2843
3086
  var import_lucide_react9 = require("lucide-react");
2844
3087
  var import_jsx_runtime21 = require("react/jsx-runtime");
3088
+ var formatDuration = (durationMs) => {
3089
+ const totalSeconds = Math.max(0, Math.floor(durationMs / 1e3));
3090
+ const minutes = Math.floor(totalSeconds / 60);
3091
+ const seconds = totalSeconds % 60;
3092
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
3093
+ };
3094
+ var interpolateSeconds = (label, seconds) => {
3095
+ if (!label) {
3096
+ return `Auto-sends in ${seconds}s`;
3097
+ }
3098
+ if (label.includes("{{seconds}}")) {
3099
+ return label.replace(/\{\{\s*seconds\s*\}\}/g, String(seconds));
3100
+ }
3101
+ return `${label} ${seconds}s`;
3102
+ };
3103
+ var resolveStateLabel = (state, labels, errorMessage) => {
3104
+ switch (state) {
3105
+ case "preparing":
3106
+ return labels?.voicePreparing || "Preparing microphone...";
3107
+ case "waiting_for_speech":
3108
+ return labels?.voiceWaiting || "Waiting for speech...";
3109
+ case "listening":
3110
+ return labels?.voiceListening || "Listening...";
3111
+ case "finishing":
3112
+ return labels?.voiceFinishing || "Finishing capture...";
3113
+ case "review":
3114
+ return labels?.voiceReview || "Ready to send";
3115
+ case "sending":
3116
+ return labels?.voiceSending || "Sending...";
3117
+ case "error":
3118
+ return errorMessage || labels?.voiceCaptureError || "Unable to capture audio.";
3119
+ case "idle":
3120
+ default:
3121
+ return labels?.voiceIdle || "Tap the mic to record";
3122
+ }
3123
+ };
3124
+ var resolveTranscriptText = (transcript, transcriptMode) => {
3125
+ if (transcriptMode === "none" || !transcript) {
3126
+ return null;
3127
+ }
3128
+ if (transcriptMode === "final-only") {
3129
+ return transcript.final?.trim() || null;
3130
+ }
3131
+ return transcript.final?.trim() || transcript.partial?.trim() || null;
3132
+ };
3133
+ var VoiceComposer = ({
3134
+ state,
3135
+ transcript,
3136
+ transcriptMode,
3137
+ showTranscriptPreview,
3138
+ attachment,
3139
+ durationMs,
3140
+ audioLevel,
3141
+ countdownMs,
3142
+ autoSendDelayMs,
3143
+ isAutoSendActive,
3144
+ errorMessage,
3145
+ disabled = false,
3146
+ labels,
3147
+ onStart,
3148
+ onStop,
3149
+ onCancelAutoSend,
3150
+ onDiscard,
3151
+ onRecordAgain,
3152
+ onSendNow,
3153
+ onExit
3154
+ }) => {
3155
+ const transcriptText = resolveTranscriptText(transcript, transcriptMode);
3156
+ const countdownSeconds = Math.max(1, Math.ceil(countdownMs / 1e3));
3157
+ const countdownValue = autoSendDelayMs > 0 ? Math.min(100, Math.max(0, (autoSendDelayMs - countdownMs) / autoSendDelayMs * 100)) : 100;
3158
+ const isBusy = state === "preparing" || state === "finishing" || state === "sending";
3159
+ const isCapturing = state === "waiting_for_speech" || state === "listening";
3160
+ const isReviewing = state === "review";
3161
+ const levelValue = isCapturing || state === "preparing" || state === "finishing" ? Math.max(8, Math.round(audioLevel * 100)) : 0;
3162
+ const headerLabel = state === "error" ? labels?.voiceCaptureError || "Unable to capture audio." : resolveStateLabel(state, labels, errorMessage);
3163
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "w-full max-w-3xl rounded-xl border bg-background p-3 shadow-sm sm:p-4 md:min-w-3xl", children: [
3164
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between gap-2 sm:gap-3", children: [
3165
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
3166
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: labels?.voiceTitle || "Voice" }),
3167
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "truncate text-xs sm:text-sm text-muted-foreground", children: headerLabel })
3168
+ ] }),
3169
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3170
+ Button,
3171
+ {
3172
+ type: "button",
3173
+ variant: "ghost",
3174
+ size: "sm",
3175
+ className: "shrink-0 px-2 sm:px-3",
3176
+ onClick: onExit,
3177
+ disabled: disabled || isBusy,
3178
+ children: [
3179
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Keyboard, { className: "h-4 w-4" }),
3180
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "hidden sm:inline", children: labels?.voiceExit || "Use keyboard" })
3181
+ ]
3182
+ }
3183
+ )
3184
+ ] }),
3185
+ !isReviewing ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mx-auto flex w-full max-w-sm flex-col items-center gap-3", children: [
3186
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3187
+ Button,
3188
+ {
3189
+ type: "button",
3190
+ size: "icon",
3191
+ variant: isCapturing ? "destructive" : "outline",
3192
+ 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"}`,
3193
+ onClick: isCapturing ? onStop : onStart,
3194
+ disabled: disabled || isBusy,
3195
+ children: isBusy ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Loader2, { className: "h-7 w-7 animate-spin" }) : isCapturing ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-7 w-7" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-7 w-7" })
3196
+ }
3197
+ ),
3198
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "w-full space-y-2", children: [
3199
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Progress, { value: levelValue, className: "h-2" }),
3200
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
3201
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: formatDuration(durationMs) }),
3202
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: isCapturing ? labels?.voiceStop || "Stop recording" : labels?.voiceStart || "Start recording" })
3203
+ ] })
3204
+ ] }),
3205
+ showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-full rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText })
3206
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-3 rounded-xl border bg-muted/20 p-3 sm:p-4", children: [
3207
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
3208
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "min-w-0", children: [
3209
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-sm font-medium text-foreground", children: labels?.voiceReview || "Ready to send" }),
3210
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-xs text-muted-foreground", children: formatDuration(durationMs) })
3211
+ ] }),
3212
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3213
+ Button,
3214
+ {
3215
+ type: "button",
3216
+ variant: "ghost",
3217
+ size: "icon",
3218
+ className: "h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive",
3219
+ onClick: onDiscard,
3220
+ disabled,
3221
+ "aria-label": labels?.voiceDiscard || "Delete recording",
3222
+ title: labels?.voiceDiscard || "Delete recording",
3223
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Trash2, { className: "h-4 w-4" })
3224
+ }
3225
+ )
3226
+ ] }),
3227
+ attachment && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-3 rounded-lg bg-background p-2", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("audio", { controls: true, preload: "metadata", className: "w-full", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("source", { src: attachment.dataUrl, type: attachment.mimeType }) }) }),
3228
+ showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-3 rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText }),
3229
+ isAutoSendActive && autoSendDelayMs > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-3 space-y-2", children: [
3230
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Progress, { value: countdownValue, className: "h-2" }),
3231
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-center text-xs text-muted-foreground", children: interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds) })
3232
+ ] }),
3233
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-3 flex items-center justify-end gap-2", children: [
3234
+ isAutoSendActive && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", variant: "ghost", size: "sm", onClick: onCancelAutoSend, disabled, children: [
3235
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-4 w-4" }),
3236
+ labels?.voiceCancel || "Cancel"
3237
+ ] }),
3238
+ !isAutoSendActive && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3239
+ Button,
3240
+ {
3241
+ type: "button",
3242
+ variant: "outline",
3243
+ size: "icon",
3244
+ onClick: onRecordAgain,
3245
+ disabled,
3246
+ "aria-label": labels?.voiceRecordAgain || "Record again",
3247
+ title: labels?.voiceRecordAgain || "Record again",
3248
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-4 w-4" })
3249
+ }
3250
+ ),
3251
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", size: "sm", onClick: onSendNow, disabled, children: [
3252
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Send, { className: "h-4 w-4" }),
3253
+ labels?.voiceSendNow || "Send now"
3254
+ ] })
3255
+ ] })
3256
+ ] }),
3257
+ state === "error" && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: errorMessage })
3258
+ ] });
3259
+ };
3260
+
3261
+ // src/components/chat/ChatInput.tsx
3262
+ var import_lucide_react10 = require("lucide-react");
3263
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2845
3264
  var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, progress, onCancel }) {
2846
3265
  const guessTypeFromName = (name) => {
2847
3266
  const ext = (name || "").split(".").pop()?.toLowerCase();
@@ -2870,10 +3289,10 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
2870
3289
  };
2871
3290
  const getFileIcon = (type, name) => {
2872
3291
  const t = typeof type === "string" && type.length > 0 ? type : guessTypeFromName(name);
2873
- if (t.startsWith("image/")) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Image, { className: "h-4 w-4" });
2874
- if (t.startsWith("video/")) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Video, { className: "h-4 w-4" });
2875
- if (t.startsWith("audio/")) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-4 w-4" });
2876
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.FileText, { className: "h-4 w-4" });
3292
+ if (t.startsWith("image/")) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Image, { className: "h-4 w-4" });
3293
+ if (t.startsWith("video/")) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Video, { className: "h-4 w-4" });
3294
+ if (t.startsWith("audio/")) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-4 w-4" });
3295
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.FileText, { className: "h-4 w-4" });
2877
3296
  };
2878
3297
  const formatFileSize = (bytes) => {
2879
3298
  if (bytes === 0) return "0 Bytes";
@@ -2882,21 +3301,21 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
2882
3301
  const i = Math.floor(Math.log(bytes) / Math.log(k));
2883
3302
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
2884
3303
  };
2885
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Card, { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
3304
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Card, { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-3", children: [
2886
3305
  getFileIcon(file.type, file.name),
2887
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 min-w-0", children: [
2888
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm font-medium truncate", children: file.name }),
2889
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
2890
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Progress, { value: progress, className: "h-1 mt-1" })
3306
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex-1 min-w-0", children: [
3307
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-sm font-medium truncate", children: file.name }),
3308
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
3309
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Progress, { value: progress, className: "h-1 mt-1" })
2891
3310
  ] }),
2892
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3311
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2893
3312
  Button,
2894
3313
  {
2895
3314
  variant: "ghost",
2896
3315
  size: "icon",
2897
3316
  className: "h-6 w-6",
2898
3317
  onClick: onCancel,
2899
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3318
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
2900
3319
  }
2901
3320
  )
2902
3321
  ] }) }) });
@@ -2930,35 +3349,35 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
2930
3349
  setIsPlaying(!isPlaying);
2931
3350
  }
2932
3351
  };
2933
- const formatDuration = (ms) => {
3352
+ const formatDuration2 = (ms) => {
2934
3353
  if (!ms) return "";
2935
3354
  const seconds = Math.floor(ms / 1e3);
2936
3355
  const minutes = Math.floor(seconds / 60);
2937
3356
  return `${minutes}:${(seconds % 60).toString().padStart(2, "0")}`;
2938
3357
  };
2939
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Card, { className: "relative group", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardContent, { className: "p-2", children: [
2940
- attachment.kind === "image" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "relative", children: [
2941
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3358
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Card, { className: "relative group", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardContent, { className: "p-2", children: [
3359
+ attachment.kind === "image" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "relative", children: [
3360
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2942
3361
  "img",
2943
3362
  {
2944
3363
  src: attachment.dataUrl,
2945
- alt: attachment.fileName || "Anexo",
3364
+ alt: attachment.fileName || "Attachment",
2946
3365
  className: "w-full h-20 object-cover rounded"
2947
3366
  }
2948
3367
  ),
2949
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3368
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2950
3369
  Button,
2951
3370
  {
2952
3371
  variant: "destructive",
2953
3372
  size: "icon",
2954
3373
  className: "h-6 w-6",
2955
3374
  onClick: onRemove,
2956
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3375
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
2957
3376
  }
2958
3377
  ) })
2959
3378
  ] }),
2960
- attachment.kind === "video" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "relative", children: [
2961
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3379
+ attachment.kind === "video" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "relative", children: [
3380
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2962
3381
  "video",
2963
3382
  {
2964
3383
  src: attachment.dataUrl,
@@ -2967,34 +3386,34 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
2967
3386
  muted: true
2968
3387
  }
2969
3388
  ),
2970
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3389
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2971
3390
  Button,
2972
3391
  {
2973
3392
  variant: "destructive",
2974
3393
  size: "icon",
2975
3394
  className: "h-6 w-6",
2976
3395
  onClick: onRemove,
2977
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3396
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
2978
3397
  }
2979
3398
  ) }),
2980
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration(attachment.durationMs) })
3399
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration2(attachment.durationMs) })
2981
3400
  ] }),
2982
- attachment.kind === "audio" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2 p-2", children: [
2983
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3401
+ attachment.kind === "audio" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 p-2", children: [
3402
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2984
3403
  Button,
2985
3404
  {
2986
3405
  variant: "outline",
2987
3406
  size: "icon",
2988
3407
  className: "h-8 w-8",
2989
3408
  onClick: handlePlayPause,
2990
- children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Play, { className: "h-3 w-3" })
3409
+ children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Pause, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Play, { className: "h-3 w-3" })
2991
3410
  }
2992
3411
  ),
2993
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1", children: [
2994
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs font-medium", children: attachment.fileName || "\xC1udio" }),
2995
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs text-muted-foreground", children: formatDuration(attachment.durationMs) })
3412
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex-1", children: [
3413
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-xs font-medium", children: attachment.fileName || "Audio" }),
3414
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-xs text-muted-foreground", children: formatDuration2(attachment.durationMs) })
2996
3415
  ] }),
2997
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3416
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2998
3417
  "audio",
2999
3418
  {
3000
3419
  ref: audioRef,
@@ -3002,21 +3421,21 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
3002
3421
  onPause: () => setIsPlaying(false),
3003
3422
  onEnded: () => setIsPlaying(false),
3004
3423
  preload: "metadata",
3005
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3424
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3006
3425
  }
3007
3426
  ),
3008
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3427
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3009
3428
  Button,
3010
3429
  {
3011
3430
  variant: "ghost",
3012
3431
  size: "icon",
3013
3432
  className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
3014
3433
  onClick: onRemove,
3015
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3434
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
3016
3435
  }
3017
3436
  )
3018
3437
  ] }),
3019
- attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "truncate", children: attachment.fileName }) })
3438
+ attachment.fileName && attachment.kind !== "audio" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "truncate", children: attachment.fileName }) })
3020
3439
  ] }) });
3021
3440
  });
3022
3441
  var AudioRecorder = (0, import_react5.memo)(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
@@ -3026,61 +3445,71 @@ var AudioRecorder = (0, import_react5.memo)(function AudioRecorder2({ isRecordin
3026
3445
  return `${mins}:${secs.toString().padStart(2, "0")}`;
3027
3446
  };
3028
3447
  if (!isRecording) {
3029
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
3030
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3448
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
3449
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3031
3450
  Button,
3032
3451
  {
3033
3452
  variant: "outline",
3034
3453
  size: "icon",
3035
3454
  onClick: onStartRecording,
3036
3455
  className: "h-10 w-10",
3037
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-4 w-4" })
3456
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-4 w-4" })
3038
3457
  }
3039
3458
  ) }),
3040
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3459
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3041
3460
  ] });
3042
3461
  }
3043
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Card, { className: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
3044
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
3045
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
3046
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: "Gravando" })
3462
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Card, { className: "border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-3", children: [
3463
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
3464
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
3465
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: config?.labels?.voiceListening || "Recording" })
3047
3466
  ] }),
3048
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
3049
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-1 ml-auto", children: [
3050
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3467
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
3468
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex gap-1 ml-auto", children: [
3469
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3051
3470
  Button,
3052
3471
  {
3053
3472
  variant: "outline",
3054
3473
  size: "sm",
3055
3474
  onClick: onCancel,
3056
3475
  children: [
3057
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3 mr-1" }),
3058
- "Cancelar"
3476
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3 mr-1" }),
3477
+ config?.labels?.cancel || "Cancel"
3059
3478
  ]
3060
3479
  }
3061
3480
  ),
3062
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3481
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3063
3482
  Button,
3064
3483
  {
3065
3484
  variant: "default",
3066
3485
  size: "sm",
3067
3486
  onClick: onStopRecording,
3068
3487
  children: [
3069
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-3 w-3 mr-1" }),
3070
- "Parar"
3488
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Square, { className: "h-3 w-3 mr-1" }),
3489
+ config?.labels?.voiceStop || "Stop"
3071
3490
  ]
3072
3491
  }
3073
3492
  )
3074
3493
  ] })
3075
3494
  ] }) }) });
3076
3495
  });
3496
+ var resolveVoiceErrorMessage = (error, config) => {
3497
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
3498
+ return config?.labels?.voicePermissionDenied || "Microphone access was denied.";
3499
+ }
3500
+ if (error instanceof Error && error.message.trim().length > 0) {
3501
+ return error.message;
3502
+ }
3503
+ return config?.labels?.voiceCaptureError || "Unable to capture audio.";
3504
+ };
3505
+ var clearVoiceTranscript = () => ({});
3077
3506
  var ChatInput = (0, import_react5.memo)(function ChatInput2({
3078
3507
  value,
3079
3508
  onChange,
3080
3509
  onSubmit,
3081
3510
  attachments,
3082
3511
  onAttachmentsChange,
3083
- placeholder = "Digite sua mensagem...",
3512
+ placeholder = "Type your message...",
3084
3513
  disabled = false,
3085
3514
  isGenerating = false,
3086
3515
  onStopGeneration,
@@ -3093,16 +3522,35 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3093
3522
  className = "",
3094
3523
  config
3095
3524
  }) {
3525
+ const voiceComposeEnabled = config?.voiceCompose?.enabled === true;
3526
+ const voiceDefaultMode = config?.voiceCompose?.defaultMode ?? "text";
3527
+ const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5e3;
3528
+ const voicePersistComposer = config?.voiceCompose?.persistComposer ?? true;
3529
+ const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;
3530
+ const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? "final-only";
3531
+ const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;
3096
3532
  const [isRecording, setIsRecording] = (0, import_react5.useState)(false);
3097
3533
  const { setContext } = useChatUserContext();
3098
3534
  const [recordingDuration, setRecordingDuration] = (0, import_react5.useState)(0);
3099
3535
  const [uploadProgress, setUploadProgress] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
3536
+ const [isVoiceComposerOpen, setIsVoiceComposerOpen] = (0, import_react5.useState)(
3537
+ () => voiceComposeEnabled && voiceDefaultMode === "voice"
3538
+ );
3539
+ const [voiceState, setVoiceState] = (0, import_react5.useState)("idle");
3540
+ const [voiceDraft, setVoiceDraft] = (0, import_react5.useState)(null);
3541
+ const [voiceTranscript, setVoiceTranscript] = (0, import_react5.useState)(clearVoiceTranscript);
3542
+ const [voiceDurationMs, setVoiceDurationMs] = (0, import_react5.useState)(0);
3543
+ const [voiceAudioLevel, setVoiceAudioLevel] = (0, import_react5.useState)(0);
3544
+ const [voiceCountdownMs, setVoiceCountdownMs] = (0, import_react5.useState)(0);
3545
+ const [isVoiceAutoSendActive, setIsVoiceAutoSendActive] = (0, import_react5.useState)(false);
3546
+ const [voiceError, setVoiceError] = (0, import_react5.useState)(null);
3100
3547
  const textareaRef = (0, import_react5.useRef)(null);
3101
3548
  const fileInputRef = (0, import_react5.useRef)(null);
3102
3549
  const mediaRecorderRef = (0, import_react5.useRef)(null);
3103
3550
  const recordingStartTime = (0, import_react5.useRef)(0);
3104
3551
  const recordingInterval = (0, import_react5.useRef)(null);
3105
3552
  const mediaStreamRef = (0, import_react5.useRef)(null);
3553
+ const voiceProviderRef = (0, import_react5.useRef)(null);
3106
3554
  (0, import_react5.useEffect)(() => {
3107
3555
  return () => {
3108
3556
  if (mediaStreamRef.current) {
@@ -3111,6 +3559,10 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3111
3559
  if (recordingInterval.current) {
3112
3560
  clearInterval(recordingInterval.current);
3113
3561
  }
3562
+ if (voiceProviderRef.current) {
3563
+ void voiceProviderRef.current.destroy();
3564
+ voiceProviderRef.current = null;
3565
+ }
3114
3566
  };
3115
3567
  }, []);
3116
3568
  const handleSubmit = (e) => {
@@ -3128,7 +3580,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3128
3580
  };
3129
3581
  const processFile = async (file) => {
3130
3582
  if (file.size > maxFileSize) {
3131
- alert(`Arquivo muito grande. M\xE1ximo permitido: ${Math.round(maxFileSize / 1024 / 1024)}MB`);
3583
+ alert(`File too large. Max allowed: ${Math.round(maxFileSize / 1024 / 1024)}MB`);
3132
3584
  return null;
3133
3585
  }
3134
3586
  const fileId = `${Date.now()}_${Math.random().toString(36).slice(2)}`;
@@ -3187,7 +3639,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3187
3639
  newMap.delete(fileId);
3188
3640
  return newMap;
3189
3641
  });
3190
- alert("Erro ao processar arquivo");
3642
+ alert("Failed to process file");
3191
3643
  return null;
3192
3644
  }
3193
3645
  };
@@ -3262,7 +3714,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3262
3714
  }, 1e3);
3263
3715
  } catch (error) {
3264
3716
  console.error("Error starting recording:", error);
3265
- alert("N\xE3o foi poss\xEDvel acessar o microfone");
3717
+ alert(config?.labels?.voicePermissionDenied || "Microphone access was denied.");
3266
3718
  }
3267
3719
  };
3268
3720
  const stopRecording = () => {
@@ -3287,13 +3739,154 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3287
3739
  }
3288
3740
  }
3289
3741
  };
3742
+ const resetVoiceComposerState = (0, import_react5.useCallback)((nextState = "idle") => {
3743
+ setVoiceState(nextState);
3744
+ setVoiceDraft(null);
3745
+ setVoiceTranscript(clearVoiceTranscript());
3746
+ setVoiceDurationMs(0);
3747
+ setVoiceAudioLevel(0);
3748
+ setVoiceCountdownMs(0);
3749
+ setIsVoiceAutoSendActive(false);
3750
+ setVoiceError(null);
3751
+ }, []);
3752
+ const ensureVoiceProvider = (0, import_react5.useCallback)(async () => {
3753
+ if (voiceProviderRef.current) {
3754
+ return voiceProviderRef.current;
3755
+ }
3756
+ const createProvider = resolveVoiceProviderFactory(config?.voiceCompose?.createProvider);
3757
+ const provider = await createProvider({
3758
+ onStateChange: setVoiceState,
3759
+ onAudioLevelChange: setVoiceAudioLevel,
3760
+ onDurationChange: setVoiceDurationMs,
3761
+ onTranscriptChange: setVoiceTranscript,
3762
+ onSegmentReady: (segment) => {
3763
+ setVoiceDraft(segment);
3764
+ setVoiceTranscript(segment.transcript ?? clearVoiceTranscript());
3765
+ setVoiceDurationMs(segment.attachment.durationMs ?? 0);
3766
+ setVoiceAudioLevel(0);
3767
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3768
+ setIsVoiceAutoSendActive(voiceAutoSendDelayMs > 0);
3769
+ setVoiceError(null);
3770
+ setVoiceState("review");
3771
+ },
3772
+ onError: (error) => {
3773
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3774
+ setVoiceAudioLevel(0);
3775
+ setVoiceCountdownMs(0);
3776
+ setIsVoiceAutoSendActive(false);
3777
+ setVoiceState("error");
3778
+ }
3779
+ }, {
3780
+ maxRecordingMs: voiceMaxRecordingMs
3781
+ });
3782
+ voiceProviderRef.current = provider;
3783
+ return provider;
3784
+ }, [config, voiceAutoSendDelayMs, voiceMaxRecordingMs]);
3785
+ const closeVoiceComposer = (0, import_react5.useCallback)(async () => {
3786
+ setIsVoiceComposerOpen(false);
3787
+ setVoiceError(null);
3788
+ setVoiceCountdownMs(0);
3789
+ setVoiceAudioLevel(0);
3790
+ setVoiceTranscript(clearVoiceTranscript());
3791
+ setVoiceDraft(null);
3792
+ setVoiceDurationMs(0);
3793
+ setVoiceState("idle");
3794
+ if (voiceProviderRef.current) {
3795
+ await voiceProviderRef.current.cancel();
3796
+ }
3797
+ }, []);
3798
+ const startVoiceCapture = (0, import_react5.useCallback)(async () => {
3799
+ if (disabled || isGenerating) {
3800
+ return;
3801
+ }
3802
+ setIsVoiceComposerOpen(true);
3803
+ setVoiceError(null);
3804
+ setVoiceDraft(null);
3805
+ setVoiceCountdownMs(0);
3806
+ setVoiceTranscript(clearVoiceTranscript());
3807
+ setVoiceAudioLevel(0);
3808
+ setVoiceDurationMs(0);
3809
+ setIsVoiceAutoSendActive(false);
3810
+ try {
3811
+ const provider = await ensureVoiceProvider();
3812
+ await provider.start();
3813
+ } catch (error) {
3814
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3815
+ setVoiceState("error");
3816
+ }
3817
+ }, [disabled, isGenerating, ensureVoiceProvider, config]);
3818
+ const stopVoiceCapture = (0, import_react5.useCallback)(async () => {
3819
+ if (!voiceProviderRef.current) return;
3820
+ try {
3821
+ await voiceProviderRef.current.stop();
3822
+ } catch (error) {
3823
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3824
+ setVoiceState("error");
3825
+ }
3826
+ }, [config]);
3827
+ const cancelVoiceCapture = (0, import_react5.useCallback)(async () => {
3828
+ if (voiceProviderRef.current) {
3829
+ await voiceProviderRef.current.cancel();
3830
+ }
3831
+ resetVoiceComposerState("idle");
3832
+ }, [resetVoiceComposerState]);
3833
+ const finalizeVoiceComposerAfterSend = (0, import_react5.useCallback)(() => {
3834
+ if (voicePersistComposer) {
3835
+ resetVoiceComposerState("idle");
3836
+ setIsVoiceComposerOpen(true);
3837
+ return;
3838
+ }
3839
+ void closeVoiceComposer();
3840
+ }, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);
3841
+ const sendVoiceDraft = (0, import_react5.useCallback)(() => {
3842
+ if (!voiceDraft || disabled || isGenerating) {
3843
+ return;
3844
+ }
3845
+ setVoiceState("sending");
3846
+ setVoiceCountdownMs(0);
3847
+ setIsVoiceAutoSendActive(false);
3848
+ onSubmit("", [...attachments, voiceDraft.attachment]);
3849
+ onChange("");
3850
+ onAttachmentsChange([]);
3851
+ finalizeVoiceComposerAfterSend();
3852
+ }, [
3853
+ voiceDraft,
3854
+ disabled,
3855
+ isGenerating,
3856
+ onSubmit,
3857
+ attachments,
3858
+ onChange,
3859
+ onAttachmentsChange,
3860
+ finalizeVoiceComposerAfterSend
3861
+ ]);
3862
+ const cancelVoiceAutoSend = (0, import_react5.useCallback)(() => {
3863
+ setVoiceCountdownMs(0);
3864
+ setIsVoiceAutoSendActive(false);
3865
+ }, []);
3866
+ (0, import_react5.useEffect)(() => {
3867
+ if (voiceState !== "review" || !voiceDraft || voiceAutoSendDelayMs <= 0 || !isVoiceAutoSendActive) {
3868
+ return;
3869
+ }
3870
+ const startedAt = Date.now();
3871
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3872
+ const timer = setInterval(() => {
3873
+ const remaining = Math.max(0, voiceAutoSendDelayMs - (Date.now() - startedAt));
3874
+ setVoiceCountdownMs(remaining);
3875
+ if (remaining <= 0) {
3876
+ clearInterval(timer);
3877
+ sendVoiceDraft();
3878
+ }
3879
+ }, 100);
3880
+ return () => clearInterval(timer);
3881
+ }, [voiceState, voiceDraft, voiceAutoSendDelayMs, isVoiceAutoSendActive, sendVoiceDraft]);
3290
3882
  const removeAttachment = (index) => {
3291
3883
  const newAttachments = attachments.filter((_, i) => i !== index);
3292
3884
  onAttachmentsChange(newAttachments);
3293
3885
  };
3294
3886
  const canAddMoreAttachments = attachments.length < maxAttachments;
3295
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
3296
- uploadProgress.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3887
+ const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;
3888
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: `border-t py-0 bg-transparent ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "px-0 md:p-2 pb-1 space-y-4 bg-transparent", children: [
3889
+ uploadProgress.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "space-y-2", children: Array.from(uploadProgress.entries()).map(([id, progress]) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3297
3890
  FileUploadItem,
3298
3891
  {
3299
3892
  file: { name: progress.fileName },
@@ -3308,7 +3901,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3308
3901
  },
3309
3902
  id
3310
3903
  )) }),
3311
- isRecording && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3904
+ isRecording && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3312
3905
  AudioRecorder,
3313
3906
  {
3314
3907
  isRecording,
@@ -3319,7 +3912,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3319
3912
  config
3320
3913
  }
3321
3914
  ),
3322
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3915
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "grid grid-cols-4 gap-2", children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3323
3916
  AttachmentPreview,
3324
3917
  {
3325
3918
  attachment,
@@ -3327,15 +3920,51 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3327
3920
  },
3328
3921
  index
3329
3922
  )) }),
3330
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3923
+ showVoiceComposer ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3924
+ VoiceComposer,
3925
+ {
3926
+ state: voiceState,
3927
+ transcript: voiceTranscript,
3928
+ transcriptMode: voiceTranscriptMode,
3929
+ showTranscriptPreview: voiceShowTranscriptPreview,
3930
+ attachment: voiceDraft?.attachment ?? null,
3931
+ durationMs: voiceDurationMs,
3932
+ audioLevel: voiceAudioLevel,
3933
+ countdownMs: voiceCountdownMs,
3934
+ autoSendDelayMs: voiceAutoSendDelayMs,
3935
+ isAutoSendActive: isVoiceAutoSendActive,
3936
+ errorMessage: voiceError,
3937
+ disabled: disabled || isGenerating,
3938
+ labels: config?.labels,
3939
+ onStart: () => {
3940
+ void startVoiceCapture();
3941
+ },
3942
+ onStop: () => {
3943
+ void stopVoiceCapture();
3944
+ },
3945
+ onCancelAutoSend: () => {
3946
+ cancelVoiceAutoSend();
3947
+ },
3948
+ onDiscard: () => {
3949
+ void cancelVoiceCapture();
3950
+ },
3951
+ onRecordAgain: () => {
3952
+ void startVoiceCapture();
3953
+ },
3954
+ onSendNow: sendVoiceDraft,
3955
+ onExit: () => {
3956
+ void closeVoiceComposer();
3957
+ }
3958
+ }
3959
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3331
3960
  "div",
3332
3961
  {
3333
3962
  className: "flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl",
3334
3963
  onDrop: handleDrop,
3335
3964
  onDragOver: handleDragOver,
3336
3965
  children: [
3337
- enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3338
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3966
+ enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3967
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3339
3968
  "input",
3340
3969
  {
3341
3970
  ref: fileInputRef,
@@ -3346,8 +3975,8 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3346
3975
  className: "hidden"
3347
3976
  }
3348
3977
  ),
3349
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
3350
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3978
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
3979
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3351
3980
  Button,
3352
3981
  {
3353
3982
  type: "button",
@@ -3360,13 +3989,13 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3360
3989
  fileInputRef.current?.click();
3361
3990
  },
3362
3991
  disabled,
3363
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Paperclip, { className: "h-4 w-4" })
3992
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Paperclip, { className: "h-4 w-4" })
3364
3993
  }
3365
3994
  ) }),
3366
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
3995
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
3367
3996
  ] })
3368
3997
  ] }),
3369
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3998
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3370
3999
  Textarea,
3371
4000
  {
3372
4001
  ref: textareaRef,
@@ -3379,7 +4008,23 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3379
4008
  rows: 1
3380
4009
  }
3381
4010
  ) }),
3382
- enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4011
+ enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (voiceComposeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
4012
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4013
+ Button,
4014
+ {
4015
+ type: "button",
4016
+ variant: "outline",
4017
+ size: "icon",
4018
+ className: "h-10 w-10",
4019
+ onClick: () => {
4020
+ void startVoiceCapture();
4021
+ },
4022
+ disabled: disabled || isGenerating,
4023
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-4 w-4" })
4024
+ }
4025
+ ) }),
4026
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip })
4027
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3383
4028
  AudioRecorder,
3384
4029
  {
3385
4030
  isRecording,
@@ -3389,9 +4034,9 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3389
4034
  recordingDuration,
3390
4035
  config
3391
4036
  }
3392
- ),
3393
- isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
3394
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4037
+ )),
4038
+ isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
4039
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3395
4040
  Button,
3396
4041
  {
3397
4042
  type: "button",
@@ -3399,36 +4044,36 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3399
4044
  size: "icon",
3400
4045
  className: "h-10 w-10",
3401
4046
  onClick: onStopGeneration,
3402
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-4 w-4" })
4047
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Square, { className: "h-4 w-4" })
3403
4048
  }
3404
4049
  ) }),
3405
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
3406
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
3407
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4050
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
4051
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
4052
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3408
4053
  Button,
3409
4054
  {
3410
4055
  type: "submit",
3411
4056
  size: "icon",
3412
4057
  className: "h-10 w-10",
3413
4058
  disabled: disabled || !value.trim() && attachments.length === 0,
3414
- children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Send, { className: "h-4 w-4" })
4059
+ children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Send, { className: "h-4 w-4" })
3415
4060
  }
3416
4061
  ) }),
3417
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
4062
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
3418
4063
  ] })
3419
4064
  ]
3420
4065
  }
3421
4066
  ) }),
3422
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-[10px] text-muted-foreground text-center", children: [
4067
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "text-[10px] text-muted-foreground text-center", children: [
3423
4068
  window.innerWidth > 768 ? config?.labels?.inputHelpText : "",
3424
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4069
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3425
4070
  " \u2022 ",
3426
4071
  attachments.length,
3427
4072
  "/",
3428
4073
  maxAttachments,
3429
4074
  " anexos"
3430
4075
  ] }),
3431
- config?.labels?.footerLabel && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4076
+ config?.labels?.footerLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3432
4077
  " \u2022 ",
3433
4078
  config.labels.footerLabel
3434
4079
  ] })
@@ -3442,16 +4087,16 @@ var import_react6 = require("react");
3442
4087
  // src/components/ui/scroll-area.tsx
3443
4088
  var React11 = __toESM(require("react"), 1);
3444
4089
  var ScrollAreaPrimitive = __toESM(require("@radix-ui/react-scroll-area"), 1);
3445
- var import_jsx_runtime22 = require("react/jsx-runtime");
4090
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3446
4091
  var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
3447
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4092
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
3448
4093
  ScrollAreaPrimitive.Root,
3449
4094
  {
3450
4095
  "data-slot": "scroll-area",
3451
4096
  className: cn("relative", className),
3452
4097
  ...props,
3453
4098
  children: [
3454
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4099
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3455
4100
  ScrollAreaPrimitive.Viewport,
3456
4101
  {
3457
4102
  ref,
@@ -3465,8 +4110,8 @@ var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, o
3465
4110
  children
3466
4111
  }
3467
4112
  ),
3468
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScrollBar, {}),
3469
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScrollAreaPrimitive.Corner, {})
4113
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScrollBar, {}),
4114
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScrollAreaPrimitive.Corner, {})
3470
4115
  ]
3471
4116
  }
3472
4117
  );
@@ -3477,7 +4122,7 @@ function ScrollBar({
3477
4122
  orientation = "vertical",
3478
4123
  ...props
3479
4124
  }) {
3480
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4125
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3481
4126
  ScrollAreaPrimitive.ScrollAreaScrollbar,
3482
4127
  {
3483
4128
  "data-slot": "scroll-area-scrollbar",
@@ -3489,7 +4134,7 @@ function ScrollBar({
3489
4134
  className
3490
4135
  ),
3491
4136
  ...props,
3492
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4137
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3493
4138
  ScrollAreaPrimitive.ScrollAreaThumb,
3494
4139
  {
3495
4140
  "data-slot": "scroll-area-thumb",
@@ -3501,8 +4146,8 @@ function ScrollBar({
3501
4146
  }
3502
4147
 
3503
4148
  // src/components/chat/UserProfile.tsx
3504
- var import_lucide_react10 = require("lucide-react");
3505
- var import_jsx_runtime23 = require("react/jsx-runtime");
4149
+ var import_lucide_react11 = require("lucide-react");
4150
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3506
4151
  var getInitials2 = (name, email) => {
3507
4152
  if (name) {
3508
4153
  return name.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase();
@@ -3516,29 +4161,29 @@ var getFieldIcon = (type, key) => {
3516
4161
  const iconClass = "h-4 w-4 text-muted-foreground";
3517
4162
  switch (type) {
3518
4163
  case "email":
3519
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Mail, { className: iconClass });
4164
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Mail, { className: iconClass });
3520
4165
  case "phone":
3521
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Phone, { className: iconClass });
4166
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Phone, { className: iconClass });
3522
4167
  case "url":
3523
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Globe, { className: iconClass });
4168
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Globe, { className: iconClass });
3524
4169
  case "date":
3525
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Calendar, { className: iconClass });
4170
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Calendar, { className: iconClass });
3526
4171
  }
3527
4172
  const lowerKey = key?.toLowerCase() || "";
3528
- if (lowerKey.includes("follower")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Users, { className: iconClass });
3529
- if (lowerKey.includes("following")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.UserPlus, { className: iconClass });
3530
- if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Image, { className: iconClass });
3531
- if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.BadgeCheck, { className: iconClass });
3532
- if (lowerKey.includes("bio")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.FileText, { className: iconClass });
3533
- if (lowerKey.includes("email")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Mail, { className: iconClass });
3534
- if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Phone, { className: iconClass });
3535
- if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.MapPin, { className: iconClass });
3536
- if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Building, { className: iconClass });
3537
- if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Briefcase, { className: iconClass });
3538
- if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Globe, { className: iconClass });
3539
- if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.AtSign, { className: iconClass });
3540
- if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Calendar, { className: iconClass });
3541
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.User, { className: iconClass });
4173
+ if (lowerKey.includes("follower")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Users, { className: iconClass });
4174
+ if (lowerKey.includes("following")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.UserPlus, { className: iconClass });
4175
+ if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Image, { className: iconClass });
4176
+ if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.BadgeCheck, { className: iconClass });
4177
+ if (lowerKey.includes("bio")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.FileText, { className: iconClass });
4178
+ if (lowerKey.includes("email")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Mail, { className: iconClass });
4179
+ if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Phone, { className: iconClass });
4180
+ if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.MapPin, { className: iconClass });
4181
+ if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Building, { className: iconClass });
4182
+ if (lowerKey.includes("job") || lowerKey.includes("role") || lowerKey.includes("title") || lowerKey.includes("position")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Briefcase, { className: iconClass });
4183
+ if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Globe, { className: iconClass });
4184
+ if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.AtSign, { className: iconClass });
4185
+ if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Calendar, { className: iconClass });
4186
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.User, { className: iconClass });
3542
4187
  };
3543
4188
  var formatValue = (value, type, key) => {
3544
4189
  if (value === null || value === void 0) return "-";
@@ -3572,15 +4217,15 @@ var getMemoryCategoryIcon = (category) => {
3572
4217
  const iconClass = "h-4 w-4 text-muted-foreground";
3573
4218
  switch (category) {
3574
4219
  case "preference":
3575
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Heart, { className: iconClass });
4220
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Heart, { className: iconClass });
3576
4221
  case "fact":
3577
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Info, { className: iconClass });
4222
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Info, { className: iconClass });
3578
4223
  case "goal":
3579
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Target, { className: iconClass });
4224
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Target, { className: iconClass });
3580
4225
  case "context":
3581
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Lightbulb, { className: iconClass });
4226
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Lightbulb, { className: iconClass });
3582
4227
  default:
3583
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Brain, { className: iconClass });
4228
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Brain, { className: iconClass });
3584
4229
  }
3585
4230
  };
3586
4231
  var getMemoryCategoryLabel = (category) => {
@@ -3650,66 +4295,66 @@ var UserProfile = ({
3650
4295
  const displayName = user?.name || user?.email?.split("@")[0] || "User";
3651
4296
  const initials = getInitials2(user?.name, user?.email);
3652
4297
  const normalizedFields = normalizeCustomFields(customFields);
3653
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4298
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3654
4299
  SheetContent,
3655
4300
  {
3656
4301
  side: "right",
3657
4302
  className: cn("w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden", className),
3658
4303
  children: [
3659
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SheetHeader, { className: "px-6 py-4 border-b shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SheetTitle, { children: labels.title }) }) }),
3660
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-6 space-y-6", children: [
3661
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center text-center space-y-4", children: [
3662
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Avatar, { className: "h-24 w-24 shrink-0", children: [
3663
- user?.avatar && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AvatarImage, { src: user.avatar, alt: displayName }),
3664
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
4304
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SheetHeader, { className: "px-6 py-4 border-b shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SheetTitle, { children: labels.title }) }) }),
4305
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "p-6 space-y-6", children: [
4306
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center text-center space-y-4", children: [
4307
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Avatar, { className: "h-24 w-24 shrink-0", children: [
4308
+ user?.avatar && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AvatarImage, { src: user.avatar, alt: displayName }),
4309
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
3665
4310
  ] }),
3666
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "w-full px-2", children: [
3667
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "text-xl font-semibold break-words", children: displayName }),
3668
- user?.email && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
4311
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "w-full px-2", children: [
4312
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-xl font-semibold break-words", children: displayName }),
4313
+ user?.email && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
3669
4314
  ] })
3670
4315
  ] }),
3671
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Separator, {}),
3672
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-3", children: [
3673
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
3674
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-2", children: [
3675
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
3676
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
3677
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-w-0", children: [
3678
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: "Name" }),
3679
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium break-words", children: displayName })
4316
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Separator, {}),
4317
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-3", children: [
4318
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
4319
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-2", children: [
4320
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4321
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4322
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4323
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "Name" }),
4324
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium break-words", children: displayName })
3680
4325
  ] })
3681
4326
  ] }),
3682
- user?.email && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
3683
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
3684
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-w-0", children: [
3685
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
3686
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium break-words", children: user.email })
4327
+ user?.email && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4328
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4329
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4330
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
4331
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium break-words", children: user.email })
3687
4332
  ] })
3688
4333
  ] }),
3689
- user?.id && user.id !== user?.name && user.id !== user?.email && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
3690
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
3691
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-w-0", children: [
3692
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: "ID" }),
3693
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm font-medium break-words", children: user.id })
4334
+ user?.id && user.id !== user?.name && user.id !== user?.email && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4335
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4336
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4337
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "ID" }),
4338
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium break-words", children: user.id })
3694
4339
  ] })
3695
4340
  ] })
3696
4341
  ] })
3697
4342
  ] }),
3698
- normalizedFields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
3699
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Separator, {}),
3700
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-3", children: [
3701
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
3702
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: normalizedFields.map((field) => {
4343
+ normalizedFields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
4344
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Separator, {}),
4345
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-3", children: [
4346
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
4347
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-2", children: normalizedFields.map((field) => {
3703
4348
  const isBioField = field.key.toLowerCase().includes("bio");
3704
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4349
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3705
4350
  "div",
3706
4351
  {
3707
4352
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50",
3708
4353
  children: [
3709
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
3710
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-w-0", children: [
3711
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: field.label }),
3712
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: cn(
4354
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
4355
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4356
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: field.label }),
4357
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: cn(
3713
4358
  "text-sm font-medium",
3714
4359
  isBioField ? "whitespace-pre-wrap break-words" : "break-words"
3715
4360
  ), children: formatValue(field.value, field.type, field.key) })
@@ -3721,26 +4366,26 @@ var UserProfile = ({
3721
4366
  }) })
3722
4367
  ] })
3723
4368
  ] }),
3724
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Separator, {}),
3725
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-3", children: [
3726
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between", children: [
3727
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
3728
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Brain, { className: "h-4 w-4" }),
4369
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Separator, {}),
4370
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-3", children: [
4371
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between", children: [
4372
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
4373
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Brain, { className: "h-4 w-4" }),
3729
4374
  labels.memories
3730
4375
  ] }),
3731
- onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4376
+ onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3732
4377
  Button,
3733
4378
  {
3734
4379
  variant: "ghost",
3735
4380
  size: "sm",
3736
4381
  className: "h-7 px-2",
3737
4382
  onClick: () => setIsAddingMemory(true),
3738
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Plus, { className: "h-4 w-4" })
4383
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Plus, { className: "h-4 w-4" })
3739
4384
  }
3740
4385
  )
3741
4386
  ] }),
3742
- isAddingMemory && onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2", children: [
3743
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4387
+ isAddingMemory && onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-2", children: [
4388
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3744
4389
  Input,
3745
4390
  {
3746
4391
  value: newMemoryContent,
@@ -3757,24 +4402,24 @@ var UserProfile = ({
3757
4402
  autoFocus: true
3758
4403
  }
3759
4404
  ),
3760
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
4405
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
3761
4406
  ] }),
3762
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: memories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm text-muted-foreground text-center py-4", children: labels.noMemories }) : memories.map((memory) => {
4407
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-2", children: memories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm text-muted-foreground text-center py-4", children: labels.noMemories }) : memories.map((memory) => {
3763
4408
  const isEditing = editingMemoryId === memory.id;
3764
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4409
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3765
4410
  "div",
3766
4411
  {
3767
4412
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
3768
4413
  children: [
3769
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Bot, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
3770
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-w-0", children: [
3771
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 mb-0.5", children: [
3772
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
3773
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
3774
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
4414
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mt-0.5 shrink-0", children: memory.source === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Bot, { className: "h-4 w-4 text-primary" }) : getMemoryCategoryIcon(memory.category) }),
4415
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4416
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2 mb-0.5", children: [
4417
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
4418
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
4419
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
3775
4420
  ] }),
3776
- isEditing ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-2", children: [
3777
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4421
+ isEditing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-2", children: [
4422
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3778
4423
  Textarea,
3779
4424
  {
3780
4425
  value: editingMemoryContent,
@@ -3791,8 +4436,8 @@ var UserProfile = ({
3791
4436
  }
3792
4437
  }
3793
4438
  ),
3794
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1 justify-end", children: [
3795
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4439
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-1 justify-end", children: [
4440
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3796
4441
  Button,
3797
4442
  {
3798
4443
  variant: "ghost",
@@ -3800,12 +4445,12 @@ var UserProfile = ({
3800
4445
  className: "h-7 px-2",
3801
4446
  onClick: handleCancelEdit,
3802
4447
  children: [
3803
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.X, { className: "h-3.5 w-3.5 mr-1" }),
4448
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.X, { className: "h-3.5 w-3.5 mr-1" }),
3804
4449
  "Cancelar"
3805
4450
  ]
3806
4451
  }
3807
4452
  ),
3808
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4453
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3809
4454
  Button,
3810
4455
  {
3811
4456
  size: "sm",
@@ -3813,33 +4458,33 @@ var UserProfile = ({
3813
4458
  onClick: handleSaveEdit,
3814
4459
  disabled: !editingMemoryContent.trim(),
3815
4460
  children: [
3816
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Check, { className: "h-3.5 w-3.5 mr-1" }),
4461
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Check, { className: "h-3.5 w-3.5 mr-1" }),
3817
4462
  "Salvar"
3818
4463
  ]
3819
4464
  }
3820
4465
  )
3821
4466
  ] })
3822
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm break-words", children: memory.content })
4467
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm break-words", children: memory.content })
3823
4468
  ] }),
3824
- !isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0", children: [
3825
- onUpdateMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4469
+ !isEditing && (onUpdateMemory || onDeleteMemory) && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0", children: [
4470
+ onUpdateMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3826
4471
  Button,
3827
4472
  {
3828
4473
  variant: "ghost",
3829
4474
  size: "icon",
3830
4475
  className: "h-7 w-7",
3831
4476
  onClick: () => handleStartEdit(memory),
3832
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
4477
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
3833
4478
  }
3834
4479
  ),
3835
- onDeleteMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4480
+ onDeleteMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3836
4481
  Button,
3837
4482
  {
3838
4483
  variant: "ghost",
3839
4484
  size: "icon",
3840
4485
  className: "h-7 w-7",
3841
4486
  onClick: () => onDeleteMemory(memory.id),
3842
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Trash2, { className: "h-3.5 w-3.5 text-destructive" })
4487
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Trash2, { className: "h-3.5 w-3.5 text-destructive" })
3843
4488
  }
3844
4489
  )
3845
4490
  ] })
@@ -3850,8 +4495,8 @@ var UserProfile = ({
3850
4495
  }) })
3851
4496
  ] })
3852
4497
  ] }) }),
3853
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
3854
- onEditProfile && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4498
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
4499
+ onEditProfile && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3855
4500
  Button,
3856
4501
  {
3857
4502
  variant: "outline",
@@ -3860,7 +4505,7 @@ var UserProfile = ({
3860
4505
  children: "Edit Profile"
3861
4506
  }
3862
4507
  ),
3863
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4508
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3864
4509
  Button,
3865
4510
  {
3866
4511
  variant: "destructive",
@@ -3876,8 +4521,8 @@ var UserProfile = ({
3876
4521
  };
3877
4522
 
3878
4523
  // src/components/chat/ChatUI.tsx
3879
- var import_lucide_react11 = require("lucide-react");
3880
- var import_jsx_runtime24 = require("react/jsx-runtime");
4524
+ var import_lucide_react12 = require("lucide-react");
4525
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3881
4526
  var ChatUI = ({
3882
4527
  messages = [],
3883
4528
  threads = [],
@@ -4140,16 +4785,16 @@ var ChatUI = ({
4140
4785
  }
4141
4786
  return component;
4142
4787
  }, [config?.customComponent?.component, closeSidebar, isMobile]);
4143
- const SuggestionIconComponents = [import_lucide_react11.MessageSquare, import_lucide_react11.Lightbulb, import_lucide_react11.Zap, import_lucide_react11.HelpCircle];
4788
+ const SuggestionIconComponents = [import_lucide_react12.MessageSquare, import_lucide_react12.Lightbulb, import_lucide_react12.Zap, import_lucide_react12.HelpCircle];
4144
4789
  const renderSuggestions = () => {
4145
4790
  if (messages.length > 0 || !suggestions.length) return null;
4146
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
4147
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "text-center mb-8", children: [
4148
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("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__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Sparkles, { className: "w-7 h-7 text-primary" }) }),
4149
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
4150
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
4791
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
4792
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "text-center mb-8", children: [
4793
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("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__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Sparkles, { className: "w-7 h-7 text-primary" }) }),
4794
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
4795
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
4151
4796
  ] }),
4152
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4797
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4153
4798
  "button",
4154
4799
  {
4155
4800
  type: "button",
@@ -4158,10 +4803,10 @@ var ChatUI = ({
4158
4803
  children: [
4159
4804
  (() => {
4160
4805
  const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];
4161
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("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__ */ (0, import_jsx_runtime24.jsx)(IconComponent, { className: "h-4 w-4" }) });
4806
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("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__ */ (0, import_jsx_runtime25.jsx)(IconComponent, { className: "h-4 w-4" }) });
4162
4807
  })(),
4163
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
4164
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.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" })
4808
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 min-w-0 pr-6", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium leading-snug line-clamp-2", children: suggestion }) }),
4809
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.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" })
4165
4810
  ]
4166
4811
  },
4167
4812
  index
@@ -4172,34 +4817,34 @@ var ChatUI = ({
4172
4817
  const items = messageSuggestions?.[messageId];
4173
4818
  if (!items || items.length === 0) return null;
4174
4819
  const inlineSuggestionOffsetClass = config.ui.showAvatars ? config.ui.compactMode ? "ml-9" : "ml-11" : "";
4175
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4820
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: `flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`, children: items.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4176
4821
  "button",
4177
4822
  {
4178
4823
  type: "button",
4179
4824
  onClick: () => handleSendMessage(suggestion),
4180
4825
  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",
4181
4826
  children: [
4182
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4183
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "max-w-[200px] truncate", children: suggestion })
4827
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4828
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "max-w-[200px] truncate", children: suggestion })
4184
4829
  ]
4185
4830
  },
4186
4831
  `${messageId}-suggestion-${index}`
4187
4832
  )) });
4188
4833
  };
4189
- const renderMessageLoadingSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4834
+ const renderMessageLoadingSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4190
4835
  const isUserRow = index % 2 === 1;
4191
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4836
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4192
4837
  "div",
4193
4838
  {
4194
4839
  className: `flex gap-3 ${isUserRow ? "justify-end" : "justify-start"}`,
4195
4840
  children: [
4196
- !isUserRow && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
4197
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
4198
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Skeleton, { className: "h-4 w-24" }),
4199
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Skeleton, { className: "h-4 w-full" }),
4200
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Skeleton, { className: "h-4 w-[85%]" })
4841
+ !isUserRow && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
4842
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
4843
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-4 w-24" }),
4844
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-4 w-full" }),
4845
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-4 w-[85%]" })
4201
4846
  ] }),
4202
- isUserRow && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4847
+ isUserRow && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4203
4848
  ]
4204
4849
  },
4205
4850
  `message-skeleton-${index}`
@@ -4255,8 +4900,8 @@ var ChatUI = ({
4255
4900
  const shouldShowAgentSelector = Boolean(
4256
4901
  config.agentSelector?.enabled && onSelectAgent && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1)
4257
4902
  );
4258
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
4259
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4903
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: `flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`, children: [
4904
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4260
4905
  Sidebar2,
4261
4906
  {
4262
4907
  threads,
@@ -4273,8 +4918,8 @@ var ChatUI = ({
4273
4918
  showThemeOptions: !!callbacks.onThemeChange
4274
4919
  }
4275
4920
  ),
4276
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
4277
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4921
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
4922
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4278
4923
  ChatHeader,
4279
4924
  {
4280
4925
  config,
@@ -4289,9 +4934,9 @@ var ChatUI = ({
4289
4934
  onSelectAgent
4290
4935
  }
4291
4936
  ),
4292
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
4293
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 flex flex-col min-h-0", children: [
4294
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4937
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
4938
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 flex flex-col min-h-0", children: [
4939
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4295
4940
  ScrollArea,
4296
4941
  {
4297
4942
  ref: scrollAreaRef,
@@ -4299,7 +4944,7 @@ var ChatUI = ({
4299
4944
  viewportClassName: "p-4 overscroll-contain",
4300
4945
  onScrollCapture: handleScroll,
4301
4946
  style: { contain: "strict" },
4302
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-4xl mx-auto pb-4", children: isMessagesLoading ? renderMessageLoadingSkeleton() : messages.length === 0 ? renderSuggestions() : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4947
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-4xl mx-auto pb-4", children: isMessagesLoading ? renderMessageLoadingSkeleton() : messages.length === 0 ? renderSuggestions() : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4303
4948
  "div",
4304
4949
  {
4305
4950
  style: {
@@ -4311,7 +4956,7 @@ var ChatUI = ({
4311
4956
  const message = messages[virtualRow.index];
4312
4957
  const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;
4313
4958
  const isGrouped = prevMessage !== null && prevMessage.role === message.role;
4314
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4959
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4315
4960
  "div",
4316
4961
  {
4317
4962
  "data-index": virtualRow.index,
@@ -4323,8 +4968,8 @@ var ChatUI = ({
4323
4968
  width: "100%",
4324
4969
  transform: `translateY(${virtualRow.start}px)`
4325
4970
  },
4326
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4327
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4971
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4972
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4328
4973
  Message,
4329
4974
  {
4330
4975
  message,
@@ -4343,7 +4988,7 @@ var ChatUI = ({
4343
4988
  ) })
4344
4989
  }
4345
4990
  ),
4346
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4991
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4347
4992
  ChatInput,
4348
4993
  {
4349
4994
  value: inputValue,
@@ -4369,17 +5014,17 @@ var ChatUI = ({
4369
5014
  }
4370
5015
  ) })
4371
5016
  ] }),
4372
- config?.customComponent?.component && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5017
+ config?.customComponent?.component && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4373
5018
  "div",
4374
5019
  {
4375
5020
  className: `h-full transition-all duration-300 ease-in-out overflow-hidden ${state.showSidebar ? "w-80" : "w-0"}`,
4376
- children: state.showSidebar && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex flex-col h-full border-l bg-background animate-in slide-in-from-right-4 duration-300 w-80", children: renderCustomComponent() })
5021
+ children: state.showSidebar && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-col h-full border-l bg-background animate-in slide-in-from-right-4 duration-300 w-80", children: renderCustomComponent() })
4377
5022
  }
4378
5023
  )
4379
5024
  ] })
4380
5025
  ] }) }),
4381
- isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fixed inset-0 z-50", children: [
4382
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5026
+ isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fixed inset-0 z-50", children: [
5027
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4383
5028
  "div",
4384
5029
  {
4385
5030
  className: `absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${isCustomVisible ? "opacity-100" : "opacity-0"}`,
@@ -4387,16 +5032,16 @@ var ChatUI = ({
4387
5032
  onClick: closeSidebar
4388
5033
  }
4389
5034
  ),
4390
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5035
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4391
5036
  "div",
4392
5037
  {
4393
5038
  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"}`,
4394
5039
  style: { willChange: "transform" },
4395
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
5040
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
4396
5041
  }
4397
5042
  )
4398
5043
  ] }),
4399
- isUserProfileOpen && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5044
+ isUserProfileOpen && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4400
5045
  UserProfile,
4401
5046
  {
4402
5047
  isOpen: isUserProfileOpen,
@@ -4420,8 +5065,8 @@ var ChatUI = ({
4420
5065
 
4421
5066
  // src/components/chat/ThreadManager.tsx
4422
5067
  var import_react8 = require("react");
4423
- var import_lucide_react12 = require("lucide-react");
4424
- var import_jsx_runtime25 = require("react/jsx-runtime");
5068
+ var import_lucide_react13 = require("lucide-react");
5069
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4425
5070
  var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
4426
5071
  const [isEditing, setIsEditing] = (0, import_react8.useState)(false);
4427
5072
  const [editTitle, setEditTitle] = (0, import_react8.useState)(thread.title);
@@ -4450,9 +5095,9 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4450
5095
  handleCancelEdit();
4451
5096
  }
4452
5097
  };
4453
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(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__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "p-3 max-w-sm", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
4454
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 min-w-0", onClick: onSelect, children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2", children: [
4455
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5098
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(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__ */ (0, import_jsx_runtime26.jsx)(CardContent, { className: "p-3 max-w-sm", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
5099
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex-1 min-w-0", onClick: onSelect, children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
5100
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4456
5101
  Input,
4457
5102
  {
4458
5103
  ref: inputRef,
@@ -4464,44 +5109,44 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4464
5109
  placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
4465
5110
  }
4466
5111
  ),
4467
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Check, { className: "h-3 w-3" }) }),
4468
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3 w-3" }) })
4469
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
4470
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
4471
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
4472
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-1", children: [
4473
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Hash, { className: "h-3 w-3" }),
5112
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { size: "sm", variant: "ghost", onClick: handleSaveEdit, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Check, { className: "h-3 w-3" }) }),
5113
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { size: "sm", variant: "ghost", onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.X, { className: "h-3 w-3" }) })
5114
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5115
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
5116
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
5117
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1", children: [
5118
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Hash, { className: "h-3 w-3" }),
4474
5119
  thread.messageCount,
4475
5120
  " msgs"
4476
5121
  ] }),
4477
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
4478
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-1", children: [
4479
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Calendar, { className: "h-3 w-3" }),
5122
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
5123
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1", children: [
5124
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Calendar, { className: "h-3 w-3" }),
4480
5125
  formatDate(thread.updatedAt, config?.labels)
4481
5126
  ] }),
4482
- thread.isArchived && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
4483
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
4484
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
4485
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Archive, { className: "h-2 w-2 mr-1" }),
5127
+ thread.isArchived && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5128
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
5129
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
5130
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Archive, { className: "h-2 w-2 mr-1" }),
4486
5131
  config?.labels?.archiveThread || "Archived"
4487
5132
  ] })
4488
5133
  ] })
4489
5134
  ] })
4490
5135
  ] }) }),
4491
- !isEditing && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DropdownMenu, { children: [
4492
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 m-auto", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.MoreVertical, { className: "h-3 w-3" }) }) }),
4493
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DropdownMenuContent, { align: "end", children: [
4494
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
4495
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Edit2, { className: "h-4 w-4 mr-2" }),
5136
+ !isEditing && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenu, { children: [
5137
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 m-auto", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.MoreVertical, { className: "h-3 w-3" }) }) }),
5138
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuContent, { align: "end", children: [
5139
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
5140
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Edit2, { className: "h-4 w-4 mr-2" }),
4496
5141
  config?.labels?.renameThread || "Rename"
4497
5142
  ] }),
4498
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DropdownMenuItem, { onClick: onArchive, children: [
4499
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Archive, { className: "h-4 w-4 mr-2" }),
5143
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: onArchive, children: [
5144
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Archive, { className: "h-4 w-4 mr-2" }),
4500
5145
  thread.isArchived ? config?.labels?.unarchiveThread || "Unarchive" : config?.labels?.archiveThread || "Archive"
4501
5146
  ] }),
4502
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropdownMenuSeparator, {}),
4503
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
4504
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Trash2, { className: "h-4 w-4 mr-2" }),
5147
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DropdownMenuSeparator, {}),
5148
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
5149
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Trash2, { className: "h-4 w-4 mr-2" }),
4505
5150
  config?.labels?.deleteThread || "Delete"
4506
5151
  ] })
4507
5152
  ] })
@@ -4516,17 +5161,17 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4516
5161
  setTitle("");
4517
5162
  setIsOpen(false);
4518
5163
  };
4519
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
4520
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DialogTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Button, { variant: "outline", className: "w-full", children: [
4521
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Plus, { className: "h-4 w-4 mr-2" }),
5164
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
5165
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Button, { variant: "outline", className: "w-full", children: [
5166
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Plus, { className: "h-4 w-4 mr-2" }),
4522
5167
  config?.labels?.createNewThread || "New Conversation"
4523
5168
  ] }) }),
4524
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DialogContent, { children: [
4525
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DialogHeader, { children: [
4526
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
4527
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
5169
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogContent, { children: [
5170
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogHeader, { children: [
5171
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
5172
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
4528
5173
  ] }),
4529
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5174
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4530
5175
  Input,
4531
5176
  {
4532
5177
  value: title,
@@ -4536,9 +5181,9 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4536
5181
  autoFocus: true
4537
5182
  }
4538
5183
  ),
4539
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DialogFooter, { children: [
4540
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
4541
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
5184
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogFooter, { children: [
5185
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
5186
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
4542
5187
  ] })
4543
5188
  ] })
4544
5189
  ] });
@@ -4592,20 +5237,20 @@ var ThreadManager = ({
4592
5237
  setDeleteThreadId(null);
4593
5238
  };
4594
5239
  if (!isOpen) return null;
4595
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: `fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`, children: [
4596
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { className: "h-full border-0 rounded-none", children: [
4597
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "border-b", children: [
4598
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
4599
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardTitle, { className: "flex items-center gap-2", children: [
4600
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.MessageSquare, { className: "h-5 w-5" }),
5240
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`, children: [
5241
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Card, { className: "h-full border-0 rounded-none", children: [
5242
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardHeader, { className: "border-b", children: [
5243
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
5244
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardTitle, { className: "flex items-center gap-2", children: [
5245
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.MessageSquare, { className: "h-5 w-5" }),
4601
5246
  config?.labels?.newChat || "Conversations"
4602
5247
  ] }),
4603
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-4 w-4" }) })
5248
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.X, { className: "h-4 w-4" }) })
4604
5249
  ] }),
4605
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-3", children: [
4606
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", children: [
4607
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
4608
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5250
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-3", children: [
5251
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "relative", children: [
5252
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
5253
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4609
5254
  Input,
4610
5255
  {
4611
5256
  placeholder: config?.labels?.search || "Search conversations...",
@@ -4615,8 +5260,8 @@ var ThreadManager = ({
4615
5260
  }
4616
5261
  )
4617
5262
  ] }),
4618
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
4619
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5263
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
5264
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4620
5265
  Button,
4621
5266
  {
4622
5267
  variant: "outline",
@@ -4624,12 +5269,12 @@ var ThreadManager = ({
4624
5269
  onClick: () => setShowArchived(!showArchived),
4625
5270
  className: "text-xs",
4626
5271
  children: [
4627
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Filter, { className: "h-3 w-3 mr-1" }),
5272
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Filter, { className: "h-3 w-3 mr-1" }),
4628
5273
  showArchived ? config?.labels?.hideArchived || "Hide Archived" : config?.labels?.showArchived || "Show Archived"
4629
5274
  ]
4630
5275
  }
4631
5276
  ),
4632
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
5277
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
4633
5278
  filteredThreads.length,
4634
5279
  " / ",
4635
5280
  threads.length
@@ -4637,14 +5282,14 @@ var ThreadManager = ({
4637
5282
  ] })
4638
5283
  ] })
4639
5284
  ] }),
4640
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardContent, { className: "p-0 flex-1", children: [
4641
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CreateThreadDialog2, { onCreateThread, config }) }),
4642
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-4 pb-4 space-y-4", children: Object.keys(groupedThreads).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "text-center py-8 text-muted-foreground", children: [
4643
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.MessageSquare, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
4644
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
4645
- ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
4646
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
4647
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5285
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardContent, { className: "p-0 flex-1", children: [
5286
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CreateThreadDialog2, { onCreateThread, config }) }),
5287
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ScrollArea, { className: "h-[calc(100vh-280px)]", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "px-4 pb-4 space-y-4", children: Object.keys(groupedThreads).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "text-center py-8 text-muted-foreground", children: [
5288
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.MessageSquare, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
5289
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
5290
+ ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
5291
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
5292
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4648
5293
  ThreadItem,
4649
5294
  {
4650
5295
  thread,
@@ -4660,14 +5305,14 @@ var ThreadManager = ({
4660
5305
  ] }, group)) }) })
4661
5306
  ] })
4662
5307
  ] }) }),
4663
- deleteThreadId && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(AlertDialogContent, { children: [
4664
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(AlertDialogHeader, { children: [
4665
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
4666
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
5308
+ deleteThreadId && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AlertDialogContent, { children: [
5309
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AlertDialogHeader, { children: [
5310
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
5311
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialogDescription, { children: config?.labels?.deleteConfirmDescription || "Are you sure you want to delete this conversation? This action cannot be undone." })
4667
5312
  ] }),
4668
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(AlertDialogFooter, { children: [
4669
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
4670
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5313
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AlertDialogFooter, { children: [
5314
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
5315
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4671
5316
  AlertDialogAction,
4672
5317
  {
4673
5318
  onClick: () => deleteThreadId && handleDeleteThread(deleteThreadId),