@contentgrowth/llm-service 1.0.0 → 1.0.2

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.
@@ -189,19 +189,174 @@ function ChatHeader({
189
189
  }
190
190
 
191
191
  // src/ui/react/components/ChatInputArea.tsx
192
- var import_react4 = require("react");
192
+ var import_react5 = require("react");
193
+ var import_outline2 = require("@heroicons/react/24/outline");
194
+
195
+ // src/ui/react/components/VoiceInputButton.tsx
193
196
  var import_outline = require("@heroicons/react/24/outline");
194
197
 
195
- // src/ui/react/hooks/useAudioRecorder.ts
198
+ // src/ui/react/hooks/useDragCancel.ts
196
199
  var import_react2 = require("react");
200
+ var useDragCancel = ({
201
+ onCancel,
202
+ onCommit,
203
+ isListening,
204
+ threshold = 50,
205
+ direction = "up"
206
+ }) => {
207
+ const [isDragging, setIsDragging] = (0, import_react2.useState)(false);
208
+ const [isPressed, setIsPressed] = (0, import_react2.useState)(false);
209
+ const startPosRef = (0, import_react2.useRef)(null);
210
+ const handlePointerDown = (0, import_react2.useCallback)((e) => {
211
+ startPosRef.current = { x: e.clientX, y: e.clientY };
212
+ e.currentTarget.setPointerCapture(e.pointerId);
213
+ setIsPressed(true);
214
+ setIsDragging(false);
215
+ }, []);
216
+ const handlePointerMove = (0, import_react2.useCallback)((e) => {
217
+ if (!startPosRef.current || !isListening) return;
218
+ const deltaY = e.clientY - startPosRef.current.y;
219
+ const deltaX = e.clientX - startPosRef.current.x;
220
+ let shouldTrigger = false;
221
+ if (direction === "up") {
222
+ shouldTrigger = deltaY < -threshold;
223
+ } else {
224
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
225
+ shouldTrigger = distance > threshold;
226
+ }
227
+ if (shouldTrigger) {
228
+ setIsDragging(true);
229
+ } else {
230
+ setIsDragging(false);
231
+ }
232
+ }, [isListening, threshold, direction]);
233
+ const handlePointerUp = (0, import_react2.useCallback)((e) => {
234
+ if (!startPosRef.current) return;
235
+ const deltaY = e.clientY - startPosRef.current.y;
236
+ const deltaX = e.clientX - startPosRef.current.x;
237
+ let isCancelled = false;
238
+ if (direction === "up") {
239
+ isCancelled = deltaY < -threshold;
240
+ } else {
241
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
242
+ isCancelled = distance > threshold;
243
+ }
244
+ if (isListening && isCancelled) {
245
+ onCancel();
246
+ } else {
247
+ onCommit();
248
+ }
249
+ startPosRef.current = null;
250
+ setIsDragging(false);
251
+ setIsPressed(false);
252
+ e.currentTarget.releasePointerCapture(e.pointerId);
253
+ }, [isListening, threshold, direction, onCancel, onCommit]);
254
+ const handlePointerCancel = (0, import_react2.useCallback)((e) => {
255
+ startPosRef.current = null;
256
+ setIsDragging(false);
257
+ setIsPressed(false);
258
+ }, []);
259
+ return {
260
+ handlers: {
261
+ onPointerDown: handlePointerDown,
262
+ onPointerMove: handlePointerMove,
263
+ onPointerUp: handlePointerUp,
264
+ onPointerCancel: handlePointerCancel
265
+ },
266
+ isDragging,
267
+ isPressed
268
+ };
269
+ };
270
+
271
+ // src/ui/react/components/VoiceInputButton.tsx
272
+ var import_jsx_runtime5 = require("react/jsx-runtime");
273
+ var VoiceInputButton = ({
274
+ voiceConfig,
275
+ voiceTrigger,
276
+ isTranscribing,
277
+ setVoiceTrigger,
278
+ setShowDebug,
279
+ tapCountRef,
280
+ customRecorder,
281
+ startRecording,
282
+ stopRecording
283
+ }) => {
284
+ const { handlers, isDragging, isPressed } = useDragCancel({
285
+ isListening: !!voiceTrigger,
286
+ onCancel: () => {
287
+ var _a;
288
+ console.log("[ChatInputArea] Gesture Cancel");
289
+ customRecorder.cancel();
290
+ setVoiceTrigger(null);
291
+ (_a = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a.call(voiceConfig);
292
+ },
293
+ onCommit: () => {
294
+ const now = Date.now();
295
+ if (now - tapCountRef.current.lastTap < 500) {
296
+ tapCountRef.current.count++;
297
+ } else {
298
+ tapCountRef.current.count = 1;
299
+ }
300
+ tapCountRef.current.lastTap = now;
301
+ if (tapCountRef.current.count >= 5) {
302
+ setShowDebug((prev) => !prev);
303
+ tapCountRef.current.count = 0;
304
+ stopRecording();
305
+ return;
306
+ }
307
+ if (voiceTrigger) {
308
+ stopRecording();
309
+ } else if (!isTranscribing) {
310
+ startRecording("click");
311
+ }
312
+ },
313
+ threshold: 30
314
+ });
315
+ let btnClass = "text-gray-500 border-gray-300 bg-white hover:text-gray-700 hover:bg-gray-100";
316
+ let icon = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.MicrophoneIcon, { className: "w-5 h-5" });
317
+ if (isTranscribing) {
318
+ btnClass = "text-white border-indigo-500 bg-indigo-600 scale-110 shadow-lg cursor-wait";
319
+ icon = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "animate-spin w-5 h-5 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { className: "w-5 h-5 text-white", viewBox: "0 0 24 24", children: [
320
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
321
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
322
+ ] }) });
323
+ } else if (voiceTrigger) {
324
+ btnClass = "text-white border-orange-400 bg-orange-500 scale-110 shadow-lg animate-pulse";
325
+ }
326
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative flex flex-col items-center", children: [
327
+ voiceTrigger && !isTranscribing && isPressed && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `absolute bottom-full mb-4 left-0 px-3 py-2 rounded-full text-xs font-semibold whitespace-nowrap shadow-xl transition-all duration-200 z-50 flex items-center gap-2 pointer-events-none transform
328
+ ${isDragging ? "bg-red-500 text-white scale-110" : "bg-white text-red-500 border border-red-100"}`, children: [
329
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `transition-transform duration-300 ${isDragging ? "rotate-180" : ""}`, children: isDragging ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.XMarkIcon, { className: "w-4 h-4" }) : "\u2191" }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: isDragging ? "Release to Cancel" : "Drag here to cancel" }),
331
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `absolute top-full left-4 -translate-x-1/2 border-8 border-transparent transition-colors duration-200
332
+ ${isDragging ? "border-t-red-500" : "border-t-white"}` })
333
+ ] }),
334
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
335
+ "button",
336
+ {
337
+ type: "button",
338
+ ...handlers,
339
+ className: `mb-1 p-2 rounded-full transition-all duration-300 flex-shrink-0 border touch-none select-none ${btnClass}`,
340
+ disabled: isTranscribing,
341
+ title: isTranscribing ? "Transcribing..." : isDragging ? "Release to Cancel" : voiceTrigger ? "Stop Recording" : "Start Voice Input",
342
+ children: icon
343
+ }
344
+ )
345
+ ] });
346
+ };
347
+
348
+ // src/ui/react/hooks/useAudioRecorder.ts
349
+ var import_react3 = require("react");
197
350
  var useAudioRecorder = (onStop) => {
198
- const [isRecording, setIsRecording] = (0, import_react2.useState)(false);
199
- const [isSimulated, setIsSimulated] = (0, import_react2.useState)(false);
200
- const [blob, setBlob] = (0, import_react2.useState)(null);
201
- const [error, setError] = (0, import_react2.useState)(null);
202
- const mediaRecorderRef = (0, import_react2.useRef)(null);
203
- const chunksRef = (0, import_react2.useRef)([]);
204
- const start = (0, import_react2.useCallback)(async () => {
351
+ const [isRecording, setIsRecording] = (0, import_react3.useState)(false);
352
+ const [isSimulated, setIsSimulated] = (0, import_react3.useState)(false);
353
+ const [blob, setBlob] = (0, import_react3.useState)(null);
354
+ const [error, setError] = (0, import_react3.useState)(null);
355
+ const mediaRecorderRef = (0, import_react3.useRef)(null);
356
+ const chunksRef = (0, import_react3.useRef)([]);
357
+ const cancelledRef = (0, import_react3.useRef)(false);
358
+ const start = (0, import_react3.useCallback)(async () => {
359
+ cancelledRef.current = false;
205
360
  try {
206
361
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
207
362
  if (process.env.NODE_ENV === "development") {
@@ -228,6 +383,14 @@ var useAudioRecorder = (onStop) => {
228
383
  }
229
384
  };
230
385
  mediaRecorder.onstop = () => {
386
+ if (cancelledRef.current) {
387
+ console.log("[useAudioRecorder] Recording cancelled, discarding data.");
388
+ setIsRecording(false);
389
+ stream.getTracks().forEach((track) => {
390
+ track.stop();
391
+ });
392
+ return;
393
+ }
231
394
  const audioBlob = new Blob(chunksRef.current, { type: "audio/webm" });
232
395
  setBlob(audioBlob);
233
396
  setIsRecording(false);
@@ -244,7 +407,7 @@ var useAudioRecorder = (onStop) => {
244
407
  setError(e.message || "Microphone access denied");
245
408
  }
246
409
  }, [onStop]);
247
- const stop = (0, import_react2.useCallback)(() => {
410
+ const stop = (0, import_react3.useCallback)(() => {
248
411
  if (isSimulated) {
249
412
  setIsRecording(false);
250
413
  setIsSimulated(false);
@@ -257,20 +420,32 @@ var useAudioRecorder = (onStop) => {
257
420
  mediaRecorderRef.current.stop();
258
421
  }
259
422
  }, [isSimulated, onStop]);
423
+ const cancel = (0, import_react3.useCallback)(() => {
424
+ cancelledRef.current = true;
425
+ if (isSimulated) {
426
+ setIsRecording(false);
427
+ setIsSimulated(false);
428
+ return;
429
+ }
430
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
431
+ mediaRecorderRef.current.stop();
432
+ }
433
+ }, [isSimulated]);
260
434
  return {
261
435
  isRecording,
262
436
  isSimulated,
263
437
  start,
264
438
  stop,
439
+ cancel,
265
440
  blob,
266
441
  error
267
442
  };
268
443
  };
269
444
 
270
445
  // src/ui/react/hooks/useProactiveResize.ts
271
- var import_react3 = require("react");
446
+ var import_react4 = require("react");
272
447
  function useProactiveResize(textareaRef, measurementRef, value, disabled) {
273
- (0, import_react3.useEffect)(() => {
448
+ (0, import_react4.useEffect)(() => {
274
449
  if (!textareaRef.current || !measurementRef.current) return;
275
450
  const styles = window.getComputedStyle(textareaRef.current);
276
451
  measurementRef.current.style.width = styles.width;
@@ -289,8 +464,8 @@ function useProactiveResize(textareaRef, measurementRef, value, disabled) {
289
464
  }
290
465
 
291
466
  // src/ui/react/components/ChatInputArea.tsx
292
- var import_jsx_runtime5 = require("react/jsx-runtime");
293
- var ChatInputArea = (0, import_react4.forwardRef)(({
467
+ var import_jsx_runtime6 = require("react/jsx-runtime");
468
+ var ChatInputArea = (0, import_react5.forwardRef)(({
294
469
  onSubmit,
295
470
  isSending,
296
471
  showInputForm,
@@ -306,15 +481,15 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
306
481
  defaultInputMode = "text"
307
482
  }, ref) => {
308
483
  var _a, _b, _c, _d;
309
- const [internalMessage, setInternalMessage] = (0, import_react4.useState)("");
310
- const [voiceTrigger, setVoiceTrigger] = (0, import_react4.useState)(null);
311
- const [isTranscribing, setIsTranscribing] = (0, import_react4.useState)(false);
312
- const [voiceError, setVoiceError] = (0, import_react4.useState)(null);
313
- const [isFocused, setIsFocused] = (0, import_react4.useState)(false);
314
- const [showDebug, setShowDebug] = (0, import_react4.useState)(false);
315
- const [logs, setLogs] = (0, import_react4.useState)([]);
316
- const tapCountRef = (0, import_react4.useRef)({ count: 0, lastTap: 0 });
317
- (0, import_react4.useEffect)(() => {
484
+ const [internalMessage, setInternalMessage] = (0, import_react5.useState)("");
485
+ const [voiceTrigger, setVoiceTrigger] = (0, import_react5.useState)(null);
486
+ const [isTranscribing, setIsTranscribing] = (0, import_react5.useState)(false);
487
+ const [voiceError, setVoiceError] = (0, import_react5.useState)(null);
488
+ const [isFocused, setIsFocused] = (0, import_react5.useState)(false);
489
+ const [showDebug, setShowDebug] = (0, import_react5.useState)(false);
490
+ const [logs, setLogs] = (0, import_react5.useState)([]);
491
+ const tapCountRef = (0, import_react5.useRef)({ count: 0, lastTap: 0 });
492
+ (0, import_react5.useEffect)(() => {
318
493
  const originalLog = console.log;
319
494
  const originalWarn = console.warn;
320
495
  const originalError = console.error;
@@ -347,17 +522,17 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
347
522
  console.error = originalError;
348
523
  };
349
524
  }, []);
350
- const copyLogs = (0, import_react4.useCallback)(() => {
525
+ const copyLogs = (0, import_react5.useCallback)(() => {
351
526
  navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
352
527
  }, [logs]);
353
- const textareaRef = (0, import_react4.useRef)(null);
354
- const measurementRef = (0, import_react4.useRef)(null);
355
- const pendingSelectionRef = (0, import_react4.useRef)(null);
528
+ const textareaRef = (0, import_react5.useRef)(null);
529
+ const measurementRef = (0, import_react5.useRef)(null);
530
+ const pendingSelectionRef = (0, import_react5.useRef)(null);
356
531
  const isControlled = value !== void 0;
357
532
  const message = isControlled ? value : internalMessage;
358
- const messageRef = (0, import_react4.useRef)(message);
533
+ const messageRef = (0, import_react5.useRef)(message);
359
534
  messageRef.current = message;
360
- (0, import_react4.useLayoutEffect)(() => {
535
+ (0, import_react5.useLayoutEffect)(() => {
361
536
  if (pendingSelectionRef.current && textareaRef.current) {
362
537
  const { start, end } = pendingSelectionRef.current;
363
538
  textareaRef.current.focus();
@@ -365,18 +540,18 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
365
540
  pendingSelectionRef.current = null;
366
541
  }
367
542
  }, [message]);
368
- const onChangeRef = (0, import_react4.useRef)(onChange);
369
- (0, import_react4.useEffect)(() => {
543
+ const onChangeRef = (0, import_react5.useRef)(onChange);
544
+ (0, import_react5.useEffect)(() => {
370
545
  onChangeRef.current = onChange;
371
546
  }, [onChange]);
372
547
  const { voice: globalVoice } = useChatConfig();
373
548
  const isVoiceEnabled = (_a = globalVoice == null ? void 0 : globalVoice.enabled) != null ? _a : !!propVoiceConfig;
374
549
  const voiceConfig = isVoiceEnabled ? propVoiceConfig || (globalVoice == null ? void 0 : globalVoice.config) : void 0;
375
- const voiceConfigRef = (0, import_react4.useRef)(voiceConfig);
376
- (0, import_react4.useEffect)(() => {
550
+ const voiceConfigRef = (0, import_react5.useRef)(voiceConfig);
551
+ (0, import_react5.useEffect)(() => {
377
552
  voiceConfigRef.current = voiceConfig;
378
553
  }, [voiceConfig]);
379
- const triggerChange = (0, import_react4.useCallback)((newValue) => {
554
+ const triggerChange = (0, import_react5.useCallback)((newValue) => {
380
555
  setVoiceError(null);
381
556
  if (isControlled && onChangeRef.current) {
382
557
  const syntheticEvent = {
@@ -390,7 +565,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
390
565
  }, [isControlled]);
391
566
  const isInputDisabled = (currentTask == null ? void 0 : currentTask.complete) || (lastInteractiveMessage == null ? void 0 : lastInteractiveMessage.interactive) && (((_b = lastInteractiveMessage == null ? void 0 : lastInteractiveMessage.interactiveData) == null ? void 0 : _b.function) === "form" && !(lastInteractiveMessage == null ? void 0 : lastInteractiveMessage.isResponseSubmitted) || ((_c = lastInteractiveMessage == null ? void 0 : lastInteractiveMessage.interactiveData) == null ? void 0 : _c.function) === "confirm" && !(lastInteractiveMessage == null ? void 0 : lastInteractiveMessage.isResponseSubmitted));
392
567
  useProactiveResize(textareaRef, measurementRef, message, isInputDisabled || !!voiceTrigger);
393
- const insertTextAtCursor = (0, import_react4.useCallback)((text) => {
568
+ const insertTextAtCursor = (0, import_react5.useCallback)((text) => {
394
569
  const textarea = textareaRef.current;
395
570
  const currentVal = messageRef.current || "";
396
571
  if (!textarea) {
@@ -408,12 +583,12 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
408
583
  pendingSelectionRef.current = { start: selectionStart, end: selectionEnd };
409
584
  triggerChange(newText);
410
585
  }, [triggerChange]);
411
- const handleVoiceResult = (0, import_react4.useCallback)((text, isFinal) => {
586
+ const handleVoiceResult = (0, import_react5.useCallback)((text, isFinal) => {
412
587
  if (isFinal) {
413
588
  insertTextAtCursor(text);
414
589
  }
415
590
  }, [insertTextAtCursor]);
416
- const handleVoiceEnd = (0, import_react4.useCallback)(() => {
591
+ const handleVoiceEnd = (0, import_react5.useCallback)(() => {
417
592
  var _a2, _b2;
418
593
  setVoiceTrigger(null);
419
594
  (_b2 = (_a2 = voiceConfigRef.current) == null ? void 0 : _a2.onVoiceEnd) == null ? void 0 : _b2.call(_a2);
@@ -445,7 +620,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
445
620
  setIsTranscribing(false);
446
621
  }
447
622
  });
448
- (0, import_react4.useImperativeHandle)(ref, () => ({
623
+ (0, import_react5.useImperativeHandle)(ref, () => ({
449
624
  focus: () => {
450
625
  var _a2;
451
626
  (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
@@ -524,62 +699,43 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
524
699
  if (!showInputForm) {
525
700
  return null;
526
701
  }
527
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col w-full relative", children: [
528
- showDebug && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
529
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
530
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Debug Logs" }),
531
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex gap-2", children: [
532
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: copyLogs, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.Square2StackIcon, { className: "w-4 h-4" }) }),
533
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => {
702
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col w-full relative", children: [
703
+ showDebug && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
704
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
705
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Debug Logs" }),
706
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex gap-2", children: [
707
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: copyLogs, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.Square2StackIcon, { className: "w-4 h-4" }) }),
708
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => {
534
709
  copyLogs();
535
710
  setShowDebug(false);
536
- }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.XMarkIcon, { className: "w-4 h-4" }) })
711
+ }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.XMarkIcon, { className: "w-4 h-4" }) })
537
712
  ] })
538
713
  ] }),
539
- logs.map((log, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
540
- logs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: "No logs yet..." })
714
+ logs.map((log, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
715
+ logs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: "No logs yet..." })
541
716
  ] }),
542
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
543
- voiceConfig && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
544
- "button",
717
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2", children: [
718
+ voiceConfig && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
719
+ VoiceInputButton,
545
720
  {
546
- type: "button",
547
- onClick: () => {
548
- const now = Date.now();
549
- if (now - tapCountRef.current.lastTap < 500) {
550
- tapCountRef.current.count++;
551
- } else {
552
- tapCountRef.current.count = 1;
553
- }
554
- tapCountRef.current.lastTap = now;
555
- if (tapCountRef.current.count >= 5) {
556
- setShowDebug((prev) => !prev);
557
- tapCountRef.current.count = 0;
558
- stopRecording();
559
- return;
560
- }
561
- if (voiceTrigger) {
562
- stopRecording();
563
- } else if (!isTranscribing) {
564
- startRecording("click");
565
- }
566
- },
567
- className: `mb-1 p-2 rounded-full transition-all duration-300 flex-shrink-0 border ${isTranscribing ? "text-white border-indigo-500 bg-indigo-600 scale-110 shadow-lg" : voiceTrigger ? "text-white border-orange-400 bg-orange-500 scale-110 shadow-lg" : "text-gray-500 border-gray-300 bg-white hover:text-gray-700 hover:bg-gray-100"} ${voiceTrigger ? "animate-pulse" : ""} ${isTranscribing ? "cursor-wait" : ""}`,
568
- disabled: isTranscribing,
569
- title: isTranscribing ? "Transcribing..." : voiceTrigger ? "Stop Recording" : "Start Voice Input",
570
- children: isTranscribing ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "animate-spin w-5 h-5 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { className: "w-5 h-5 text-white", viewBox: "0 0 24 24", children: [
571
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
572
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
573
- ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.MicrophoneIcon, { className: "w-5 h-5" })
721
+ voiceConfig,
722
+ voiceTrigger,
723
+ isTranscribing,
724
+ setVoiceTrigger,
725
+ setShowDebug,
726
+ tapCountRef,
727
+ customRecorder,
728
+ startRecording,
729
+ stopRecording
574
730
  }
575
731
  ),
576
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
732
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
577
733
  "div",
578
734
  {
579
735
  tabIndex: -1,
580
736
  className: `flex-1 flex items-center border border-gray-300 rounded-lg overflow-hidden outline-none bg-white min-h-[42px] mb-1 transition-all ${voiceTrigger ? "ring-2 ring-orange-100 border-orange-300" : "focus-within:ring-2 focus-within:ring-blue-500 focus-within:border-blue-500"}`,
581
737
  children: [
582
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
738
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
583
739
  "span",
584
740
  {
585
741
  ref: measurementRef,
@@ -587,7 +743,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
587
743
  style: { fontSize: "1rem" }
588
744
  }
589
745
  ),
590
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
746
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
591
747
  "textarea",
592
748
  {
593
749
  ref: textareaRef,
@@ -612,8 +768,8 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
612
768
  className: `flex-grow px-4 py-2 outline-none text-gray-700 placeholder-gray-500 resize-none leading-6 w-full ${isInputDisabled ? "bg-gray-100 cursor-not-allowed" : "bg-transparent"} ${voiceTrigger || isTranscribing ? "cursor-default" : ""}`
613
769
  }
614
770
  ),
615
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative mx-2 flex-shrink-0", children: [
616
- isSending && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "absolute -inset-1", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
771
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative mx-2 flex-shrink-0", children: [
772
+ isSending && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "absolute -inset-1", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
617
773
  "svg",
618
774
  {
619
775
  className: "animate-spin h-full w-full text-blue-500 opacity-75",
@@ -621,7 +777,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
621
777
  fill: "none",
622
778
  viewBox: "0 0 24 24",
623
779
  children: [
624
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
780
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
625
781
  "circle",
626
782
  {
627
783
  className: "opacity-25",
@@ -632,7 +788,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
632
788
  strokeWidth: "4"
633
789
  }
634
790
  ),
635
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
791
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
636
792
  "path",
637
793
  {
638
794
  className: "opacity-75",
@@ -643,7 +799,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
643
799
  ]
644
800
  }
645
801
  ) }),
646
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
802
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
647
803
  "button",
648
804
  {
649
805
  type: "button",
@@ -658,7 +814,7 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
658
814
  disabled: (currentTask == null ? void 0 : currentTask.complete) || isSending && !onStop || isInputDisabled,
659
815
  className: `relative z-10 text-white rounded-full p-2 transition-colors duration-200 disabled:bg-gray-400 disabled:cursor-not-allowed ${isSending && onStop ? "bg-red-500 hover:bg-red-600" : "bg-blue-600 hover:bg-blue-700"}`,
660
816
  title: isSending && onStop ? "Stop generating" : "Send message",
661
- children: isSending ? onStop ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.StopIcon, { className: "h-5 w-5" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-5 h-5" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_outline.PaperAirplaneIcon, { className: "h-5 w-5" })
817
+ children: isSending ? onStop ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.StopIcon, { className: "h-5 w-5" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w-5 h-5" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.PaperAirplaneIcon, { className: "h-5 w-5" })
662
818
  }
663
819
  )
664
820
  ] })
@@ -666,19 +822,19 @@ var ChatInputArea = (0, import_react4.forwardRef)(({
666
822
  }
667
823
  )
668
824
  ] }),
669
- inputHint && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-sm text-red-500 bg-red-50 py-1 px-4 rounded-lg mt-1", children: inputHint }),
670
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ml-[46px] mb-2 mt-0.5 min-h-[0.75rem]", style: { marginLeft: "48px" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: `text-[10px] leading-tight transition-all duration-200 ${voiceError ? "text-red-500" : isTranscribing ? "text-indigo-600 font-bold" : voiceTrigger ? "text-orange-600 font-medium" : "text-gray-400"}`, children: voiceError ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex items-center gap-1 font-semibold italic", children: [
825
+ inputHint && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-sm text-red-500 bg-red-50 py-1 px-4 rounded-lg mt-1", children: inputHint }),
826
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ml-[46px] mb-2 mt-0.5 min-h-[0.75rem]", style: { marginLeft: "48px" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: `text-[10px] leading-tight transition-all duration-200 ${voiceError ? "text-red-500" : isTranscribing ? "text-indigo-600 font-bold" : voiceTrigger ? "text-orange-600 font-medium" : "text-gray-400"}`, children: voiceError ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "flex items-center gap-1 font-semibold italic", children: [
671
827
  "Error: ",
672
828
  voiceError
673
- ] }) : isTranscribing ? "Transcribing... please wait" : voiceTrigger ? "Transcribing, please wait..." : voiceTrigger ? "Listening... tap mic icon again to stop" : hintText || (voiceConfig ? "Type in text or tap mic icon to talk" : "Type your message...") }) })
829
+ ] }) : isTranscribing ? "Transcribing... please wait" : voiceTrigger ? "Listening... Tap again to stop" : hintText || (voiceConfig ? "Type in text or tap mic icon to talk" : "Type your message...") }) })
674
830
  ] });
