@copilotz/chat-ui 0.1.30 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -86,6 +86,23 @@ 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 input",
92
+ voicePreparing: "Preparing microphone...",
93
+ voiceWaiting: "Waiting for speech...",
94
+ voiceListening: "Listening...",
95
+ voiceFinishing: "Finishing capture...",
96
+ voiceReview: "Ready to send",
97
+ voiceStart: "Start recording",
98
+ voiceStop: "Stop recording",
99
+ voiceSendNow: "Send now",
100
+ voiceCancel: "Cancel",
101
+ voiceRecordAgain: "Record again",
102
+ voiceAutoSendIn: "Auto-sends in {{seconds}}s",
103
+ voiceTranscriptPending: "Transcript unavailable",
104
+ voicePermissionDenied: "Microphone access was denied.",
105
+ voiceCaptureError: "Unable to capture audio.",
89
106
  // Header labels
90
107
  exportData: "Export data",
91
108
  importData: "Import data",
@@ -148,6 +165,15 @@ var defaultChatConfig = {
148
165
  longMessageChunkChars: 12e3,
149
166
  renderUserMarkdown: true
150
167
  },
168
+ voiceCompose: {
169
+ enabled: false,
170
+ autoSendDelayMs: 5e3,
171
+ persistComposer: true,
172
+ showTranscriptPreview: true,
173
+ transcriptMode: "final-only",
174
+ maxRecordingMs: 6e4,
175
+ createProvider: void 0
176
+ },
151
177
  customComponent: {},
152
178
  headerActions: null
153
179
  };
@@ -170,6 +196,10 @@ function mergeConfig(_baseConfig, userConfig) {
170
196
  ...defaultChatConfig.ui,
171
197
  ...userConfig.ui
172
198
  },
199
+ voiceCompose: {
200
+ ...defaultChatConfig.voiceCompose,
201
+ ...userConfig.voiceCompose
202
+ },
173
203
  agentSelector: {
174
204
  ...defaultChatConfig.agentSelector,
175
205
  ...userConfig.agentSelector
@@ -777,7 +807,7 @@ var MediaRenderer = (0, import_react.memo)(function MediaRenderer2({ attachment
777
807
  URL.revokeObjectURL(objectUrl);
778
808
  };
779
809
  }, [attachment.kind, attachment.dataUrl]);
780
- const formatDuration = (ms) => {
810
+ const formatDuration2 = (ms) => {
781
811
  if (!ms) return "";
782
812
  const seconds = Math.floor(ms / 1e3);
783
813
  const minutes = Math.floor(seconds / 60);
@@ -2810,6 +2840,215 @@ function useChatUserContext() {
2810
2840
  return v;
2811
2841
  }
2812
2842
 
2843
+ // src/lib/voiceCompose.ts
2844
+ var AUDIO_MIME_TYPES = [
2845
+ "audio/webm;codecs=opus",
2846
+ "audio/webm",
2847
+ "audio/mp4",
2848
+ "audio/ogg;codecs=opus"
2849
+ ];
2850
+ var pickRecorderMimeType = () => {
2851
+ if (typeof MediaRecorder === "undefined") return void 0;
2852
+ for (const mimeType of AUDIO_MIME_TYPES) {
2853
+ if (typeof MediaRecorder.isTypeSupported === "function" && MediaRecorder.isTypeSupported(mimeType)) {
2854
+ return mimeType;
2855
+ }
2856
+ }
2857
+ return void 0;
2858
+ };
2859
+ var blobToDataUrl = (blob) => new Promise((resolve, reject) => {
2860
+ const reader = new FileReader();
2861
+ reader.onload = () => resolve(reader.result);
2862
+ reader.onerror = () => reject(reader.error ?? new Error("Failed to read recorded audio"));
2863
+ reader.readAsDataURL(blob);
2864
+ });
2865
+ var stopStream = (stream) => {
2866
+ if (!stream) return;
2867
+ stream.getTracks().forEach((track) => track.stop());
2868
+ };
2869
+ var closeAudioContext = async (audioContext) => {
2870
+ if (!audioContext) return;
2871
+ try {
2872
+ await audioContext.close();
2873
+ } catch {
2874
+ }
2875
+ };
2876
+ var emitDuration = (handlers, startedAt) => {
2877
+ handlers.onDurationChange?.(Math.max(0, Date.now() - startedAt));
2878
+ };
2879
+ var createManualVoiceProvider = async (handlers, options = {}) => {
2880
+ let mediaRecorder = null;
2881
+ let mediaStream = null;
2882
+ let audioContext = null;
2883
+ let analyser = null;
2884
+ let levelData = null;
2885
+ let levelFrame = 0;
2886
+ let durationTimer = null;
2887
+ let maxDurationTimer = null;
2888
+ let startedAt = 0;
2889
+ let shouldEmitSegment = true;
2890
+ let isStarting = false;
2891
+ const clearTimers = () => {
2892
+ if (durationTimer) {
2893
+ clearInterval(durationTimer);
2894
+ durationTimer = null;
2895
+ }
2896
+ if (maxDurationTimer) {
2897
+ clearTimeout(maxDurationTimer);
2898
+ maxDurationTimer = null;
2899
+ }
2900
+ };
2901
+ const stopLevelLoop = () => {
2902
+ if (levelFrame) {
2903
+ cancelAnimationFrame(levelFrame);
2904
+ levelFrame = 0;
2905
+ }
2906
+ handlers.onAudioLevelChange?.(0);
2907
+ };
2908
+ const startLevelLoop = () => {
2909
+ if (!analyser || !levelData) return;
2910
+ const tick = () => {
2911
+ if (!analyser || !levelData) return;
2912
+ analyser.getByteTimeDomainData(levelData);
2913
+ let sum = 0;
2914
+ for (let index = 0; index < levelData.length; index += 1) {
2915
+ const centered = (levelData[index] - 128) / 128;
2916
+ sum += centered * centered;
2917
+ }
2918
+ const rms = Math.sqrt(sum / levelData.length);
2919
+ handlers.onAudioLevelChange?.(Math.min(1, rms * 4));
2920
+ levelFrame = requestAnimationFrame(tick);
2921
+ };
2922
+ tick();
2923
+ };
2924
+ const cleanupActiveResources = async () => {
2925
+ clearTimers();
2926
+ stopLevelLoop();
2927
+ stopStream(mediaStream);
2928
+ mediaStream = null;
2929
+ analyser = null;
2930
+ levelData = null;
2931
+ await closeAudioContext(audioContext);
2932
+ audioContext = null;
2933
+ };
2934
+ const finalizeStop = async () => {
2935
+ mediaRecorder = null;
2936
+ isStarting = false;
2937
+ await cleanupActiveResources();
2938
+ };
2939
+ const start = async () => {
2940
+ if (isStarting || mediaRecorder?.state === "recording") {
2941
+ return;
2942
+ }
2943
+ if (!navigator.mediaDevices?.getUserMedia) {
2944
+ throw new Error("Audio capture is not supported in this browser");
2945
+ }
2946
+ if (typeof MediaRecorder === "undefined") {
2947
+ throw new Error("MediaRecorder is not supported in this browser");
2948
+ }
2949
+ isStarting = true;
2950
+ shouldEmitSegment = true;
2951
+ handlers.onTranscriptChange?.({});
2952
+ handlers.onDurationChange?.(0);
2953
+ handlers.onAudioLevelChange?.(0);
2954
+ handlers.onStateChange?.("preparing");
2955
+ try {
2956
+ mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
2957
+ const mimeType = pickRecorderMimeType();
2958
+ mediaRecorder = mimeType ? new MediaRecorder(mediaStream, { mimeType }) : new MediaRecorder(mediaStream);
2959
+ const chunks = [];
2960
+ mediaRecorder.ondataavailable = (event) => {
2961
+ if (event.data.size > 0) {
2962
+ chunks.push(event.data);
2963
+ }
2964
+ };
2965
+ mediaRecorder.onerror = (event) => {
2966
+ const error = event.error ?? new Error("Audio recorder failed");
2967
+ handlers.onError?.(error);
2968
+ };
2969
+ mediaRecorder.onstop = async () => {
2970
+ const durationMs = startedAt > 0 ? Math.max(0, Date.now() - startedAt) : 0;
2971
+ try {
2972
+ if (shouldEmitSegment && chunks.length > 0) {
2973
+ const blob = new Blob(chunks, {
2974
+ type: mediaRecorder?.mimeType || mimeType || "audio/webm"
2975
+ });
2976
+ const dataUrl = await blobToDataUrl(blob);
2977
+ handlers.onSegmentReady?.({
2978
+ attachment: {
2979
+ kind: "audio",
2980
+ dataUrl,
2981
+ mimeType: blob.type || "audio/webm",
2982
+ durationMs,
2983
+ fileName: `voice-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.webm`,
2984
+ size: blob.size
2985
+ },
2986
+ metadata: { source: "manual" }
2987
+ });
2988
+ } else {
2989
+ handlers.onStateChange?.("idle");
2990
+ }
2991
+ } catch (error) {
2992
+ handlers.onError?.(error);
2993
+ } finally {
2994
+ await finalizeStop();
2995
+ }
2996
+ };
2997
+ const AudioContextCtor = globalThis.AudioContext || globalThis.webkitAudioContext;
2998
+ if (AudioContextCtor) {
2999
+ audioContext = new AudioContextCtor();
3000
+ await audioContext.resume().catch(() => void 0);
3001
+ const sourceNode = audioContext.createMediaStreamSource(mediaStream);
3002
+ analyser = audioContext.createAnalyser();
3003
+ analyser.fftSize = 1024;
3004
+ levelData = new Uint8Array(analyser.fftSize);
3005
+ sourceNode.connect(analyser);
3006
+ startLevelLoop();
3007
+ }
3008
+ startedAt = Date.now();
3009
+ emitDuration(handlers, startedAt);
3010
+ durationTimer = setInterval(() => emitDuration(handlers, startedAt), 200);
3011
+ if (options.maxRecordingMs && options.maxRecordingMs > 0) {
3012
+ maxDurationTimer = setTimeout(() => {
3013
+ void stop();
3014
+ }, options.maxRecordingMs);
3015
+ }
3016
+ mediaRecorder.start();
3017
+ handlers.onStateChange?.("listening");
3018
+ } catch (error) {
3019
+ isStarting = false;
3020
+ await cleanupActiveResources();
3021
+ throw error;
3022
+ }
3023
+ };
3024
+ const stop = async () => {
3025
+ if (!mediaRecorder || mediaRecorder.state === "inactive") {
3026
+ return;
3027
+ }
3028
+ handlers.onStateChange?.("finishing");
3029
+ mediaRecorder.stop();
3030
+ };
3031
+ const cancel = async () => {
3032
+ shouldEmitSegment = false;
3033
+ if (mediaRecorder && mediaRecorder.state !== "inactive") {
3034
+ mediaRecorder.stop();
3035
+ return;
3036
+ }
3037
+ await finalizeStop();
3038
+ handlers.onStateChange?.("idle");
3039
+ };
3040
+ const destroy = async () => {
3041
+ await cancel();
3042
+ };
3043
+ return {
3044
+ start,
3045
+ stop,
3046
+ cancel,
3047
+ destroy
3048
+ };
3049
+ };
3050
+ var resolveVoiceProviderFactory = (createProvider) => createProvider ?? createManualVoiceProvider;
3051
+
2813
3052
  // src/components/ui/progress.tsx
2814
3053
  var ProgressPrimitive = __toESM(require("@radix-ui/react-progress"), 1);
2815
3054
  var import_jsx_runtime20 = require("react/jsx-runtime");
@@ -2839,9 +3078,162 @@ function Progress({
2839
3078
  );
2840
3079
  }
2841
3080
 
2842
- // src/components/chat/ChatInput.tsx
3081
+ // src/components/chat/VoiceComposer.tsx
2843
3082
  var import_lucide_react9 = require("lucide-react");
2844
3083
  var import_jsx_runtime21 = require("react/jsx-runtime");
3084
+ var formatDuration = (durationMs) => {
3085
+ const totalSeconds = Math.max(0, Math.floor(durationMs / 1e3));
3086
+ const minutes = Math.floor(totalSeconds / 60);
3087
+ const seconds = totalSeconds % 60;
3088
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
3089
+ };
3090
+ var interpolateSeconds = (label, seconds) => {
3091
+ if (!label) {
3092
+ return `Auto-sends in ${seconds}s`;
3093
+ }
3094
+ if (label.includes("{{seconds}}")) {
3095
+ return label.replace(/\{\{\s*seconds\s*\}\}/g, String(seconds));
3096
+ }
3097
+ return `${label} ${seconds}s`;
3098
+ };
3099
+ var resolveStateLabel = (state, labels, errorMessage) => {
3100
+ switch (state) {
3101
+ case "preparing":
3102
+ return labels?.voicePreparing || "Preparing microphone...";
3103
+ case "waiting_for_speech":
3104
+ return labels?.voiceWaiting || "Waiting for speech...";
3105
+ case "listening":
3106
+ return labels?.voiceListening || "Listening...";
3107
+ case "finishing":
3108
+ return labels?.voiceFinishing || "Finishing capture...";
3109
+ case "review":
3110
+ return labels?.voiceReview || "Ready to send";
3111
+ case "sending":
3112
+ return "Sending...";
3113
+ case "error":
3114
+ return errorMessage || labels?.voiceCaptureError || "Unable to capture audio.";
3115
+ case "idle":
3116
+ default:
3117
+ return labels?.voiceTitle || "Voice input";
3118
+ }
3119
+ };
3120
+ var resolveTranscriptText = (transcript, transcriptMode) => {
3121
+ if (transcriptMode === "none" || !transcript) {
3122
+ return null;
3123
+ }
3124
+ if (transcriptMode === "final-only") {
3125
+ return transcript.final?.trim() || null;
3126
+ }
3127
+ return transcript.final?.trim() || transcript.partial?.trim() || null;
3128
+ };
3129
+ var VoiceComposer = ({
3130
+ state,
3131
+ transcript,
3132
+ transcriptMode,
3133
+ showTranscriptPreview,
3134
+ durationMs,
3135
+ audioLevel,
3136
+ countdownMs,
3137
+ autoSendDelayMs,
3138
+ errorMessage,
3139
+ disabled = false,
3140
+ labels,
3141
+ onStart,
3142
+ onStop,
3143
+ onCancel,
3144
+ onSendNow,
3145
+ onRecordAgain,
3146
+ onExit
3147
+ }) => {
3148
+ const transcriptText = resolveTranscriptText(transcript, transcriptMode);
3149
+ const countdownSeconds = Math.max(1, Math.ceil(countdownMs / 1e3));
3150
+ const countdownValue = autoSendDelayMs > 0 ? Math.min(100, Math.max(0, (autoSendDelayMs - countdownMs) / autoSendDelayMs * 100)) : 100;
3151
+ const isBusy = state === "preparing" || state === "finishing" || state === "sending";
3152
+ const isCapturing = state === "waiting_for_speech" || state === "listening";
3153
+ const levelValue = isCapturing || state === "preparing" || state === "finishing" ? Math.max(8, Math.round(audioLevel * 100)) : 0;
3154
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "w-full md:min-w-3xl max-w-3xl rounded-xl border bg-background p-4 shadow-sm", children: [
3155
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
3156
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
3157
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: labels?.voiceTitle || "Voice input" }),
3158
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm text-muted-foreground", children: resolveStateLabel(state, labels, errorMessage) })
3159
+ ] }),
3160
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3161
+ Button,
3162
+ {
3163
+ type: "button",
3164
+ variant: "ghost",
3165
+ size: "sm",
3166
+ onClick: onExit,
3167
+ disabled: disabled || isBusy,
3168
+ children: [
3169
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Keyboard, { className: "h-4 w-4" }),
3170
+ labels?.voiceExit || "Use keyboard"
3171
+ ]
3172
+ }
3173
+ )
3174
+ ] }),
3175
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-4 flex flex-col items-center gap-4 rounded-xl border border-dashed border-primary/30 bg-primary/5 px-4 py-6 text-center", children: [
3176
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex h-20 w-20 items-center justify-center rounded-full bg-primary/10", children: isBusy ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Loader2, { className: "h-8 w-8 animate-spin text-primary" }) : isCapturing ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-8 w-8 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-8 w-8 text-primary" }) }),
3177
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "w-full max-w-md space-y-2", children: [
3178
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Progress, { value: levelValue, className: "h-2" }),
3179
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
3180
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: formatDuration(durationMs) }),
3181
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: resolveStateLabel(state, labels, errorMessage) })
3182
+ ] })
3183
+ ] }),
3184
+ showTranscriptPreview && transcriptMode !== "none" && transcriptText && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-full max-w-md rounded-lg border bg-background px-3 py-2 text-left text-sm", children: transcriptText })
3185
+ ] }),
3186
+ state === "review" && autoSendDelayMs > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-4 space-y-2", children: [
3187
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Progress, { value: countdownValue, className: "h-2" }),
3188
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-center text-xs text-muted-foreground", children: interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds) })
3189
+ ] }),
3190
+ state === "error" && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-4 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: errorMessage }),
3191
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mt-4 flex flex-wrap items-center justify-center gap-2", children: [
3192
+ state === "idle" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", onClick: onStart, disabled, children: [
3193
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-4 w-4" }),
3194
+ labels?.voiceStart || "Start recording"
3195
+ ] }),
3196
+ isCapturing && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3197
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", onClick: onStop, disabled, children: [
3198
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-4 w-4" }),
3199
+ labels?.voiceStop || "Stop recording"
3200
+ ] }),
3201
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", variant: "outline", onClick: onCancel, disabled, children: [
3202
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-4 w-4" }),
3203
+ labels?.voiceCancel || "Cancel"
3204
+ ] })
3205
+ ] }),
3206
+ state === "review" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3207
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", variant: "outline", onClick: onCancel, disabled, children: [
3208
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-4 w-4" }),
3209
+ labels?.voiceCancel || "Cancel"
3210
+ ] }),
3211
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", variant: "outline", onClick: onRecordAgain, disabled, children: [
3212
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.RotateCcw, { className: "h-4 w-4" }),
3213
+ labels?.voiceRecordAgain || "Record again"
3214
+ ] }),
3215
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", onClick: onSendNow, disabled, children: [
3216
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Send, { className: "h-4 w-4" }),
3217
+ labels?.voiceSendNow || "Send now"
3218
+ ] })
3219
+ ] }),
3220
+ state === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3221
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", variant: "outline", onClick: onCancel, disabled, children: [
3222
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-4 w-4" }),
3223
+ labels?.voiceCancel || "Cancel"
3224
+ ] }),
3225
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Button, { type: "button", onClick: onRecordAgain, disabled, children: [
3226
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.RotateCcw, { className: "h-4 w-4" }),
3227
+ labels?.voiceRecordAgain || "Record again"
3228
+ ] })
3229
+ ] })
3230
+ ] })
3231
+ ] });
3232
+ };
3233
+
3234
+ // src/components/chat/ChatInput.tsx
3235
+ var import_lucide_react10 = require("lucide-react");
3236
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2845
3237
  var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, progress, onCancel }) {
2846
3238
  const guessTypeFromName = (name) => {
2847
3239
  const ext = (name || "").split(".").pop()?.toLowerCase();
@@ -2870,10 +3262,10 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
2870
3262
  };
2871
3263
  const getFileIcon = (type, name) => {
2872
3264
  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" });
3265
+ if (t.startsWith("image/")) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Image, { className: "h-4 w-4" });
3266
+ if (t.startsWith("video/")) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Video, { className: "h-4 w-4" });
3267
+ if (t.startsWith("audio/")) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-4 w-4" });
3268
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.FileText, { className: "h-4 w-4" });
2877
3269
  };