675
831
  });
676
832
  ChatInputArea.displayName = "ChatInputArea";
677
833
 
678
834
  // src/ui/react/components/TapToTalk.tsx
679
- var import_react5 = __toESM(require("react"), 1);
680
- var import_outline2 = require("@heroicons/react/24/outline");
681
- var import_jsx_runtime6 = require("react/jsx-runtime");
835
+ var import_react6 = __toESM(require("react"), 1);
836
+ var import_outline3 = require("@heroicons/react/24/outline");
837
+ var import_jsx_runtime7 = require("react/jsx-runtime");
682
838
  var TapToTalk = ({
683
839
  onResult,
684
840
  voiceConfig: propVoiceConfig,
@@ -691,13 +847,13 @@ var TapToTalk = ({
691
847
  var _a;
692
848
  const globalConfig = useChatConfig();
693
849
  const voiceConfig = propVoiceConfig || ((_a = globalConfig.voice) == null ? void 0 : _a.config);
694
- const [isTranscribing, setIsTranscribing] = (0, import_react5.useState)(false);
695
- const [voiceTrigger, setVoiceTrigger] = (0, import_react5.useState)(null);
696
- const [errorMsg, setErrorMsg] = (0, import_react5.useState)(null);
697
- const [showDebug, setShowDebug] = (0, import_react5.useState)(false);
698
- const [logs, setLogs] = (0, import_react5.useState)([]);
699
- const tapCountRef = (0, import_react5.useRef)({ count: 0, lastTap: 0 });
700
- import_react5.default.useEffect(() => {
850
+ const [isTranscribing, setIsTranscribing] = (0, import_react6.useState)(false);
851
+ const [voiceTrigger, setVoiceTrigger] = (0, import_react6.useState)(null);
852
+ const [errorMsg, setErrorMsg] = (0, import_react6.useState)(null);
853
+ const [showDebug, setShowDebug] = (0, import_react6.useState)(false);
854
+ const [logs, setLogs] = (0, import_react6.useState)([]);
855
+ const tapCountRef = (0, import_react6.useRef)({ count: 0, lastTap: 0 });
856
+ import_react6.default.useEffect(() => {
701
857
  const originalLog = console.log;
702
858
  const originalWarn = console.warn;
703
859
  const originalError = console.error;
@@ -730,13 +886,14 @@ var TapToTalk = ({
730
886
  console.error = originalError;
731
887
  };
732
888
  }, []);
733
- const copyLogs = (0, import_react5.useCallback)(() => {
889
+ const copyLogs = (0, import_react6.useCallback)(() => {
734
890
  navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
735
891
  }, [logs]);
736
- const handleVoiceEnd = (0, import_react5.useCallback)(() => {
892
+ const handleVoiceEnd = (0, import_react6.useCallback)(() => {
737
893
  setVoiceTrigger(null);
738
894
  }, []);
739
895
  const customRecorder = useAudioRecorder(async (blob) => {
896
+ var _a2;
740
897
  setVoiceTrigger(null);
741
898
  setIsTranscribing(true);
742
899
  setErrorMsg(null);
@@ -760,11 +917,13 @@ var TapToTalk = ({
760
917
  } else {
761
918
  setIsTranscribing(false);
762
919
  }
920
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
763
921
  });
764
922
  const isListening = !!voiceTrigger || customRecorder.isRecording;
765
923
  const isActive = isListening || isTranscribing;
766
- const processingRef = (0, import_react5.useRef)(false);
924
+ const processingRef = (0, import_react6.useRef)(false);
767
925
  const toggleVoice = async () => {
926
+ var _a2, _b, _c;
768
927
  if (processingRef.current) {
769
928
  console.log("[TapToTalk] toggleVoice ignored - processing");
770
929
  return;
@@ -797,17 +956,20 @@ var TapToTalk = ({
797
956
  console.log("[TapToTalk] Stopping voice...");
798
957
  customRecorder.stop();
799
958
  setVoiceTrigger(null);
959
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
800
960
  } else {
801
961
  console.log("[TapToTalk] Starting voice...");
802
962
  setErrorMsg(null);
803
963
  onFocusTarget == null ? void 0 : onFocusTarget();
804
964
  setVoiceTrigger("click");
965
+ (_b = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _b.call(voiceConfig);
805
966
  try {
806
967
  await customRecorder.start();
807
968
  } catch (e) {
808
969
  console.error("[TapToTalk] Custom recorder failed:", e);
809
970
  setErrorMsg("Mic access denied");
810
971
  setVoiceTrigger(null);
972
+ (_c = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _c.call(voiceConfig);
811
973
  }
812
974
  }
813
975
  } finally {
@@ -816,54 +978,75 @@ var TapToTalk = ({
816
978
  }, 300);
817
979
  }
818
980
  };
981
+ const { handlers, isDragging, isPressed } = useDragCancel({
982
+ isListening: !!voiceTrigger,
983
+ onCancel: () => {
984
+ var _a2;
985
+ console.log("[TapToTalk] Gesture Cancel");
986
+ customRecorder.cancel();
987
+ setVoiceTrigger(null);
988
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceEnd) == null ? void 0 : _a2.call(voiceConfig);
989
+ },
990
+ onCommit: () => {
991
+ toggleVoice();
992
+ },
993
+ threshold: 30
994
+ });
819
995
  let bgColor = accentColor;
820
996
  let label = "Tap to Talk";
821
- let Icon = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.MicrophoneIcon, { className: "h-5 w-5" });
997
+ let Icon = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.MicrophoneIcon, { className: "h-5 w-5" });
822
998
  if (isListening) {
823
999
  bgColor = "bg-orange-500";
824
- label = "Listening ... Tap to stop";
825
- Icon = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.MicrophoneIcon, { className: "h-5 w-5 animate-pulse" });
1000
+ label = "Listening... Tap again to stop";
1001
+ Icon = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.MicrophoneIcon, { className: "h-5 w-5 animate-pulse" });
826
1002
  } else if (isTranscribing) {
827
1003
  bgColor = "bg-indigo-600";
828
1004
  label = "Transcribing ...";
829
- Icon = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { className: "animate-spin h-5 w-5 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
830
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
831
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
1005
+ Icon = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { className: "animate-spin h-5 w-5 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
1006
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
1007
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
832
1008
  ] });
833
1009
  }
834
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col w-full relative", children: [
835
- showDebug && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
836
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
837
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Debug Logs" }),
838
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex gap-2", children: [
839
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: (e) => {
1010
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col w-full relative items-center", children: [
1011
+ isListening && !isTranscribing && isPressed && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `absolute bottom-full mb-6 left-1/2 -translate-x-1/2 px-4 py-2 rounded-full text-sm font-semibold whitespace-nowrap shadow-xl transition-all duration-200 z-50 flex items-center gap-2 pointer-events-none transform
1012
+ ${isDragging ? "bg-red-500 text-white scale-110" : "bg-white text-red-500 border border-red-100"}`, children: [
1013
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `transition-transform duration-300 ${isDragging ? "rotate-180" : ""}`, children: isDragging ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.XMarkIcon, { className: "w-5 h-5" }) : "\u2191" }),
1014
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: isDragging ? "Release to Cancel" : "Drag here to cancel" }),
1015
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `absolute top-full left-1/2 -translate-x-1/2 border-8 border-transparent transition-colors duration-200
1016
+ ${isDragging ? "border-t-red-500" : "border-t-white"}` })
1017
+ ] }),
1018
+ showDebug && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
1019
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
1020
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Debug Logs" }),
1021
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex gap-2", children: [
1022
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { onClick: (e) => {
840
1023
  e.stopPropagation();
841
1024
  copyLogs();
842
- }, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.Square2StackIcon, { className: "w-4 h-4" }) }),
843
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: (e) => {
1025
+ }, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.Square2StackIcon, { className: "w-4 h-4" }) }),
1026
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { onClick: (e) => {
844
1027
  e.stopPropagation();
845
1028
  copyLogs();
846
1029
  setShowDebug(false);
847
- }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outline2.XMarkIcon, { className: "w-4 h-4" }) })
1030
+ }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_outline3.XMarkIcon, { className: "w-4 h-4" }) })
848
1031
  ] })
849
1032
  ] }),
850
- logs.map((log, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
851
- logs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: "No logs yet..." })
1033
+ logs.map((log, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
1034
+ logs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: "No logs yet..." })
852
1035
  ] }),
853
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1036
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
854
1037
  "button",
855
1038
  {
856
- onClick: toggleVoice,
1039
+ ...handlers,
857
1040
  disabled: disabled || isTranscribing && !isListening,
858
- className: `flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md active:scale-[0.98]
1041
+ className: `flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md touch-none select-none
859
1042
  ${bgColor} text-white
860
1043
  ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
861
1044
  ${className}`,
862
1045
  title: label,
863
1046
  children: [
864
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
865
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: label }),
866
- errorMsg && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[10px] bg-white/20 px-1.5 py-0.5 rounded text-red-100 animate-in fade-in slide-in-from-right-1", children: errorMsg })
1047
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
1048
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate", children: label }),
1049
+ errorMsg && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-[10px] bg-white/20 px-1.5 py-0.5 rounded text-red-100 animate-in fade-in slide-in-from-right-1", children: errorMsg })
867
1050
  ]
868
1051
  }
869
1052
  )
@@ -871,17 +1054,17 @@ var TapToTalk = ({
871
1054
  };
872
1055
 
873
1056
  // src/ui/react/components/ChatMessageList.tsx
874
- var import_react9 = require("react");
1057
+ var import_react10 = require("react");
875
1058
 
876
1059
  // src/ui/react/components/interactive/ConfirmInteraction.tsx
877
- var import_react6 = require("react");
878
- var import_jsx_runtime7 = require("react/jsx-runtime");
1060
+ var import_react7 = require("react");
1061
+ var import_jsx_runtime8 = require("react/jsx-runtime");
879
1062
  var ConfirmInteraction = ({
880
1063
  parameters,
881
1064
  onResponse,
882
1065
  isResponseSubmitted
883
1066
  }) => {
884
- const [selectedOption, setSelectedOption] = (0, import_react6.useState)(null);
1067
+ const [selectedOption, setSelectedOption] = (0, import_react7.useState)(null);
885
1068
  const params = parameters;
886
1069
  const { yesPrompt, noPrompt } = params;
887
1070
  console.log("[ConfirmInteraction] Parameters:", params);
@@ -890,8 +1073,8 @@ var ConfirmInteraction = ({
890
1073
  setSelectedOption(buttonText);
891
1074
  onResponse(value);
892
1075
  };
893
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex space-x-2", children: [
894
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1076
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mt-2 mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex space-x-2", children: [
1077
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
895
1078
  "button",
896
1079
  {
897
1080
  onClick: () => handleOptionClick(true, yesPrompt),
@@ -900,7 +1083,7 @@ var ConfirmInteraction = ({
900
1083
  children: yesPrompt
901
1084
  }
902
1085
  ),
903
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1086
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
904
1087
  "button",
905
1088
  {
906
1089
  onClick: () => handleOptionClick(false, noPrompt),
@@ -914,19 +1097,19 @@ var ConfirmInteraction = ({
914
1097
  var ConfirmInteraction_default = ConfirmInteraction;
915
1098
 
916
1099
  // src/ui/react/components/interactive/SelectInteraction.tsx
917
- var import_react7 = require("react");
918
- var import_jsx_runtime8 = require("react/jsx-runtime");
1100
+ var import_react8 = require("react");
1101
+ var import_jsx_runtime9 = require("react/jsx-runtime");
919
1102
  var SelectInteraction = ({
920
1103
  parameters,
921
1104
  onResponse,
922
1105
  isResponseSubmitted,
923
1106
  message
924
1107
  }) => {
925
- const [selectedOption, setSelectedOption] = (0, import_react7.useState)(null);
926
- const [customOption, setCustomOption] = (0, import_react7.useState)(null);
1108
+ const [selectedOption, setSelectedOption] = (0, import_react8.useState)(null);
1109
+ const [customOption, setCustomOption] = (0, import_react8.useState)(null);
927
1110
  const params = parameters;
928
1111
  const { question, options, placeholder } = params;
929
- (0, import_react7.useEffect)(() => {
1112
+ (0, import_react8.useEffect)(() => {
930
1113
  if (isResponseSubmitted && (message == null ? void 0 : message.responseValue)) {
931
1114
  const responseValueStr = String(message.responseValue);
932
1115
  setSelectedOption(responseValueStr);
@@ -941,8 +1124,8 @@ var SelectInteraction = ({
941
1124
  setCustomOption(null);
942
1125
  onResponse(option);
943
1126
  };
944
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "mt-2 mb-4", children: [
945
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex flex-wrap gap-2", children: options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1127
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 mb-4", children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-wrap gap-2", children: options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
946
1129
  "button",
947
1130
  {
948
1131
  onClick: () => handleOptionClick(option),
@@ -952,9 +1135,9 @@ var SelectInteraction = ({
952
1135
  },
953
1136
  index
954
1137
  )) }),
955
- customOption && isResponseSubmitted && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded", children: [
1138
+ customOption && isResponseSubmitted && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 text-sm text-amber-600 bg-amber-50 p-2 rounded", children: [
956
1139
  "User provided custom option: ",
957
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "font-semibold", children: [
1140
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "font-semibold", children: [
958
1141
  '"',
959
1142
  customOption,
960
1143
  '"'
@@ -965,20 +1148,20 @@ var SelectInteraction = ({
965
1148
  var SelectInteraction_default = SelectInteraction;
966
1149
 
967
1150
  // src/ui/react/components/interactive/FormInteraction.tsx
968
- var import_react8 = require("react");
1151
+ var import_react9 = require("react");
969
1152
  var import_lucide_react = require("lucide-react");
970
- var import_jsx_runtime9 = require("react/jsx-runtime");
1153
+ var import_jsx_runtime10 = require("react/jsx-runtime");
971
1154
  var FormInteraction = ({
972
1155
  parameters,
973
1156
  onResponse,
974
1157
  isResponseSubmitted,
975
1158
  submittedValues
976
1159
  }) => {
977
- const [isModalOpen, setIsModalOpen] = (0, import_react8.useState)(false);
978
- const [formValues, setFormValues] = (0, import_react8.useState)({});
979
- const [isExpanded, setIsExpanded] = (0, import_react8.useState)(false);
980
- const [parsedFields, setParsedFields] = (0, import_react8.useState)([]);
981
- const formButtonsRef = (0, import_react8.useRef)(null);
1160
+ const [isModalOpen, setIsModalOpen] = (0, import_react9.useState)(false);
1161
+ const [formValues, setFormValues] = (0, import_react9.useState)({});
1162
+ const [isExpanded, setIsExpanded] = (0, import_react9.useState)(false);
1163
+ const [parsedFields, setParsedFields] = (0, import_react9.useState)([]);
1164
+ const formButtonsRef = (0, import_react9.useRef)(null);
982
1165
  const parseParameters = () => {
983
1166
  const { prompt, description, submitText = "Submit", cancelText = "Cancel" } = parameters;
984
1167
  let fieldsArray = [];
@@ -1039,7 +1222,7 @@ var FormInteraction = ({
1039
1222
  };
1040
1223
  };
1041
1224
  const params = parseParameters();
1042
- (0, import_react8.useEffect)(() => {
1225
+ (0, import_react9.useEffect)(() => {
1043
1226
  const processedParams = parseParameters();
1044
1227
  setParsedFields(processedParams.fields);
1045
1228
  const initialValues = {};
@@ -1057,7 +1240,7 @@ var FormInteraction = ({
1057
1240
  setIsModalOpen(true);
1058
1241
  }
1059
1242
  }, [parameters, isResponseSubmitted]);
1060
- (0, import_react8.useEffect)(() => {
1243
+ (0, import_react9.useEffect)(() => {
1061
1244
  if (isModalOpen && formButtonsRef.current) {
1062
1245
  setTimeout(() => {
1063
1246
  var _a;
@@ -1087,12 +1270,12 @@ var FormInteraction = ({
1087
1270
  case "email":
1088
1271
  case "number":
1089
1272
  case "password":
1090
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-4 flex items-center space-x-4", children: [
1091
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1273
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-4 flex items-center space-x-4", children: [
1274
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1092
1275
  label,
1093
- required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-red-500", children: "*" })
1276
+ required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
1094
1277
  ] }),
1095
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1278
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1096
1279
  "input",
1097
1280
  {
1098
1281
  type: type === "string" ? "text" : type,
@@ -1108,12 +1291,12 @@ var FormInteraction = ({
1108
1291
  )
1109
1292
  ] }, name);
1110
1293
  case "textarea":
1111
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-4 flex items-start space-x-4", children: [
1112
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1294
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-4 flex items-start space-x-4", children: [
1295
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1113
1296
  label,
1114
- required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-red-500", children: "*" })
1297
+ required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
1115
1298
  ] }),
1116
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1299
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1117
1300
  "textarea",
1118
1301
  {
1119
1302
  id: name,
@@ -1129,12 +1312,12 @@ var FormInteraction = ({
1129
1312
  )
1130
1313
  ] }, name);
1131
1314
  case "select":
1132
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-4 flex items-center space-x-4", children: [
1133
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1315
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-4 flex items-center space-x-4", children: [
1316
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { htmlFor: name, className: "text-sm font-medium text-gray-700 min-w-[120px]", children: [
1134
1317
  label,
1135
- required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-red-500", children: "*" })
1318
+ required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
1136
1319
  ] }),
1137
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1320
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1138
1321
  "select",
1139
1322
  {
1140
1323
  id: name,
@@ -1145,17 +1328,17 @@ var FormInteraction = ({
1145
1328
  disabled: isResponseSubmitted,
1146
1329
  className: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",
1147
1330
  children: [
1148
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: true, children: placeholder || "Select an option" }),
1149
- options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: option, children: option }, index))
1331
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", disabled: true, children: placeholder || "Select an option" }),
1332
+ options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: option, children: option }, index))
1150
1333
  ]
1151
1334
  }
1152
1335
  )
1153
1336
  ] }, name);
1154
1337
  case "checkbox":
1155
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-4 flex items-center space-x-4", children: [
1156
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "min-w-[120px]" }),
1157
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center", children: [
1158
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1338
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-4 flex items-center space-x-4", children: [
1339
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "min-w-[120px]" }),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center", children: [
1341
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1159
1342
  "input",
1160
1343
  {
1161
1344
  type: "checkbox",
@@ -1168,20 +1351,20 @@ var FormInteraction = ({
1168
1351
  className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
1169
1352
  }
1170
1353
  ),
1171
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { htmlFor: name, className: "ml-2 text-sm text-gray-700", children: [
1354
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { htmlFor: name, className: "ml-2 text-sm text-gray-700", children: [
1172
1355
  label,
1173
- required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-red-500", children: "*" })
1356
+ required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
1174
1357
  ] })
1175
1358
  ] })
1176
1359
  ] }, name);
1177
1360
  case "radio":
1178
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-4 flex space-x-4", children: [
1179
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1361
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-4 flex space-x-4", children: [
1362
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "text-sm font-medium text-gray-700 min-w-[120px] pt-2", children: [
1180
1363
  label,
1181
- required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-red-500", children: "*" })
1364
+ required && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-red-500", children: "*" })
1182
1365
  ] }),
1183
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex-1 space-y-2", children: options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center", children: [
1184
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1366
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-1 space-y-2", children: options == null ? void 0 : options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center", children: [
1367
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1185
1368
  "input",
1186
1369
  {
1187
1370
  id: `${name}-${index}`,
@@ -1195,7 +1378,7 @@ var FormInteraction = ({
1195
1378
  className: "h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500"
1196
1379
  }
1197
1380
  ),
1198
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { htmlFor: `${name}-${index}`, className: "ml-2 text-sm text-gray-700", children: option })
1381
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `${name}-${index}`, className: "ml-2 text-sm text-gray-700", children: option })
1199
1382
  ] }, index)) })
1200
1383
  ] }, name);
1201
1384
  default:
@@ -1203,27 +1386,27 @@ var FormInteraction = ({
1203
1386
  }
1204
1387
  };
1205
1388
  if (isResponseSubmitted) {
1206
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 bg-gray-50 p-3 rounded-md border border-gray-200", children: [
1207
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-between items-center cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
1208
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "font-medium text-gray-700", children: [
1389
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mt-2 bg-gray-50 p-3 rounded-md border border-gray-200", children: [
1390
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between items-center cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
1391
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-medium text-gray-700", children: [
1209
1392
  isExpanded ? "Hide" : "Show",
1210
1393
  " Form Responses"
1211
1394
  ] }),
1212
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react.ChevronUpIcon, { className: "h-5 w-5 text-gray-500" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react.ChevronDownIcon, { className: "h-5 w-5 text-gray-500" })
1395
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react.ChevronUpIcon, { className: "h-5 w-5 text-gray-500" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react.ChevronDownIcon, { className: "h-5 w-5 text-gray-500" })
1213
1396
  ] }),
1214
- isExpanded && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-2 space-y-2", children: parsedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex", children: [
1215
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "text-sm font-medium text-gray-600 mr-2", children: [
1397
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-2 space-y-2", children: parsedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex", children: [
1398
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-sm font-medium text-gray-600 mr-2", children: [
1216
1399
  field.label,
1217
1400
  ":"
1218
1401
  ] }),
1219
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm text-gray-800", children: typeof (submittedValues == null ? void 0 : submittedValues[field.name]) === "boolean" ? submittedValues[field.name] ? "Yes" : "No" : (submittedValues == null ? void 0 : submittedValues[field.name]) || "Not provided" })
1402
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm text-gray-800", children: typeof (submittedValues == null ? void 0 : submittedValues[field.name]) === "boolean" ? submittedValues[field.name] ? "Yes" : "No" : (submittedValues == null ? void 0 : submittedValues[field.name]) || "Not provided" })
1220
1403
  ] }, field.name)) })
1221
1404
  ] });
1222
1405
  }
1223
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-2", children: isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: handleSubmit, className: "mt-4", children: [
1406
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-2", children: isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: handleSubmit, className: "mt-4", children: [
1224
1407
  parsedFields.map((field) => renderField(field)),
1225
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref: formButtonsRef, className: "flex justify-end mt-4 space-x-2", children: [
1226
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1408
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref: formButtonsRef, className: "flex justify-end mt-4 space-x-2", children: [
1409
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1227
1410
  "button",
1228
1411
  {
1229
1412
  type: "button",
@@ -1233,7 +1416,7 @@ var FormInteraction = ({
1233
1416
  children: params.cancelText
1234
1417
  }
1235
1418
  ),
1236
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1419
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1237
1420
  "button",
1238
1421
  {
1239
1422
  type: "submit",
@@ -1248,12 +1431,12 @@ var FormInteraction = ({
1248
1431
  var FormInteraction_default = FormInteraction;
1249
1432
 
1250
1433
  // src/ui/react/components/interactive/PresentInteraction.tsx
1251
- var import_jsx_runtime10 = require("react/jsx-runtime");
1434
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1252
1435
  var ReactMarkdown2;
1253
1436
  try {
1254
1437
  ReactMarkdown2 = require("react-markdown");
1255
1438
  } catch (error) {
1256
- ReactMarkdown2 = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "whitespace-pre-wrap", children });
1439
+ ReactMarkdown2 = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "whitespace-pre-wrap", children });
1257
1440
  }
1258
1441
  var PresentInteraction = ({
1259
1442
  parameters
@@ -1291,15 +1474,15 @@ var PresentInteraction = ({
1291
1474
  }
1292
1475
  };
1293
1476
  const styles = getLevelStyles();
1294
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `mt-2 mb-4 p-4 ${styles.container} border rounded-md`, children: [
1295
- title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `font-medium ${styles.title} mb-2`, children: title }),
1296
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `text-sm ${styles.content}`, children: format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ReactMarkdown2, { className: "prose prose-sm max-w-none", children: content }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { dangerouslySetInnerHTML: { __html: content } }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "whitespace-pre-wrap", children: content }) })
1477
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `mt-2 mb-4 p-4 ${styles.container} border rounded-md`, children: [
1478
+ title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `font-medium ${styles.title} mb-2`, children: title }),
1479
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `text-sm ${styles.content}`, children: format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ReactMarkdown2, { className: "prose prose-sm max-w-none", children: content }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { dangerouslySetInnerHTML: { __html: content } }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "whitespace-pre-wrap", children: content }) })
1297
1480
  ] });
1298
1481
  };
1299
1482
  var PresentInteraction_default = PresentInteraction;
1300
1483
 
1301
1484
  // src/ui/react/components/interactive/InteractiveMessageHandler.tsx
1302
- var import_jsx_runtime11 = require("react/jsx-runtime");
1485
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1303
1486
  var InteractiveMessageHandler = ({
1304
1487
  message,
1305
1488
  onResponse,
@@ -1310,7 +1493,7 @@ var InteractiveMessageHandler = ({
1310
1493
  const submittedResponse = parentMessage == null ? void 0 : parentMessage.responseValue;
1311
1494
  switch (functionType) {
1312
1495
  case "confirm":
1313
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1496
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1314
1497
  ConfirmInteraction_default,
1315
1498
  {
1316
1499
  parameters,
@@ -1319,7 +1502,7 @@ var InteractiveMessageHandler = ({
1319
1502
  }
1320
1503
  );
1321
1504
  case "select":
1322
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1505
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1323
1506
  SelectInteraction_default,
1324
1507
  {
1325
1508
  parameters,
@@ -1329,7 +1512,7 @@ var InteractiveMessageHandler = ({
1329
1512
  }
1330
1513
  );
1331
1514
  case "form":
1332
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1515
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1333
1516
  FormInteraction_default,
1334
1517
  {
1335
1518
  parameters,
@@ -1339,7 +1522,7 @@ var InteractiveMessageHandler = ({
1339
1522
  }
1340
1523
  );
1341
1524
  case "present":
1342
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1525
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1343
1526
  PresentInteraction_default,
1344
1527
  {
1345
1528
  parameters
@@ -1355,8 +1538,8 @@ var InteractiveMessageHandler = ({
1355
1538
  var InteractiveMessageHandler_default = InteractiveMessageHandler;
1356
1539
 
1357
1540
  // src/ui/react/components/ChatMessageList.tsx
1358
- var import_outline3 = require("@heroicons/react/24/outline");
1359
- var import_jsx_runtime12 = require("react/jsx-runtime");
1541
+ var import_outline4 = require("@heroicons/react/24/outline");
1542
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1360
1543
  var ChatMessageList = ({
1361
1544
  chatHistory,
1362
1545
  isProcessing,
@@ -1365,10 +1548,10 @@ var ChatMessageList = ({
1365
1548
  getContextExample,
1366
1549
  onInteractiveResponse
1367
1550
  }) => {
1368
- const chatContainerRef = (0, import_react9.useRef)(null);
1369
- const lastMessageRef = (0, import_react9.useRef)(null);
1370
- const processingIndicatorRef = (0, import_react9.useRef)(null);
1371
- (0, import_react9.useEffect)(() => {
1551
+ const chatContainerRef = (0, import_react10.useRef)(null);
1552
+ const lastMessageRef = (0, import_react10.useRef)(null);
1553
+ const processingIndicatorRef = (0, import_react10.useRef)(null);
1554
+ (0, import_react10.useEffect)(() => {
1372
1555
  if (isProcessing && processingIndicatorRef.current) {
1373
1556
  processingIndicatorRef.current.scrollIntoView({ behavior: "smooth" });
1374
1557
  return;
@@ -1384,15 +1567,15 @@ var ChatMessageList = ({
1384
1567
  onInteractiveResponse(messageId, response);
1385
1568
  }
1386
1569
  };
1387
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1570
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1388
1571
  "div",
1389
1572
  {
1390
1573
  ref: chatContainerRef,
1391
1574
  className: "flex-1 overflow-y-auto p-4 space-y-8 bg-gray-50",
1392
1575
  children: [
1393
- chatHistory.length === 0 && !isProcessing && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-center py-8", children: [
1394
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-medium text-gray-700 mb-2", children: "How can I help you today?" }),
1395
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "text-sm text-gray-500 mb-4", children: [
1576
+ chatHistory.length === 0 && !isProcessing && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-center py-8", children: [
1577
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "text-lg font-medium text-gray-700 mb-2", children: "How can I help you today?" }),
1578
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "text-sm text-gray-500 mb-4", children: [
1396
1579
  "Try asking me something like ",
1397
1580
  getContextExample()
1398
1581
  ] })
@@ -1401,14 +1584,14 @@ var ChatMessageList = ({
1401
1584
  const isLastMessage = index === chatHistory.length - 1;
1402
1585
  const isUser = message.role === "user";
1403
1586
  const isError = message.role === "error";
1404
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1587
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1405
1588
  "div",
1406
1589
  {
1407
1590
  ref: isLastMessage ? lastMessageRef : void 0,
1408
1591
  className: `flex flex-col w-full ${isUser ? "items-end" : "items-start"}`,
1409
1592
  children: [
1410
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-xs text-gray-400 mb-1 px-1", children: message.timestamp ? `${isUser ? "Sent" : "Received"} at ${new Date(message.timestamp).toLocaleString()}` : "" }),
1411
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full", children: message.interactive && message.interactiveData ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: `max-w-[85%] ${isUser ? "ml-auto" : "mr-auto"}`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1593
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-xs text-gray-400 mb-1 px-1", children: message.timestamp ? `${isUser ? "Sent" : "Received"} at ${new Date(message.timestamp).toLocaleString()}` : "" }),
1594
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-full", children: message.interactive && message.interactiveData ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `max-w-[85%] ${isUser ? "ml-auto" : "mr-auto"}`, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1412
1595
  InteractiveMessageHandler_default,
1413
1596
  {
1414
1597
  message: message.interactiveData,
@@ -1420,16 +1603,16 @@ var ChatMessageList = ({
1420
1603
  isResponseSubmitted: !!message.isResponseSubmitted,
1421
1604
  parentMessage: message
1422
1605
  }
1423
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1606
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1424
1607
  MessageBubble,
1425
1608
  {
1426
1609
  message,
1427
1610
  isUser
1428
1611
  }
1429
1612
  ) }),
1430
- isUser && message.interactive && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center mt-1 space-x-1 text-xs text-gray-500 italic", children: [
1431
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_outline3.InformationCircleIcon, { className: "h-3 w-3 text-blue-400" }),
1432
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1613
+ isUser && message.interactive && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center mt-1 space-x-1 text-xs text-gray-500 italic", children: [
1614
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_outline4.InformationCircleIcon, { className: "h-3 w-3 text-blue-400" }),
1615
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
1433
1616
  message.request === "form" && "Response to form submission",
1434
1617
  message.request === "select" && "Response to selection prompt",
1435
1618
  message.request === "confirm" && "Response to confirmation prompt"
@@ -1440,29 +1623,29 @@ var ChatMessageList = ({
1440
1623
  message.id || `message-${index}`
1441
1624
  );
1442
1625
  }),
1443
- isProcessing && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1626
+ isProcessing && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1444
1627
  "div",
1445
1628
  {
1446
1629
  ref: processingIndicatorRef,
1447
1630
  className: "flex justify-start my-4",
1448
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "bg-white text-gray-800 border border-gray-200 rounded-lg px-4 py-2 max-w-[85%]", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center", children: [
1449
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-sm", children: processingHint }),
1450
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ml-2 flex space-x-1", children: [
1451
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
1452
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
1453
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "300ms" } })
1631
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "bg-white text-gray-800 border border-gray-200 rounded-lg px-4 py-2 max-w-[85%]", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center", children: [
1632
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm", children: processingHint }),
1633
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ml-2 flex space-x-1", children: [
1634
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
1635
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
1636
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-2 w-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "300ms" } })
1454
1637
  ] })
1455
1638
  ] }) })
1456
1639
  }
1457
1640
  ),
1458
- currentTask && !currentTask.complete && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3", children: [
1459
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-sm text-blue-800 mb-1", children: [
1641
+ currentTask && !currentTask.complete && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mt-4 bg-blue-50 border border-blue-100 rounded-lg p-3", children: [
1642
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-sm text-blue-800 mb-1", children: [
1460
1643
  "Task in progress: Step ",
1461
1644
  currentTask.currentStep,
1462
1645
  " of ",
1463
1646
  currentTask.steps
1464
1647
  ] }),
1465
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full bg-blue-200 rounded-full h-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1648
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-full bg-blue-200 rounded-full h-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1466
1649
  "div",
1467
1650
  {
1468
1651
  className: "bg-blue-500 h-2 rounded-full",
@@ -1477,34 +1660,34 @@ var ChatMessageList = ({
1477
1660
 
1478
1661
  // src/ui/react/components/ConnectionStatus.tsx
1479
1662
  var import_lucide_react2 = require("lucide-react");
1480
- var import_jsx_runtime13 = require("react/jsx-runtime");
1663
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1481
1664
  var ConnectionStatus = ({
1482
1665
  connectionStatus,
1483
1666
  onReconnect
1484
1667
  }) => {
1485
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs", children: [
1486
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-gray-700 font-medium", children: "You are talking with your personal Content Strategist" }),
1487
- connectionStatus === "connected" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center text-green-600", children: [
1488
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.Wifi, { className: "w-3 h-3 mr-1" }),
1489
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Connected" })
1668
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "bg-amber-100 connection-status flex items-center justify-between px-4 py-1 text-xs", children: [
1669
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "text-gray-700 font-medium", children: "You are talking with your personal Content Strategist" }),
1670
+ connectionStatus === "connected" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center text-green-600", children: [
1671
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react2.Wifi, { className: "w-3 h-3 mr-1" }),
1672
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Connected" })
1490
1673
  ] }),
1491
- connectionStatus === "reconnecting" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center text-amber-600", children: [
1492
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.RefreshCw, { className: "w-3 h-3 mr-1 animate-spin" }),
1493
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Reconnecting..." })
1674
+ connectionStatus === "reconnecting" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center text-amber-600", children: [
1675
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react2.RefreshCw, { className: "w-3 h-3 mr-1 animate-spin" }),
1676
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Reconnecting..." })
1494
1677
  ] }),
1495
- connectionStatus === "disconnected" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
1496
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "text-red-600 flex items-center", children: [
1497
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.WifiOff, { className: "w-3 h-3 mr-1" }),
1498
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Disconnected" })
1678
+ connectionStatus === "disconnected" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
1679
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "text-red-600 flex items-center", children: [
1680
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react2.WifiOff, { className: "w-3 h-3 mr-1" }),
1681
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Disconnected" })
1499
1682
  ] }),
1500
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1683
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1501
1684
  "button",
1502
1685
  {
1503
1686
  onClick: onReconnect,
1504
1687
  className: "text-blue-600 hover:text-blue-800 flex items-center",
1505
1688
  children: [
1506
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.RefreshCw, { className: "w-3 h-3 mr-1" }),
1507
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Reconnect" })
1689
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react2.RefreshCw, { className: "w-3 h-3 mr-1" }),
1690
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Reconnect" })
1508
1691
  ]
1509
1692
  }
1510
1693
  )
@@ -1513,7 +1696,7 @@ var ConnectionStatus = ({
1513
1696
  };
1514
1697
 
1515
1698
  // src/ui/react/components/Spinner.tsx
1516
- var import_jsx_runtime14 = require("react/jsx-runtime");
1699
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1517
1700
  var Spinner = ({
1518
1701
  size = "md",
1519
1702
  className = "",
@@ -1525,7 +1708,7 @@ var Spinner = ({
1525
1708
  lg: "h-8 w-8",
1526
1709
  xl: "h-12 w-12"
1527
1710
  };
1528
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1711
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1529
1712
  "svg",
1530
1713
  {
1531
1714
  className: `animate-spin ${sizeClasses[size]} ${color} ${className}`,
@@ -1533,7 +1716,7 @@ var Spinner = ({
1533
1716
  fill: "none",
1534
1717
  viewBox: "0 0 24 24",
1535
1718
  children: [
1536
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1719
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1537
1720
  "circle",
1538
1721
  {
1539
1722
  className: "opacity-25",
@@ -1544,7 +1727,7 @@ var Spinner = ({
1544
1727
  strokeWidth: "4"
1545
1728
  }
1546
1729
  ),
1547
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1730
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1548
1731
  "path",
1549
1732
  {
1550
1733
  className: "opacity-75",