2878
3270
  const formatFileSize = (bytes) => {
2879
3271
  if (bytes === 0) return "0 Bytes";
@@ -2882,21 +3274,21 @@ var FileUploadItem = (0, import_react5.memo)(function FileUploadItem2({ file, pr
2882
3274
  const i = Math.floor(Math.log(bytes) / Math.log(k));
2883
3275
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
2884
3276
  };
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: [
3277
+ 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
3278
  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" })
3279
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex-1 min-w-0", children: [
3280
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-sm font-medium truncate", children: file.name }),
3281
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-xs text-muted-foreground", children: formatFileSize(file.size ?? 0) }),
3282
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Progress, { value: progress, className: "h-1 mt-1" })
2891
3283
  ] }),
2892
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3284
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2893
3285
  Button,
2894
3286
  {
2895
3287
  variant: "ghost",
2896
3288
  size: "icon",
2897
3289
  className: "h-6 w-6",
2898
3290
  onClick: onCancel,
2899
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3291
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
2900
3292
  }
2901
3293
  )
2902
3294
  ] }) }) });
@@ -2930,15 +3322,15 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
2930
3322
  setIsPlaying(!isPlaying);
2931
3323
  }
2932
3324
  };
2933
- const formatDuration = (ms) => {
3325
+ const formatDuration2 = (ms) => {
2934
3326
  if (!ms) return "";
2935
3327
  const seconds = Math.floor(ms / 1e3);
2936
3328
  const minutes = Math.floor(seconds / 60);
2937
3329
  return `${minutes}:${(seconds % 60).toString().padStart(2, "0")}`;
2938
3330
  };
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)(
3331
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Card, { className: "relative group", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardContent, { className: "p-2", children: [
3332
+ attachment.kind === "image" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "relative", children: [
3333
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2942
3334
  "img",
2943
3335
  {
2944
3336
  src: attachment.dataUrl,
@@ -2946,19 +3338,19 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
2946
3338
  className: "w-full h-20 object-cover rounded"
2947
3339
  }
2948
3340
  ),
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)(
3341
+ /* @__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
3342
  Button,
2951
3343
  {
2952
3344
  variant: "destructive",
2953
3345
  size: "icon",
2954
3346
  className: "h-6 w-6",
2955
3347
  onClick: onRemove,
2956
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3348
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
2957
3349
  }
2958
3350
  ) })
2959
3351
  ] }),
2960
- attachment.kind === "video" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "relative", children: [
2961
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3352
+ attachment.kind === "video" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "relative", children: [
3353
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2962
3354
  "video",
2963
3355
  {
2964
3356
  src: attachment.dataUrl,
@@ -2967,34 +3359,34 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
2967
3359
  muted: true
2968
3360
  }
2969
3361
  ),
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)(
3362
+ /* @__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
3363
  Button,
2972
3364
  {
2973
3365
  variant: "destructive",
2974
3366
  size: "icon",
2975
3367
  className: "h-6 w-6",
2976
3368
  onClick: onRemove,
2977
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3369
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
2978
3370
  }
2979
3371
  ) }),
2980
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration(attachment.durationMs) })
3372
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { className: "absolute bottom-1 right-1 text-xs", children: formatDuration2(attachment.durationMs) })
2981
3373
  ] }),
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)(
3374
+ attachment.kind === "audio" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 p-2", children: [
3375
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2984
3376
  Button,
2985
3377
  {
2986
3378
  variant: "outline",
2987
3379
  size: "icon",
2988
3380
  className: "h-8 w-8",
2989
3381
  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" })
3382
+ 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
3383
  }
2992
3384
  ),
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) })
3385
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex-1", children: [
3386
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-xs font-medium", children: attachment.fileName || "\xC1udio" }),
3387
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-xs text-muted-foreground", children: formatDuration2(attachment.durationMs) })
2996
3388
  ] }),
2997
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3389
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2998
3390
  "audio",
2999
3391
  {
3000
3392
  ref: audioRef,
@@ -3002,21 +3394,21 @@ var AttachmentPreview = (0, import_react5.memo)(function AttachmentPreview2({ at
3002
3394
  onPause: () => setIsPlaying(false),
3003
3395
  onEnded: () => setIsPlaying(false),
3004
3396
  preload: "metadata",
3005
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3397
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("source", { src: audioPlaybackSrc, type: attachment.mimeType })
3006
3398
  }
3007
3399
  ),
3008
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3400
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3009
3401
  Button,
3010
3402
  {
3011
3403
  variant: "ghost",
3012
3404
  size: "icon",
3013
3405
  className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
3014
3406
  onClick: onRemove,
3015
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
3407
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3" })
3016
3408
  }
3017
3409
  )
3018
3410
  ] }),
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 }) })
3411
+ 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
3412
  ] }) });
3021
3413
  });
3022
3414
  var AudioRecorder = (0, import_react5.memo)(function AudioRecorder2({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {
@@ -3026,47 +3418,47 @@ var AudioRecorder = (0, import_react5.memo)(function AudioRecorder2({ isRecordin
3026
3418
  return `${mins}:${secs.toString().padStart(2, "0")}`;
3027
3419
  };
3028
3420
  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)(
3421
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
3422
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3031
3423
  Button,
3032
3424
  {
3033
3425
  variant: "outline",
3034
3426
  size: "icon",
3035
3427
  onClick: onStartRecording,
3036
3428
  className: "h-10 w-10",
3037
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Mic, { className: "h-4 w-4" })
3429
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-4 w-4" })
3038
3430
  }
3039
3431
  ) }),
3040
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3432
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.recordAudioTooltip })
3041
3433
  ] });
3042
3434
  }
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" })
3435
+ 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: [
3436
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
3437
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "h-3 w-3 bg-red-500 rounded-full animate-pulse" }),
3438
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-sm font-medium text-red-700 dark:text-red-300", children: "Gravando" })
3047
3439
  ] }),
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)(
3440
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "outline", className: "text-xs", children: formatTime(recordingDuration) }),
3441
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex gap-1 ml-auto", children: [
3442
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3051
3443
  Button,
3052
3444
  {
3053
3445
  variant: "outline",
3054
3446
  size: "sm",
3055
3447
  onClick: onCancel,
3056
3448
  children: [
3057
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.X, { className: "h-3 w-3 mr-1" }),
3449
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.X, { className: "h-3 w-3 mr-1" }),
3058
3450
  "Cancelar"
3059
3451
  ]
3060
3452
  }
3061
3453
  ),
3062
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3454
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3063
3455
  Button,
3064
3456
  {
3065
3457
  variant: "default",
3066
3458
  size: "sm",
3067
3459
  onClick: onStopRecording,
3068
3460
  children: [
3069
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-3 w-3 mr-1" }),
3461
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Square, { className: "h-3 w-3 mr-1" }),
3070
3462
  "Parar"
3071
3463
  ]
3072
3464
  }
@@ -3074,6 +3466,16 @@ var AudioRecorder = (0, import_react5.memo)(function AudioRecorder2({ isRecordin
3074
3466
  ] })
3075
3467
  ] }) }) });
3076
3468
  });
3469
+ var resolveVoiceErrorMessage = (error, config) => {
3470
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
3471
+ return config?.labels?.voicePermissionDenied || "Microphone access was denied.";
3472
+ }
3473
+ if (error instanceof Error && error.message.trim().length > 0) {
3474
+ return error.message;
3475
+ }
3476
+ return config?.labels?.voiceCaptureError || "Unable to capture audio.";
3477
+ };
3478
+ var clearVoiceTranscript = () => ({});
3077
3479
  var ChatInput = (0, import_react5.memo)(function ChatInput2({
3078
3480
  value,
3079
3481
  onChange,
@@ -3097,12 +3499,27 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3097
3499
  const { setContext } = useChatUserContext();
3098
3500
  const [recordingDuration, setRecordingDuration] = (0, import_react5.useState)(0);
3099
3501
  const [uploadProgress, setUploadProgress] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
3502
+ const [isVoiceComposerOpen, setIsVoiceComposerOpen] = (0, import_react5.useState)(false);
3503
+ const [voiceState, setVoiceState] = (0, import_react5.useState)("idle");
3504
+ const [voiceDraft, setVoiceDraft] = (0, import_react5.useState)(null);
3505
+ const [voiceTranscript, setVoiceTranscript] = (0, import_react5.useState)(clearVoiceTranscript);
3506
+ const [voiceDurationMs, setVoiceDurationMs] = (0, import_react5.useState)(0);
3507
+ const [voiceAudioLevel, setVoiceAudioLevel] = (0, import_react5.useState)(0);
3508
+ const [voiceCountdownMs, setVoiceCountdownMs] = (0, import_react5.useState)(0);
3509
+ const [voiceError, setVoiceError] = (0, import_react5.useState)(null);
3100
3510
  const textareaRef = (0, import_react5.useRef)(null);
3101
3511
  const fileInputRef = (0, import_react5.useRef)(null);
3102
3512
  const mediaRecorderRef = (0, import_react5.useRef)(null);
3103
3513
  const recordingStartTime = (0, import_react5.useRef)(0);
3104
3514
  const recordingInterval = (0, import_react5.useRef)(null);
3105
3515
  const mediaStreamRef = (0, import_react5.useRef)(null);
3516
+ const voiceProviderRef = (0, import_react5.useRef)(null);
3517
+ const voiceComposeEnabled = config?.voiceCompose?.enabled === true;
3518
+ const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5e3;
3519
+ const voicePersistComposer = config?.voiceCompose?.persistComposer ?? true;
3520
+ const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;
3521
+ const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? "final-only";
3522
+ const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;
3106
3523
  (0, import_react5.useEffect)(() => {
3107
3524
  return () => {
3108
3525
  if (mediaStreamRef.current) {
@@ -3111,6 +3528,10 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3111
3528
  if (recordingInterval.current) {
3112
3529
  clearInterval(recordingInterval.current);
3113
3530
  }
3531
+ if (voiceProviderRef.current) {
3532
+ void voiceProviderRef.current.destroy();
3533
+ voiceProviderRef.current = null;
3534
+ }
3114
3535
  };
3115
3536
  }, []);
3116
3537
  const handleSubmit = (e) => {
@@ -3287,13 +3708,149 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3287
3708
  }
3288
3709
  }
3289
3710
  };
3711
+ const resetVoiceComposerState = (0, import_react5.useCallback)((nextState = "idle") => {
3712
+ setVoiceState(nextState);
3713
+ setVoiceDraft(null);
3714
+ setVoiceTranscript(clearVoiceTranscript());
3715
+ setVoiceDurationMs(0);
3716
+ setVoiceAudioLevel(0);
3717
+ setVoiceCountdownMs(0);
3718
+ setVoiceError(null);
3719
+ }, []);
3720
+ const ensureVoiceProvider = (0, import_react5.useCallback)(async () => {
3721
+ if (voiceProviderRef.current) {
3722
+ return voiceProviderRef.current;
3723
+ }
3724
+ const createProvider = resolveVoiceProviderFactory(config?.voiceCompose?.createProvider);
3725
+ const provider = await createProvider({
3726
+ onStateChange: setVoiceState,
3727
+ onAudioLevelChange: setVoiceAudioLevel,
3728
+ onDurationChange: setVoiceDurationMs,
3729
+ onTranscriptChange: setVoiceTranscript,
3730
+ onSegmentReady: (segment) => {
3731
+ setVoiceDraft(segment);
3732
+ setVoiceTranscript(segment.transcript ?? clearVoiceTranscript());
3733
+ setVoiceDurationMs(segment.attachment.durationMs ?? 0);
3734
+ setVoiceAudioLevel(0);
3735
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3736
+ setVoiceError(null);
3737
+ setVoiceState("review");
3738
+ },
3739
+ onError: (error) => {
3740
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3741
+ setVoiceAudioLevel(0);
3742
+ setVoiceCountdownMs(0);
3743
+ setVoiceState("error");
3744
+ }
3745
+ }, {
3746
+ maxRecordingMs: voiceMaxRecordingMs
3747
+ });
3748
+ voiceProviderRef.current = provider;
3749
+ return provider;
3750
+ }, [config, voiceAutoSendDelayMs, voiceMaxRecordingMs]);
3751
+ const closeVoiceComposer = (0, import_react5.useCallback)(async () => {
3752
+ setIsVoiceComposerOpen(false);
3753
+ setVoiceError(null);
3754
+ setVoiceCountdownMs(0);
3755
+ setVoiceAudioLevel(0);
3756
+ setVoiceTranscript(clearVoiceTranscript());
3757
+ setVoiceDraft(null);
3758
+ setVoiceDurationMs(0);
3759
+ setVoiceState("idle");
3760
+ if (voiceProviderRef.current) {
3761
+ await voiceProviderRef.current.cancel();
3762
+ }
3763
+ }, []);
3764
+ const startVoiceCapture = (0, import_react5.useCallback)(async () => {
3765
+ if (disabled || isGenerating) {
3766
+ return;
3767
+ }
3768
+ setIsVoiceComposerOpen(true);
3769
+ setVoiceError(null);
3770
+ setVoiceDraft(null);
3771
+ setVoiceCountdownMs(0);
3772
+ setVoiceTranscript(clearVoiceTranscript());
3773
+ setVoiceAudioLevel(0);
3774
+ setVoiceDurationMs(0);
3775
+ try {
3776
+ const provider = await ensureVoiceProvider();
3777
+ await provider.start();
3778
+ } catch (error) {
3779
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3780
+ setVoiceState("error");
3781
+ }
3782
+ }, [disabled, isGenerating, ensureVoiceProvider, config]);
3783
+ const stopVoiceCapture = (0, import_react5.useCallback)(async () => {
3784
+ if (!voiceProviderRef.current) return;
3785
+ try {
3786
+ await voiceProviderRef.current.stop();
3787
+ } catch (error) {
3788
+ setVoiceError(resolveVoiceErrorMessage(error, config));
3789
+ setVoiceState("error");
3790
+ }
3791
+ }, [config]);
3792
+ const cancelVoiceCapture = (0, import_react5.useCallback)(async () => {
3793
+ if (voiceProviderRef.current) {
3794
+ await voiceProviderRef.current.cancel();
3795
+ }
3796
+ resetVoiceComposerState("idle");
3797
+ }, [resetVoiceComposerState]);
3798
+ const finalizeVoiceComposerAfterSend = (0, import_react5.useCallback)(() => {
3799
+ if (voicePersistComposer) {
3800
+ resetVoiceComposerState("idle");
3801
+ setIsVoiceComposerOpen(true);
3802
+ return;
3803
+ }
3804
+ void closeVoiceComposer();
3805
+ }, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);
3806
+ const sendVoiceDraft = (0, import_react5.useCallback)(() => {
3807
+ if (!voiceDraft || disabled || isGenerating) {
3808
+ return;
3809
+ }
3810
+ setVoiceState("sending");
3811
+ setVoiceCountdownMs(0);
3812
+ onSubmit("", [...attachments, voiceDraft.attachment]);
3813
+ onChange("");
3814
+ onAttachmentsChange([]);
3815
+ finalizeVoiceComposerAfterSend();
3816
+ }, [
3817
+ voiceDraft,
3818
+ disabled,
3819
+ isGenerating,
3820
+ onSubmit,
3821
+ attachments,
3822
+ onChange,
3823
+ onAttachmentsChange,
3824
+ finalizeVoiceComposerAfterSend
3825
+ ]);
3826
+ const recordVoiceAgain = (0, import_react5.useCallback)(async () => {
3827
+ resetVoiceComposerState("idle");
3828
+ await startVoiceCapture();
3829
+ }, [resetVoiceComposerState, startVoiceCapture]);
3830
+ (0, import_react5.useEffect)(() => {
3831
+ if (voiceState !== "review" || !voiceDraft || voiceAutoSendDelayMs <= 0) {
3832
+ return;
3833
+ }
3834
+ const startedAt = Date.now();
3835
+ setVoiceCountdownMs(voiceAutoSendDelayMs);
3836
+ const timer = setInterval(() => {
3837
+ const remaining = Math.max(0, voiceAutoSendDelayMs - (Date.now() - startedAt));
3838
+ setVoiceCountdownMs(remaining);
3839
+ if (remaining <= 0) {
3840
+ clearInterval(timer);
3841
+ sendVoiceDraft();
3842
+ }
3843
+ }, 100);
3844
+ return () => clearInterval(timer);
3845
+ }, [voiceState, voiceDraft, voiceAutoSendDelayMs, sendVoiceDraft]);
3290
3846
  const removeAttachment = (index) => {
3291
3847
  const newAttachments = attachments.filter((_, i) => i !== index);
3292
3848
  onAttachmentsChange(newAttachments);
3293
3849
  };
3294
3850
  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)(
3851
+ const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;
3852
+ 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: [
3853
+ 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
3854
  FileUploadItem,
3298
3855
  {
3299
3856
  file: { name: progress.fileName },
@@ -3308,7 +3865,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3308
3865
  },
3309
3866
  id
3310
3867
  )) }),
3311
- isRecording && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3868
+ isRecording && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3312
3869
  AudioRecorder,
3313
3870
  {
3314
3871
  isRecording,
@@ -3319,7 +3876,7 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3319
3876
  config
3320
3877
  }
3321
3878
  ),
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)(
3879
+ 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
3880
  AttachmentPreview,
3324
3881
  {
3325
3882
  attachment,
@@ -3327,15 +3884,46 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3327
3884
  },
3328
3885
  index
3329
3886
  )) }),
3330
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3887
+ showVoiceComposer ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3888
+ VoiceComposer,
3889
+ {
3890
+ state: voiceState,
3891
+ transcript: voiceTranscript,
3892
+ transcriptMode: voiceTranscriptMode,
3893
+ showTranscriptPreview: voiceShowTranscriptPreview,
3894
+ durationMs: voiceDurationMs,
3895
+ audioLevel: voiceAudioLevel,
3896
+ countdownMs: voiceCountdownMs,
3897
+ autoSendDelayMs: voiceAutoSendDelayMs,
3898
+ errorMessage: voiceError,
3899
+ disabled: disabled || isGenerating,
3900
+ labels: config?.labels,
3901
+ onStart: () => {
3902
+ void startVoiceCapture();
3903
+ },
3904
+ onStop: () => {
3905
+ void stopVoiceCapture();
3906
+ },
3907
+ onCancel: () => {
3908
+ void cancelVoiceCapture();
3909
+ },
3910
+ onSendNow: sendVoiceDraft,
3911
+ onRecordAgain: () => {
3912
+ void recordVoiceAgain();
3913
+ },
3914
+ onExit: () => {
3915
+ void closeVoiceComposer();
3916
+ }
3917
+ }
3918
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("form", { onSubmit: handleSubmit, className: "mb-1 flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3331
3919
  "div",
3332
3920
  {
3333
3921
  className: "flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl",
3334
3922
  onDrop: handleDrop,
3335
3923
  onDragOver: handleDragOver,
3336
3924
  children: [
3337
- enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3338
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3925
+ enableFileUpload && canAddMoreAttachments && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3926
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3339
3927
  "input",
3340
3928
  {
3341
3929
  ref: fileInputRef,
@@ -3346,8 +3934,8 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3346
3934
  className: "hidden"
3347
3935
  }
3348
3936
  ),
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)(
3937
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
3938
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3351
3939
  Button,
3352
3940
  {
3353
3941
  type: "button",
@@ -3360,13 +3948,13 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3360
3948
  fileInputRef.current?.click();
3361
3949
  },
3362
3950
  disabled,
3363
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Paperclip, { className: "h-4 w-4" })
3951
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Paperclip, { className: "h-4 w-4" })
3364
3952
  }
3365
3953
  ) }),
3366
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
3954
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.attachFileTooltip })
3367
3955
  ] })
3368
3956
  ] }),
3369
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3957
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3370
3958
  Textarea,
3371
3959
  {
3372
3960
  ref: textareaRef,
@@ -3379,7 +3967,23 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3379
3967
  rows: 1
3380
3968
  }
3381
3969
  ) }),
3382
- enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3970
+ enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (voiceComposeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
3971
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3972
+ Button,
3973
+ {
3974
+ type: "button",
3975
+ variant: "outline",
3976
+ size: "icon",
3977
+ className: "h-10 w-10",
3978
+ onClick: () => {
3979
+ void startVoiceCapture();
3980
+ },
3981
+ disabled: disabled || isGenerating,
3982
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Mic, { className: "h-4 w-4" })
3983
+ }
3984
+ ) }),
3985
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip })
3986
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3383
3987
  AudioRecorder,
3384
3988
  {
3385
3989
  isRecording,
@@ -3389,9 +3993,9 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3389
3993
  recordingDuration,
3390
3994
  config
3391
3995
  }
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)(
3996
+ )),
3997
+ isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
3998
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3395
3999
  Button,
3396
4000
  {
3397
4001
  type: "button",
@@ -3399,36 +4003,36 @@ var ChatInput = (0, import_react5.memo)(function ChatInput2({
3399
4003
  size: "icon",
3400
4004
  className: "h-10 w-10",
3401
4005
  onClick: onStopGeneration,
3402
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Square, { className: "h-4 w-4" })
4006
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Square, { className: "h-4 w-4" })
3403
4007
  }
3404
4008
  ) }),
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)(
4009
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.stopGenerationTooltip })
4010
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
4011
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3408
4012
  Button,
3409
4013
  {
3410
4014
  type: "submit",
3411
4015
  size: "icon",
3412
4016
  className: "h-10 w-10",
3413
4017
  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" })
4018
+ 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
4019
  }
3416
4020
  ) }),
3417
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
4021
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { children: config?.labels?.sendMessageTooltip })
3418
4022
  ] })
3419
4023
  ]
3420
4024
  }
3421
4025
  ) }),
3422
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-[10px] text-muted-foreground text-center", children: [
4026
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "text-[10px] text-muted-foreground text-center", children: [
3423
4027
  window.innerWidth > 768 ? config?.labels?.inputHelpText : "",
3424
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4028
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3425
4029
  " \u2022 ",
3426
4030
  attachments.length,
3427
4031
  "/",
3428
4032
  maxAttachments,
3429
4033
  " anexos"
3430
4034
  ] }),
3431
- config?.labels?.footerLabel && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4035
+ config?.labels?.footerLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3432
4036
  " \u2022 ",
3433
4037
  config.labels.footerLabel
3434
4038
  ] })
@@ -3442,16 +4046,16 @@ var import_react6 = require("react");
3442
4046
  // src/components/ui/scroll-area.tsx
3443
4047
  var React11 = __toESM(require("react"), 1);
3444
4048
  var ScrollAreaPrimitive = __toESM(require("@radix-ui/react-scroll-area"), 1);
3445
- var import_jsx_runtime22 = require("react/jsx-runtime");
4049
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3446
4050
  var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {
3447
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4051
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
3448
4052
  ScrollAreaPrimitive.Root,
3449
4053
  {
3450
4054
  "data-slot": "scroll-area",
3451
4055
  className: cn("relative", className),
3452
4056
  ...props,
3453
4057
  children: [
3454
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4058
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3455
4059
  ScrollAreaPrimitive.Viewport,
3456
4060
  {
3457
4061
  ref,
@@ -3465,8 +4069,8 @@ var ScrollArea = React11.forwardRef(({ className, children, viewportClassName, o
3465
4069
  children
3466
4070
  }
3467
4071
  ),
3468
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScrollBar, {}),
3469
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScrollAreaPrimitive.Corner, {})
4072
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScrollBar, {}),
4073
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ScrollAreaPrimitive.Corner, {})
3470
4074
  ]
3471
4075
  }
3472
4076
  );
@@ -3477,7 +4081,7 @@ function ScrollBar({
3477
4081
  orientation = "vertical",
3478
4082
  ...props
3479
4083
  }) {
3480
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4084
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3481
4085
  ScrollAreaPrimitive.ScrollAreaScrollbar,
3482
4086
  {
3483
4087
  "data-slot": "scroll-area-scrollbar",
@@ -3489,7 +4093,7 @@ function ScrollBar({
3489
4093
  className
3490
4094
  ),
3491
4095
  ...props,
3492
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4096
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3493
4097
  ScrollAreaPrimitive.ScrollAreaThumb,
3494
4098
  {
3495
4099
  "data-slot": "scroll-area-thumb",
@@ -3501,8 +4105,8 @@ function ScrollBar({
3501
4105
  }
3502
4106
 
3503
4107
  // src/components/chat/UserProfile.tsx
3504
- var import_lucide_react10 = require("lucide-react");
3505
- var import_jsx_runtime23 = require("react/jsx-runtime");
4108
+ var import_lucide_react11 = require("lucide-react");
4109
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3506
4110
  var getInitials2 = (name, email) => {
3507
4111
  if (name) {
3508
4112
  return name.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase();
@@ -3516,29 +4120,29 @@ var getFieldIcon = (type, key) => {
3516
4120
  const iconClass = "h-4 w-4 text-muted-foreground";
3517
4121
  switch (type) {
3518
4122
  case "email":
3519
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Mail, { className: iconClass });
4123
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Mail, { className: iconClass });
3520
4124
  case "phone":
3521
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Phone, { className: iconClass });
4125
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Phone, { className: iconClass });
3522
4126
  case "url":
3523
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Globe, { className: iconClass });
4127
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Globe, { className: iconClass });
3524
4128
  case "date":
3525
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Calendar, { className: iconClass });
4129
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Calendar, { className: iconClass });
3526
4130
  }
3527
4131
  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 });
4132
+ if (lowerKey.includes("follower")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Users, { className: iconClass });
4133
+ if (lowerKey.includes("following")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.UserPlus, { className: iconClass });
4134
+ if (lowerKey.includes("post") || lowerKey.includes("publication")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Image, { className: iconClass });
4135
+ if (lowerKey.includes("verified") || lowerKey.includes("badge")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.BadgeCheck, { className: iconClass });
4136
+ if (lowerKey.includes("bio")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.FileText, { className: iconClass });
4137
+ if (lowerKey.includes("email")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Mail, { className: iconClass });
4138
+ if (lowerKey.includes("phone") || lowerKey.includes("tel")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Phone, { className: iconClass });
4139
+ if (lowerKey.includes("location") || lowerKey.includes("address") || lowerKey.includes("city")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.MapPin, { className: iconClass });
4140
+ if (lowerKey.includes("company") || lowerKey.includes("org")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Building, { className: iconClass });
4141
+ 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 });
4142
+ if (lowerKey.includes("website") || lowerKey.includes("url") || lowerKey.includes("link")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Globe, { className: iconClass });
4143
+ if (lowerKey.includes("username") || lowerKey.includes("handle")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.AtSign, { className: iconClass });
4144
+ if (lowerKey.includes("date") || lowerKey.includes("birthday") || lowerKey.includes("joined")) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Calendar, { className: iconClass });
4145
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.User, { className: iconClass });
3542
4146
  };
3543
4147
  var formatValue = (value, type, key) => {
3544
4148
  if (value === null || value === void 0) return "-";
@@ -3572,15 +4176,15 @@ var getMemoryCategoryIcon = (category) => {
3572
4176
  const iconClass = "h-4 w-4 text-muted-foreground";
3573
4177
  switch (category) {
3574
4178
  case "preference":
3575
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Heart, { className: iconClass });
4179
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Heart, { className: iconClass });
3576
4180
  case "fact":
3577
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Info, { className: iconClass });
4181
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Info, { className: iconClass });
3578
4182
  case "goal":
3579
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Target, { className: iconClass });
4183
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Target, { className: iconClass });
3580
4184
  case "context":
3581
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Lightbulb, { className: iconClass });
4185
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Lightbulb, { className: iconClass });
3582
4186
  default:
3583
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Brain, { className: iconClass });
4187
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Brain, { className: iconClass });
3584
4188
  }
3585
4189
  };
3586
4190
  var getMemoryCategoryLabel = (category) => {
@@ -3650,66 +4254,66 @@ var UserProfile = ({
3650
4254
  const displayName = user?.name || user?.email?.split("@")[0] || "User";
3651
4255
  const initials = getInitials2(user?.name, user?.email);
3652
4256
  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)(
4257
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Sheet, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3654
4258
  SheetContent,
3655
4259
  {
3656
4260
  side: "right",
3657
4261
  className: cn("w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden", className),
3658
4262
  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 })
4263
+ /* @__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 }) }) }),
4264
+ /* @__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: [
4265
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center text-center space-y-4", children: [
4266
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Avatar, { className: "h-24 w-24 shrink-0", children: [
4267
+ user?.avatar && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AvatarImage, { src: user.avatar, alt: displayName }),
4268
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AvatarFallback, { className: "text-2xl bg-primary/10 text-primary", children: initials })
3665
4269
  ] }),
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 })
4270
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "w-full px-2", children: [
4271
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-xl font-semibold break-words", children: displayName }),
4272
+ user?.email && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm text-muted-foreground break-words", children: user.email })
3669
4273
  ] })
3670
4274
  ] }),
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 })
4275
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Separator, {}),
4276
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-3", children: [
4277
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.basicInfo }),
4278
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-2", children: [
4279
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4280
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4281
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4282
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "Name" }),
4283
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium break-words", children: displayName })
3680
4284
  ] })
3681
4285
  ] }),
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 })
4286
+ user?.email && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50", children: [
4287
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.AtSign, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4288
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4289
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "Handle" }),
4290
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium break-words", children: user.email })
3687
4291
  ] })
3688
4292
  ] }),
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 })
4293
+ 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: [
4294
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.User, { className: "h-4 w-4 text-muted-foreground mt-0.5 shrink-0" }),
4295
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4296
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "ID" }),
4297
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm font-medium break-words", children: user.id })
3694
4298
  ] })
3695
4299
  ] })
3696
4300
  ] })
3697
4301
  ] }),
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) => {
4302
+ normalizedFields.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
4303
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Separator, {}),
4304
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-3", children: [
4305
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider", children: labels.customFields }),
4306
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-2", children: normalizedFields.map((field) => {
3703
4307
  const isBioField = field.key.toLowerCase().includes("bio");
3704
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4308
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3705
4309
  "div",
3706
4310
  {
3707
4311
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50",
3708
4312
  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(
4313
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mt-0.5 shrink-0", children: field.icon || getFieldIcon(field.type, field.key) }),
4314
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4315
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: field.label }),
4316
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: cn(
3713
4317
  "text-sm font-medium",
3714
4318
  isBioField ? "whitespace-pre-wrap break-words" : "break-words"
3715
4319
  ), children: formatValue(field.value, field.type, field.key) })
@@ -3721,26 +4325,26 @@ var UserProfile = ({
3721
4325
  }) })
3722
4326
  ] })
3723
4327
  ] }),
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" }),
4328
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Separator, {}),
4329
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-3", children: [
4330
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between", children: [
4331
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
4332
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Brain, { className: "h-4 w-4" }),
3729
4333
  labels.memories
3730
4334
  ] }),
3731
- onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4335
+ onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3732
4336
  Button,
3733
4337
  {
3734
4338
  variant: "ghost",
3735
4339
  size: "sm",
3736
4340
  className: "h-7 px-2",
3737
4341
  onClick: () => setIsAddingMemory(true),
3738
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Plus, { className: "h-4 w-4" })
4342
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Plus, { className: "h-4 w-4" })
3739
4343
  }
3740
4344
  )
3741
4345
  ] }),
3742
- isAddingMemory && onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2", children: [
3743
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4346
+ isAddingMemory && onAddMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-2", children: [
4347
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3744
4348
  Input,
3745
4349
  {
3746
4350
  value: newMemoryContent,
@@ -3757,24 +4361,24 @@ var UserProfile = ({
3757
4361
  autoFocus: true
3758
4362
  }
3759
4363
  ),
3760
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
4364
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { size: "sm", onClick: handleAddMemory, disabled: !newMemoryContent.trim(), children: "Salvar" })
3761
4365
  ] }),
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) => {
4366
+ /* @__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
4367
  const isEditing = editingMemoryId === memory.id;
3764
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4368
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3765
4369
  "div",
3766
4370
  {
3767
4371
  className: "flex items-start gap-3 p-3 rounded-lg bg-muted/50 group",
3768
4372
  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" })
4373
+ /* @__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) }),
4374
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex-1 min-w-0", children: [
4375
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2 mb-0.5", children: [
4376
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-muted-foreground", children: getMemoryCategoryLabel(memory.category) }),
4377
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-muted-foreground", children: "\u2022" }),
4378
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-xs text-muted-foreground", children: memory.source === "agent" ? "IA" : "Voc\xEA" })
3775
4379
  ] }),
3776
- isEditing ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-2", children: [
3777
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4380
+ isEditing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-2", children: [
4381
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3778
4382
  Textarea,
3779
4383
  {
3780
4384
  value: editingMemoryContent,
@@ -3791,8 +4395,8 @@ var UserProfile = ({
3791
4395
  }
3792
4396
  }
3793
4397
  ),
3794
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-1 justify-end", children: [
3795
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4398
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-1 justify-end", children: [
4399
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3796
4400
  Button,
3797
4401
  {
3798
4402
  variant: "ghost",
@@ -3800,12 +4404,12 @@ var UserProfile = ({
3800
4404
  className: "h-7 px-2",
3801
4405
  onClick: handleCancelEdit,
3802
4406
  children: [
3803
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.X, { className: "h-3.5 w-3.5 mr-1" }),
4407
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.X, { className: "h-3.5 w-3.5 mr-1" }),
3804
4408
  "Cancelar"
3805
4409
  ]
3806
4410
  }
3807
4411
  ),
3808
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4412
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
3809
4413
  Button,
3810
4414
  {
3811
4415
  size: "sm",
@@ -3813,33 +4417,33 @@ var UserProfile = ({
3813
4417
  onClick: handleSaveEdit,
3814
4418
  disabled: !editingMemoryContent.trim(),
3815
4419
  children: [
3816
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Check, { className: "h-3.5 w-3.5 mr-1" }),
4420
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Check, { className: "h-3.5 w-3.5 mr-1" }),
3817
4421
  "Salvar"
3818
4422
  ]
3819
4423
  }
3820
4424
  )
3821
4425
  ] })
3822
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm break-words", children: memory.content })
4426
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm break-words", children: memory.content })
3823
4427
  ] }),
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)(
4428
+ !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: [
4429
+ onUpdateMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3826
4430
  Button,
3827
4431
  {
3828
4432
  variant: "ghost",
3829
4433
  size: "icon",
3830
4434
  className: "h-7 w-7",
3831
4435
  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" })
4436
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Pencil, { className: "h-3.5 w-3.5 text-muted-foreground" })
3833
4437
  }
3834
4438
  ),
3835
- onDeleteMemory && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4439
+ onDeleteMemory && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3836
4440
  Button,
3837
4441
  {
3838
4442
  variant: "ghost",
3839
4443
  size: "icon",
3840
4444
  className: "h-7 w-7",
3841
4445
  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" })
4446
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Trash2, { className: "h-3.5 w-3.5 text-destructive" })
3843
4447
  }
3844
4448
  )
3845
4449
  ] })
@@ -3850,8 +4454,8 @@ var UserProfile = ({
3850
4454
  }) })
3851
4455
  ] })
3852
4456
  ] }) }),
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)(
4457
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "p-4 border-t space-y-2 shrink-0", children: [
4458
+ onEditProfile && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3855
4459
  Button,
3856
4460
  {
3857
4461
  variant: "outline",
@@ -3860,7 +4464,7 @@ var UserProfile = ({
3860
4464
  children: "Edit Profile"
3861
4465
  }
3862
4466
  ),
3863
- onLogout && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4467
+ onLogout && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3864
4468
  Button,
3865
4469
  {
3866
4470
  variant: "destructive",
@@ -3876,8 +4480,8 @@ var UserProfile = ({
3876
4480
  };
3877
4481
 
3878
4482
  // src/components/chat/ChatUI.tsx
3879
- var import_lucide_react11 = require("lucide-react");
3880
- var import_jsx_runtime24 = require("react/jsx-runtime");
4483
+ var import_lucide_react12 = require("lucide-react");
4484
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3881
4485
  var ChatUI = ({
3882
4486
  messages = [],
3883
4487
  threads = [],
@@ -4140,16 +4744,16 @@ var ChatUI = ({
4140
4744
  }
4141
4745
  return component;
4142
4746
  }, [config?.customComponent?.component, closeSidebar, isMobile]);
4143
- const SuggestionIconComponents = [import_lucide_react11.MessageSquare, import_lucide_react11.Lightbulb, import_lucide_react11.Zap, import_lucide_react11.HelpCircle];
4747
+ const SuggestionIconComponents = [import_lucide_react12.MessageSquare, import_lucide_react12.Lightbulb, import_lucide_react12.Zap, import_lucide_react12.HelpCircle];
4144
4748
  const renderSuggestions = () => {
4145
4749
  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 })
4750
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center justify-center min-h-[60vh] py-8 px-4", children: [
4751
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "text-center mb-8", children: [
4752
+ /* @__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" }) }),
4753
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-xl font-semibold mb-2", children: config.branding.title }),
4754
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-muted-foreground text-sm max-w-md", children: config.branding.subtitle })
4151
4755
  ] }),
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)(
4756
+ /* @__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
4757
  "button",
4154
4758
  {
4155
4759
  type: "button",
@@ -4158,10 +4762,10 @@ var ChatUI = ({
4158
4762
  children: [
4159
4763
  (() => {
4160
4764
  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" }) });
4765
+ 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
4766
  })(),
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" })
4767
+ /* @__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 }) }),
4768
+ /* @__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
4769
  ]
4166
4770
  },
4167
4771
  index
@@ -4172,34 +4776,34 @@ var ChatUI = ({
4172
4776
  const items = messageSuggestions?.[messageId];
4173
4777
  if (!items || items.length === 0) return null;
4174
4778
  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)(
4779
+ 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
4780
  "button",
4177
4781
  {
4178
4782
  type: "button",
4179
4783
  onClick: () => handleSendMessage(suggestion),
4180
4784
  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
4785
  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 })
4786
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Sparkles, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4787
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "max-w-[200px] truncate", children: suggestion })
4184
4788
  ]
4185
4789
  },
4186
4790
  `${messageId}-suggestion-${index}`
4187
4791
  )) });
4188
4792
  };
4189
- const renderMessageLoadingSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4793
+ const renderMessageLoadingSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-6 py-2", children: [0, 1, 2, 3].map((index) => {
4190
4794
  const isUserRow = index % 2 === 1;
4191
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4795
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4192
4796
  "div",
4193
4797
  {
4194
4798
  className: `flex gap-3 ${isUserRow ? "justify-end" : "justify-start"}`,
4195
4799
  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%]" })
4800
+ !isUserRow && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
4801
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: `space-y-2 ${isUserRow ? "w-[70%]" : "w-[75%]"}`, children: [
4802
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-4 w-24" }),
4803
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-4 w-full" }),
4804
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-4 w-[85%]" })
4201
4805
  ] }),
4202
- isUserRow && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4806
+ isUserRow && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
4203
4807
  ]
4204
4808
  },
4205
4809
  `message-skeleton-${index}`
@@ -4255,8 +4859,8 @@ var ChatUI = ({
4255
4859
  const shouldShowAgentSelector = Boolean(
4256
4860
  config.agentSelector?.enabled && onSelectAgent && agentOptions.length > 0 && (!config.agentSelector?.hideIfSingle || agentOptions.length > 1)
4257
4861
  );
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)(
4862
+ 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: [
4863
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4260
4864
  Sidebar2,
4261
4865
  {
4262
4866
  threads,
@@ -4273,8 +4877,8 @@ var ChatUI = ({
4273
4877
  showThemeOptions: !!callbacks.onThemeChange
4274
4878
  }
4275
4879
  ),
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)(
4880
+ /* @__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: [
4881
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4278
4882
  ChatHeader,
4279
4883
  {
4280
4884
  config,
@@ -4289,9 +4893,9 @@ var ChatUI = ({
4289
4893
  onSelectAgent
4290
4894
  }
4291
4895
  ),
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)(
4896
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-1 flex-row min-h-0 overflow-hidden", children: [
4897
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex-1 flex flex-col min-h-0", children: [
4898
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4295
4899
  ScrollArea,
4296
4900
  {
4297
4901
  ref: scrollAreaRef,
@@ -4299,7 +4903,7 @@ var ChatUI = ({
4299
4903
  viewportClassName: "p-4 overscroll-contain",
4300
4904
  onScrollCapture: handleScroll,
4301
4905
  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)(
4906
+ 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
4907
  "div",
4304
4908
  {
4305
4909
  style: {
@@ -4311,7 +4915,7 @@ var ChatUI = ({
4311
4915
  const message = messages[virtualRow.index];
4312
4916
  const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;
4313
4917
  const isGrouped = prevMessage !== null && prevMessage.role === message.role;
4314
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4918
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4315
4919
  "div",
4316
4920
  {
4317
4921
  "data-index": virtualRow.index,
@@ -4323,8 +4927,8 @@ var ChatUI = ({
4323
4927
  width: "100%",
4324
4928
  transform: `translateY(${virtualRow.start}px)`
4325
4929
  },
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)(
4930
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: virtualRow.index === 0 ? "" : isGrouped ? "pt-2" : "pt-4", children: [
4931
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4328
4932
  Message,
4329
4933
  {
4330
4934
  message,
@@ -4343,7 +4947,7 @@ var ChatUI = ({
4343
4947
  ) })
4344
4948
  }
4345
4949
  ),
4346
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4950
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "bg-background pb-[env(safe-area-inset-bottom)]", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4347
4951
  ChatInput,
4348
4952
  {
4349
4953
  value: inputValue,
@@ -4369,17 +4973,17 @@ var ChatUI = ({
4369
4973
  }
4370
4974
  ) })
4371
4975
  ] }),
4372
- config?.customComponent?.component && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4976
+ config?.customComponent?.component && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4373
4977
  "div",
4374
4978
  {
4375
4979
  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() })
4980
+ 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
4981
  }
4378
4982
  )
4379
4983
  ] })
4380
4984
  ] }) }),
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)(
4985
+ isCustomMounted && config.customComponent?.component && isMobile && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fixed inset-0 z-50", children: [
4986
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4383
4987
  "div",
4384
4988
  {
4385
4989
  className: `absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${isCustomVisible ? "opacity-100" : "opacity-0"}`,
@@ -4387,16 +4991,16 @@ var ChatUI = ({
4387
4991
  onClick: closeSidebar
4388
4992
  }
4389
4993
  ),
4390
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4994
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4391
4995
  "div",
4392
4996
  {
4393
4997
  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
4998
  style: { willChange: "transform" },
4395
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
4999
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "h-full flex flex-col", children: renderCustomComponent() })
4396
5000
  }
4397
5001
  )
4398
5002
  ] }),
4399
- isUserProfileOpen && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5003
+ isUserProfileOpen && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4400
5004
  UserProfile,
4401
5005
  {
4402
5006
  isOpen: isUserProfileOpen,
@@ -4420,8 +5024,8 @@ var ChatUI = ({
4420
5024
 
4421
5025
  // src/components/chat/ThreadManager.tsx
4422
5026
  var import_react8 = require("react");
4423
- var import_lucide_react12 = require("lucide-react");
4424
- var import_jsx_runtime25 = require("react/jsx-runtime");
5027
+ var import_lucide_react13 = require("lucide-react");
5028
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4425
5029
  var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {
4426
5030
  const [isEditing, setIsEditing] = (0, import_react8.useState)(false);
4427
5031
  const [editTitle, setEditTitle] = (0, import_react8.useState)(thread.title);
@@ -4450,9 +5054,9 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4450
5054
  handleCancelEdit();
4451
5055
  }
4452
5056
  };
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)(
5057
+ 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: [
5058
+ /* @__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: [
5059
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4456
5060
  Input,
4457
5061
  {
4458
5062
  ref: inputRef,
@@ -4464,44 +5068,44 @@ var ThreadItem = ({ thread, isActive, config, onSelect, onRename, onDelete, onAr
4464
5068
  placeholder: config?.labels?.threadNamePlaceholder || "Conversation name"
4465
5069
  }
4466
5070
  ),
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" }),
5071
+ /* @__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" }) }),
5072
+ /* @__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" }) })
5073
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5074
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h4", { className: "font-medium text-sm truncate mb-1", children: thread.title }),
5075
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
5076
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1", children: [
5077
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Hash, { className: "h-3 w-3" }),
4474
5078
  thread.messageCount,
4475
5079
  " msgs"
4476
5080
  ] }),
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" }),
5081
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
5082
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1", children: [
5083
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Calendar, { className: "h-3 w-3" }),
4480
5084
  formatDate(thread.updatedAt, config?.labels)
4481
5085
  ] }),
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" }),
5086
+ thread.isArchived && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5087
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator, { orientation: "vertical", className: "h-3" }),
5088
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
5089
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Archive, { className: "h-2 w-2 mr-1" }),
4486
5090
  config?.labels?.archiveThread || "Archived"
4487
5091
  ] })
4488
5092
  ] })
4489
5093
  ] })
4490
5094
  ] }) }),
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" }),
5095
+ !isEditing && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenu, { children: [
5096
+ /* @__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" }) }) }),
5097
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuContent, { align: "end", children: [
5098
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: () => setIsEditing(true), children: [
5099
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Edit2, { className: "h-4 w-4 mr-2" }),
4496
5100
  config?.labels?.renameThread || "Rename"
4497
5101
  ] }),
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" }),
5102
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: onArchive, children: [
5103
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Archive, { className: "h-4 w-4 mr-2" }),
4500
5104
  thread.isArchived ? config?.labels?.unarchiveThread || "Unarchive" : config?.labels?.archiveThread || "Archive"
4501
5105
  ] }),
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" }),
5106
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DropdownMenuSeparator, {}),
5107
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DropdownMenuItem, { onClick: onDelete, className: "text-destructive", children: [
5108
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Trash2, { className: "h-4 w-4 mr-2" }),
4505
5109
  config?.labels?.deleteThread || "Delete"
4506
5110
  ] })
4507
5111
  ] })
@@ -4516,17 +5120,17 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4516
5120
  setTitle("");
4517
5121
  setIsOpen(false);
4518
5122
  };
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" }),
5123
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
5124
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Button, { variant: "outline", className: "w-full", children: [
5125
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Plus, { className: "h-4 w-4 mr-2" }),
4522
5126
  config?.labels?.createNewThread || "New Conversation"
4523
5127
  ] }) }),
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." })
5128
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogContent, { children: [
5129
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogHeader, { children: [
5130
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogTitle, { children: config?.labels?.createNewThread || "Create New Conversation" }),
5131
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogDescription, { children: "Give your new conversation a name or leave blank to auto-generate one." })
4528
5132
  ] }),
4529
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5133
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4530
5134
  Input,
4531
5135
  {
4532
5136
  value: title,
@@ -4536,9 +5140,9 @@ var CreateThreadDialog2 = ({ onCreateThread, config }) => {
4536
5140
  autoFocus: true
4537
5141
  }
4538
5142
  ),
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" })
5143
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogFooter, { children: [
5144
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { variant: "outline", onClick: () => setIsOpen(false), children: config?.labels?.cancel || "Cancel" }),
5145
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { onClick: handleCreate, children: config?.labels?.create || "Create" })
4542
5146
  ] })
4543
5147
  ] })
4544
5148
  ] });
@@ -4592,20 +5196,20 @@ var ThreadManager = ({
4592
5196
  setDeleteThreadId(null);
4593
5197
  };
4594
5198
  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" }),
5199
+ 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: [
5200
+ /* @__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: [
5201
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardHeader, { className: "border-b", children: [
5202
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
5203
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardTitle, { className: "flex items-center gap-2", children: [
5204
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.MessageSquare, { className: "h-5 w-5" }),
4601
5205
  config?.labels?.newChat || "Conversations"
4602
5206
  ] }),
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" }) })
5207
+ /* @__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
5208
  ] }),
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)(
5209
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-3", children: [
5210
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "relative", children: [
5211
+ /* @__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" }),
5212
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4609
5213
  Input,
4610
5214
  {
4611
5215
  placeholder: config?.labels?.search || "Search conversations...",
@@ -4615,8 +5219,8 @@ var ThreadManager = ({
4615
5219
  }
4616
5220
  )
4617
5221
  ] }),
4618
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
4619
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5222
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
5223
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4620
5224
  Button,
4621
5225
  {
4622
5226
  variant: "outline",
@@ -4624,12 +5228,12 @@ var ThreadManager = ({
4624
5228
  onClick: () => setShowArchived(!showArchived),
4625
5229
  className: "text-xs",
4626
5230
  children: [
4627
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Filter, { className: "h-3 w-3 mr-1" }),
5231
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Filter, { className: "h-3 w-3 mr-1" }),
4628
5232
  showArchived ? config?.labels?.hideArchived || "Hide Archived" : config?.labels?.showArchived || "Show Archived"
4629
5233
  ]
4630
5234
  }
4631
5235
  ),
4632
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
5236
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-xs", children: [
4633
5237
  filteredThreads.length,
4634
5238
  " / ",
4635
5239
  threads.length
@@ -4637,14 +5241,14 @@ var ThreadManager = ({
4637
5241
  ] })
4638
5242
  ] })
4639
5243
  ] }),
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)(
5244
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardContent, { className: "p-0 flex-1", children: [
5245
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "p-4", children: onCreateThread && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CreateThreadDialog2, { onCreateThread, config }) }),
5246
+ /* @__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: [
5247
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.MessageSquare, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
5248
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm", children: searchQuery ? config?.labels?.noThreadsFound || "No conversations found" : config?.labels?.noThreadsYet || "No conversations yet" })
5249
+ ] }) : Object.entries(groupedThreads).map(([group, groupThreads]) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
5250
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "text-sm font-medium text-muted-foreground mb-2 px-2", children: group }),
5251
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-2", children: groupThreads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4648
5252
  ThreadItem,
4649
5253
  {
4650
5254
  thread,
@@ -4660,14 +5264,14 @@ var ThreadManager = ({
4660
5264
  ] }, group)) }) })
4661
5265
  ] })
4662
5266
  ] }) }),
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." })
5267
+ deleteThreadId && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialog, { open: !!deleteThreadId, onOpenChange: () => setDeleteThreadId(null), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AlertDialogContent, { children: [
5268
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AlertDialogHeader, { children: [
5269
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialogTitle, { children: config?.labels?.deleteConfirmTitle || "Delete Conversation" }),
5270
+ /* @__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
5271
  ] }),
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)(
5272
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AlertDialogFooter, { children: [
5273
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AlertDialogCancel, { children: config?.labels?.cancel || "Cancel" }),
5274
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4671
5275
  AlertDialogAction,
4672
5276
  {
4673
5277
  onClick: () => deleteThreadId && handleDeleteThread(deleteThreadId),